@charset "UTF-8";
/* ==========================================================================
   Keith Insurance — assets/style.css
   Hand-written CSS. No build step, no framework, no preprocessor.
   Everything is driven by the custom properties in :root, so the whole site
   can be re-themed by editing the DESIGN TOKENS block below.

   Built around the agency's own brand colour: deep forest green #1E4A26,
   taken from the logo artwork, with white and warm neutral greys. The only
   secondary colour is a warm sand used as a background band; it never carries
   text meaning and never competes with the green.

   Contents
   --------
   01  Design tokens          11  Photography
   02  Dark theme tokens      12  People + timeline
   03  Reset + base           13  Placeholder slots
   04  A11y utilities         14  Forms
   05  Layout                 15  Footer
   06  Typography helpers     16  Prose (legal pages)
   07  Buttons                17  Accordion (Customers page)
   08  Header + navigation    18  404
   09  Hero                   19  Progressive enhancement + motion
   10  Cards + content blocks 20  Utilities + print

   --------------------------------------------------------------------------
   CONTRAST AUDIT (WCAG 2.1) — every ratio below was computed, not estimated.
   Target: 4.5:1 for body text, 3:1 for large text (>=24px, or >=18.66px bold)
   and for non-text UI components and focus indicators.

   LIGHT THEME
     --ink   #14170F on --paper   #FAF9F6 ............. 17.21:1  AAA
     --ink   #14170F on --surface #FFFFFF ............. 18.12:1  AAA
     --ink   #14170F on --tint    #F1F0EA ............. 15.87:1  AAA
     --ink   #14170F on --mist    #E8EDE6 ............. 15.26:1  AAA
     --ink   #14170F on --sand    #E4D9C3 ............. 12.95:1  AAA
     --muted #4E564A on --paper ....................... 7.24:1   AAA
     --muted #4E564A on --tint ........................ 6.68:1   AAA
     --muted #4E564A on --mist ........................ 6.42:1   AAA
     --brand #1E4A26 on --paper ....................... 9.67:1   AAA   (brand green text)
     --brand #1E4A26 on --surface .....................10.18:1   AAA
     --brand #1E4A26 on --tint ........................ 8.92:1   AAA
     --brand #1E4A26 on --mist ........................ 8.57:1   AAA
     --brand #1E4A26 on --sand ........................ 7.28:1   AAA
     --rule / --accent-text #2C6A38 on --paper ........ 6.18:1   AAA
       (heading rules, eyebrows, section labels, detail icons)
     #FFFFFF on --brand #1E4A26 (primary button) ......10.18:1   AAA
     #FFFFFF on --brand-700 #2C6A38 (button hover) .... 6.51:1   AAA
     --paper #FAF9F6 on --brand ....................... 9.67:1   AAA
     --paper #FAF9F6 on --brand-800 #193D20 ...........11.53:1   AAA
     --paper #FAF9F6 on --brand-900 #143119 ...........13.45:1   AAA
     --on-brand-mut #C9DBC6 on --brand ................ 7.00:1   AAA
     --on-brand-mut #C9DBC6 on --brand-900 ............ 9.73:1   AAA
     --focus-on-dark #DCE9DA on --brand ............... 8.29:1   (>=3:1 required)
     --border-strong #737C6E on --surface ............. 4.34:1   (field borders, >=3:1)
     --error   #97231D on --paper ..................... 7.75:1   AAA
     #FFFFFF on --error ............................... 8.16:1   AAA
     --success #1E5C3A on --paper ..................... 7.53:1   AAA
     --ph-ink  #6B5A22 on --ph-bg #FBF6E6 ............. 6.25:1   AAA   (placeholders)
     #FFFFFF on --ph-ink (placeholder badge) .......... 6.75:1   AAA
     Text over the hero photograph sits on a green scrim whose thinnest point
     is 64% opaque. Full working, plus ratios measured off the rendered page
     at five viewport widths, is in section 09 below. Floor for white text
     anywhere in the hero, against the single brightest pixel in the
     photograph: 5.00:1. Lowest figure actually measured on screen: 5.85:1.

     The five INTERIOR page heroes (Auto, Home, Commercial, Specialty, Flood)
     have their own scrim, also in section 09. Its narrow-viewport behaviour
     was corrected while the Specialty and Flood photographs were added —
     three of the five were failing 4.5:1 on a phone. Worst figure now, across
     all five photographs and every element: 6.30:1. Working in section 09.

     The two PHOTO BANDS, on Specialty and Commercial, carry white copy over
     their own scrim. Worst figure across both, all elements, all viewports
     and the whole parallax travel: 8.44:1. Working in section 11c.

   DARK THEME
     --ink   #E8ECE4 on --paper   #0E120C ............. 15.80:1  AAA
     --ink   #E8ECE4 on --surface #171D14 ............. 14.36:1  AAA
     --muted #AAB6A4 on --paper ....................... 8.95:1   AAA
     --muted #AAB6A4 on --surface ..................... 8.13:1   AAA
     --link  #9FD6A6 on --paper .......................11.39:1   AAA
     --link  #9FD6A6 on --surface .....................10.34:1   AAA
     --accent-text / --rule #86C48F on --paper ........ 9.28:1   AAA
       (eyebrows, labels, rules and the focus ring)
     --accent-text #86C48F on --surface ............... 8.43:1   AAA
     #0E120C on --accent (primary button) ............. 9.28:1   AAA
     --border-strong #7C8A78 on --field-bg #131811 .... 4.94:1   (>=3:1 required)
     --error   #FF9C93 on --paper ..................... 9.39:1   AAA
     --success #7FD3A2 on --paper .....................10.57:1   AAA
     --ph-ink  #D9BE72 on --ph-bg #1B1B14 ............. 9.53:1   AAA

   Purely decorative hairlines (--border) are intentionally low contrast. They
   are never the only way a control or a piece of information is identified.
   ========================================================================== */


/* ==========================================================================
   01  DESIGN TOKENS
   ========================================================================== */
:root {
  color-scheme: light dark;

  /* --- Brand green (from the agency's logo artwork) -------------------- */
  --brand:        #1E4A26;
  --brand-800:    #193D20;
  --brand-900:    #143119;
  --brand-700:    #2C6A38;

  /* --- Surfaces -------------------------------------------------------- */
  --paper:        #FAF9F6;   /* page, warm off-white */
  --surface:      #FFFFFF;   /* raised cards */
  --tint:         #F1F0EA;   /* warm neutral band */
  --mist:         #E8EDE6;   /* faintest green band */
  --sand:         #E4D9C3;   /* warm sand band, used sparingly */

  /* --- Text ------------------------------------------------------------ */
  --ink:          #14170F;
  --muted:        #4E564A;
  --on-brand:     #FAF9F6;
  --on-brand-mut: #C9DBC6;
  --link:         #1E4A26;
  --link-hover:   #143119;

  /* --- Lines + state --------------------------------------------------- */
  --border:        #E2E0D8;  /* decorative hairline */
  --border-strong: #737C6E;  /* interactive component boundary (>=3:1) */
  --rule:          #2C6A38;  /* short accent rules under headings */
  --accent-text:   #2C6A38;  /* green used as text: eyebrows, labels, icons */
  --field-bg:      #FFFFFF;
  --error:         #97231D;
  --error-bg:      #FCF1F0;
  --success:       #1E5C3A;
  --success-bg:    #EDF5F0;
  --ph-bg:         #FBF6E6;  /* placeholder slots */
  --ph-ink:        #6B5A22;
  --focus:         #1E4A26;
  --focus-on-dark: #DCE9DA;

  /* --- Typography ------------------------------------------------------ */
  --font-display: "Fraunces", "Iowan Old Style", "Palatino Linotype", Palatino,
                  Georgia, "Times New Roman", serif;
  --font-body:    "Inter", system-ui, -apple-system, "Segoe UI", Roboto,
                  "Helvetica Neue", Arial, sans-serif;

  /* Fluid type scale, roughly a 1.25 ratio. */
  --fs-xs:   0.8125rem;
  --fs-sm:   0.9375rem;
  --fs-base: clamp(1rem, 0.978rem + 0.11vw, 1.0625rem);
  --fs-md:   clamp(1.0625rem, 1.02rem + 0.23vw, 1.1875rem);
  --fs-lg:   clamp(1.1875rem, 1.11rem + 0.38vw, 1.375rem);
  --fs-xl:   clamp(1.375rem, 1.25rem + 0.62vw, 1.75rem);
  --fs-2xl:  clamp(1.625rem, 1.4rem + 1.12vw, 2.25rem);
  --fs-3xl:  clamp(1.9375rem, 1.6rem + 1.7vw, 2.875rem);
  --fs-4xl:  clamp(2.25rem, 1.72rem + 2.6vw, 3.75rem);

  --lh-tight: 1.1;
  --lh-snug:  1.26;
  --lh-body:  1.68;

  /* --- Space (8px rhythm, 4px halves) ---------------------------------- */
  --sp-1: 0.25rem;  --sp-2: 0.5rem;  --sp-3: 0.75rem;  --sp-4: 1rem;
  --sp-5: 1.5rem;   --sp-6: 2rem;    --sp-7: 2.5rem;   --sp-8: 3rem;
  --sp-9: 4rem;     --sp-10: 5rem;   --sp-11: 6.5rem;
  --section-y: clamp(3.5rem, 2rem + 5.5vw, 6.5rem);
  --gutter:    clamp(1.25rem, 0.6rem + 2.4vw, 2.75rem);
  --measure:   66ch;

  /* --- Radius, shadow, motion, sizing ---------------------------------- */
  --r-sm: 4px;  --r-md: 8px;  --r-lg: 14px;  --r-xl: 20px;  --r-pill: 999px;
  --shadow-sm: 0 1px 2px rgba(20, 49, 25, .05), 0 2px 8px rgba(20, 49, 25, .045);
  --shadow-md: 0 2px 6px rgba(20, 49, 25, .06), 0 12px 26px rgba(20, 49, 25, .075);
  --shadow-lg: 0 6px 16px rgba(20, 49, 25, .08), 0 28px 52px rgba(20, 49, 25, .11);

  --dur-fast: 120ms;
  --dur:      200ms;
  --dur-slow: 480ms;
  --ease:     cubic-bezier(.22, .61, .36, 1);
  /* A longer, heavier decelerate for anything that arrives on scroll. */
  --ease-out-soft: cubic-bezier(.16, .84, .30, 1);

  --header-h: 4.75rem;
  --tap: 44px;               /* minimum touch target (WCAG 2.5.5 / 2.5.8) */

  /* Height of the layered curve dividers. Fluid, so the sweep keeps the same
     proportion from a 320px phone to a 2560px display. */
  --curve-h: clamp(4rem, 13vw, 13rem);
}


/* ==========================================================================
   02  DARK THEME
   Every pair below was re-checked against AA. See the audit at the top.
   ========================================================================== */
