@charset "utf-8";
/* ==========================================================================
   Norris Law — Design System
   Palette locked to approved brand: burgundy #750227, slate #455768.
   Type: Newsreader (display + long-form), Archivo (UI, labels, nav).
   Target: WCAG 2.2 AA.
   ========================================================================== */

/* ---------- Fonts (self-hosted, no third-party requests) ---------- */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/newsreader-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 400 600;
  font-display: swap;
  src: url('/assets/fonts/newsreader-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/archivo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- Tokens ---------- */
:root {
  /* Brand — approved, do not substitute.
     Slate is the primary SURFACE colour (hero, page heads, accents).
     Burgundy is reserved for ACTION: buttons, links, urgent callouts.
     This keeps the burgundy wordmark integrated without red section blocks. */
  --brand: #455768;
  --brand-deep: #37444f;
  --brand-900: #28323b;
  --brand-50: #eef1f4;
  --brand-100: #dfe5ea;

  --burgundy: #750227;
  --burgundy-700: #5c021f;
  --burgundy-900: #3d0114;
  --burgundy-50: #fbf2f4;

  /* Legacy aliases — kept so older rules keep resolving */
  --slate: var(--brand);
  --slate-700: var(--brand-deep);
  --slate-100: var(--brand-50);

  /* Neutrals */
  --ink: #1a1a1a;
  --ink-muted: #55555a;
  --line: #e5e7eb;
  --line-strong: #cfd4da;
  --paper: #ffffff;
  --paper-alt: #f7f7f5;

  /* Type */
  --font-display: 'Newsreader', Georgia, 'Times New Roman', serif;
  --font-ui: 'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  --fs-xs: 0.8125rem;
  --fs-sm: 0.9375rem;
  --fs-base: 1.0625rem;
  --fs-md: clamp(1.125rem, 0.4vw + 1.05rem, 1.25rem);
  --fs-lg: clamp(1.3rem, 0.7vw + 1.15rem, 1.6rem);
  --fs-xl: clamp(1.6rem, 1.3vw + 1.3rem, 2.15rem);
  --fs-2xl: clamp(2rem, 2.2vw + 1.5rem, 3rem);
  /* Hero headline only. The old floor of 2.4rem was larger than a 320-360px
     screen can carry, which pushed the headline into ragged breaks and, on
     narrower phones, past the edge of the hero. */
  --fs-3xl: clamp(1.95rem, 4.6vw + 0.9rem, 4.25rem);

  /* Space */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;
  --sp-7: 3rem;
  --sp-8: 4rem;
  --sp-9: 6rem;

  --shell: 76rem;
  --measure: 68ch;
  --radius: 3px;
  --section-y: clamp(3.5rem, 7vw, 6.5rem);
}

/* ---------- Very large displays ----------
   Bumping a couple of tokens was not enough: on a 3840px monitor a 16-19px
   page inside a 1500px column reads as a postage stamp. The root font size
   itself now grows with the viewport above 1600px, which lifts type, spacing,
   controls, icons and the shell together — every value in this file is
   already rem-based — so the page scales rather than just re-flowing.

   Two things make this safe:
   - `rem` inside a media query always resolves against the *initial* root
     size, never the scaled one, so nothing below 100rem changes and there is
     no feedback loop between the query and the value it sets.
   - The ramp is expressed in rem, not px, so a reader who has raised their
     browser's default text size keeps that increase on top of it.

   Ramp: 1x at 1600px climbing to 1.375x at 3840px, then held. */
@media (min-width: 100rem) {
  :root {
    font-size: clamp(1rem, calc(1rem + (100vw - 100rem) * 0.00268), 1.375rem);
    --shell: 84rem;
  }
}
/* The shell takes discrete steps on top of the ramp so the content column
   keeps gaining share of the screen as the display gets wider, instead of
   holding a constant fraction. Roughly: 84% of a 1600px screen, 73% at
   2240px, 66% at 2880px, 56% at 3840px. */
@media (min-width: 140rem) { :root { --shell: 92rem; } }
@media (min-width: 180rem) { :root { --shell: 98rem; } }

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-display);
  font-size: var(--fs-base);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, picture, svg { max-width: 100%; height: auto; display: block; }
h1, h2, h3, h4 { margin: 0; font-weight: 600; line-height: 1.12; letter-spacing: -0.015em; }
p, ul, ol { margin: 0 0 var(--sp-4); }
a { color: var(--burgundy); text-underline-offset: 0.18em; text-decoration-thickness: 1px; }
a:hover { color: var(--burgundy-700); }

/* Focus — visible on every interactive element (WCAG 2.4.7 / 2.4.11) */
:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 2px;
  border-radius: 2px;
}
/* On dark surfaces the outline must switch to white to stay visible. */
.hero :focus-visible,
.pagehead :focus-visible,
.cta :focus-visible,
.topbar :focus-visible,
.site-footer :focus-visible { outline-color: #fff; }

/* ---------- Layout primitives ---------- */
.shell { width: min(100% - 2.5rem, var(--shell)); margin-inline: auto; }
.section { padding-block: var(--section-y); }
.section--alt { background: var(--paper-alt); }
.section--tint { background: var(--brand-50); }
.stack > * + * { margin-top: var(--sp-4); }
.prose { max-width: var(--measure); }
.prose h2 { font-size: var(--fs-xl); margin-top: var(--sp-7); margin-bottom: var(--sp-4); }
.prose h3 { font-size: var(--fs-lg); margin-top: var(--sp-6); margin-bottom: var(--sp-3); }
.prose > :first-child { margin-top: 0; }
.prose ul, .prose ol { padding-left: 1.25em; }
.prose li { margin-bottom: var(--sp-2); }
.prose li::marker { color: var(--brand); }
.lede { font-size: var(--fs-md); color: var(--ink-muted); line-height: 1.55; }

/* ---------- Eyebrow: encodes the governing statute / real label ---------- */
.eyebrow {
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--slate);
  margin: 0 0 var(--sp-3);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}
.eyebrow::before {
  content: "";
  width: 1.75rem;
  height: 1px;
  background: var(--brand);
  flex: none;
}
/* Dark surfaces — scoped explicitly rather than relying on a wrapper class. */
.hero .eyebrow,
.pagehead .eyebrow,
.cta .eyebrow { color: rgba(255, 255, 255, 0.96); }
.hero .eyebrow::before,
.pagehead .eyebrow::before,
.cta .eyebrow::before { background: rgba(255, 255, 255, 0.7); }

/* ---------- Skip link ---------- */
.skip-link {
  position: absolute;
  left: var(--sp-4);
  top: -100%;
  z-index: 200;
  background: var(--burgundy);
  color: #fff;
  padding: var(--sp-3) var(--sp-5);
  font-family: var(--font-ui);
  font-weight: 600;
  text-decoration: none;
  border-radius: 0 0 var(--radius) var(--radius);
}
.skip-link:focus { top: 0; color: #fff; }

/* ---------- Header ---------- */
.topbar {
  background: var(--brand);
  color: #fff;
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  letter-spacing: 0.02em;
}
.topbar__inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-5);
  align-items: center;
  justify-content: center;
  padding-block: var(--sp-2);
  text-align: center;
}
.topbar a { color: #fff; text-decoration: none; font-weight: 600; }
.topbar a:hover { color: #fff; text-decoration: underline; }
/* The middle dot only makes sense while both items share a line. */
@media (max-width: 47.99rem) {
  .topbar__inner > [aria-hidden="true"] { display: none; }
  .topbar__inner { gap: 0 var(--sp-4); line-height: 1.5; }
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(255, 255, 255, 0.97);
  backdrop-filter: saturate(1.4) blur(8px);
  border-bottom: 1px solid var(--line);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-5);
  padding-block: var(--sp-4);
}
/* The logo file is cropped tight to the wordmark (603x91), so these widths are
   the true visible size — the old file carried ~12% transparent padding.
   All logo sizing lives here, narrowest last, so the cascade resolves in one
   place rather than being overridden by later blocks further down the file. */
.brand { display: inline-flex; align-items: center; flex: none; }
/* rem, not px, so the wordmark rides the large-display ramp with the nav
   beside it rather than shrinking against it. 15.6rem is the same 250px at
   the default root size. */
.brand img { width: 15.6rem; height: auto; }
@media (max-width: 78rem)    { .brand img { width: 200px; } }  /* nav needs room */
/* Below the desktop nav breakpoint the header carries only the wordmark, the
   call button, and Menu, so the logo can take most of the width back. Each
   step is the widest that still leaves the two controls on the same row. */
@media (max-width: 61.99rem) { .brand img { width: 205px; } }  /* burger + phone */
@media (max-width: 26rem)    { .brand img { width: 185px; } }
@media (max-width: 22.5rem)  { .brand img { width: 158px; } }
@media (max-width: 20.5rem)  { .brand img { width: 128px; } }  /* 320px devices */
.nav { display: flex; align-items: center; gap: var(--sp-2); }
.nav__list { display: flex; align-items: center; gap: var(--sp-1); list-style: none; margin: 0; padding: 0; }
.nav__link {
  display: block;
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius);
  white-space: nowrap;
}
.nav__link:hover { color: var(--burgundy); background: var(--burgundy-50); }
.nav__link[aria-current="page"] { color: var(--burgundy); font-weight: 600; box-shadow: inset 0 -2px 0 var(--burgundy); }

/* Dropdown */
.nav__item { position: relative; }
.nav__toggle {
  font: inherit;
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--ink);
  background: none;
  border: 0;
  cursor: pointer;
  padding: var(--sp-2) var(--sp-3);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  border-radius: var(--radius);
}
.nav__toggle:hover { color: var(--burgundy); background: var(--burgundy-50); }
.nav__toggle svg { width: 0.7em; height: 0.7em; transition: transform 0.2s ease; }
.nav__toggle[aria-expanded="true"] svg { transform: rotate(180deg); }
.nav__panel {
  display: none;
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  min-width: 17rem;
  background: #fff;
  border: 1px solid var(--line);
  border-top: 3px solid var(--brand);
  border-radius: var(--radius);
  box-shadow: 0 18px 40px -12px rgba(26, 26, 26, 0.22);
  padding: var(--sp-3);
  list-style: none;
  margin: 0;
}
.nav__toggle[aria-expanded="true"] + .nav__panel { display: block; }
/* The panel is offset 0.5rem below the toggle, and that gap belongs to neither
   element. Without this bridge the pointer crosses unhovered space on its way
   down, `mouseleave` fires on .nav__item, and the menu closes mid-travel.
   0.7rem covers the 0.5rem offset plus the 3px brand border. */
.nav__panel::before {
  content: "";
  position: absolute;
  bottom: 100%;
  left: 0;
  right: 0;
  height: 0.7rem;
}
.nav__panel a {
  display: block;
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  color: var(--ink);
  text-decoration: none;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius);
}
.nav__panel a:hover { background: var(--burgundy-50); color: var(--burgundy); }