@media (prefers-color-scheme: dark) {
  :root {
    --brand:        #1E4A26;
    --brand-800:    #17331C;
    --brand-900:    #0B1409;
    --brand-700:    #2C6A38;

    --paper:        #0E120C;
    --surface:      #171D14;
    --tint:         #131811;
    --mist:         #131A12;
    --sand:         #1C1B15;

    --ink:          #E8ECE4;
    --muted:        #AAB6A4;
    --on-brand:     #E8ECE4;
    --on-brand-mut: #C9DBC6;
    --link:         #9FD6A6;
    --link-hover:   #C6E8CB;

    --border:        #26301F;
    --border-strong: #7C8A78;
    --rule:          #86C48F;
    --accent-text:   #86C48F;
    --field-bg:      #131811;
    --error:         #FF9C93;
    --error-bg:      #26100E;
    --success:       #7FD3A2;
    --success-bg:    #0E2117;
    --ph-bg:         #1B1B14;
    --ph-ink:        #D9BE72;
    --focus:         #86C48F;
    --focus-on-dark: #DCE9DA;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .5);
    --shadow-md: 0 2px 6px rgba(0, 0, 0, .45), 0 12px 26px rgba(0, 0, 0, .45);
    --shadow-lg: 0 6px 16px rgba(0, 0, 0, .5),  0 28px 52px rgba(0, 0, 0, .55);
  }
}


/* ==========================================================================
   03  RESET + BASE
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

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

/* Anything that can be jumped to keeps clear of the header, which is fixed
   over the photograph on the homepage. */
[id] { scroll-margin-top: calc(var(--header-h) + 1rem); }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;           /* never allow sideways scroll */
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: var(--lh-tight);
  letter-spacing: -0.014em;
  color: var(--ink);
  margin: 0 0 var(--sp-4);
  text-wrap: balance;
}
h1 { font-size: var(--fs-3xl); }
h2 { font-size: var(--fs-2xl); }
h3 { font-size: var(--fs-xl); line-height: var(--lh-snug); letter-spacing: -0.01em; }
h4 { font-size: var(--fs-lg); line-height: var(--lh-snug); letter-spacing: -0.005em; }

p, ul, ol, dl, figure, table { margin: 0 0 var(--sp-4); }
p { max-width: var(--measure); text-wrap: pretty; }

a {
  color: var(--link);
  text-decoration-thickness: max(1px, .06em);
  text-underline-offset: .2em;
}
a:hover { color: var(--link-hover); text-decoration-thickness: max(2px, .1em); }

img, svg, video { max-width: 100%; height: auto; }
img { display: block; }

strong, b { font-weight: 700; }

hr { border: 0; border-top: 1px solid var(--border); margin: var(--sp-7) 0; }

ul, ol { padding-left: 1.3em; }
li { margin-bottom: var(--sp-2); max-width: var(--measure); }

abbr[title] { text-decoration: underline dotted; cursor: help; }

:where(p, li, h1, h2, h3, h4, dd, dt, td, th, address) { overflow-wrap: break-word; }


/* ==========================================================================
   04  ACCESSIBILITY UTILITIES
   ========================================================================== */

/* Skip link. position: fixed so it lands at the top of the VIEWPORT whatever
   the scroll position is, and held off-screen by a transform rather than by
   display:none, so it always stays in the tab order. */
.skip-link {
  position: fixed;
  top: 0;
  left: var(--sp-4);
  z-index: 200;
  display: inline-flex;
  align-items: center;
  padding: var(--sp-3) var(--sp-5);
  min-height: var(--tap);
  background: var(--brand);
  color: #FFFFFF;                  /* 10.18:1 on --brand */
  font-weight: 600;
  text-decoration: none;
  border-radius: 0 0 var(--r-md) var(--r-md);
  box-shadow: var(--shadow-md);
  transform: translateY(-130%);
  transition: transform var(--dur) var(--ease);
}
.skip-link:focus {
  transform: translateY(0);
  color: #FFFFFF;
  outline: 3px solid var(--focus-on-dark);
  outline-offset: -6px;
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

/* One high-contrast focus indicator, never removed. */
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}
.on-brand :focus-visible,
.hero :focus-visible,
.page-hero :focus-visible,
.photo-band :focus-visible,
.site-footer :focus-visible {
  outline-color: var(--focus-on-dark);
}
@supports not selector(:focus-visible) {
  :focus { outline: 3px solid var(--focus); outline-offset: 3px; }
}


/* ==========================================================================
   05  LAYOUT
   ========================================================================== */
.container      { width: min(100% - (var(--gutter) * 2), 1160px); margin-inline: auto; }
.container--mid { width: min(100% - (var(--gutter) * 2), 980px); }
.container--narrow { width: min(100% - (var(--gutter) * 2), 760px); }

.section { padding-block: var(--section-y); }
.section--tight { padding-block: calc(var(--section-y) * .6); }
.section--tint { background: var(--tint); }
.section--mist { background: var(--mist); }
.section--sand { background: var(--sand); }