.nav__burger { display: none; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  padding: 0.85em 1.6em;
  border-radius: var(--radius);
  border: 1.5px solid transparent;
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
  min-height: 44px; /* WCAG 2.5.8 target size */
}
.btn--primary { background: var(--burgundy); color: #fff; border-color: var(--burgundy); }
.btn--primary:hover { background: var(--burgundy-700); border-color: var(--burgundy-700); color: #fff; }
.btn--ghost { background: transparent; color: var(--burgundy); border-color: var(--line-strong); }
.btn--ghost:hover { border-color: var(--burgundy); background: var(--burgundy-50); color: var(--burgundy); }
.btn--onDark { background: #fff; color: var(--burgundy); border-color: #fff; }
.btn--onDark:hover { background: rgba(255, 255, 255, 0.88); color: var(--burgundy-900); }
.btn--outlineDark { background: transparent; color: #fff; border-color: rgba(255, 255, 255, 0.55); }
.btn--outlineDark:hover { background: rgba(255, 255, 255, 0.12); color: #fff; border-color: #fff; }
.btn-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
/* Once a pair of buttons wraps onto two rows they size to their own labels and
   read as a mismatched stack. Below 40rem every button row becomes a single
   full-width column instead, which also gives each one a full-width tap
   target. */
@media (max-width: 40rem) {
  .btn-row { display: grid; gap: var(--sp-3); }
  .btn-row .btn { width: 100%; }
}

/* ---------- Hero ----------
   Lady Justice photograph carried over from the previous site. The subject
   sits on the right, so the overlay is weighted heavily to the left where
   the headline sits, and lifts toward the right to let the statue read. */
.hero {
  color: #fff;
  position: relative;
  overflow: hidden;
  /* Fill the screen below the masthead so the photograph runs to the bottom
     edge of the first view and the next section never peeks in as a white
     strip. --head-h is the measured topbar + header height, set by site.js and
     kept current on resize; the literal here is only the pre-script fallback.
     svh (not vh) so mobile browser chrome does not overshoot the viewport. */
  min-height: calc(100vh - var(--head-h, 7.5rem));
  min-height: calc(100svh - var(--head-h, 7.5rem));
  /* Grid rather than flex: .hero__inner keeps its percentage left margin,
     which still resolves against the full hero width. align-content centres
     the block when there is surplus height and is a no-op when there is not. */
  display: grid;
  align-content: center;
  background-color: var(--brand);
  background-image:
    linear-gradient(100deg,
      rgba(58, 74, 89, 0.98) 0%,
      rgba(60, 76, 92, 0.96) 38%,
      rgba(69, 87, 104, 0.78) 62%,
      rgba(69, 87, 104, 0.40) 100%),
    image-set(url('/assets/img/hero-bg.webp') type('image/webp'),
              url('/assets/img/hero-bg.png') type('image/png'));
  background-size: cover, cover;
  background-position: center, center right;
  background-repeat: no-repeat, no-repeat;
}
/* Single column of text, aligned to the shell's left edge. Not a grid —
   an earlier grid `gap` was spacing every child apart and ballooning the
   hero to over 1100px tall. */
.hero__inner {
  position: relative;
  z-index: 1;
  padding-block: clamp(2.25rem, 4vw, 3.75rem);
  padding-inline: 1.25rem;
  max-width: min(46rem, 100%);
  margin-left: max(1.25rem, calc(50% - var(--shell) / 2));
}
.hero__inner > * { margin-bottom: 0; }
.hero__inner > * + * { margin-top: var(--sp-5); }
.hero h1 { margin-top: var(--sp-4); }
.hero__lede { margin-top: var(--sp-4); }
.credrail { margin-top: var(--sp-5); padding-top: var(--sp-4); }
/* Below the two-column breakpoint the statue is mostly cropped out, so the
   overlay goes flat and darker to keep the headline legible. */
@media (max-width: 61.99rem) {
  .hero {
    background-image:
      linear-gradient(180deg, rgba(69, 87, 104, 0.93), rgba(69, 87, 104, 0.88)),
      image-set(url('/assets/img/hero-bg.webp') type('image/webp'),
                url('/assets/img/hero-bg.png') type('image/png'));
    background-position: center, center 30%;
  }
  .hero__inner { margin-inline: auto; max-width: none; }
}
/* Once the hero is the two-column composition, the inner block's own inline
   padding is doing nothing except pushing the headline off the shell's left
   edge — 28px of it at 4K, enough to read as a misalignment against the
   wordmark and every section below. The margin already supplies the gutter. */
@media (min-width: 62rem) {
  .hero__inner { padding-inline: 0; }
}
/* Very large displays. Filling the viewport is right up to a point: at 4K the
   hero became an 1830px band holding a 700px block of text, and the page read
   as an empty poster with nothing to suggest it continued. Capping the height
   leaves the top of the attorney band showing without shrinking the
   photograph — `cover` is driven by width here, so the crop is unchanged. */
@media (min-width: 100rem) {
  .hero {
    min-height: min(calc(100vh - var(--head-h, 7.5rem)), 70rem);
    min-height: min(calc(100svh - var(--head-h, 7.5rem)), 70rem);
  }
}
/* The global .btn-row rule at 40rem now covers the hero pair as well. */
.hero h1 {
  font-size: var(--fs-3xl);
  font-weight: 500;
  letter-spacing: -0.026em;
  line-height: 1.06;
  text-wrap: balance;
  /* Nothing in this headline should ever be clipped by the hero's own
     overflow, whatever the device text size. */
  overflow-wrap: break-word;
  /* The headline runs over a photograph on its right half. One tight, dark
     shadow firms the stroke edges there without reading as an applied effect
     on the flat slate at the left. */
  text-shadow: 0 1px 3px rgba(18, 24, 30, 0.4);
}
/* Newsreader's italic reads optically lighter than its roman at the same
   weight, and this line was set lighter still (400 against 500), so at
   display size the hairlines thinned out and the accent fell away from the
   line above it. Matching the weight up and easing the negative tracking
   keeps the italic voice and returns the contrast. */
/* Block, not inline: the italic clause is the payoff line and has to start on
   its own row at every width. Left inline, `text-wrap: balance` pulled it up
   beside the end of the roman clause on narrow screens ("line, experience")
   and the sentence stopped scanning. */
.hero h1 em {
  display: block;
  font-style: italic;
  font-weight: 600;
  letter-spacing: -0.008em;
}
.hero__lede {
  font-size: var(--fs-md);
  color: rgba(255, 255, 255, 0.94);
  line-height: 1.6;
  max-width: 46ch;
  margin-top: var(--sp-5);
  text-shadow: 0 1px 2px rgba(18, 24, 30, 0.35);
}
/* The tenure is the one fact the client wants carried out of the hero, so it
   is emphasised in place rather than added as a fourth element: full-strength
   white, a heavier stroke, and a hairline rule under the phrase. The
   underline is a text-decoration, not a border, so it follows the phrase
   correctly when the line wraps mid-clause on a phone. */
.hero__lede strong {
  font-weight: 600;
  color: #fff;
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.5);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}
.hero__cta { margin-top: var(--sp-6); }

/* Credential rail — masthead-style, single line of facts */
.credrail {
  margin-top: var(--sp-6);
  padding-top: var(--sp-5);
  border-top: 1px solid rgba(255, 255, 255, 0.28);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3) var(--sp-5);
  font-family: var(--font-ui);
  /* One step up from --fs-xs, with the tracking eased to match, so the rail
     itself carries at a glance. Measured from 48rem to 4K: the three facts
     still hold a single masthead line inside the 46rem text column. */
  font-size: var(--fs-sm);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.95);
}
.credrail li { list-style: none; }
/* Lead fact, set as a hard-edged chip so the years read at a glance from
   across the rail. Outline only — a filled block would compete with the two
   buttons directly above it. */
.credrail__lead {
  font-weight: 700;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 2px;
  padding: 0.4em 0.75em;
}
.credrail { padding-left: 0; margin-bottom: 0; }

/* Short phone viewports. The hero carries an eyebrow, a three-line headline,
   a two-sentence lede, two stacked buttons and the credential rail, which on a
   320x568 screen pushed the call button below the fold. Tightening the rhythm,
   rather than dropping content, brings the primary action back into the first
   screenful. Placed after the base hero rules so these win the cascade. */
@media (max-width: 30rem) {
  .hero__inner { padding-block: 1.5rem 2rem; }
  .hero__inner > * + * { margin-top: var(--sp-4); }
  .hero h1 { margin-top: var(--sp-3); }
  .hero__lede { margin-top: var(--sp-3); font-size: var(--fs-base); line-height: 1.55; }
  .hero__cta { margin-top: var(--sp-5); }
  .hero .eyebrow { letter-spacing: 0.06em; gap: var(--sp-2); margin-bottom: 0; }
  .hero .eyebrow::before { width: 1.1rem; }
  /* The rail carries the larger type from 30rem up; on a phone it drops back
     to --fs-xs and a tighter chip, where the three facts stack anyway and
     every pixel is holding the call button above the fold. */
  .credrail { margin-top: var(--sp-5); padding-top: var(--sp-4); gap: var(--sp-2) var(--sp-4); font-size: var(--fs-xs); letter-spacing: 0.09em; }
  .credrail__lead { padding: 0.3em 0.6em; }
}
/* Very short phone viewports (a 320x568 handset, or any phone in landscape).
   Gated on height as well as width so it cannot reach a modern portrait phone,
   where the hero already resolves comfortably. Buys back the few pixels that
   were pushing the call button past the fold. */
@media (max-width: 30rem) and (max-height: 40rem) {
  .hero__inner { padding-block: 1rem 1.25rem; }
  .hero__inner > * + * { margin-top: var(--sp-3); }
  .hero__lede { font-size: var(--fs-sm); line-height: 1.5; }
  .hero__cta { margin-top: var(--sp-4); }
  .credrail { margin-top: var(--sp-4); padding-top: var(--sp-3); }
}

/* Portrait — hard-edged frame, not a soft card */
.portrait { position: relative; justify-self: center; max-width: 25rem; width: 100%; }
.portrait img {
  width: 100%;
  border-radius: 2px;
  filter: saturate(0.92) contrast(1.04);
}
/* Offset frame. Now only used on the About page, so it takes a neutral
   line colour rather than the white it used inside the old burgundy hero. */
.portrait::before {
  content: "";
  position: absolute;
  inset: -0.75rem -0.75rem 0.75rem 0.75rem;
  border: 1px solid var(--line-strong);
  border-radius: 2px;
  pointer-events: none;
}
.hero .portrait::before { border-color: rgba(255, 255, 255, 0.4); }
.portrait__plate {
  position: absolute;
  left: 0;
  bottom: 0;
  transform: translateY(35%);
  background: #fff;
  color: var(--ink);
  padding: var(--sp-3) var(--sp-5);
  border-left: 3px solid var(--brand);
  box-shadow: 0 12px 30px -10px rgba(0, 0, 0, 0.35);
  max-width: 92%;
}
.portrait__plate strong {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-base);
  font-weight: 600;
  line-height: 1.2;
}
.portrait__plate span {
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
@media (max-width: 61.99rem) {
  .portrait { margin-bottom: var(--sp-6); }
}

/* ---------- Photographic surfaces ----------
   Photographs are a surface treatment here, not content: the same slate band
   the page already used, with a courthouse behind it. That is why they are
   background images and not <img>. It also means they scale with the band at
   every width — `cover` cannot produce the 2156px-wide plate that a fixed
   ratio <figure> did on a 4K screen.

   Each plate is a .photo--* class rather than an inline custom property,
   because every one carries a webp/jpeg pair through image-set() and that does
   not fit legibly in a style attribute. Same fallback pattern as the hero.

   The scrim is directional, the way the hero's is, and for the same reason.
   Anything uniform — an even alpha wash, or `multiply` against the brand
   slate — has to be heavy enough for white text at the darkest point it
   covers, and applying that weight across the whole frame turns these pale
   courthouse interiors into a flat slate band with no picture in it. Weighting
   it to the left instead buys full contrast under the text and lets the right
   side of the photograph come through at close to its own value. */
.pagehead.pagehead--photo,
.cta.cta--photo {
  background-color: var(--brand-900);
  background-image:
    linear-gradient(90deg,
      rgba(38, 48, 57, 0.95) 0%,
      rgba(38, 48, 57, 0.90) 42%,
      rgba(44, 55, 65, 0.48) 72%,
      rgba(48, 60, 71, 0.28) 100%),
    var(--surface-photo);
  background-size: cover, cover;
  background-position: center, center right;
  background-repeat: no-repeat, no-repeat;
}
/* A photograph needs vertical room. At the flat band's natural height `cover`
   crops a ~300px horizontal slice out of the middle of a 2400px-tall plate,
   which is almost always a featureless patch of wall — the reason the first
   attempt read as plain slate. These bands are roughly doubled so the frame
   carries enough of the picture to be legible as one. */
.pagehead.pagehead--photo .pagehead__inner { padding-block: clamp(4rem, 8vw, 7rem); }
.cta.cta--photo .cta__inner { padding-block: clamp(4rem, 7vw, 6.5rem); }
/* Below the two-column breakpoint the text runs the full width of the band,
   so there is no clear side to hand the photograph. The scrim goes flat and
   heavy, and the picture becomes texture rather than subject. */
@media (max-width: 61.99rem) {
  .pagehead.pagehead--photo,
  .cta.cta--photo {
    background-image:
      linear-gradient(180deg, rgba(38, 48, 57, 0.93), rgba(44, 55, 65, 0.90)),
      var(--surface-photo);
    background-position: center, center;
  }
}

/* A background image has no alt text, and should not: it is decorative, and
   assistive technology is right to ignore it. The credit therefore has to be
   real text in the page. Small and quiet, but present and selectable. */
.photo-credit {
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  letter-spacing: 0.04em;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.74);
  margin: var(--sp-6) 0 0;
  max-width: 62ch;
}
.photo-credit a { color: rgba(255, 255, 255, 0.74); text-decoration: underline; }
.photo-credit a:hover { color: #fff; }

/* The plates. All four are the Tallahassee federal courthouse or the Historic
   Capitol, photographed by Carol M. Highsmith; the credit under each band
   names the building. Assigned by what the page is about: the corridor is the
   door a defendant walks through, the lobby stair is the building a family
   case is heard in, the Capitol is the state whose statutes the injury pages
   spend their time explaining. The CTA plate is the one decorative choice —
   a call to action does not need its picture to argue anything. */
.photo--corridor {
  --surface-photo: image-set(
    url('/assets/img/courthouse-corridor.webp') type('image/webp'),
    url('/assets/img/courthouse-corridor.jpg') type('image/jpeg'));
}
.photo--staircase {
  --surface-photo: image-set(
    url('/assets/img/courthouse-staircase.webp') type('image/webp'),
    url('/assets/img/courthouse-staircase.jpg') type('image/jpeg'));
}
.photo--stairs {
  --surface-photo: image-set(
    url('/assets/img/courthouse-stairs.webp') type('image/webp'),
    url('/assets/img/courthouse-stairs.jpg') type('image/jpeg'));
}
.photo--capitol {
  --surface-photo: image-set(
    url('/assets/img/historic-capitol.webp') type('image/webp'),
    url('/assets/img/historic-capitol.jpg') type('image/jpeg'));
}

/* ---------- Page header (interior pages) ---------- */
.pagehead { background: var(--brand); color: #fff; }
.pagehead__inner { padding-block: clamp(2.5rem, 5vw, 4rem); }
.pagehead h1 { font-size: var(--fs-2xl); font-weight: 500; letter-spacing: -0.025em; max-width: 22ch; text-wrap: balance; }
.pagehead__lede { color: rgba(255, 255, 255, 0.94); font-size: var(--fs-md); line-height: 1.6; max-width: 58ch; margin-top: var(--sp-4); margin-bottom: 0; }

/* ---------- Breadcrumbs ---------- */
.crumbs { font-family: var(--font-ui); font-size: var(--fs-xs); padding-block: var(--sp-3); border-bottom: 1px solid var(--line); }
.crumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: 0; padding: 0; }
.crumbs li { display: flex; align-items: center; gap: var(--sp-2); color: var(--ink-muted); }
.crumbs li + li::before { content: "/"; color: var(--line-strong); }
.crumbs a { color: var(--ink-muted); text-decoration: none; }
.crumbs a:hover { color: var(--burgundy); text-decoration: underline; }
.crumbs [aria-current="page"] { color: var(--ink); }

/* ---------- Signature: the process spine ----------
   A real sequence — Florida procedure, in order. Numbering is used here
   because the order genuinely carries information the reader needs. */
.spine { list-style: none; margin: 0; padding: 0; position: relative; }
.spine::before {
  content: "";
  position: absolute;
  left: 1.15rem;
  top: 0.6rem;
  bottom: 0.6rem;
  width: 1px;
  background: linear-gradient(180deg, var(--brand), rgba(69, 87, 104, 0.15));
}
.spine__step { position: relative; padding-left: 3.75rem; padding-bottom: var(--sp-6); }
.spine__step:last-child { padding-bottom: 0; }
.spine__num {
  position: absolute;
  left: 0;
  top: 0;
  width: 2.3rem;
  height: 2.3rem;
  border-radius: 50%;
  background: #fff;
  border: 1px solid var(--brand);
  color: var(--brand);
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  font-weight: 700;
  display: grid;
  place-items: center;
  letter-spacing: 0;
}
.spine__step h3 { font-size: var(--fs-lg); margin-bottom: var(--sp-2); }
.spine__step p { color: var(--ink-muted); margin-bottom: 0; max-width: 62ch; }
.section--alt .spine__num { background: var(--paper-alt); }
.section--tint .spine__num { background: var(--brand-50); }

/* ---------- Attorney band ----------
   Sits directly under the hero. The hero photograph occupies the right side,
   so Toby's portrait moved here rather than competing with the statue. */
.attorney { background: var(--paper-alt); border-bottom: 1px solid var(--line); }
.attorney__inner {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3.5rem);
  align-items: center;
  padding-block: clamp(2.5rem, 4vw, 4rem);
}
@media (min-width: 48rem) {
  .attorney__inner { grid-template-columns: auto 1fr; }
}
.attorney__photo {
  width: clamp(8rem, 20vw, 12.5rem);
  flex: none;
  position: relative;
}
.attorney__photo img {
  width: 100%;
  border-radius: 2px;
  border-bottom: 3px solid var(--brand);
}
.attorney__name {
  font-size: var(--fs-xl);
  font-weight: 500;
  letter-spacing: -0.02em;
  margin-bottom: var(--sp-2);
}
.attorney__role {
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--brand);
  margin-bottom: var(--sp-4);
}
.attorney__bio { max-width: 60ch; margin-bottom: var(--sp-5); }