.on-brand { background: var(--brand-900); color: var(--on-brand); }
.on-brand h1, .on-brand h2, .on-brand h3, .on-brand h4 { color: var(--on-brand); }
.on-brand p, .on-brand li { color: var(--on-brand-mut); }
.on-brand a:not(.btn) { color: #FFFFFF; text-decoration-thickness: 1px; }
.on-brand a:not(.btn):hover { color: var(--on-brand-mut); }

/* Mobile first, ascending order: later rules win at equal specificity. */
.grid { display: grid; gap: var(--sp-5); }
@media (min-width: 620px) {
  .grid--2 { grid-template-columns: repeat(2, 1fr); }
  .grid--3 { grid-template-columns: repeat(2, 1fr); }
  .grid--4 { grid-template-columns: repeat(2, 1fr); }
  .grid--5 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 900px) {
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
  .grid--5 { grid-template-columns: repeat(3, 1fr); }
  /* The four "other coverage" cards sit on ONE row from 900px up. They are
     short link cards, so a quarter of 900px is still a comfortable measure. */
  .grid--4 { grid-template-columns: repeat(4, 1fr); }
}
/* The five coverage cards on ONE row, the way the agency's own site has them.
   320-619  1 across
   620-899  2 across
   900-1179 3 across (3 + 2)
   1180+    5 across, and the cards switch to their compact layout below.
   1180 is the width at which a fifth column is still ~200px wide, which is
   enough for a readable measure; below that they would be slivers. */
@media (min-width: 1180px) {
  .grid--5 { grid-template-columns: repeat(5, 1fr); gap: var(--sp-4); }
}

.split { display: grid; gap: clamp(var(--sp-6), 4.5vw, var(--sp-9)); align-items: center; }
@media (min-width: 900px) {
  .split { grid-template-columns: 1fr 1fr; }
  .split--wide-left  { grid-template-columns: 1.3fr .7fr; }
  .split--wide-right { grid-template-columns: .78fr 1.22fr; }
  .split--top { align-items: start; }
}

.stack > * + * { margin-top: var(--sp-5); }
.center { text-align: center; }
.center p { margin-inline: auto; }


/* ==========================================================================
   06  TYPOGRAPHY HELPERS
   ========================================================================== */
.eyebrow {
  display: block;
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin: 0 0 var(--sp-3);
}
.on-brand .eyebrow, .hero .eyebrow, .page-hero .eyebrow { color: var(--on-brand-mut); }

.lede { font-size: var(--fs-md); color: var(--muted); max-width: 60ch; }
.on-brand .lede, .hero .lede, .page-hero .lede { color: var(--on-brand-mut); }

.section-head { margin-bottom: var(--sp-8); }
.section-head p:last-child { margin-bottom: 0; }

/* Short accent rule under a heading. Decorative. */
.rule::after {
  content: "";
  display: block;
  width: 3rem;
  height: 3px;
  border-radius: 2px;
  background: var(--rule);
  margin-top: var(--sp-4);
}
.center .rule::after, .center.rule::after { margin-inline: auto; }
.on-brand .rule::after, .hero .rule::after, .page-hero .rule::after { background: var(--on-brand-mut); }

.quote {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  line-height: 1.45;
  font-style: italic;
  color: var(--ink);
  border-left: 3px solid var(--rule);
  padding-left: var(--sp-5);
  margin: 0 0 var(--sp-5);
  max-width: 46ch;
}
.on-brand .quote { color: var(--on-brand); border-left-color: var(--on-brand-mut); }


/* ==========================================================================
   07  BUTTONS  (all meet the 44x44px minimum target)
   ========================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  padding: var(--sp-3) var(--sp-6);
  border: 2px solid transparent;
  border-radius: var(--r-md);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 650;
  letter-spacing: .01em;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
.btn:hover { text-decoration: none; }

.btn--primary { background: var(--brand); color: #FFFFFF; box-shadow: var(--shadow-sm); }
.btn--primary:hover { background: var(--brand-700); color: #FFFFFF; box-shadow: var(--shadow-md); transform: translateY(-1px); }

.btn--outline { background: transparent; color: var(--brand); border-color: var(--brand); }
.btn--outline:hover { background: var(--brand); color: #FFFFFF; }

/* On a dark green band or over the hero photograph. */
.on-brand .btn--primary,
.hero .btn--primary,
.page-hero .btn--primary { background: #FFFFFF; color: var(--brand-900); }
.on-brand .btn--primary:hover,
.hero .btn--primary:hover,
.page-hero .btn--primary:hover { background: var(--on-brand-mut); color: var(--brand-900); }

.on-brand .btn--outline,
.hero .btn--outline,
.page-hero .btn--outline { color: #FFFFFF; border-color: rgba(255,255,255,.72); }
/* The homepage hero copies the agency's own two outline buttons. Their border
   is the only thing that describes the control, so it is solid white: 5.00:1
   against the lightest possible backdrop in the hero, well past the 3:1 that
   WCAG 1.4.11 asks of a non-text UI component. */
.hero--home .btn--outline { border-color: #FFFFFF; }
.on-brand .btn--outline:hover,
.hero .btn--outline:hover,
.page-hero .btn--outline:hover { background: #FFFFFF; color: var(--brand-900); border-color: #FFFFFF; }

@media (prefers-color-scheme: dark) {
  .btn--primary { background: #86C48F; color: #0E120C; }
  .btn--primary:hover { background: #A6DBAE; color: #0E120C; }
  .btn--outline { color: #86C48F; border-color: #86C48F; }
  .btn--outline:hover { background: #86C48F; color: #0E120C; }
}

.btn--lg { font-size: var(--fs-base); padding: var(--sp-4) var(--sp-7); }
.btn--block { width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-6); }
.btn-row--center { justify-content: center; }

/* Underlined, so colour is never the only cue that it is a link. */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: .45em;
  min-height: var(--tap);
  font-weight: 650;
  font-size: var(--fs-sm);
  color: var(--link);
  text-decoration: underline;
  text-underline-offset: .24em;
}
.arrow-link svg { flex: none; transition: transform var(--dur) var(--ease); }
/* Focus gets the identical affordance, so a keyboard user sees what a mouse
   user sees. */
.arrow-link:hover svg,
.arrow-link:focus-visible svg { transform: translateX(4px); }


/* ==========================================================================
   08  HEADER + NAVIGATION
   ========================================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background-color: color-mix(in srgb, var(--paper) 94%, transparent);
  -webkit-backdrop-filter: saturate(160%) blur(12px);
  backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid var(--border);
  transition: background-color 220ms var(--ease), border-color 220ms var(--ease),
              box-shadow 220ms var(--ease);
}
@supports not (backdrop-filter: blur(1px)) { .site-header { background-color: var(--paper); } }

/* --------------------------------------------------------------------------
   TRANSPARENT HEADER OVER THE HOMEPAGE HERO

   The agency's own site puts the navigation straight onto the photograph, so
   the homepage does the same. Three things keep it accessible:

   1. It is gated on `.js`. The solid-on-scroll swap is a JavaScript class, so
      without JavaScript the header simply stays the ordinary solid sticky bar
      it is on every other page — readable at every scroll position.
   2. The header carries its OWN top gradient (`::before`), so the logo and the
      nav links never depend on what the photograph happens to be doing.
   3. `.is-top` is removed as soon as the page scrolls (and while the mobile
      nav panel is open), which restores the solid bar.

   Measured, over the brightest pixel in the hero photograph (#FFFCF0):
     header gradient + hero scrim = ~87% of #09130A  ->  effective bg #293128
       #FFFFFF logo, nav links, phone button ............ 13.4:1   AAA
       --focus-on-dark #DCE9DA focus ring ............... 10.7:1   (>=3:1)
   -------------------------------------------------------------------------- */
.js .has-overlay-header .site-header {
  position: fixed;
  left: 0; right: 0; top: 0;
}
.js .has-overlay-header .site-header.is-top {
  background-color: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-bottom-color: transparent;
}
.js .has-overlay-header .site-header.is-top::before {
  content: "";
  position: absolute;
  inset: 0;
  bottom: -2.75rem;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(8, 17, 9, .62) 0%,
    rgba(8, 17, 9, .44) 46%,
    rgba(8, 17, 9, .17) 78%,
    rgba(8, 17, 9, 0)   100%);
}
/* White marque and white nav while the header floats on the photograph. */
.js .has-overlay-header .site-header.is-top .brand__logo--dark { display: none; }
.js .has-overlay-header .site-header.is-top .brand__logo--light { display: block; }
.js .has-overlay-header .site-header.is-top .nav-link,
.js .has-overlay-header .site-header.is-top .nav-disclosure,
.js .has-overlay-header .site-header.is-top .nav-toggle { color: #FFFFFF; }
.js .has-overlay-header .site-header.is-top .nav-toggle { border-color: rgba(255, 255, 255, .8); }
.js .has-overlay-header .site-header.is-top .nav-toggle:hover,
.js .has-overlay-header .site-header.is-top .nav-link:hover,
.js .has-overlay-header .site-header.is-top .nav-disclosure:hover {
  background: rgba(255, 255, 255, .18);
  color: #FFFFFF;
  border-color: #FFFFFF;
}
.js .has-overlay-header .site-header.is-top .nav-link[aria-current="page"],
.js .has-overlay-header .site-header.is-top .nav-disclosure.is-current { color: #FFFFFF; }
.js .has-overlay-header .site-header.is-top .nav-link[aria-current="page"]::after,
.js .has-overlay-header .site-header.is-top .nav-disclosure.is-current::after { background: #FFFFFF; }
.js .has-overlay-header .site-header.is-top .btn--primary {
  background: #FFFFFF;             /* 14.2:1 for the #143119 label */
  color: var(--brand-900);
  box-shadow: 0 2px 10px rgba(8, 17, 9, .3);
}
.js .has-overlay-header .site-header.is-top .btn--primary:hover {
  background: var(--on-brand-mut);
  color: var(--brand-900);
}
/* The focus ring has to be visible against the photograph too. */
.js .has-overlay-header .site-header.is-top :focus-visible { outline-color: var(--focus-on-dark); }

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  min-height: var(--header-h);
  padding-block: var(--sp-2);
}

/* --- The agency's own logo ---------------------------------------------- */
.brand {
  display: inline-flex;
  align-items: center;
  flex: none;
  padding: var(--sp-2) var(--sp-1);
  border-radius: var(--r-sm);
  text-decoration: none;
}
.brand__logo { width: clamp(168px, 20vw, 210px); height: auto; }
.site-footer .brand__logo { width: clamp(180px, 22vw, 220px); }
/* The dark logo is for light backgrounds and vice versa; each page uses the
   right file, and dark mode swaps the header one with a filter-free rule. */
.brand__logo--dark { display: block; }
.brand__logo--light { display: none; }
@media (prefers-color-scheme: dark) {
  .site-header .brand__logo--dark { display: none; }
  .site-header .brand__logo--light { display: block; }
}

/* --- Nav toggle (mobile) ------------------------------------------------ */
.nav-toggle {
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  min-width: var(--tap);
  padding: var(--sp-2) var(--sp-4);
  background: transparent;
  border: 2px solid var(--border-strong);
  border-radius: var(--r-md);
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 650;
  cursor: pointer;
}
.nav-toggle:hover { background: var(--mist); border-color: var(--brand); }
.nav-toggle__bars { display: block; width: 20px; height: 14px; position: relative; }
.nav-toggle__bars span {
  position: absolute; left: 0; right: 0; height: 2px; border-radius: 2px;
  background: currentColor;
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.nav-toggle__bars span:nth-child(1) { top: 0; }
.nav-toggle__bars span:nth-child(2) { top: 6px; }
.nav-toggle__bars span:nth-child(3) { top: 12px; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* --- Nav ---------------------------------------------------------------- */
@media (max-width: 1049px) {
  .site-nav {
    position: absolute;
    left: 0; right: 0; top: 100%;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow-lg);
    padding: var(--sp-4) var(--gutter) var(--sp-6);
    max-height: calc(100vh - var(--header-h));
    overflow-y: auto;
  }
  .site-nav[hidden] { display: none; }
  .nav-list { flex-direction: column; align-items: stretch; gap: 0; }
  .nav-list > li { border-bottom: 1px solid var(--border); }
  .nav-list > li:last-child { border-bottom: 0; }
  .nav-link, .nav-disclosure { width: 100%; justify-content: space-between; }
  .subnav { padding: 0 0 var(--sp-3) var(--sp-4); }
  .nav-cta { margin-top: var(--sp-5); }
  .nav-cta .btn { width: 100%; }
}
@media (min-width: 1050px) {
  .site-nav { display: block !important; }
  .site-nav[hidden] { display: block; }
  .nav-list { flex-direction: row; align-items: center; gap: var(--sp-1); }
  .nav-cta { margin-left: var(--sp-3); }
}

.nav-list { display: flex; list-style: none; margin: 0; padding: 0; }
.nav-list li { margin: 0; max-width: none; }

.nav-link, .nav-disclosure {
  position: relative;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  padding: var(--sp-2) var(--sp-4);
  border: 0;
  background: transparent;
  border-radius: var(--r-md);
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.nav-link { display: inline-flex; }
.nav-link:hover, .nav-disclosure:hover { background: var(--mist); color: var(--brand); text-decoration: none; }

/* Current page: aria-current plus weight AND a rule, never colour alone. */
.nav-link[aria-current="page"], .nav-disclosure.is-current { color: var(--brand); font-weight: 750; }
.nav-link[aria-current="page"]::after, .nav-disclosure.is-current::after {
  content: "";
  position: absolute;
  left: var(--sp-4); right: var(--sp-4); bottom: 4px;
  height: 2px; border-radius: 2px;
  background: var(--rule);
}
@media (max-width: 1049px) {
  .nav-link[aria-current="page"]::after,
  .nav-disclosure.is-current::after { right: auto; width: 2.25rem; bottom: 8px; }
}

.nav-disclosure__chev { transition: transform var(--dur) var(--ease); flex: none; }
.nav-disclosure[aria-expanded="true"] .nav-disclosure__chev { transform: rotate(180deg); }

.nav-item--has-menu { position: relative; }

.subnav { list-style: none; margin: 0; padding: 0; }
.subnav[hidden] { display: none; }
.subnav a {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: var(--tap);
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-md);
  color: var(--ink);
  font-size: var(--fs-sm);
  font-weight: 600;
  text-decoration: none;
}
.subnav a:hover { background: var(--mist); color: var(--brand); text-decoration: none; }
.subnav a[aria-current="page"] { font-weight: 750; color: var(--brand); }
.subnav a[aria-current="page"] .subnav__dot { background: var(--rule); }
.subnav__dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--border-strong); }
.subnav__label { display: block; }
.subnav__desc { display: block; font-size: var(--fs-xs); font-weight: 400; color: var(--muted); line-height: 1.35; }

@media (min-width: 1050px) {
  .subnav a { align-items: flex-start; padding: var(--sp-3); }
  .subnav__dot { margin-top: .5em; }
}

.nav-cta { list-style: none; }
.nav-phone-icon { flex: none; }


/* ==========================================================================
   09  HERO
   The homepage hero follows the agency's own site: the aerial photograph of
   Fort Myers Beach runs full bleed edge to edge, the navigation floats on
   top of it, and the bottom edge of the photograph is cut by a layered
   curved sweep rather than a straight line.

   --------------------------------------------------------------------------
   HERO SCRIM — MEASURED CONTRAST
   Every ratio below is computed against #FFFCF0, the single brightest pixel
   anywhere in the photograph (a sun glint on the water), so the figures hold
   no matter how the photograph is cropped, at any viewport width, and they
   will still hold when the animated MP4 replaces the still.

   The scrim is two stacked gradients. The horizontal one never falls below
   64% opacity, which is the number that carries the whole guarantee; the
   vertical one only ever adds to it. That is a lot lighter than the 88-96%
   this hero used to carry, so the photograph now reads the way it does on
   the agency's own site, while still clearing AA everywhere:

     effective backdrop            #FFFFFF text   #FAF9F6   #DCE9DA focus ring
     right edge   64% of #10261 4   #667363  5.00:1    4.75:1     3.98:1
     x = 70%      68% of #0D1F10    #5A6658  6.05:1    5.75:1     4.82:1
     x = 40%      72% of #0B190D    #4F594D  7.35:1    6.99:1     5.85:1
     left edge    78% of #0A150B    #40483D  9.51:1    9.03:1     7.57:1
     header band  87% of #09130A    #293128 13.39:1   12.71:1    10.65:1

   Required: 4.5:1 for the lede, the eyebrow and the facts (normal text),
   3:1 for the h1 (large text), the outline-button borders and focus rings.
   All hero text is pure #FFFFFF so the 4.5:1 floor holds at the right edge
   as well; nothing in the hero relies on the sage --on-brand-mut, which
   would only reach 3.9:1 out there.

   --------------------------------------------------------------------------
   AND AS ACTUALLY RENDERED
   The figures above are the guaranteed floor. These are measured off the
   real page: the hero was screenshotted with the copy hidden, and each
   element's own bounding box was searched for its single brightest backdrop
   pixel. #FFFFFF text against that worst pixel:

                     375px   768px  1024px  1440px  2560px
     h1               7.53    6.10    7.61    6.88    6.98
     lede             6.17    6.76    7.49    7.63    7.54
     eyebrow         10.20    7.80    9.35    9.24    9.34
     facts            6.61    6.90    7.31    7.75    7.84
     buttons          6.73    6.36    6.58    7.87    7.94
     header logo     14.83   14.99   15.14   15.14   16.34
     header nav         --      --    5.85   13.94   13.04
       (the nav is behind the Menu button below 1024px)

   The --focus-on-dark #DCE9DA ring against the same worst pixels never falls
   below 4.66:1, against a 3:1 requirement.

   If the photograph is ever swapped, re-measure. Nothing else has to change
   so long as the new picture is no brighter than this one; if it is, raise
   the 64% floor in .hero__scrim.
   ========================================================================== */
.hero {
  position: relative;
  isolation: isolate;
  color: #FFFFFF;
  background: var(--brand-900);
  padding-block: clamp(3.5rem, 2rem + 8vw, 8rem);
  overflow: hidden;
}
/* Homepage variant: room at the top for the floating header, room at the
   bottom for the curved sweep. */
.hero--home {
  padding-top: calc(var(--header-h) + clamp(2.5rem, 1.4rem + 5vw, 6rem));
  padding-bottom: calc(var(--curve-h) + clamp(1.5rem, 1rem + 2.5vw, 3.5rem));
}

.hero__media {
  position: absolute;
  left: 0; right: 0;
  /* 12% of head-room top and bottom. The parallax never shifts the box by
     more than 11% of the hero's height (see PARALLAX, section 19a), so a
     full percentage point of the photograph is still in reserve at the
     extreme and no edge can ever be exposed. Whatever is showing — the
     still or the MP4 — is inside this one box, so both parallax the same. */
  top: -12%; bottom: -12%;
  z-index: -2;
  transform: translate3d(0, var(--pshift, 0px), 0);
}
.hero__media > img,
.hero__media > video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 62%;
  border: 0;
}
/* The still is the fallback and stays put. The video only fades in once it is
   genuinely playing, so an absent, blocked or slow MP4 shows the photograph
   and never a black box. Both fill the same absolutely positioned box, so
   swapping between them can never shift the layout. */
.hero__video { opacity: 0; transition: opacity 240ms var(--ease); }
.hero__video.is-playing { opacity: 1; }

.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    /* Horizontal: heaviest under the copy, opening up towards the right so
       the photograph is genuinely visible. Floor 64%. */
    linear-gradient(102deg,
      rgba(10, 21, 11, .78)  0%,
      rgba(11, 25, 13, .72) 40%,
      rgba(13, 31, 16, .68) 70%,
      rgba(16, 38, 20, .64) 100%),
    /* Vertical: seats the floating header at the top and the curved sweep at
       the bottom. Additive only. */
    linear-gradient(180deg,
      rgba(8, 17, 9, .24)  0%,
      rgba(8, 17, 9, 0)   28%,
      rgba(8, 17, 9, 0)   58%,
      rgba(8, 17, 9, .22) 100%);
}
.hero h1, .hero h2, .hero h3 { color: #FFFFFF; }
.hero p,
.hero .lede,
.hero .eyebrow,
.hero__facts li { color: #FFFFFF; }

.hero__inner { max-width: 46rem; }
.hero__title { font-size: var(--fs-4xl); letter-spacing: -0.022em; margin-bottom: var(--sp-5); }
.hero__lede { font-size: var(--fs-md); max-width: 40ch; }

.hero__facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: var(--sp-4) var(--sp-6);
  list-style: none;
  margin: var(--sp-8) 0 0;
  padding: var(--sp-5) 0 0;
  border-top: 1px solid rgba(255,255,255,.34);
  max-width: 42rem;
}
.hero__facts li { margin: 0; max-width: none; font-size: var(--fs-sm); }
.hero__facts b {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 600;
  color: #FFFFFF;
  line-height: 1.15;
  margin-bottom: 2px;
}

/* --- Pause control for the animated hero --------------------------------
   WCAG 2.2.2: anything that moves automatically for more than five seconds
   needs a way to stop it. assets/site.js inserts this button only when a
   video is actually playing, so it never appears while the hero is a still
   photograph. It is absolutely positioned, so inserting it shifts nothing.
   White on rgba(8,17,9,.72) over the lightest possible backdrop = 14.0:1. */
.hero__motion-toggle {
  position: absolute;
  z-index: 3;
  right: var(--gutter);
  bottom: calc(var(--curve-h) * .62);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  min-width: var(--tap);
  padding: var(--sp-2) var(--sp-4);
  border: 2px solid #FFFFFF;
  border-radius: var(--r-pill);
  background: rgba(8, 17, 9, .72);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: #FFFFFF;
  font: inherit;
  font-size: var(--fs-xs);
  font-weight: 650;
  letter-spacing: .02em;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.hero__motion-toggle:hover { background: rgba(8, 17, 9, .88); transform: translateY(-1px); }
.hero__motion-toggle svg { flex: none; }


/* ==========================================================================
   09b  LAYERED CURVE DIVIDERS
   The element the client singled out on his own site: three overlapping
   curved bands in different tones of the brand green, cutting the bottom of
   the hero and opening the closing section.

   Each band is now its OWN <svg> layer so it can carry its own parallax
   rate (section 19a). That makes the no-seam question the important one,
   and it is answered by geometry rather than by the script:

     - one inline <svg> PER BAND, viewBox "0 0 1000 100",
       preserveAspectRatio="none" so the sweep stretches to any width;
     - every band's path runs DOWN TO y = 520 — 420 units past the bottom of
       a 100-unit viewBox — and the band <svg> is overflow: visible, so each
       band really does carry 4.2x the divider's own height of spare fill
       below the join. The largest shift this page ever applies is under a
       fifth of the divider height, so the spare fill is over twenty times
       what any band could need, at any width from 320px to 2560px and at
       any scroll position, in either direction;
     - .curve itself is overflow: hidden with an explicit height, so IT is
       what decides where the divider ends. A band can move; the edge cannot;
     - the divider is pulled 1px past the section edge (top/bottom: -1px),
       so the join overlaps rather than abuts;
     - the front band is filled with the ADJACENT SECTION'S OWN background
       token, so it also follows the dark theme automatically, and it is the
       band given the SMALLEST rate — the seal moves least;
     - parallax is off below 900px and under reduced motion, where every
       band sits at exactly the resting position drawn above;
     - aria-hidden + focusable="false": they are pure decoration.
   ========================================================================== */
.curve {
  position: absolute;
  left: 0;
  right: 0;
  height: var(--curve-h);
  z-index: 2;
  line-height: 0;
  pointer-events: none;
  /* THE SEAM GUARANTEE, PART 2. Each band overshoots its own viewport by
     4.2x the divider height (the path runs to y = 520 in a 100-unit
     viewBox, and the band <svg> is overflow: visible so that spare fill is
     really painted). This box is what clips it, and this box is pinned 1px
     into the neighbouring section. So every band always paints past the
     join, at every scroll position, and this element decides where the
     divider ends — not the bands, which are free to move. */
  overflow: hidden;
}
/* One <svg> per band, stacked, each independently transformable. They are
   layered in DOM order: band 1 furthest back, band 3 (the section's own
   background colour) in front, sealing the join. */
.curve__band {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  display: block;
  width: 100%;
  height: var(--curve-h);
  overflow: visible;            /* let the y > 100 overshoot actually paint */
  /* preserveAspectRatio="none" is on the element; this stops the browser
     antialiasing a seam between two bands that share an edge. */
  shape-rendering: geometricPrecision;
  transform: translate3d(0, var(--pshift, 0px), 0);
}
.curve--bottom { bottom: -1px; }
/* A "top" divider HANGS ABOVE its section, the way the agency's own does: the
   translucent bands arch up into the section before it, and the front band —
   filled with this section's own background — meets its straight top edge.
   That is what turns a hard horizontal join into a curved one. */
.curve--top    { top: calc(1px - var(--curve-h)); }

.curve__band--1 path { fill: var(--curve-1); }
.curve__band--2 path { fill: var(--curve-2); }
.curve__band--3 path { fill: var(--curve-3); }

/* Hero -> page background. Sage, then brand green, then the page itself. */
.curve--hero {
  --curve-1: rgba(139, 186, 147, .42);
  --curve-2: rgba(30, 74, 38, .72);
  --curve-3: var(--paper);
}
/* Page background -> the dark green closing section. */
.curve--brand {
  --curve-1: #5EA871;
  --curve-2: var(--brand-700);
  --curve-3: var(--brand-900);
}
/* A section that opens with a curve is the positioning context for it, and
   must NOT clip it — the bands deliberately reach up past its top edge. */
.has-curve-top { position: relative; }
/* ...so the section before it leaves room for the sweep to arch into. */
.section--before-curve { padding-bottom: calc(var(--section-y) + var(--curve-h) * .75); }

/* --- Interior page hero -------------------------------------------------- */
.page-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: var(--brand-900);
  color: var(--on-brand);
  padding-block: clamp(2.75rem, 1.8rem + 5vw, 5.25rem);
}
.page-hero h1 { color: var(--on-brand); max-width: 19ch; }
.page-hero p { color: var(--on-brand-mut); }
.page-hero__inner { max-width: 42rem; }

/* Plain green variant: a soft tonal wash, no photograph. */
.page-hero--plain {
  background:
    radial-gradient(115% 130% at 88% 0%, rgba(44,106,56,.55) 0%, rgba(44,106,56,0) 62%),
    linear-gradient(145deg, var(--brand-900) 0%, var(--brand) 100%);
}
/* Photo variant: same scrim as the homepage hero. */
.page-hero__media { position: absolute; inset: 0; z-index: -2; }
.page-hero__media img { width: 100%; height: 100%; object-fit: cover; }
.page-hero__scrim {
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(100deg,
    rgba(11,20,9,.96) 0%, rgba(20,49,25,.93) 34%, rgba(20,49,25,.88) 62%,
    rgba(23,55,28,.70) 82%, rgba(30,74,38,.52) 100%);
}
/* Below 1100px the hero copy runs the full width of the container, so it
   reaches the thin end of that gradient — where the scrim is only .52 opaque
   and the photograph is doing most of the work. Hold the wash flat at .90
   instead. Measured worst pixel inside each element's own box, at 375px,
   against the real photograph (was / now):

     specialty-boat      lede 3.13 -> 7.44   crumbs 6.11 -> 8.19   h1 4.76 -> 10.26
     flood-storm-coast   lede 4.33 -> 8.31   crumbs 4.80 -> 8.15   h1 6.67 -> 11.31
     auto (existing)     lede 2.82 -> 7.36   crumbs 4.77 -> 8.11   h1 4.86 -> 10.41
     home (existing)     lede 3.13 -> 7.50   crumbs 3.89 -> 7.72   h1 4.74 -> 10.37
     commercial (exist.) lede 5.80 -> 8.14   crumbs 7.13 -> 8.42   h1 4.89 -> 10.42

   Four of the five were failing the 4.5:1 body-text floor on a phone before
   this rule existed; all five now clear it with room to spare. Above 1100px
   the gradient above applies and the copy box cannot reach past ~64% of the
   band, where it is still .86 opaque: worst measured there is 6.30:1 (Home).
   The five heroes at 1100px, worst element in each: Specialty 7.32, Flood
   7.64, Auto 6.95, Home 6.30, Commercial 8.10. */
@media (max-width: 1099px) {
  .page-hero__scrim {
    background: linear-gradient(100deg,
      rgba(11,20,9,.96) 0%, rgba(20,49,25,.93) 45%, rgba(20,49,25,.90) 100%);
  }
}

.crumbs {
  font-size: var(--fs-xs);
  letter-spacing: .12em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--on-brand-mut);
  margin-bottom: var(--sp-4);
}
.crumbs a { color: #FFFFFF; }


/* ==========================================================================
   10  CARDS + CONTENT BLOCKS
   ========================================================================== */
.card {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-6);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.card h3 { margin-bottom: var(--sp-3); }
.card p { margin-bottom: var(--sp-4); flex: 1 1 auto; }
.card .arrow-link { margin-top: auto; align-self: flex-start; }
.card--flat { background: transparent; border-color: var(--border); }
li.card { margin-bottom: 0; max-width: none; }

/* --- The five coverage cards ---------------------------------------------
   Deliberately ONE treatment for all five, so they read as a single set:
   a green tile carrying a hand-drawn line illustration, then the agency's
   own copy. The real photographs are used at full size on the coverage
   pages themselves, where they have room to be worth looking at. */
.cov-card {
  overflow: hidden;
  padding: 0;
  box-shadow: var(--shadow-sm);
}
/* Hover and keyboard focus get exactly the same treatment, so nothing is
   only discoverable with a mouse. The lift is written as a custom property
   rather than a literal transform, so the pointer tilt in section 19c can
   compose with it instead of overwriting it — and so the keyboard path and
   the pointer path stay a single rule. */
.cov-card { transform: translate3d(0, var(--lift, 0px), 0); }
.cov-card:hover,
.cov-card:focus-within {
  --lift: -4px;
  box-shadow: var(--shadow-md);
  border-color: var(--brand);
}

.cov-card__tile {
  position: relative;
  aspect-ratio: 16 / 9;
  display: grid;
  place-items: center;
  background:
    radial-gradient(120% 140% at 78% 8%, rgba(44,106,56,.85) 0%, rgba(44,106,56,0) 60%),
    linear-gradient(150deg, var(--brand-800) 0%, var(--brand) 100%);
  border-bottom: 1px solid var(--border);
}
.cov-card__tile svg {
  width: 34%; max-width: 92px; height: auto;
  color: var(--on-brand-mut);
  transition: color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.cov-card:hover .cov-card__tile svg,
.cov-card:focus-within .cov-card__tile svg { color: #FFFFFF; transform: scale(1.05); }
.cov-card:hover .arrow-link svg,
.cov-card:focus-within .arrow-link svg { transform: translateX(4px); }

.cov-card__body { display: flex; flex-direction: column; flex: 1 1 auto; padding: var(--sp-6); }
.cov-card__body h3 { margin-bottom: var(--sp-2); }
.cov-card__body p {
  margin-bottom: var(--sp-5);
  flex: 1 1 auto;
  font-size: var(--fs-sm);
  color: var(--muted);
  max-width: none;
}

/* --- Five across: the compact card ---------------------------------------
   At five columns each card is about 200-215px wide, so the internal layout
   tightens: a shallower illustration tile, less padding, a slightly smaller
   heading and a smaller link label. Nothing drops below 13px, the tap target
   stays 44px, and the copy is the agency's own, unabridged. */
@media (min-width: 1180px) {
  .cov-card__tile { aspect-ratio: 16 / 10; }
  .cov-card__tile svg { width: 44%; max-width: 74px; }
  .cov-card__body { padding: var(--sp-5) var(--sp-5) var(--sp-4); }
  .cov-card__body h3 { font-size: var(--fs-lg); }
  .cov-card__body p { margin-bottom: var(--sp-4); line-height: 1.55; }
  .cov-card .arrow-link { font-size: var(--fs-xs); gap: .35em; }
  .cov-card .arrow-link svg { width: 15px; height: 15px; }
}
/* Past ~1500px there is room to relax again. */
@media (min-width: 1500px) {
  .cov-card__body { padding: var(--sp-6) var(--sp-5) var(--sp-5); }
  .cov-card .arrow-link { font-size: var(--fs-sm); }
}

/* --- Numbered steps ------------------------------------------------------ */
.steps { list-style: none; padding: 0; counter-reset: step; display: grid; gap: var(--sp-6); }
.steps li { position: relative; padding-left: 3.75rem; margin: 0; counter-increment: step; max-width: none; }
.steps li::before {
  content: counter(step);
  position: absolute; left: 0; top: .1rem;
  display: grid; place-items: center;
  width: 2.6rem; height: 2.6rem;
  border-radius: 50%;
  background: var(--brand);
  color: #FFFFFF;
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
}
.on-brand .steps li::before { background: #FFFFFF; color: var(--brand-900); }
.steps h3 { margin-bottom: var(--sp-2); font-size: var(--fs-lg); }
.steps p { margin-bottom: 0; }

/* --- Check / cross lists. Shape differs as well as colour, and each item
       carries a screen-reader-only prefix. ---------------------------------- */
.marked-list { list-style: none; padding: 0; display: grid; gap: var(--sp-3); }
.marked-list li { display: flex; gap: var(--sp-3); margin: 0; }
.marked-list svg { flex: none; margin-top: .3em; }
.marked-list .m-yes { color: var(--success); }
.marked-list .m-no  { color: var(--error); }

/* --- Callout ------------------------------------------------------------- */
.callout {
  border-left: 4px solid var(--rule);
  background: var(--surface);
  border-radius: 0 var(--r-lg) var(--r-lg) 0;
  padding: clamp(var(--sp-5), 3vw, var(--sp-7));
  box-shadow: var(--shadow-sm);
}
.callout > :last-child { margin-bottom: 0; }
.callout--warn { border-left-color: var(--error); }
.callout--warn .callout__label { color: var(--error); }
.callout__label {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-xs); font-weight: 800; letter-spacing: .13em;
  text-transform: uppercase; color: var(--accent-text);
  margin-bottom: var(--sp-3);
}

/* --- The contact card (Contact page) --------------------------------------
   What stands where the message form used to. It has to carry the weight the
   form carried, so it is built as a real object: a brand-green panel holding
   the telephone number at display size, then the agency's own explanation of
   why the telephone is the route, then the written alternatives.

   Florida Relay sits INSIDE the green panel, immediately under the number and
   above the fold of the card, because it is a normal way to reach this office
   and not a footnote. Contrast on --brand-900: #FFFFFF 13.45:1, and
   --on-brand-mut is the same token every other on-brand paragraph uses.
   -------------------------------------------------------------------------- */
.contact-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-md);
}
.contact-card__call { padding: clamp(var(--sp-5), 3vw, var(--sp-7)); }
.contact-card__call h2 { font-size: var(--fs-xl); margin-bottom: var(--sp-5); }
.contact-card__number {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: var(--tap);
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 1.1rem + 2.1vw, 2.6rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.015em;
  color: #FFFFFF;
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: .16em;
}
.contact-card__number:hover { color: var(--on-brand-mut); }
.contact-card__icon { display: inline-flex; color: var(--on-brand-mut); }
.contact-card__hours { margin: var(--sp-4) 0 0; font-size: var(--fs-sm); }
.contact-card__relay {
  margin: var(--sp-5) 0 0;
  padding-top: var(--sp-5);
  border-top: 1px solid rgba(255,255,255,.30);
  font-size: var(--fs-sm);
}
.contact-card__relay strong { color: #FFFFFF; }

.contact-card__body { padding: clamp(var(--sp-5), 3vw, var(--sp-7)); }
.contact-card__lede {
  font-size: var(--fs-md);
  font-weight: 500;
  color: var(--ink);
  max-width: none;
}
.contact-card__body p { max-width: none; }
.contact-card__subhead { margin-top: var(--sp-7); font-size: var(--fs-lg); }
.contact-ways { display: grid; gap: var(--sp-4); margin: var(--sp-4) 0 0; }
.contact-ways li { display: flex; gap: var(--sp-3); margin: 0; max-width: none; }
.contact-ways svg { flex: none; color: var(--accent-text); margin-top: .2em; }
.contact-ways b {
  display: block;
  font-size: var(--fs-xs);
  font-weight: 800;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: 2px;
}
.contact-card__note { margin-top: var(--sp-6); color: var(--muted); }
.contact-card__note small { line-height: 1.55; }


/* --- His legal footnote, and the "talk to an agent" note ----------------- */
.disclaimer {
  font-size: var(--fs-sm);
  color: var(--muted);
  background: var(--tint);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--sp-5);
}
.disclaimer > :last-child { margin-bottom: 0; }
.disclaimer p { max-width: none; }

/* --- FAQ ----------------------------------------------------------------- */
.faq { display: grid; gap: var(--sp-6); }
.faq__q { font-size: var(--fs-lg); margin-bottom: var(--sp-2); }
.faq__a { margin-bottom: 0; }

/* --- Contact detail list -------------------------------------------------- */
.detail-list { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--sp-5); }
.detail-list li { display: flex; gap: var(--sp-4); margin: 0; max-width: none; }
.detail-list svg { flex: none; color: var(--accent-text); margin-top: .15em; }
.detail-list .dt {
  font-size: var(--fs-xs); font-weight: 800; letter-spacing: .11em;
  text-transform: uppercase; color: var(--muted); margin: 0 0 2px;
}
.detail-list .dd { font-size: var(--fs-md); font-weight: 600; margin: 0; }
.detail-list dt, .detail-list dd { margin: 0; }

.phone-cta {
  display: inline-flex; align-items: center; gap: var(--sp-3);
  min-height: var(--tap);
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: .18em;
}

.social-list { display: flex; flex-wrap: wrap; gap: var(--sp-2); list-style: none; padding: 0; margin: 0; }
.social-list li { margin: 0; }
.social-list a {
  display: inline-grid; place-items: center;
  width: var(--tap); height: var(--tap);
  border-radius: var(--r-md);
  border: 1px solid rgba(255,255,255,.3);
  color: #FFFFFF;
}
.social-list a:hover { background: rgba(255,255,255,.12); color: #FFFFFF; }


/* ==========================================================================
   11  PHOTOGRAPHY
   ========================================================================== */
.figure { margin: 0; }
.photo {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--r-lg);
  background: var(--mist);
}
.photo-frame {
  position: relative;
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-md);
}
/* A hairline inside the frame keeps light photos from bleeding into paper. */
.photo-frame::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(20, 49, 25, .12);
  pointer-events: none;
}
.photo-frame img { display: block; width: 100%; height: auto; }
/* The portrait frame reserves the box (4/5 of its own width, exactly the box
   the image used to create) and the photograph is laid inside it with 6% of
   head-room top and bottom. The frame's height therefore does not depend on
   the image, so the parallax in section 19a can move the photograph by up to
   4.5% of the frame height without ever exposing an edge and without the
   frame itself moving one pixel. Zero layout shift either way. */
.photo-frame--portrait { aspect-ratio: 4 / 5; }
.photo-frame--portrait img {
  position: absolute;
  top: -6%; bottom: -6%; left: 0; right: 0;
  width: 100%; height: 112%;
  aspect-ratio: auto;
  object-fit: cover;
  object-position: 50% 18%;
  transform: translate3d(0, var(--pshift, 0px), 0);
}
.photo-caption { margin: var(--sp-3) 0 0; font-size: var(--fs-xs); color: var(--muted); }

/* Feature band: a full-width photograph with copy beside it. */
.feature-photo { border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow-md); }
.feature-photo img { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; }
/* A hairline inside the frame, the same one .photo-frame carries, so a pale
   photograph does not bleed into the paper behind it. */
.feature-photo { position: relative; }
.feature-photo::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(20, 49, 25, .12);
  pointer-events: none;
}


/* --------------------------------------------------------------------------
   11b  PHOTO CARDS
   The coverage-card anatomy — a tile above, the agency's copy below — with a
   photograph in the tile where the five coverage cards carry a line
   illustration. Same proportions, same border, same radius, same shadow, so
   a row of photo cards reads as a member of the same family rather than as
   pictures dropped into a grid.

   These are not links and carry no lift, no tilt and no sheen: the five
   coverage cards are the only interactive tiles on the site and nothing here
   is allowed to compete with them.

   The tile reserves its box with aspect-ratio, and the image is given
   explicit width/height as well, so the row's height is known before a
   single byte of photograph has arrived. Zero layout shift.
   -------------------------------------------------------------------------- */
.photo-card { overflow: hidden; padding: 0; box-shadow: var(--shadow-sm); }
.photo-card__media {
  position: relative;
  display: block;
  background: var(--mist);
  border-bottom: 1px solid var(--border);
}
.photo-card__media img {
  display: block;
  width: 100%; height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}
/* A faint green fall-off into the card edge, so the photograph sits down onto
   the surface the way the illustrated tiles do instead of stopping dead.
   Decorative only: nothing is read through it. */
.photo-card__media::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg,
                rgba(20, 49, 25, 0) 52%,
                rgba(20, 49, 25, .16) 88%,
                rgba(20, 49, 25, .26) 100%);
  pointer-events: none;
}
.photo-card__body { display: flex; flex-direction: column; flex: 1 1 auto; padding: var(--sp-6); }
.photo-card__body h3 { margin-bottom: var(--sp-3); }
.photo-card__body p:last-child { margin-bottom: 0; }


/* --------------------------------------------------------------------------
   11c  PHOTO BAND
   A full-bleed photograph carrying one short piece of copy, used as the join
   between two sections on the coverage pages.

   It is deliberately the same construction as the interior page hero: the
   photograph is the backdrop, a deep green scrim is the surface, and the copy
   is pure white on top of it. A band therefore reads as another green section
   that happens to have a picture behind it, not as a photograph that has
   taken the page over — the brand green still leads.

   ZERO LAYOUT SHIFT
   The band's height comes from its own padding and its copy. The photograph
   is absolutely positioned behind that box, so it can arrive late, fail to
   arrive, or be replaced with a taller one, and nothing on the page moves.

   THE SCRIM
   Two layers, as on the homepage hero: a horizontal wash that carries the
   accessibility guarantee, and a soft vertical wash that only ever deepens
   it further at the top and bottom edges.

   Below 900px the copy runs the full width of the container, so the
   horizontal wash is held flat at .88 across the whole band. From 900px up
   the copy is capped at 40rem, which cannot reach past ~75% of the band
   width, and the wash is allowed to open out to .58 at the far right where
   only photograph sits.

   CONTRAST (WCAG 1.4.3 — 4.5:1 body, 3:1 large text)
   Every figure below was measured, not estimated: the real scrim was
   composited over the real photograph at the real element boxes taken off
   the rendered page, and the WORST pixel inside each element's own box was
   used. All band copy is pure white, so one floor covers the eyebrow, the
   heading and the sentence.

     Worst case anywhere, against a hypothetical pure-white photograph:
       .88 of #143119 over #FFFFFF ....................... 7.21:1
       .58 of #1E4A26 over #FFFFFF (far right, no copy) ... 2.44:1  (no text)

     MEASURED on the rendered page — worst pixel inside each element's own
     box, with the real photograph composited under the real scrim at the real
     element rectangles. The desktop column is taken at 900px, which is the
     WORST desktop case: it is the narrowest viewport that gets the opened-out
     gradient, so the 40rem copy box reaches further across the band there
     (~75%) than at any wider viewport (~54% at 1440px). The band figures also
     hold across the full +/-3% parallax travel; the lowest number in the set
     moves by 0.07 across it.

                                    eyebrow   heading   sentence
       specialty, classic car  375    13.58     11.38      10.97
                               900    11.16      9.63       9.18   (9.11 worst
                                                                    over travel)
                              1440    12.11     10.75      10.73
       commercial, warehouse   375    12.19     10.85      11.12
                               900    10.05      8.44       8.71
                              1440    11.45     10.73      10.92

     Lowest figure anywhere in the set: 8.44:1, against a 4.5:1 requirement.

     Only two pages carry a band. The Flood page does not: its photograph is
     the flooded street, which is dark enough that a scrim swallows it, so it
     runs unscrimmed in a .figure frame instead, with no text over it.
   -------------------------------------------------------------------------- */