/* ---------- Cards / grids ---------- */
/* min() guard: without it the track minimum (19rem / 17rem) is larger than a
   narrow container and the grid overflows the viewport on 320px devices. */
.grid { display: grid; gap: var(--sp-5); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr)); }
/* On a wide shell a 17rem minimum lets four and then five cards onto a row,
   which turns a six-card set into 5 + 1 and reads as a mistake. Raising the
   minimum caps the row at three across every large size. Still auto-fit, so
   pages with only two cards keep collapsing to two full-width tracks rather
   than sitting in two thirds of the row. */
@media (min-width: 100rem) {
  .grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(25rem, 100%), 1fr)); }
}

.card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--sp-5);
  display: flex;
  flex-direction: column;
  transition: border-color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
}
.card:hover { border-color: var(--brand); box-shadow: 0 14px 34px -18px rgba(69, 87, 104, 0.45); transform: translateY(-2px); }
.card h3 { font-size: var(--fs-lg); margin-bottom: var(--sp-3); }
.card h3 a { color: var(--ink); text-decoration: none; }
.card h3 a::after { content: ""; position: absolute; inset: 0; } /* whole-card click target */
.card { position: relative; }
.card:hover h3 a { color: var(--burgundy); }
.card p { color: var(--ink-muted); font-size: var(--fs-sm); margin-bottom: var(--sp-4); }
.card__more {
  margin-top: auto;
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--burgundy);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