.photo-band {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: var(--brand-900);
  color: #FFFFFF;
  padding-block: clamp(3rem, 1.9rem + 5.4vw, 6rem);
}
.photo-band__media { position: absolute; inset: 0; z-index: -2; overflow: hidden; }
/* The photograph is 112% of its box and hangs 6% above it, exactly as the
   portrait frame does, so the parallax in section 19a can move it by up to
   3% of the band height in either direction without ever exposing an edge —
   and the band itself never moves one pixel. */
.photo-band__media img {
  position: absolute;
  top: -6%; left: 0; right: 0;
  width: 100%; height: 112%;
  object-fit: cover;
  object-position: 50% 50%;
  transform: translate3d(0, var(--pshift, 0px), 0);
}
.photo-band__scrim {
  position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(180deg, rgba(11,20,9,.34) 0%, rgba(11,20,9,.10) 42%,
                            rgba(11,20,9,.10) 62%, rgba(11,20,9,.36) 100%),
    linear-gradient(100deg, rgba(11,20,9,.94) 0%, rgba(20,49,25,.91) 45%,
                            rgba(20,49,25,.88) 100%);
}
@media (min-width: 900px) {
  .photo-band__scrim {
    background:
      linear-gradient(180deg, rgba(11,20,9,.30) 0%, rgba(11,20,9,0) 38%,
                              rgba(11,20,9,0) 62%, rgba(11,20,9,.30) 100%),
      linear-gradient(100deg, rgba(11,20,9,.95) 0%, rgba(20,49,25,.92) 38%,
                              rgba(20,49,25,.88) 66%, rgba(24,58,30,.76) 86%,
                              rgba(30,74,38,.58) 100%);
  }
}
/* 40rem. The number the scrim's guarantee is written against: at 900px, the
   narrowest viewport that gets the opened-out gradient, a 40rem box still
   stops at about 75% of the band width. Do not widen it without redoing the
   measurement above. */
.photo-band__inner { max-width: 40rem; }
.photo-band h2 { color: #FFFFFF; max-width: 22ch; }
.photo-band p  { color: #FFFFFF; margin-bottom: 0; }
.photo-band .eyebrow { color: #FFFFFF; }
.photo-band .rule::after { background: rgba(255, 255, 255, .85); }


/* ==========================================================================
   12  PEOPLE + TIMELINE
   ========================================================================== */
.people { display: grid; gap: var(--sp-7); }
@media (min-width: 780px) { .people { grid-template-columns: repeat(2, 1fr); } }

.person {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
}
.person__media img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; object-position: 50% 15%; }
.person__body { padding: clamp(var(--sp-5), 3vw, var(--sp-7)); }
.person__role {
  font-size: var(--fs-xs); font-weight: 800; letter-spacing: .13em;
  text-transform: uppercase; color: var(--accent-text); margin-bottom: var(--sp-2);
}
.person h3 { margin-bottom: var(--sp-3); }
.person > .placeholder:first-child {
  border-radius: 0; border-top: 0; border-left: 0; border-right: 0;
  border-bottom: 2px dashed var(--ph-ink);
}

.timeline { list-style: none; padding: 0; margin: 0; position: relative; }
.timeline::before {
  content: ""; position: absolute; left: 7px; top: .7rem; bottom: .7rem;
  width: 2px; background: var(--border); border-radius: 2px;
}
.timeline li { position: relative; padding-left: var(--sp-7); margin-bottom: var(--sp-6); max-width: none; }
.timeline li::before {
  content: ""; position: absolute; left: 0; top: .5rem;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--brand); border: 3px solid var(--paper);
  box-shadow: 0 0 0 2px var(--brand);
}
.timeline__year {
  display: block; font-family: var(--font-display); font-size: var(--fs-lg);
  font-weight: 600; color: var(--brand); line-height: 1.2;
}
@media (prefers-color-scheme: dark) { .timeline__year { color: #86C48F; } }
.timeline p { margin: var(--sp-1) 0 0; }


/* ==========================================================================
   13  PLACEHOLDER SLOTS
   Deliberately visible, so nothing unfinished can pass for real content.
   ========================================================================== */
.placeholder {
  position: relative;
  background: var(--ph-bg);
  border: 2px dashed var(--ph-ink);
  border-radius: var(--r-lg);
  padding: var(--sp-6);
  color: var(--ph-ink);
  display: grid;
  place-items: center;
  gap: var(--sp-3);
  text-align: center;
  min-height: 8rem;
}
.placeholder p { color: var(--ph-ink); margin: 0; max-width: 46ch; font-size: var(--fs-sm); }
.placeholder svg { color: var(--ph-ink); }
.placeholder__badge {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-xs); font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase;
  background: var(--ph-ink);
  color: #FFFFFF;                 /* 6.75:1 on --ph-ink */
  padding: var(--sp-1) var(--sp-3);
  border-radius: var(--r-pill);
}
@media (prefers-color-scheme: dark) { .placeholder__badge { color: #0E120C; } }
.placeholder--photo { aspect-ratio: 4 / 5; min-height: 0; }
.placeholder--wide { min-height: 10rem; }
.placeholder--note { text-align: left; place-items: start; min-height: 0; padding: var(--sp-5); }
.placeholder--note p { max-width: 78ch; }


/* ==========================================================================
   14  FIELDS
   The site has NO form. The agency removed the message form from its own
   website on advice — a free-text box on an insurance site creates a
   written, timestamped request that the agency may not action in time, and
   that is real professional-liability exposure. The Contact page is
   telephone, Florida Relay, fax and postal address instead.

   What is left here is the search field on the Customers page (the carrier
   filter) and the label/hint typography it shares. Everything that belonged
   to the message form — .form, .form-card, .form-status, .error-msg, .req,
   .choice, .hp, the text/email/tel/select/textarea control styling and the
   [aria-invalid] state — has been deleted with it. Do not put it back
   without talking to the agency first.
   ========================================================================== */
.field { display: grid; gap: var(--sp-2); }
label, .label { font-weight: 650; font-size: var(--fs-sm); color: var(--ink); }
.hint { font-size: var(--fs-xs); color: var(--muted); margin: 0; }


/* ==========================================================================
   15  FOOTER
   ========================================================================== */
.site-footer {
  background: var(--brand-900);
  color: var(--on-brand-mut);
  padding-block: var(--sp-9) var(--sp-6);
}
.site-footer h2, .site-footer h3 { color: var(--on-brand); }
.site-footer p { color: var(--on-brand-mut); }
.site-footer a:not(.btn) { color: #FFFFFF; text-decoration: none; }
.site-footer a:not(.btn):hover { color: var(--on-brand-mut); text-decoration: underline; }
.site-footer address { font-style: normal; font-size: var(--fs-sm); line-height: 1.65; }

.footer-grid { display: grid; gap: var(--sp-7); }
@media (min-width: 700px)  { .footer-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1020px) { .footer-grid { grid-template-columns: 1.5fr 1fr 1fr 1.25fr; } }

.footer-title {
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--on-brand-mut);
  margin-bottom: var(--sp-4);
}
.footer-list { list-style: none; padding: 0; margin: 0; }
.footer-list li { margin: 0; }
.footer-list a { display: inline-flex; align-items: center; min-height: var(--tap); font-size: var(--fs-sm); font-weight: 500; }

.footer-brand p { font-size: var(--fs-sm); max-width: 34ch; margin-top: var(--sp-4); }
.footer-phone {
  display: inline-flex; align-items: center; min-height: var(--tap);
  font-family: var(--font-display); font-size: var(--fs-lg); font-weight: 600;
  text-decoration: underline; text-underline-offset: .18em;
}
.footer-placeholder-note { margin-top: var(--sp-2); }

.footer-bottom {
  margin-top: var(--sp-8);
  padding-top: var(--sp-5);
  border-top: 1px solid rgba(255,255,255,.22);
  display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-6);
  align-items: center; justify-content: space-between;
  font-size: var(--fs-xs);
}
.footer-bottom p { margin: 0; font-size: var(--fs-xs); max-width: 70ch; }
.footer-legal { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-5); list-style: none; margin: 0; padding: 0; }
.footer-legal li { margin: 0; }
.footer-legal a { display: inline-flex; align-items: center; min-height: var(--tap); font-size: var(--fs-xs); }

.footer-fineprint { margin-top: var(--sp-5); }
.footer-fineprint small { display: block; max-width: 92ch; line-height: 1.65; color: var(--on-brand-mut); opacity: .92; }


/* ==========================================================================
   16  PROSE (legal / statement pages)
   ========================================================================== */
.prose h2 { margin-top: var(--sp-8); font-size: var(--fs-xl); }
.prose h3 { margin-top: var(--sp-6); font-size: var(--fs-lg); }
.prose > :first-child { margin-top: 0; }
.prose ul, .prose ol { max-width: var(--measure); }
.prose .updated {
  font-size: var(--fs-sm); color: var(--muted);
  border-bottom: 1px solid var(--border); padding-bottom: var(--sp-4);
}
.legal-note {
  border-left: 3px solid var(--ph-ink);
  background: var(--ph-bg);
  color: var(--ph-ink);
  padding: var(--sp-4) var(--sp-5);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  font-size: var(--fs-sm);
  margin-bottom: var(--sp-5);
}
.legal-note p { color: inherit; margin: 0; max-width: none; }
.legal-note b { letter-spacing: .04em; text-transform: uppercase; font-size: var(--fs-xs); }

.toc { background: var(--mist); border: 1px solid var(--border); border-radius: var(--r-lg); padding: var(--sp-5); }
.toc h2 { margin: 0 0 var(--sp-3); font-size: var(--fs-lg); }
.toc ol { margin: 0; }
.toc a { display: inline-flex; align-items: center; min-height: 2rem; }


/* ==========================================================================
   17  ACCORDION  (Customers page: Find Your Carrier)
   The panel is a real [hidden] element, so when it is collapsed its links
   are out of the tab order AND out of the accessibility tree. This is the
   single biggest accessibility defect on the agency's current site.
   ========================================================================== */
.carrier-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--border); }
.carrier-list > li { margin: 0; max-width: none; border-bottom: 1px solid var(--border); }