/* ---------- Stat / proof strip ---------- */
.proof { display: grid; gap: var(--sp-5); grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
.proof__item { border-left: 2px solid var(--brand); padding-left: var(--sp-4); }
.proof__item strong { display: block; font-size: var(--fs-xl); font-weight: 600; line-height: 1.1; letter-spacing: -0.02em; }
.proof__item span { font-family: var(--font-ui); font-size: var(--fs-sm); color: var(--ink-muted); }

/* ---------- Testimonials ----------
   These run eight to ten lines each. Set in italic they were slow reading, so
   the body is roman now and a hanging quote mark carries the pull-quote
   signal the italic used to. */
.quote { border-top: 2px solid var(--brand); padding-top: var(--sp-5); }
.quote blockquote {
  margin: 0 0 var(--sp-4);
  font-size: var(--fs-md);
  line-height: 1.68;
  color: var(--ink);
}
.quote blockquote::before {
  content: "\201C";
  display: block;
  font-family: var(--font-display);
  font-size: 3.75rem;
  font-weight: 600;
  line-height: 0.72;
  color: var(--brand);
  opacity: 0.38;
  margin-bottom: var(--sp-2);
}
.quote figcaption { font-family: var(--font-ui); font-size: var(--fs-sm); }
.quote figcaption strong { display: block; font-weight: 600; }
.quote figcaption span { color: var(--ink-muted); font-size: var(--fs-xs); }

/* Lead testimonial. The section sits high on the home page and this quote is
   the thing it is built around, so it takes a white card against the tinted
   band, a heavier top rule, and a size step above the supporting pair. */
.quote--lead {
  background: var(--paper);
  border: 1px solid var(--line);
  border-top: 3px solid var(--brand);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 3.5vw, 2.75rem);
  margin: 0 0 var(--sp-6);
  box-shadow: 0 18px 44px -30px rgba(26, 26, 26, 0.5);
}
/* The card runs the full shell for prominence; the text inside still has to
   hold a readable measure. */
.quote--lead blockquote { margin-bottom: 0; font-size: var(--fs-md); line-height: 1.65; max-width: 70ch; }
.quote--lead blockquote p { margin-bottom: var(--sp-4); }
.quote--lead blockquote p:last-child { margin-bottom: 0; }
.quote--lead blockquote::before { font-size: 4.5rem; line-height: 0.75; margin-bottom: var(--sp-1); }
.quote--lead figcaption {
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line);
  font-size: var(--fs-md);
}
.quote--lead figcaption span { font-size: var(--fs-sm); }
/* Wide screens: the quote holds its measure and the attribution takes the
   column it would otherwise leave empty. */
@media (min-width: 62rem) {
  .quote--lead {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(11rem, 15rem);
    gap: clamp(2rem, 4vw, 3.5rem);
    align-items: start;
  }
  .quote--lead blockquote { max-width: none; }
  .quote--lead figcaption {
    margin-top: 0;
    padding-top: 0.35rem;
    padding-left: clamp(1.5rem, 2.5vw, 2.5rem);
    border-top: 0;
    border-left: 1px solid var(--line);
  }
}
/* Supporting pair sits on the tint, so the card border is unnecessary. */
.section--tint .grid .quote { border-top-color: var(--brand); }
.testimonials__note { margin-top: var(--sp-6); max-width: 80ch; margin-bottom: 0; }

.disclaimer { font-family: var(--font-ui); font-size: var(--fs-xs); color: var(--ink-muted); line-height: 1.6; }

/* Form disclaimer. The notice that submitting creates no attorney-client
   relationship is the one piece of fine print on this site that carries real
   consequence for the reader, so it does not get set as fine print: full body
   size, full-strength ink, and a burgundy rule marking it as a notice rather
   than another muted footnote. */
.disclaimer--notice {
  font-size: var(--fs-sm);
  color: var(--ink);
  background: var(--burgundy-50);
  border-left: 3px solid var(--burgundy);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: var(--sp-4) var(--sp-5);
  margin-bottom: 0;
}
.disclaimer--notice strong { color: var(--burgundy); }

/* ---------- Definition list (folded practice topics) ---------- */
.deflist { margin: 0 0 var(--sp-4); }
.deflist dt {
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--ink);
  margin-top: var(--sp-5);
  padding-left: var(--sp-4);
  border-left: 2px solid var(--brand);
}
.deflist dt:first-of-type { margin-top: 0; }
.deflist dd {
  margin: var(--sp-2) 0 0;
  padding-left: calc(var(--sp-4) + 2px);
  color: var(--ink-muted);
  max-width: var(--measure);
}
/* The definition body is muted by default, which is right for prose but wrong
   when it leads with a proper noun the reader is scanning for — a firm name in
   the About page history. Full-strength ink returns that contrast. */
.deflist dd strong { color: var(--ink); }

/* ---------- Callout ---------- */
.callout {
  background: var(--slate-100);
  border-left: 3px solid var(--slate);
  padding: var(--sp-5);
  margin-bottom: var(--sp-6);
  border-radius: 0 var(--radius) var(--radius) 0;
}
.callout > :last-child { margin-bottom: 0; }
.callout--urgent { background: var(--burgundy-50); border-left-color: var(--burgundy); }