.carrier-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  width: 100%;
  min-height: 3.75rem;
  padding: var(--sp-4) var(--sp-3);
  background: transparent;
  border: 0;
  border-radius: var(--r-sm);
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-md);
  font-weight: 650;
  text-align: left;
  cursor: pointer;
}
.carrier-toggle:hover { background: var(--mist); color: var(--brand); }
.carrier-toggle__icon {
  flex: none;
  display: grid; place-items: center;
  width: 1.75rem; height: 1.75rem;
  border: 2px solid var(--border-strong);
  border-radius: 50%;
  color: var(--brand);
  transition: transform var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.carrier-toggle:hover .carrier-toggle__icon { border-color: var(--brand); }
.carrier-toggle[aria-expanded="true"] { color: var(--brand); }
.carrier-toggle[aria-expanded="true"] .carrier-toggle__icon { transform: rotate(180deg); border-color: var(--brand); }

.carrier-panel { padding: 0 var(--sp-3) var(--sp-6); }
.carrier-panel[hidden] { display: none; }
.carrier-panel dl { display: grid; gap: var(--sp-3); margin: 0; }
.carrier-panel dt {
  font-size: var(--fs-xs); font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted);
}
.carrier-panel dd { margin: 2px 0 0; }
.carrier-panel a { display: inline-flex; align-items: center; min-height: 2.25rem; font-weight: 600; }

/* Four "how can we help" action cards */
.action-card {
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-top: 3px solid var(--brand);
  border-radius: var(--r-md);
  padding: var(--sp-6);
  box-shadow: var(--shadow-sm);
}
.action-card h3 { font-size: var(--fs-lg); margin-bottom: var(--sp-2); }
.action-card p { font-size: var(--fs-sm); color: var(--muted); flex: 1 1 auto; margin-bottom: var(--sp-4); }
.action-card .arrow-link, .action-card .btn { margin-top: auto; align-self: flex-start; }


/* ==========================================================================
   18  404
   ========================================================================== */
.notfound { display: grid; place-items: center; text-align: center; padding-block: var(--sp-11); }
.notfound__code {
  font-family: var(--font-display);
  font-size: clamp(4rem, 14vw, 8rem);
  line-height: 1;
  color: var(--brand);
  margin: 0 0 var(--sp-4);
}
@media (prefers-color-scheme: dark) { .notfound__code { color: #86C48F; } }
.notfound ul { list-style: none; padding: 0; }


/* ==========================================================================
   19  PROGRESSIVE ENHANCEMENT + MOTION
   Controls that need JavaScript are only shown when <html> has .js, added by
   a two-line inline script in every <head>. With JS off, the whole navigation
   and every carrier panel is visible as plain content: nothing is ever locked
   behind a control that cannot be operated.
   ========================================================================== */
.nav-toggle     { display: none; }
.nav-disclosure { display: none; }
.js .nav-toggle     { display: inline-flex; }
.js .nav-disclosure { display: inline-flex; }
@media (min-width: 1050px) { .js .nav-toggle { display: none; } }

@media (min-width: 1050px) {
  .js .subnav {
    position: absolute;
    top: calc(100% + var(--sp-2));
    left: 0;
    min-width: 21rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-lg);
    padding: var(--sp-3);
    z-index: 110;
  }
  html:not(.js) .subnav { display: flex; gap: var(--sp-1); }
  html:not(.js) .subnav__desc { display: none; }
  /* With JavaScript off every coverage link is laid out inline, which is more
     than one row of header can hold on a laptop. Let it wrap rather than run
     off the edge — body has overflow-x: hidden, so anything that overflows
     would be lost rather than scrollable. */
  html:not(.js) .site-header__inner { flex-wrap: wrap; row-gap: var(--sp-2); }
  html:not(.js) .nav-list { flex-wrap: wrap; justify-content: flex-end; }
  html:not(.js) .nav-cta { margin-left: 0; }
}

/* Carrier accordions collapse only once the script is running. */
.carrier-toggle { display: none; }
.js .carrier-toggle { display: flex; }
html:not(.js) .carrier-panel { padding-top: var(--sp-4); }

/* Reveal-on-scroll: the hidden state is gated on .reveal-anim, which
   assets/site.js adds only when it is running and motion is welcome. If the
   script fails to load, or an IntersectionObserver never fires, nothing is
   ever hidden — the class that hides is only ever added by the script that
   is also responsible for un-hiding.
   Transform + opacity only: a reveal can never cause layout shift. */
.reveal-anim .reveal {
  opacity: 0;
  /* The independent `translate` property, deliberately NOT `transform`: a card
     that is also a reveal target uses `transform` for its hover/focus lift,
     and the two would otherwise overwrite each other. Browsers without
     `translate` still get the fade. */
  translate: 0 18px;
  /* --ease-out-soft is a long, heavy decelerate: most of the distance is
     covered early and the last few pixels are almost free. It reads as
     weight rather than as an animation. The fade finishes before the move
     does, so nothing is still visibly sliding while it is legible. */
  transition: opacity 560ms var(--ease-out-soft), translate 840ms var(--ease-out-soft);
  transition-delay: var(--reveal-delay, 0ms);
}
.reveal-anim .reveal.is-visible { opacity: 1; translate: none; }

/* Stagger. Written in CSS rather than set from JavaScript, so the delays
   cannot outlive the animation. 90ms steps: slow enough to read as one row
   arriving in sequence, short enough that the last card is not left behind. */
.reveal-anim .grid--4 > .reveal:nth-child(1) { --reveal-delay:   0ms; }
.reveal-anim .grid--4 > .reveal:nth-child(2) { --reveal-delay:  90ms; }
.reveal-anim .grid--4 > .reveal:nth-child(3) { --reveal-delay: 180ms; }
.reveal-anim .grid--4 > .reveal:nth-child(4) { --reveal-delay: 270ms; }
.reveal-anim .grid--5 > .reveal:nth-child(1) { --reveal-delay:   0ms; }
.reveal-anim .grid--5 > .reveal:nth-child(2) { --reveal-delay:  90ms; }
.reveal-anim .grid--5 > .reveal:nth-child(3) { --reveal-delay: 180ms; }
.reveal-anim .grid--5 > .reveal:nth-child(4) { --reveal-delay: 270ms; }
.reveal-anim .grid--5 > .reveal:nth-child(5) { --reveal-delay: 360ms; }
/* The two-column sections: copy first, then the thing beside it. */
.reveal-anim .split > .reveal:nth-child(2) { --reveal-delay: 130ms; }

/* --- The green rule marks draw themselves in -----------------------------
   scaleX from the left, not an animated width: transform only, so it cannot
   cost a layout. It starts a beat after its heading has begun to arrive, so
   it reads as underlining the heading rather than racing it. Gated on
   .reveal-anim like everything else here, so with the script absent or
   reduced motion on, the rule is simply drawn. */
.reveal-anim .reveal .rule::after,
.reveal-anim .reveal.rule::after {
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 820ms var(--ease-out-soft);
  transition-delay: calc(var(--reveal-delay, 0ms) + 240ms);
}
.reveal-anim .center .rule::after { transform-origin: center; }
.reveal-anim .reveal.is-visible .rule::after,
.reveal-anim .reveal.is-visible.rule::after { transform: scaleX(1); }

/* --- The portrait uncovers itself ----------------------------------------
   A curtain in the section's own background colour, collapsed downwards on
   entry. transform: scaleY only. The curtain is painted by ::before, which
   exists ONLY under .reveal-anim, so with JavaScript off there is no
   curtain to be stuck in front of the photograph. */
.reveal-anim .reveal .photo-frame--portrait::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  background: var(--mist);
  transform-origin: 50% 100%;
  transform: scaleY(1);
  transition: transform 940ms var(--ease-out-soft);
  transition-delay: calc(var(--reveal-delay, 0ms) + 120ms);
  pointer-events: none;
}
.reveal-anim .reveal.is-visible .photo-frame--portrait::before { transform: scaleY(0); }


/* --------------------------------------------------------------------------
   19a  LAYERED SCROLL PARALLAX
   The thing the agency singled out on its own site: the white curved sweep
   does not travel with the photograph behind it. Here every layer has its
   own rate, so they separate as the page moves and re-converge as it stops.

   ONE custom property, --pshift, in pixels, written by assets/site.js and
   applied by these rules as translate3d. Transform only, on elements that
   are already positioned: no layer can cost a layout or a pixel of CLS.

   RATES (the script owns the numbers; this is the shape of it)
     hero group, anchored at scroll 0 so the first paint is the design:
       photograph            0.200 of scroll, capped at 11% of hero height
       hero curve band 1     0.075      (furthest back, the sage band)
       hero curve band 2     0.056
       hero curve band 3     0.038      (the seal: moves least)
       the hero section itself, and all of its copy: 1.000
     closing curve, centred on its own transit of the viewport:
       band 1  +/-22px    band 2  +/-13px    band 3  +/-4px
     Ian's portrait   +/-4.5% of the frame height
     photo band       +/-3% of the band height (11c). The band does not move;
                      only the photograph inside it does, and it overhangs
                      its box by 6% top and bottom, so no edge can appear.
     closing copy     -9px .. +9px, slightly AHEAD of the page, so it sits
                      in front of the bands rather than behind them.

   Everything here is inert until .parallax-on is on <html>, which
   assets/site.js adds only when the viewport is at least 900px wide AND
   prefers-reduced-motion is not "reduce". It is removed again, and every
   --pshift cleared, the moment either stops being true.
   -------------------------------------------------------------------------- */
.parallax-on .hero__media,
.parallax-on .curve__band,
.parallax-on .photo-frame--portrait img,
.parallax-on .photo-band__media img,
.parallax-on .cta-drift { will-change: transform; }
.cta-drift { transform: translate3d(0, var(--pshift, 0px), 0); }

/* --------------------------------------------------------------------------
   19c  POINTER TILT + SHEEN  (the five coverage tiles)

   A shallow 3D tilt that follows the cursor across a card, with a soft
   highlight travelling with it. Both are transform + opacity only.

   WHO GETS IT
     - Only pointing devices: the whole block is inside
       (hover: hover) and (pointer: fine), so a touch screen never gets it
       and no card can be left stuck mid-tilt by a stray tap. The script
       tests the SAME media query with matchMedia before it listens to
       anything, and re-tests it live.
     - Keyboard users get the lift, the shadow, the border and the tile
       accent through :focus-within — the same states hover already gave
       them — but NOT the tilt, because there is no cursor to derive an
       angle from and a rotated card would only make the focus ring harder
       to follow. The ring itself is drawn on the untransformed card.
     - Nobody gets it under prefers-reduced-motion.

   The tilt is composed from custom properties, so the resting state, the
   :focus-within lift and the pointer tilt are one transform and never fight.
   The card's own <a> stays a plain link inside a rotated box: rotation does
   not change hit testing, so clicking, tabbing and the focus ring all behave
   exactly as they did before.
   -------------------------------------------------------------------------- */
@media (hover: hover) and (pointer: fine) {
  .tilt-on .cov-card {
    transform:
      perspective(900px)
      rotateX(var(--tilt-x, 0deg))
      rotateY(var(--tilt-y, 0deg))
      translate3d(0, var(--lift, 0px), 0);
    /* Long ease BACK to flat when the pointer leaves. While the pointer is
       actually on the card the script adds .is-tilting, which shortens this
       to a tracking-speed value — so it follows the cursor, but it never
       snaps home. */
    transition: transform 620ms var(--ease-out-soft),
                box-shadow var(--dur) var(--ease),
                border-color var(--dur) var(--ease);
  }
  .tilt-on .cov-card.is-tilting {
    transition: transform 120ms linear,
                box-shadow var(--dur) var(--ease),
                border-color var(--dur) var(--ease);
  }
  /* Hover and keyboard focus lift by the same amount. The keyboard path
     simply stops at the lift; it never gets an angle. */
  .tilt-on .cov-card:hover,
  .tilt-on .cov-card:focus-within { --lift: -6px; }

  /* The sheen. A soft circle of light parked at the centre of the tile and
     moved by transform alone — the gradient itself never changes, so this
     is a composited move, not a repaint of a gradient. */
  .tilt-on .cov-card__tile { overflow: hidden; }
  .tilt-on .cov-card__tile::after {
    content: "";
    position: absolute;
    left: 50%; top: 50%;
    width: 260px; height: 260px;
    margin: -130px 0 0 -130px;
    border-radius: 50%;
    background: radial-gradient(circle closest-side,
                  rgba(255,255,255,.26) 0%,
                  rgba(255,255,255,.10) 45%,
                  rgba(255,255,255,0)   72%);
    opacity: 0;
    pointer-events: none;
    transform: translate3d(var(--sheen-x, 0px), var(--sheen-y, 0px), 0);
    transition: opacity 380ms var(--ease);
  }
  .tilt-on .cov-card.is-tilting .cov-card__tile::after { opacity: 1; }
  .tilt-on .cov-card.is-tilting .cov-card__tile::after { will-change: transform; }
}


/* --------------------------------------------------------------------------
   REDUCED MOTION
   Everything added for the redesign is switched off here, not merely
   shortened: the scroll reveals, the card lift, the button lift, the arrow
   nudge, the illustration scale, the header fade and the hero parallax. The
   page renders in its final state immediately. assets/site.js checks the same
   media query and additionally never requests the hero video at all.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
  .reveal-anim .reveal { opacity: 1 !important; translate: none !important; transform: none !important; }
  /* The rule marks are drawn, the portrait is uncovered, and every parallax
     layer sits at its resting position. Not shortened — absent. */
  .reveal-anim .reveal .rule::after,
  .reveal-anim .reveal.rule::after,
  .reveal-anim .reveal.is-visible .rule::after { transform: none !important; }
  .reveal-anim .reveal .photo-frame--portrait::before { content: none !important; }
  .hero__media,
  .curve__band,
  .photo-frame--portrait img,
  .photo-band__media img,
  .cta-drift { transform: none !important; will-change: auto !important; }
  .btn:hover,
  .cov-card,
  .cov-card:hover,
  .cov-card:focus-within,
  .hero__motion-toggle:hover { transform: none !important; }
  .cov-card__tile::after { display: none !important; }
  .arrow-link:hover svg,
  .arrow-link:focus-visible svg,
  .cov-card:hover .arrow-link svg,
  .cov-card:focus-within .arrow-link svg { transform: none; }
  .cov-card:hover .cov-card__tile svg,
  .cov-card:focus-within .cov-card__tile svg { transform: none; }
}


/* ==========================================================================
   19b  MOBILE BODY-COPY FLOOR
   Several components drop to --fs-sm (15px) on desktop, where they sit in a
   narrow column. On a phone those columns are full width, so there is no
   reason for running copy to be under 16px. Deliberately placed after every
   component rule so it wins the cascade without needing !important.
   Uppercase micro-labels (.eyebrow, .callout__label, .dt, .person__role) are
   not running copy and stay at their label size.
   ========================================================================== */
@media (max-width: 899px) {
  .cov-card__body p,
  .action-card p,
  .disclaimer p,
  .legal-note p,
  .prose .updated,
  .hero__facts li { font-size: var(--fs-base); }
}


/* ==========================================================================
   20  UTILITIES + PRINT
   These exist so no page needs an inline style="" attribute, which lets the
   Content-Security-Policy in _headers omit style-src 'unsafe-inline'.
   Keep it that way when hand-editing.
   ========================================================================== */
.list-plain { list-style: none; padding: 0; }
.list-left  { text-align: left; display: inline-block; }
.not-italic { font-style: normal; }
.fw-normal  { font-weight: 400; }
.mx-auto    { margin-inline: auto; }
.mt-md  { margin-top: var(--sp-5); }
.mt-lg  { margin-top: var(--sp-6); }
.mt-xl  { margin-top: var(--sp-7); }
.mt-2xl { margin-top: var(--sp-8); }
.mb-lg  { margin-bottom: var(--sp-6); }
.hide-sm { display: none; }
@media (min-width: 760px) { .hide-sm { display: inline; } }

code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: .92em;
  background: var(--tint);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: .1em .35em;
}

@media print {
  .site-header, .site-footer, .skip-link, .btn-row, .hero__media, .hero__scrim { display: none !important; }
  body { background: #fff; color: #000; }
  .hero, .page-hero, .on-brand { background: #fff !important; color: #000 !important; }
  .hero h1, .page-hero h1, .on-brand h2, .on-brand p, .hero p { color: #000 !important; }
  .carrier-panel[hidden] { display: block !important; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .8em; }
}

/* --- Customers page: filter + expand-all toolbar -------------------------- */
.carrier-tools {
  display: grid;
  gap: var(--sp-4);
  align-items: end;
  margin-bottom: var(--sp-2);
}
@media (min-width: 700px) {
  .carrier-tools { grid-template-columns: 1fr auto; }
  .carrier-tools .hint { grid-column: 1 / -1; order: 3; }
}
.carrier-tools .field { max-width: 26rem; }
input[type="search"] {
  width: 100%;
  min-height: var(--tap);
  padding: var(--sp-3) var(--sp-4);
  background: var(--field-bg);
  color: var(--ink);
  border: 2px solid var(--border-strong);
  border-radius: var(--r-md);
  font: inherit;
  font-size: var(--fs-base);
  transition: border-color var(--dur) var(--ease);
}
input[type="search"]:hover { border-color: var(--brand); }
input::placeholder { color: var(--muted); opacity: 1; }
#carrier-count:empty { display: none; }