/* ---------- FAQ ---------- */
.faq { border-top: 1px solid var(--line); }
.faq__item { border-bottom: 1px solid var(--line); }
.faq__item summary {
  cursor: pointer;
  list-style: none;
  padding: var(--sp-5) 3rem var(--sp-5) 0;
  position: relative;
  font-size: var(--fs-md);
  font-weight: 600;
  line-height: 1.35;
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary::after {
  content: "";
  position: absolute;
  right: 0.5rem;
  top: 50%;
  width: 0.65rem;
  height: 0.65rem;
  border-right: 2px solid var(--brand);
  border-bottom: 2px solid var(--brand);
  transform: translateY(-70%) rotate(45deg);
  transition: transform 0.2s ease;
}
.faq__item[open] summary::after { transform: translateY(-30%) rotate(-135deg); }
.faq__item summary:hover { color: var(--burgundy); }
.faq__answer { padding-bottom: var(--sp-5); color: var(--ink-muted); max-width: var(--measure); }
.faq__answer > :last-child { margin-bottom: 0; }

/* ---------- CTA band ---------- */
.cta {
  background: var(--brand);
  color: #fff;
}
.cta__inner {
  padding-block: clamp(2.75rem, 5vw, 4.5rem);
  display: grid;
  gap: var(--sp-5);
  align-items: center;
}
@media (min-width: 52rem) {
  .cta__inner { grid-template-columns: 1.4fr auto; gap: var(--sp-8); }
}
.cta h2 { font-size: var(--fs-xl); font-weight: 500; letter-spacing: -0.02em; text-wrap: balance; }
.cta p { color: rgba(255, 255, 255, 0.94); line-height: 1.6; margin-top: var(--sp-3); margin-bottom: 0; max-width: 54ch; }

/* ---------- Forms ---------- */
.form { display: grid; gap: var(--sp-5); }
.form__row { display: grid; gap: var(--sp-5); }
@media (min-width: 40rem) { .form__row--2 { grid-template-columns: 1fr 1fr; } }
.field { display: grid; gap: var(--sp-2); }
.field label { font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 600; }
.field .req { color: var(--burgundy); }
.field .hint { font-family: var(--font-ui); font-size: var(--fs-xs); color: var(--ink-muted); }
.field input, .field select, .field textarea {
  font: inherit;
  font-size: var(--fs-base);
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: 0.75rem 0.9rem;
  width: 100%;
  min-height: 44px;
}
.field textarea { min-height: 9rem; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--brand); }
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"], .field select[aria-invalid="true"] {
  border-color: #b3261e;
  background: #fef6f5;
}
.field__error { font-family: var(--font-ui); font-size: var(--fs-xs); color: #b3261e; font-weight: 600; min-height: 0; }
.field__error:empty { display: none; }
.form__status { font-family: var(--font-ui); font-size: var(--fs-sm); padding: var(--sp-4); border-radius: var(--radius); }
.form__status:empty { display: none; }
.form__status[data-state="error"] { background: #fef6f5; border: 1px solid #b3261e; color: #8c1d18; }
.form__status[data-state="ok"] { background: #f0f7f2; border: 1px solid #2e6b45; color: #1d4a2e; }
.form__status[data-state="sending"] { background: var(--slate-100); border: 1px solid var(--line-strong); color: var(--slate-700); }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* Turnstile. The widget renders in a fixed-size iframe that Cloudflare styles,
   so this only reserves its space and keeps the form from jumping when the
   challenge finishes loading. */
.turnstile-field { gap: var(--sp-2); }
.turnstile-field .cf-turnstile { min-height: 65px; }
.turnstile-field iframe { max-width: 100%; }

/* ---------- Contact page layout ----------
   Two columns on desktop: form left, details and the urgent-call block right.
   Single column on mobile, where source order put "if your matter is urgent,
   call rather than using this form" *below* the entire form — advice the
   reader only reached after doing the thing it advises against. Below the
   two-column breakpoint the call block is hoisted above the form, which also
   matches the page lede ("Call for the fastest response"). `display: contents`
   promotes the aside's children to grid items so `order` can reach them
   without duplicating the block in the markup. */
@media (max-width: 47.99rem) {
  .contact-layout > aside { display: contents; }
  .contact-layout .callout {
    order: -1;
    margin-top: 0 !important;   /* beats the inline margin that spaced it below */
    margin-bottom: 0;
  }
  .contact-layout > div { order: 0; }
  .contact-layout .contactcard { order: 1; }
}

/* ---------- Contact detail block ---------- */
.contactcard { border: 1px solid var(--line); border-top: 3px solid var(--brand); padding: var(--sp-6); background: #fff; }
.contactcard dt {
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--slate);
  margin-top: var(--sp-5);
}
.contactcard dt:first-of-type { margin-top: 0; }
.contactcard dd { margin: var(--sp-2) 0 0; font-size: var(--fs-md); }
.contactcard dd a { text-decoration: none; font-weight: 600; }
.contactcard dd a:hover { text-decoration: underline; }

/* ---------- Footer ---------- */
/* The CTA band directly above is the same slate, so a hairline keeps the two
   from reading as one undifferentiated block. */
.site-footer {
  background: var(--brand);
  color: rgba(255, 255, 255, 0.92);
  font-size: var(--fs-sm);
  border-top: 1px solid rgba(255, 255, 255, 0.28);
}
.site-footer__inner { padding-block: var(--sp-8) var(--sp-6); display: grid; gap: var(--sp-7); }
@media (min-width: 52rem) { .site-footer__inner { grid-template-columns: 1.3fr 1fr 1fr 1fr; } }
.site-footer h2 {
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #fff;
  margin-bottom: var(--sp-4);
}
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: var(--sp-2); }
.site-footer a { color: rgba(255, 255, 255, 0.92); text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
/* The wordmark is transparent-background burgundy, which all but disappears
   on the dark footer. Knock it out to white instead of shipping a 2nd file. */
.footer-brand { display: inline-block; }
.footer-brand:hover img { opacity: 1; }
.site-footer img {
  width: 13.4rem;   /* rem so it scales with the large-display ramp */
  height: auto;
  display: block;
  margin: 0 0 var(--sp-5);   /* flush left, no auto centring */
  filter: brightness(0) invert(1);
  opacity: 0.92;
  transition: opacity 0.18s ease;
}
.footer-legal {
  border-top: 1px solid rgba(255, 255, 255, 0.24);
  padding-block: var(--sp-5) var(--sp-6);
  font-size: var(--fs-xs);
  line-height: 1.75;
  color: rgba(255, 255, 255, 0.87);
}
.footer-legal p { margin-bottom: var(--sp-3); max-width: 90ch; }
.footer-legal p:last-child { margin-bottom: 0; }

/* ---------- Header phone (mobile) ----------
   The sticky bottom call bar was removed at the client's request. This keeps
   the number one tap away in the sticky header instead, so mobile visitors
   never have to scroll back up to call. */
.header-tel { display: none; }
@media (max-width: 61.99rem) {
  .header-tel {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    margin-left: auto;
    margin-right: var(--sp-3);
    padding: 0.55rem 0.85rem;
    min-height: 44px;
    background: var(--burgundy);
    color: #fff;
    border-radius: var(--radius);
    font-family: var(--font-ui);
    font-size: var(--fs-sm);
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
  }
  .header-tel:hover { background: var(--burgundy-700); color: #fff; }
  .header-tel svg { width: 1em; height: 1em; flex: none; }
}
/* Logo + number + Menu will not fit together on a phone, so below 544px the
   button goes icon-only (it keeps its aria-label). */
@media (max-width: 34rem) {
  .header-tel__label { display: none; }
  .header-tel { padding: 0.55rem 0.75rem; margin-right: var(--sp-2); }
}
/* 320px devices. */
@media (max-width: 22.5rem) {
  .site-header__inner { gap: var(--sp-2); }
  .nav__burger { padding: 0.5rem 0.55rem; }
  .header-tel { padding: 0.5rem 0.6rem; }
  .topbar { font-size: 0.75rem; }
}

/* ---------- Mobile nav ---------- */
@media (max-width: 61.99rem) {
  .site-header__inner { gap: var(--sp-3); }
  .nav__burger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    font-family: var(--font-ui);
    font-size: var(--fs-sm);
    font-weight: 600;
    background: none;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    color: var(--ink);
    padding: 0.6rem 0.9rem;
    min-height: 44px;
    cursor: pointer;
  }
  .nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: #fff;
    border-bottom: 1px solid var(--line);
    box-shadow: 0 20px 30px -20px rgba(0, 0, 0, 0.3);
    padding: var(--sp-4) 0 var(--sp-6);
    max-height: calc(100vh - 100%);
    overflow-y: auto;
  }
  .site-header { position: relative; }
  .site-header.is-open .nav { display: block; }
  .nav__list { flex-direction: column; align-items: stretch; gap: 0; width: min(100% - 2.5rem, var(--shell)); margin-inline: auto; }
  .nav__link, .nav__toggle { width: 100%; padding: var(--sp-4) var(--sp-2); border-bottom: 1px solid var(--line); border-radius: 0; justify-content: space-between; }
  .nav__toggle { text-align: left; }
  .nav__panel {
    position: static;
    display: none;
    box-shadow: none;
    border: 0;
    border-bottom: 1px solid var(--line);
    border-radius: 0;
    padding: var(--sp-2) 0 var(--sp-4) var(--sp-4);
    min-width: 0;
    background: var(--paper-alt);
  }
  /* Panel is static here, so the desktop hover bridge would resolve against
     .nav__item and leave a stray strip over the toggle. */
  .nav__panel::before { content: none; }
  .nav__toggle[aria-expanded="true"] + .nav__panel { display: block; }
  /* .btn is inline-flex, so `margin-inline: auto` could not centre it and the
     call button sat hard against the left edge. Block-level flex fixes it. */
  .nav .btn {
    display: flex;
    width: min(100% - 2.5rem, var(--shell));
    margin: var(--sp-5) auto 0;
  }
}

/* ---------- Back to top ----------
   Every breakpoint. Idle state is fully hidden (opacity + visibility, so it is
   also out of the tab order) and site.js reveals it once the reader is roughly
   a screen down, which keeps it off the initial view of every page. */
.to-top {
  position: fixed;
  right: clamp(0.75rem, 2.5vw, 2rem);
  bottom: clamp(0.75rem, 2.5vw, 2rem);
  z-index: 90;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 44px;
  min-width: 44px;           /* WCAG 2.5.8 target size in the icon-only state */
  padding: 0.6rem 1rem;
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: #fff;
  /* Burgundy, not slate. The footer and the CTA band are both --brand, so a
     slate button vanished into them at the exact point of the page where it
     is most likely to be used. Burgundy is also the system's action colour,
     which is what this control is. */
  background: var(--burgundy);
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: var(--radius);
  box-shadow: 0 14px 30px -12px rgba(26, 26, 26, 0.55);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(0.5rem);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s,
              background-color 0.18s ease;
}
.to-top svg { width: 0.95em; height: 0.95em; flex: none; }
.to-top.is-visible { opacity: 1; visibility: visible; transform: none; }
.to-top:hover { background: var(--burgundy-700); color: #fff; }
/* Phones: icon only, square, and slightly translucent so it never fully
   masks the text it floats over. The label is redundant next to the arrow. */
@media (max-width: 61.99rem) {
  .to-top { padding: 0; width: 44px; height: 44px; opacity: 0; }
  .to-top span { display: none; }
  .to-top svg { width: 1.15rem; height: 1.15rem; }
  .to-top.is-visible { opacity: 0.94; }
}
/* Outline switches to white over the footer, where a burgundy ring would sit
   on burgundy. */
.to-top:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }

/* ---------- Motion: single restrained reveal ---------- */
@media (prefers-reduced-motion: no-preference) {
  .reveal { opacity: 0; transform: translateY(14px); transition: opacity 0.6s ease, transform 0.6s ease; }
  .reveal.is-in { opacity: 1; transform: none; }
}

/* ---------- Utilities ---------- */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.text-center { text-align: center; }
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }
.section__head { max-width: 54ch; margin-bottom: var(--sp-7); }
.section__head h2 { font-size: var(--fs-2xl); font-weight: 500; letter-spacing: -0.025em; text-wrap: balance; }
.section__head p { margin-top: var(--sp-4); margin-bottom: 0; }

/* ==========================================================================
   Very large displays — composition
   The root-size ramp near the top of this file fixes *scale*. These rules fix
   *composition*: several blocks hold a fixed measure (62ch, 60ch, one column)
   that sat fine in a 1216px shell and reads as stranded in a 2156px one, with
   two thirds of the row empty to the right of the text.
   ========================================================================== */
@media (min-width: 100rem) {
  /* Process spine: two columns, reading across. One column left three
     quarters of the band empty. The connecting rule is dropped here because
     the sequence now flows horizontally — the numerals carry the order. */
  .spine {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: clamp(3rem, 4vw, 5.5rem);
    /* Row spacing moves to the grid rather than each step's bottom padding.
       Padding could not do it here: with an odd number of steps the step that
       needs no space below is not the last one in source order. */
    row-gap: var(--sp-7);
  }
  .spine::before { content: none; }
  .spine__step { padding-bottom: 0; }

  /* Attorney band: photograph plus a 60ch bio came to about half the shell
     and hugged the left edge. Centring the pair makes the whitespace
     symmetrical and deliberate, and the portrait takes a step up. */
  .attorney__inner {
    grid-template-columns: auto minmax(0, 62ch);
    justify-content: center;
  }
  .attorney__photo { width: 16rem; }

  /* Lead testimonial: max-width was released to fill its grid column, which
     at this width is a 95-character line. Back to a readable measure — and
     size the first track to that measure, so the attribution's divider rule
     sits beside the text instead of stranded at the far right of the card
     with 550px of nothing between them. */
  .quote--lead { grid-template-columns: minmax(0, 78ch) minmax(11rem, 1fr); }
  .quote--lead blockquote { max-width: 78ch; }

  /* Cards: more air inside, and more between them, so a three-across row
     does not read as three wide slivers. */
  .grid { gap: var(--sp-6); }
  .card { padding: var(--sp-6); }

  /* FAQ rows: a 20-character question with its chevron 1900px away on the
     far right. Capping the accordion keeps the row and its control related,
     and holds the same left anchor as the section head above it. */
  .faq { max-width: 68rem; }
}

@media print {
  .site-header, .topbar, .cta, .nav, .header-tel, .to-top { display: none !important; }
  body { color: #000; }
}
