/* ============================================================================
   Practice IQ — GLENN'S DRAFT · stylesheet v2
   Restyle pass 2026-07-27 (Joseph: "less monotonous, better sectioning and
   backgrounds, more bullet points, icons").

   v1 problem: five platform pillars that were structurally identical (eyebrow
   → h2 → list → notice) on the same white background, and capability lists
   marked with a thin dash that did not read as bullets.

   v2: four background tiers in rotation, a numbered + icon'd head per pillar,
   real disc bullets, icon tiles on every card, and outcome chips.
   Icons are one inline SVG sprite per page — no CDN, no icon font.
   ============================================================================ */

:root {
  --navy:        #0E2A45;
  --navy-deep:   #08192A;
  --ink:         #12253A;          /* darker than v1 for body contrast */
  --ink-muted:   #4E6377;
  --accent:      #07595F;
  --accent-hi:   #0B7A82;
  --accent-soft: #D9EDEE;
  --gold:        #B07A1E;
  /* Reserved for the calculator's total and nothing else. See .bignum--green. */
  --green:       #047857;          /* on white  — 5.48:1 */
  --green-hi:    #34D399;          /* on navy   — 7.61:1 */
  --green-soft:  #E8F7F1;
  --bg:          #FFFFFF;
  --tint-1:      #F3F7FA;
  --tint-2:      #EAF4F4;
  --rule:        #D2DEE7;
  --rule-soft:   #E6EDF2;

  --container-max: 1140px;
  --gutter:        32px;
  --section-pad-y: 104px;
  --measure:       68ch;

  --s1: 8px;  --s2: 16px; --s3: 24px; --s4: 32px;
  --s5: 48px; --s6: 64px; --s7: 88px; --s8: 120px;

  --radius: 4px;

  --font-head: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-body: "Source Sans 3", "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
}

@media (max-width: 760px) {
  :root { --gutter: 20px; --section-pad-y: 68px; }
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg, #FFFFFF);
  color: var(--ink, #12253A);
  font-family: var(--font-body);
  font-size: 18px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
@media (max-width: 760px) { body { font-size: 17px; } }

/* `height: auto` is load-bearing, not tidy-up. Every <img> on this site carries
   width/height attributes (correctly, to reserve layout space). Constraining the
   width to 100% without releasing the height pins the element to the ATTRIBUTE
   height while the width shrinks, so on a narrow phone the picture is stretched
   vertically. It does not bite today only because .figure img and .shot img each
   set a height of their own; it would bite the first image added outside them. */
img, svg { max-width: 100%; height: auto; }

a:focus-visible, button:focus-visible, input:focus-visible,
textarea:focus-visible, select:focus-visible {
  outline: 3px solid var(--accent-hi, #0B7A82);
  outline-offset: 2px;
}

.skip-link {
  position: absolute; top: 0; left: 0;
  width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  background: var(--navy, #0E2A45); color: #FFFFFF;
  z-index: 100; text-decoration: none; font-weight: 700;
}
.skip-link:focus {
  width: auto; height: auto; min-height: 44px;
  display: inline-flex; align-items: center;
  clip: auto; clip-path: none; padding: var(--s2, 16px) var(--s3, 24px);
}

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---------------------------------------------------------- structure */

.wrap { max-width: var(--container-max, 1140px); margin-inline: auto; padding-inline: var(--gutter, 32px); }
.wrap--narrow > * { max-width: 860px; }

/* FOUR background tiers in rotation, so no two adjacent bands look alike */
.section        { padding-block: var(--section-pad-y, 104px); }
.section--tint  { background: var(--tint-1, #F3F7FA); }
.section--tint2 { background: var(--tint-2, #EAF4F4); }
.section--navy  { background: var(--navy, #0E2A45); color: #FFFFFF; }
.section--navy h2, .section--navy h3, .section--navy h4 { color: #FFFFFF; }
.section--navy p, .section--navy .lede { color: #CFDDE7; }
.section--navy .eyebrow { color: #7FD0D6; }

hr.rule { border: 0; border-top: 1px solid var(--rule, #D2DEE7); margin: 0; }

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

h1, h2, h3, h4 {
  font-family: var(--font-head);
  color: var(--navy, #0E2A45);
  margin: 0; font-weight: 700; letter-spacing: -0.015em; text-wrap: balance;
}
h1 { font-size: clamp(34px, 4.6vw, 54px); line-height: 1.08; }
h2 { font-size: clamp(27px, 3.2vw, 38px); line-height: 1.16; }
h3 { font-size: clamp(20px, 2.1vw, 25px); line-height: 1.25; letter-spacing: -0.01em; }
h4 { font-size: 19px; line-height: 1.3; letter-spacing: 0; }

p { margin: 0 0 var(--s3, 24px); max-width: var(--measure, 68ch); }
p:last-child { margin-bottom: 0; }

/* Eyebrow now carries a rule + optional icon, so it reads as a section marker
   rather than another line of text */
.eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-body);
  font-size: 15px; font-weight: 700; letter-spacing: 0.02em;
  color: var(--accent, #07595F);
  margin: 0 0 var(--s2, 16px);
  padding-bottom: 6px;
  border-bottom: 2px solid var(--accent-hi, #0B7A82);
}
.section--navy .eyebrow { border-bottom-color: #7FD0D6; }

.lede { font-size: 20px; line-height: 1.55; color: var(--ink-muted, #4E6377); }
.muted { color: var(--ink-muted, #4E6377); }
.small { font-size: 16px; }

a.textlink { color: var(--accent, #07595F); text-decoration: underline; text-underline-offset: 3px; font-weight: 600; }
a.textlink:hover { color: var(--accent-hi, #0B7A82); }

/* ---------------------------------------------------------------- icons */

.ico { width: 24px; height: 24px; flex: 0 0 auto; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.ico--sm { width: 19px; height: 19px; }

/* the tile that sits at the top of a card or pillar */
.icotile {
  width: 56px; height: 56px; border-radius: var(--radius, 4px);
  background: var(--accent-soft, #D9EDEE);
  color: var(--accent, #07595F);
  display: inline-flex; align-items: center; justify-content: center;
  margin-bottom: var(--s3, 24px);
}
.icotile .ico { width: 28px; height: 28px; }
.icotile--navy { background: rgba(255,255,255,.12); color: #7FD0D6; }
.icotile--gold { background: #F6EDDC; color: var(--gold, #B07A1E); }

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

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  font-family: var(--font-body);
  font-size: 17px; font-weight: 700; line-height: 1.2;
  min-height: 54px; min-width: 240px;
  padding: var(--s2, 16px) var(--s4, 32px);
  border-radius: var(--radius, 4px);
  text-decoration: none; border: 2px solid transparent;
  transition: background-color 130ms ease, color 130ms ease, border-color 130ms ease;
  cursor: pointer;
}
.btn--primary { background: var(--accent, #07595F); color: #FFFFFF; border-color: var(--accent, #07595F); }
.btn--primary:hover { background: var(--accent-hi, #0B7A82); border-color: var(--accent-hi, #0B7A82); }
.btn--outline { background: transparent; color: var(--navy, #0E2A45); border-color: var(--navy, #0E2A45); }
.btn--outline:hover { background: var(--navy, #0E2A45); color: #FFFFFF; }
.btn--onnavy { background: #FFFFFF; color: var(--navy, #0E2A45); border-color: #FFFFFF; }
.btn--onnavy:hover { background: transparent; color: #FFFFFF; }
.btn--ghostnavy { background: transparent; color: #FFFFFF; border-color: rgba(255,255,255,.6); }
.btn--ghostnavy:hover { background: #FFFFFF; color: var(--navy, #0E2A45); border-color: #FFFFFF; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--s2, 16px); margin-top: var(--s5, 48px); }
.btn-row--center { justify-content: center; }
@media (max-width: 560px) { .btn { width: 100%; min-width: 0; } }

/* ------------------------------------------------------------ nav / foot */

/* FLOATING HEADER — a pill inset from the viewport edges, translucent with a
   blur, riding over the page rather than sitting above it.
   Height is the constraint, not the look: a fixed bar that eats more than 20%
   of a phone viewport fails the geometry gate, and the earlier sticky version
   did exactly that at 220px. This one is measured to stay well under. */
/* STICKY, not fixed. Fixed is out of flow, so the bar sits on top of the
   document at every scroll position and the geometry gate reports occluded
   text no matter how much padding the hero gets. Sticky keeps the bar in
   flow (nothing is covered at rest) and still floats and follows on scroll,
   which is the whole point of the pill. The hero is pulled up by exactly the
   bar's height so the glass still reads as floating ON the photo. */
/* The bar follows the page. It was `absolute`, so it scrolled away with the
   hero despite the comment below calling it sticky. `fixed` is safe here:
   .pagewrap is only `position: relative`, with no transform/filter/perspective
   anywhere above it, which are the things that would silently re-root a fixed
   element to an ancestor instead of the viewport. The glass is dark enough to
   hold white text over BOTH the photo heroes and the white sections it now
   travels across; measured, not assumed. */
.sitehead {
  position: fixed; top: 12px; left: 0; right: 0; z-index: 60;
  background: transparent; border: 0;
  pointer-events: none;
}
.sitehead .wrap { pointer-events: auto; }
.sitehead .bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s4, 32px); flex-wrap: wrap;
  padding: 8px 10px 8px 22px;
  background: rgba(10,28,46,.78);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  backdrop-filter: blur(16px) saturate(150%);
  border: 1px solid rgba(255,255,255,.14);
  border-radius: 100px;
  box-shadow: 0 10px 34px rgba(0,0,0,.28);
}
/* Pull the hero up under the sticky bar so the pill floats on the photo,
   then push the COPY down past it. Measured bar: 62px desktop, 56px mobile,
   plus a 12px / 8px inset. */
.hero, .hero--image { padding-top: calc(var(--s8, 120px) + 40px); }
@media (max-width: 760px) {
  .hero, .hero--image { padding-top: calc(var(--s7, 88px) + 40px); }
}
.wordmark {
  font-family: var(--font-head); font-weight: 700; font-size: 21px;
  letter-spacing: -0.02em; color: #FFFFFF; text-decoration: none;
  min-height: 44px; display: inline-flex; align-items: center; white-space: nowrap;
}
.wordmark span { color: #7FD0D6; }
.sitenav { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s4, 32px); }
.sitenav a {
  font-size: 16px; font-weight: 600; color: #D7E4EC; text-decoration: none;
  min-height: 44px; display: inline-flex; align-items: center;
  border-bottom: 2px solid transparent;
}
.sitenav a:hover, .sitenav a[aria-current="page"] { color: #FFFFFF; border-bottom-color: #7FD0D6; }
/* Deep links live in the markup on every page but only surface inside the
   burger. The desktop bar has to stay ONE row (a 3-row wrap is what pushed the
   old header to 220px and failed the viewport check), so they are display:none
   here and flex inside the panel below. */
.sitenav a.subnav { display: none; }
/* Phone: the bar has to stay ONE nav row. Short labels do that; a 3-row wrap
   is what pushed the old header to 220px and failed the viewport check. */
/* ------------------------------------------------------- burger (mobile)
   Wordmark + burger on ONE row takes the bar from 80px to ~54px, which is
   the real fix for the height problem: nav links wrapping is what made it
   tall, so the links come out of the bar entirely. */

.navtoggle {
  display: none;
  width: 46px; height: 46px; padding: 0;
  align-items: center; justify-content: center;
  background: transparent; border: 1px solid rgba(255,255,255,.22);
  border-radius: 50%; cursor: pointer;
}
.navtoggle span {
  position: relative; display: block; width: 19px; height: 2px;
  background: #FFFFFF; border-radius: 2px;
  transition: background-color 120ms ease;
}
.navtoggle span::before, .navtoggle span::after {
  content: ""; position: absolute; left: 0; width: 19px; height: 2px;
  background: #FFFFFF; border-radius: 2px;
  transition: transform 160ms ease, top 160ms ease;
}
.navtoggle span::before { top: -6px; }
.navtoggle span::after  { top: 6px; }
.navtoggle[aria-expanded="true"] span { background: transparent; }
.navtoggle[aria-expanded="true"] span::before { top: 0; transform: rotate(45deg); }
.navtoggle[aria-expanded="true"] span::after  { top: 0; transform: rotate(-45deg); }

@media (max-width: 760px) {
  .sitehead { top: 8px; }
  .sitehead .bar { padding: 4px 4px 4px 16px; gap: var(--s2, 16px); border-radius: 30px; flex-wrap: nowrap; }
  .wordmark { font-size: 18px; min-height: 46px; }
  .navtoggle { display: inline-flex; }

  /* the panel drops out of the pill, same glass, own rounded card */
  .sitenav {
    position: absolute; top: calc(100% + 8px); left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    padding: 8px;
    background: rgba(10,28,46,.94);
    -webkit-backdrop-filter: blur(16px) saturate(150%);
    backdrop-filter: blur(16px) saturate(150%);
    border: 1px solid rgba(255,255,255,.14);
    border-radius: 18px;
    box-shadow: 0 16px 44px rgba(0,0,0,.36);
    /* display:none, NOT visibility:hidden. A hidden panel still occupies its
       box and sits on top of the hero, which the geometry gate correctly
       reports as four occluded links. Hidden is not gone. */
    display: none;
  }
  .sitehead .wrap { position: relative; }
  .sitenav[data-open="true"] { display: flex; }
  /* Eleven items do not fit a 320x568 screen, so the panel scrolls itself
     rather than pushing the page or spilling off the bottom. */
  .sitenav[data-open="true"] {
    max-height: calc(100dvh - 104px);
    overflow-y: auto; overscroll-behavior: contain;
  }
  .sitenav[data-open="true"] a.subnav { display: flex; }
  .sitenav .subnav {
    font-size: 15.5px; font-weight: 600; color: #A9C2D3;
    min-height: 46px; padding-left: 30px; position: relative;
  }
  .sitenav .subnav::before {
    content: ""; position: absolute; left: 15px; top: 50%;
    width: 7px; height: 1px; background: #7FD0D6;
  }
  .sitenav .subnav:hover { color: #FFFFFF; }
  .sitenav a {
    min-height: 50px; font-size: 17px; padding-inline: 14px;
    border-bottom: 1px solid rgba(255,255,255,.10);
    border-radius: 0; justify-content: flex-start;
  }
  .sitenav a:last-child { border-bottom: 0; }
  .sitenav a:hover, .sitenav a[aria-current="page"] {
    border-bottom-color: rgba(255,255,255,.10);
    background: rgba(255,255,255,.08); color: #FFFFFF;
  }
}
@media (prefers-reduced-motion: reduce) {
  .sitenav, .navtoggle span, .navtoggle span::before, .navtoggle span::after { transition: none !important; }
}

.sitefoot { background: var(--navy-deep, #08192A); color: #B4C7D6; padding-block: var(--s6, 64px); font-size: 16px; }
.sitefoot h4 { color: #FFFFFF; margin-bottom: var(--s2, 16px); }
.sitefoot a { color: #8FD3D9; }
.sitefoot p { max-width: 68ch; }
.foot-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: var(--s6, 64px); }
@media (max-width: 800px) { .foot-grid { grid-template-columns: 1fr; gap: var(--s5, 48px); } }
.foot-links { list-style: none; margin: 0; padding: 0; }
.foot-links li { margin-bottom: 10px; }
.foot-links a { display: inline-flex; align-items: center; gap: 8px; }

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

.hero {
  position: relative; overflow: hidden; isolation: isolate;
  background: var(--navy, #0E2A45);
  background-image:
    radial-gradient(ellipse 900px 500px at 82% 8%, rgba(11,122,130,.42), transparent 62%),
    radial-gradient(ellipse 700px 420px at 8% 96%, rgba(11,122,130,.18), transparent 60%);
  color: #FFFFFF; padding-block: var(--s8, 120px);
}
.hero > .wrap { position: relative; z-index: 1; }

/* HERO ART — an abstract connected-network motif, drawn rather than
   photographed. Practice IQ has no practices, no doctors and no offices, so
   there is nothing real to photograph, and licensed stock of "a practice"
   would imply ownership the company does not have. This depicts the idea in
   Glenn's own copy ("a connected platform of high-performing practices")
   without asserting a single fact.
   Weighted to the right so the left half stays clean under the headline. */
.hero-art {
  position: absolute; inset: 0; width: 100%; height: 100%;
  z-index: 0; pointer-events: none;
  opacity: .85;
}
@media (max-width: 900px) { .hero-art { opacity: .5; } }
.hero h1 { color: #FFFFFF; max-width: 19ch; }
.hero .eyebrow { color: #7FD0D6; border-bottom-color: #7FD0D6; }
.hero .tagline {
  font-family: var(--font-head); font-weight: 700;
  font-size: clamp(19px, 2.1vw, 24px); color: #7FD0D6;
  margin: var(--s3, 24px) 0 0; letter-spacing: -0.01em;
}
.hero p.lede, .hero p { color: #D2E0EA; }
.hero p.lede { margin-top: var(--s4, 32px); max-width: 62ch; }
@media (max-width: 760px) { .hero { padding-block: var(--s7, 88px); } }

/* ---------------------------------------------------------------- imagery
   These are brand RENDERINGS, not photographs of operating locations. The
   company has no headquarters, no practices and no patients. They are used
   as concept imagery and the page says so once, in `.render-note`, so no
   reader mistakes them for documentary evidence. Removing that note is a
   deliberate decision, not a tidy-up. */

.shot { position: relative; overflow: hidden; background: var(--tint-1, #F3F7FA); }
.shot img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* FULL-BLEED PHOTO HERO.
   Scrim is two layers on purpose: a left-weighted horizontal wash so the
   headline column sits on near-solid navy while the right side of the frame
   (patient, window, mountains) stays readable as a picture, plus an overall
   darkening so nothing depends on where the crop lands at a given width.
   Every value below was set from measured pixels, not by eye. */
/* The backdrop is a CSS background, not an <img>. It is purely decorative
   (aria-hidden, empty alt), and a decorative image in the DOM is an element
   the geometry gate correctly reports as occluded by the copy sitting on it.
   Preloaded in the <head> so moving it out of the DOM costs nothing on LCP. */
.hero--image { position: relative; overflow: hidden; background: var(--navy, #0E2A45); }
.hero--image .hero-bg {
  position: absolute; inset: 0; z-index: 0;
  background-image: url("img/consult.jpg");
  background-size: cover;
  background-position: 62% 42%;
  background-repeat: no-repeat;
}
.hero--image .hero-bg::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(100deg, rgba(8,22,38,.96) 0%, rgba(8,22,38,.93) 34%, rgba(8,22,38,.72) 56%, rgba(8,22,38,.45) 78%, rgba(8,22,38,.38) 100%),
    linear-gradient(to top, rgba(8,22,38,.55), rgba(8,22,38,0) 45%);
}
.hero--image > .wrap { position: relative; z-index: 1; }
.hero--image .hero-copy { max-width: 640px; }

/* Hero bullets. Replaces 81 words of hero prose with four scannable lines. */
.hero-points { list-style: none; margin: var(--s4, 32px) 0 0; padding: 0; max-width: 34em; }
.hero-points li {
  position: relative; padding: 9px 0 9px 34px;
  font-size: 18px; line-height: 1.45; color: #E4EDF4;
  border-top: 1px solid rgba(255,255,255,.16);
}
.hero-points li:first-child { border-top: 0; }
.hero-points li::before {
  content: ""; position: absolute; left: 4px; top: 18px;
  width: 13px; height: 7px;
  border-left: 2.5px solid #7FD0D6; border-bottom: 2.5px solid #7FD0D6;
  transform: rotate(-45deg);
}

@media (max-width: 960px) {
  /* on a phone the text spans the frame, so the wash has to be flat and heavy */
  .hero--image .hero-bg { background-position: 58% 38%; }
  .hero--image .hero-bg::after {
    background:
      linear-gradient(180deg, rgba(8,22,38,.90) 0%, rgba(8,22,38,.93) 100%),
      linear-gradient(to top, rgba(8,22,38,.5), rgba(8,22,38,0) 55%);
  }
  .hero--image .hero-copy { max-width: none; }
}

/* Partnerships hero backdrop. Same scrim as the home hero, different plate.
   The source frame carried a garbled mirror-image of the wordmark in the
   table reflection, so the file is cropped to the top 70% and the artefact is
   gone from the bytes rather than hidden under a background-position that
   only holds at one viewport. Double class so it beats the phone override
   above on specificity, not on source order. */
.hero--image.hero--boardroom .hero-bg {
  background-image: url("img/boardroom.jpg");
  background-position: 50% 34%;
}

/* PHONE: this hero is art-directed, not just re-cropped by `cover`.
   On a 390x743 portrait hero, `cover` scales the 2.14:1 desktop plate UP 1.24x
   and shows about a quarter of its width, which reads as an unidentifiable
   smear. Counter-intuitively a TALLER crop is less zoomed on screen, because
   an aspect closer to the viewport's needs less upscaling to cover it: the
   1.25:1 phone plate lands at 0.85x and shows ~42% of its width.
   The wash then comes down from the near-opaque .90/.93 (which hid the picture
   almost completely) to .52/.78. What sets the floor on how light it can go is
   the 15px cyan eyebrow needing 4.5:1, NOT the headline, so the eyebrow goes
   white here and pays for the rest of the lightening.
   Measured under the glyph mask (background sampled only where letters are),
   5th percentile, 390 / 320: eyebrow 5.86 / 5.36 · h1 6.25 / 5.67 ·
   lede 7.14 / 5.24, against floors of 4.5 / 3.0 / 4.5.
   Tool: tools/render-check/_piq-phone-hero-final.mjs */
@media (max-width: 960px) {
  .hero--image.hero--boardroom .hero-bg {
    background-image: url("img/boardroom-phone.jpg");
    background-position: 40% 28%;
  }
  .hero--image.hero--boardroom .hero-bg::after {
    background:
      linear-gradient(180deg, rgba(8,22,38,.52) 0%, rgba(8,22,38,.78) 100%),
      linear-gradient(to top, rgba(8,22,38,.45), rgba(8,22,38,0) 62%);
  }
  .hero--image.hero--boardroom .eyebrow { color: #FFFFFF; border-bottom-color: #FFFFFF; }
}

/* The About and Platform heroes carry photography on the same terms as the
   partnerships one: desktop plate + a TALLER phone plate so `cover` upscales
   less and the scene reads at a smaller zoom, a measured wash, and a white
   eyebrow at phone widths because the 15px cyan one is the contrast floor.
   Every ratio below is measured under a glyph mask, not estimated. */
.hero--image.hero--strategy .hero-bg {
  background-image: url("img/strategy-room.jpg");
  background-position: 50% 42%;
}
.hero--image.hero--dashboard .hero-bg {
  background-image: url("img/dashboard-team.jpg");
  background-position: 42% 38%;
}
@media (max-width: 960px) {
  .hero--image.hero--strategy .hero-bg {
    background-image: url("img/strategy-room-phone.jpg");
    background-position: 46% 34%;
  }
  .hero--image.hero--dashboard .hero-bg {
    background-image: url("img/dashboard-team-phone.jpg");
    background-position: 38% 30%;
  }
  .hero--image.hero--strategy .hero-bg::after,
  .hero--image.hero--dashboard .hero-bg::after {
    background:
      linear-gradient(180deg, rgba(8,22,38,.52) 0%, rgba(8,22,38,.78) 100%),
      linear-gradient(to top, rgba(8,22,38,.45), rgba(8,22,38,0) 62%);
  }
  .hero--image.hero--strategy .eyebrow,
  .hero--image.hero--dashboard .eyebrow { color: #FFFFFF; border-bottom-color: #FFFFFF; }
}

/* PORTRAIT PHONE. The hero has to fit a vertical screen without becoming a
   scroll of its own, so type steps down, the block is bounded to the visible
   viewport with dvh (which accounts for browser chrome), and the buttons
   stack full width. */
@media (max-width: 760px) {
  .hero--image { padding-block: calc(var(--s6, 64px) + 26px) var(--s6, 64px); }
  .hero--image h1 { font-size: clamp(28px, 8.2vw, 36px); line-height: 1.12; }
  .hero--image .tagline { font-size: 17px; margin-top: var(--s2, 16px); }
  .hero--image .eyebrow { font-size: 13px; }
  .hero-points { margin-top: var(--s3, 24px); }
  .hero-points li { font-size: 16px; padding: 7px 0 7px 30px; }
  .hero-points li::before { top: 15px; }
  .hero--image .btn-row { margin-top: var(--s4, 32px); gap: 10px; }
}
/* PORTRAIT: the goal is the whole hero on one screen, so this tightens until
   it fits rather than setting a floor. min-height is a FLOOR and does nothing
   about overflow — the first attempt used one and the hero still ran 130vh on
   a 360-wide phone and 152vh at 320. */
@media (max-width: 760px) and (orientation: portrait) {
  /* top padding must CLEAR the floating bar. Measured bar is 80-86px plus an
     8px inset, so anything under ~96px puts the pill on top of the headline —
     which is exactly what the geometry gate caught at 320 and 390. */
  .hero--image {
    min-height: 88dvh;
    display: flex; align-items: center;
    padding-block: 128px var(--s5, 48px);
  }
  .hero--image h1 { font-size: clamp(26px, 7.4vw, 33px); }
  .hero--image .tagline { font-size: 16px; margin-top: 10px; }
  .hero-points { margin-top: var(--s3, 24px); }
  .hero-points li { font-size: 15.5px; padding: 6px 0 6px 28px; line-height: 1.4; }
  .hero-points li::before { top: 13px; }
  .hero--image .btn-row { margin-top: var(--s3, 24px); }
  .hero--image .btn { min-height: 50px; font-size: 16px; }
}
/* Very small portrait screens (320x568 and similar). Measured at 620px of
   content against a 568px viewport, so this trims the last 52px: the 4th
   bullet goes, the tagline goes (the H1 already carries it), and the type
   and rhythm step down once more. */
@media (max-width: 400px) and (orientation: portrait) and (max-height: 700px) {
  .hero--image { padding-block: 118px var(--s3, 24px); }
  .hero--image h1 { font-size: 23px; line-height: 1.14; }
  .hero--image .eyebrow { font-size: 12px; margin-bottom: 10px; padding-bottom: 4px; }
  .hero--image .tagline { display: none; }
  .hero-points { margin-top: var(--s2, 16px); }
  .hero-points li:last-child { display: none; }
  .hero-points li { font-size: 14.5px; padding: 5px 0 5px 26px; }
  .hero-points li::before { top: 12px; }
  .hero--image .btn-row { margin-top: var(--s2, 16px); gap: 8px; }
  .hero--image .btn { min-height: 44px; font-size: 15px; }
}

/* full-bleed band */
.band { position: relative; }
.band .shot { aspect-ratio: 21 / 8; }
/* Scrim strength is measured, not guessed. The building shot is a dusk
   exterior with a bright sky, and the first version left white text at
   2.00:1 over it (large text needs 3:1, the sub-line needs 4.5:1). Sampled
   with tools/render-check/_piq-band-contrast.mjs, which hides the glyphs and
   reads the actual pixels underneath. */
.band-cap {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: var(--s6, 64px) 0 var(--s5, 48px);
  background: linear-gradient(to top,
    rgba(10,28,46,.97) 0%,
    rgba(10,28,46,.94) 45%,
    rgba(10,28,46,.72) 72%,
    rgba(10,28,46,0) 100%);
  color: #FFFFFF;
}
.band-cap h2, .band-cap p { color: #FFFFFF; }
.band-cap p { color: #D6E3EC; }
@media (max-width: 760px) {
  .band .shot { aspect-ratio: 4 / 3; }
  /* The 4:3 crop puts more bright sky behind the caption than the 21:8 one
     does, and the building band measured 2.69:1 here while passing on
     desktop. One viewport is not a contrast test. */
  .band-cap {
    padding: var(--s5, 48px) 0 var(--s4, 32px);
    background: linear-gradient(to top,
      rgba(10,28,46,.98) 0%,
      rgba(10,28,46,.96) 55%,
      rgba(10,28,46,.82) 80%,
      rgba(10,28,46,0) 100%);
  }
}

/* ------------------------------------------------------- contained figure
   Not a .band. The band crops to 21:8 with object-fit:cover, which on a 3:2
   source throws away the top and bottom thirds. This image's whole subject
   is the screens, so it is shown whole inside the container instead. */
.figure { margin: 0; }
.figure img {
  display: block; width: 100%; height: auto;
  border-radius: var(--radius, 4px);
  border: 1px solid var(--rule, #D2DEE7);
}
.figure figcaption {
  margin-top: var(--s2, 16px);
  font-size: 15px; line-height: 1.55;
  color: var(--ink-muted, #4E6377);
  max-width: var(--measure, 68ch);
}
.pillar--navy .figure img, .section--navy .figure img { border-color: rgba(255,255,255,.18); }
.pillar--navy .figure figcaption, .section--navy .figure figcaption { color: #9FB6C8; }

/* the disclosure. Small, but present and readable. */
.render-note {
  font-size: 14px; line-height: 1.5;
  color: var(--ink-muted, #4E6377);
  padding-top: var(--s3, 24px);
  border-top: 1px solid var(--rule, #D2DEE7);
  max-width: 78ch;
}
.section--navy .render-note, .sitefoot .render-note { color: #9FB6C8; border-top-color: rgba(255,255,255,.2); }

/* --------------------------------------------------------- capability list
   Real disc bullets now, plus a hairline so 19 items still scan. */

.caplist { list-style: none; margin: 0; padding: 0; columns: 3; column-gap: var(--s6, 64px); }
.caplist--2 { columns: 2; }
.caplist li {
  break-inside: avoid;
  padding: 11px 0 11px 28px;
  border-bottom: 1px solid var(--rule-soft, #E6EDF2);
  position: relative;
  font-size: 17.5px; line-height: 1.45;
}
.caplist li::before {
  content: "";
  position: absolute; left: 4px; top: 19px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--accent-hi, #0B7A82);
  box-shadow: 0 0 0 4px var(--accent-soft, #D9EDEE);
}
.section--tint2 .caplist li::before { box-shadow: 0 0 0 4px #FFFFFF; }
@media (max-width: 900px) { .caplist { columns: 2; } }
@media (max-width: 620px) { .caplist, .caplist--2 { columns: 1; } }

/* outcome chips: short statements, each with a check icon */
.outcomes { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: var(--s2, 16px); }
.outcomes li {
  display: flex; align-items: flex-start; gap: 12px;
  font-family: var(--font-head); font-weight: 700; font-size: 17.5px;
  color: var(--navy, #0E2A45); letter-spacing: -0.01em; line-height: 1.35;
  background: #FFFFFF; border: 1px solid var(--rule, #D2DEE7);
  border-left: 4px solid var(--accent-hi, #0B7A82);
  border-radius: var(--radius, 4px);
  padding: var(--s3, 24px);
}
.outcomes li .ico { color: var(--accent-hi, #0B7A82); margin-top: 1px; }
.section--navy .outcomes li { background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.18); border-left-color: #7FD0D6; color: #FFFFFF; }
.section--navy .outcomes li .ico { color: #7FD0D6; }

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

.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s5, 48px); }
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s4, 32px); }
@media (max-width: 900px) { .grid-3 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 760px) { .grid-2, .grid-3 { grid-template-columns: 1fr; gap: var(--s4, 32px); } }

.card {
  background: #FFFFFF;
  border: 1px solid var(--rule, #D2DEE7);
  border-top: 5px solid var(--accent, #07595F);
  border-radius: var(--radius, 4px);
  padding: var(--s5, 48px);
  display: flex; flex-direction: column;
}
.card .num {
  font-family: var(--font-head); font-weight: 700; font-size: 15px;
  color: var(--accent, #07595F); margin: 0 0 var(--s2, 16px);
}
.card h3 { margin-bottom: var(--s2, 16px); }
.card p { color: var(--ink-muted, #4E6377); }
.card .btn { margin-top: auto; align-self: flex-start; }
.card p + .btn, .card ul + .btn { margin-top: var(--s4, 32px); }
.card--gold { border-top-color: var(--gold, #B07A1E); }
.card--navy { border-top-color: var(--navy, #0E2A45); }
@media (max-width: 560px) { .card { padding: var(--s4, 32px); } }

/* "Best For" block, now with tick bullets */
.bestfor { background: #FFFFFF; border: 1px solid var(--rule, #D2DEE7); border-radius: var(--radius, 4px); padding: var(--s5, 48px); }
.bestfor--tint { background: var(--tint-2, #EAF4F4); border-color: transparent; }
.bestfor h4 { margin-bottom: var(--s3, 24px); display: flex; align-items: center; gap: 10px; color: var(--accent, #07595F); }
.bestfor ul { list-style: none; margin: 0; padding: 0; columns: 2; column-gap: var(--s5, 48px); }
.bestfor li { break-inside: avoid; padding: 7px 0 7px 30px; position: relative; font-size: 17.5px; line-height: 1.45; }
.bestfor li::before {
  content: "";
  position: absolute; left: 4px; top: 14px;
  width: 13px; height: 7px;
  border-left: 2.5px solid var(--accent-hi, #0B7A82);
  border-bottom: 2.5px solid var(--accent-hi, #0B7A82);
  transform: rotate(-45deg);
}
@media (max-width: 700px) { .bestfor ul { columns: 1; } .bestfor { padding: var(--s4, 32px); } }

/* ---------------------------------------------------------------- pillar
   Alternating tiers so five sections do not read as one block. */

.pillar { padding-block: var(--s7, 88px); }
.pillar--tint  { background: var(--tint-1, #F3F7FA); }
.pillar--tint2 { background: var(--tint-2, #EAF4F4); }

/* one dark pillar mid-page so five sections never read as one slab */
.pillar--navy { background: var(--navy, #0E2A45); color: #FFFFFF; }
.pillar--navy h2, .pillar--navy h3, .pillar--navy .sublabel { color: #FFFFFF; }
.pillar--navy p { color: #CFDDE7; }
.pillar--navy .eyebrow { color: #7FD0D6; border-bottom-color: #7FD0D6; }
.pillar--navy .pillar-num { color: #7FD0D6; }
.pillar--navy .sublabel .ico { color: #7FD0D6; }
.pillar--navy .caplist li { border-bottom-color: rgba(255,255,255,.16); }
.pillar--navy .caplist li::before { background: #7FD0D6; box-shadow: 0 0 0 4px rgba(127,208,214,.18); }
.pillar--navy .outcomes li { background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.18); border-left-color: #7FD0D6; color: #FFFFFF; }
.pillar--navy .outcomes li .ico { color: #7FD0D6; }
.pillar--navy .notice { background: rgba(255,255,255,.08); color: #E4EEF4; }
.pillar--navy .notice strong { color: #FFFFFF; }
.pillar--navy .notice .ico { color: #7FD0D6; }

.pillar-head { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: var(--s6, 64px); align-items: start; margin-bottom: var(--s6, 64px); }
.pillar-num {
  font-family: var(--font-head); font-weight: 700; font-size: 15px;
  color: var(--accent-hi, #0B7A82); margin: 0 0 var(--s2, 16px);
  letter-spacing: 0.04em;
}
@media (max-width: 860px) { .pillar-head { grid-template-columns: 1fr; gap: var(--s3, 24px); margin-bottom: var(--s5, 48px); } }

.sublabel {
  display: flex; align-items: center; gap: 10px;
  font-family: var(--font-head); font-weight: 700; font-size: 19px;
  color: var(--navy, #0E2A45); margin: 0 0 var(--s3, 24px);
}
.sublabel .ico { color: var(--accent-hi, #0B7A82); }

/* the difference: four stacked statements */
.diff { list-style: none; margin: 0; padding: 0; }
.diff li {
  display: flex; align-items: center; gap: var(--s3, 24px);
  font-family: var(--font-head); font-weight: 700;
  font-size: clamp(21px, 2.6vw, 30px); line-height: 1.25; letter-spacing: -0.015em;
  padding: var(--s4, 32px) 0; border-bottom: 1px solid rgba(255,255,255,.2);
  color: #9FB6C8;
}
.diff li .ico { color: #5E7D96; }
.diff li:last-child { color: #FFFFFF; border-bottom: 0; }
.diff li:last-child .ico { color: #7FD0D6; }

/* notice / callout */
.notice {
  background: var(--accent-soft, #D9EDEE);
  border-radius: var(--radius, 4px);
  padding: var(--s4, 32px);
  font-size: 17.5px; line-height: 1.55;
  display: flex; gap: var(--s3, 24px); align-items: flex-start;
}
.notice .ico { color: var(--accent, #07595F); margin-top: 3px; }
.notice strong { color: var(--navy, #0E2A45); }
.notice p { margin: 0; max-width: none; }
.notice--gold { background: #F6EDDC; }
.notice--gold .ico { color: var(--gold, #B07A1E); }
@media (max-width: 560px) { .notice { flex-direction: column; gap: var(--s2, 16px); padding: var(--s3, 24px); } }

/* ---------------------------------------------------------------- forms */

.field { margin-bottom: var(--s4, 32px); }
.field label { display: block; font-weight: 700; font-size: 16px; margin-bottom: var(--s1, 8px); }
.field input, .field textarea, .field select {
  width: 100%; font-family: var(--font-body); font-size: 16px; line-height: 1.5;
  color: var(--ink, #12253A); background: #FFFFFF;
  border: 2px solid var(--rule, #D2DEE7); border-radius: var(--radius, 4px);
  padding: 14px var(--s2, 16px); min-height: 54px;
}
.field input:focus, .field textarea:focus, .field select:focus { border-color: var(--accent-hi, #0B7A82); }
.field textarea { min-height: 150px; resize: vertical; }
.field .hint { font-size: 15px; color: var(--ink-muted, #4E6377); margin: var(--s1, 8px) 0 0; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

@media print {
  .sitehead, .sitenav, .btn, .btn-row { display: none !important; }
  body { font-size: 11pt; }
  .hero, .section--navy { background: #FFFFFF !important; color: #000000 !important; }
  .hero h1, .section--navy h2, .diff li { color: #000000 !important; }
}

/* card bullets: same tick language as .bestfor, tighter for a card */
.bestfor-inline { list-style: none; margin: 0; padding: 0; }
.bestfor-inline li {
  position: relative; padding: 7px 0 7px 28px;
  font-size: 17px; line-height: 1.45; color: var(--ink-muted, #4E6377);
}
.bestfor-inline li::before {
  content: ""; position: absolute; left: 2px; top: 15px;
  width: 12px; height: 6px;
  border-left: 2.5px solid var(--accent-hi, #0B7A82);
  border-bottom: 2.5px solid var(--accent-hi, #0B7A82);
  transform: rotate(-45deg);
}

/* h1 steps down hard on small screens, so h2's floor has to follow or the
   page ends up with an h2 LARGER than its h1 — caught by the gate at 320. */
@media (max-width: 400px) {
  h2 { font-size: clamp(21px, 6vw, 27px); }
  h3 { font-size: 18px; }
}

.pagewrap { position: relative; }

/* ============================================================================
   MERGE LAYER — components the merged site adds on top of the v2 stylesheet.

   The v2 sheet above is Glenn's design system and is unchanged. Everything from
   here down exists because the merged site carries three things his draft did
   not: a published clause sheet, a value stack, and a working calculator and
   booking flow. Same tokens, same type scale, same four background tiers.
   ============================================================================ */

/* ------------------------------------------------------------- nav CTA
   One nav item is a booking button. It has to read as the action in a bar of
   links without breaking the single-row constraint, so it is a short pill at
   the same 44px touch height rather than a taller .btn. */
.sitenav a.navcta {
  background: var(--accent-hi, #0B7A82); color: #FFFFFF;
  padding: 0 20px; border-radius: 100px; border-bottom: 0;
  font-weight: 700; white-space: nowrap;
}
.sitenav a.navcta:hover, .sitenav a.navcta[aria-current="page"] {
  background: #FFFFFF; color: var(--navy, #0E2A45); border-bottom: 0;
}
/* Six top-level items plus the wordmark is tighter than Glenn's four. The gap
   collapses before anything wraps, because a second nav row is what took the
   old header to 220px. */
@media (min-width: 761px) and (max-width: 1120px) {
  .sitenav { gap: 20px; }
  .sitenav a { font-size: 15px; }
  .wordmark { font-size: 19px; }
}
@media (max-width: 760px) {
  .sitenav a.navcta { border-radius: 0; background: transparent; color: #7FD0D6; }
  .sitenav a.navcta:hover { background: rgba(255,255,255,.08); color: #FFFFFF; }
}

/* ------------------------------------------------------------ big numbers
   A figure set at display size, because the strongest fact on a page should not
   be buried mid-sentence. Archivo 800 is only loaded for these. */
.bignum {
  font-family: var(--font-head); font-weight: 800;
  font-size: clamp(64px, 12vw, 132px); line-height: .88;
  letter-spacing: -0.045em; color: var(--navy, #0E2A45);
  margin: 0; font-variant-numeric: tabular-nums;
}
.section--navy .bignum, .pillar--navy .bignum, .hero .bignum { color: #7FD0D6; }
.bignum--gold { color: var(--gold, #B07A1E); }

/* ------------------------------------------------------- the money figure
   Glenn's call, 2026-08-01: the total a visitor came for should read as money,
   not as another teal heading. Green is used for EXACTLY one thing on this site,
   the figure the visitor's own assumptions produce, so it never becomes decoration.

   Measured, not eyeballed: #34D399 on navy #0E2A45 is 7.61:1 and #047857 on white
   is 5.48:1, both clear of the 4.5 body floor. The teal it sits beside is 8.29:1,
   so the two are separated by hue rather than by weight and both stay legible.

   It does NOT get a second label. The caption beside it is the only name this
   quantity has; a figure carrying two names loses the first reader who checks. */
.bignum--green { color: var(--green, #047857); }
.section--navy .bignum--green,
.pillar--navy .bignum--green,
.hero .bignum--green { color: var(--green-hi, #34D399); }

/* The highlight itself: a green rule and a soft green wash behind the figure, so
   it reads as the answer rather than as one more paragraph in a navy band. */
.mdl-headline--hl {
  position: relative;
  padding: var(--s5, 48px) var(--s5, 48px) var(--s4, 32px);
  border-radius: 4px;
  background:
    linear-gradient(180deg, rgba(52, 211, 153, .10), rgba(52, 211, 153, .02));
  box-shadow: inset 0 0 0 1px rgba(52, 211, 153, .34);
}
.mdl-headline--hl::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  border-radius: 4px 0 0 4px; background: var(--green-hi, #34D399);
}
@media (max-width: 640px) {
  .mdl-headline--hl { padding: var(--s4, 32px) var(--s3, 24px) var(--s3, 24px); }
}
/* A viewer who has asked for less motion or more contrast still gets the frame;
   nothing here animates, so there is nothing to disable. */
@media (prefers-contrast: more) {
  .mdl-headline--hl { box-shadow: inset 0 0 0 2px var(--green-hi, #34D399); }
}
/* A currency string does not wrap, so on a phone the figure sets the page's minimum
   width. "$13,542,336" at the 64px floor is one unbreakable 409px run, which pushed
   the whole document 19px past a 390px viewport and made every page scroll sideways.
   A nine-location group is exactly the reader this figure is for, so the big number is
   the common case, not the edge one. Below 700px it scales with the viewport instead
   of stopping at a floor wider than the screen. */
@media (max-width: 700px) {
  .bignum { font-size: clamp(34px, 10.5vw, 64px); letter-spacing: -0.05em; }
}
.bignum-cap {
  font-size: 16px; line-height: 1.5; color: var(--ink-muted, #4E6377);
  margin: var(--s3, 24px) 0 0; max-width: 42ch;
}
.section--navy .bignum-cap, .pillar--navy .bignum-cap { color: #A9C2D3; }

/* a row of them */
.statrow { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--s5, 48px); }
.statrow .bignum { font-size: clamp(44px, 6vw, 76px); }

/* the split: one huge figure beside the prose that earns it */
.figure-block { display: grid; grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr); gap: var(--s7, 88px); align-items: start; }
@media (max-width: 900px) { .figure-block { grid-template-columns: 1fr; gap: var(--s5, 48px); } }

/* --------------------------------------------------------------- the stack
   Value stacking, done the one way it survives a lawyer: enumerate what is
   included and name the category of vendor it replaces. No invented dollar
   anchor beside any row. A brand-new company has no substantiation for a
   price it has never charged, and an anchor is a price claim.
   FTC substantiation rule, and REGULATORY-FLAGS section 6. */
.stack { border-top: 2px solid var(--navy, #0E2A45); margin: 0; }
.stack-row {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr) minmax(0, 1fr);
  gap: var(--s4, 32px); align-items: start;
  padding: var(--s4, 32px) 0;
  border-bottom: 1px solid var(--rule, #D2DEE7);
}
.stack-row > * { margin: 0; }
.stack-name {
  font-family: var(--font-head); font-weight: 700; font-size: 19px;
  color: var(--navy, #0E2A45); line-height: 1.3;
  display: flex; align-items: flex-start; gap: 12px;
}
.stack-name .ico { color: var(--accent-hi, #0B7A82); margin-top: 2px; }
.stack-what { color: var(--ink-muted, #4E6377); font-size: 17px; max-width: none; }
.stack-repl {
  font-size: 15.5px; line-height: 1.45; color: var(--ink-muted, #4E6377);
  padding-left: var(--s3, 24px); border-left: 3px solid var(--accent-soft, #D9EDEE);
  max-width: none;
}
.stack-repl b { display: block; font-family: var(--font-head); font-size: 13px;
  letter-spacing: .06em; text-transform: uppercase; color: var(--accent, #07595F);
  margin-bottom: 5px; font-weight: 700; }
.stack-foot {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s3, 24px);
  padding: var(--s4, 32px) 0 0;
  border-top: 2px solid var(--navy, #0E2A45);
  font-family: var(--font-head); font-weight: 700;
  font-size: clamp(21px, 2.6vw, 29px); line-height: 1.2;
  color: var(--navy, #0E2A45); letter-spacing: -0.015em;
}
.section--navy .stack, .section--navy .stack-foot { border-color: rgba(255,255,255,.45); }
.section--navy .stack-row { border-bottom-color: rgba(255,255,255,.16); }
.section--navy .stack-name, .section--navy .stack-foot { color: #FFFFFF; }
.section--navy .stack-what, .section--navy .stack-repl { color: #CFDDE7; }
.section--navy .stack-repl { border-left-color: rgba(127,208,214,.5); }
.section--navy .stack-repl b, .section--navy .stack-name .ico { color: #7FD0D6; }
@media (max-width: 940px) {
  .stack-row { grid-template-columns: 1fr; gap: var(--s2, 16px); }
  .stack-repl { padding-left: var(--s2, 16px); }
}

/* ---------------------------------------------------------------- steps
   A numbered sequence. Used for "what happens next", which is the single
   objection every practice owner has and nobody in the category answers. */
.steps { list-style: none; margin: 0; padding: 0; counter-reset: step; display: grid; gap: var(--s2, 16px); }
.steps li {
  counter-increment: step; position: relative;
  padding: var(--s4, 32px) var(--s4, 32px) var(--s4, 32px) 86px;
  background: #FFFFFF; border: 1px solid var(--rule, #D2DEE7);
  border-radius: var(--radius, 4px);
}
.steps li::before {
  content: counter(step, decimal-leading-zero);
  position: absolute; left: var(--s4, 32px); top: var(--s4, 32px);
  font-family: var(--font-head); font-weight: 800; font-size: 26px;
  line-height: 1; color: var(--accent-hi, #0B7A82);
  font-variant-numeric: tabular-nums;
}
.steps h3 { margin: 0 0 8px; font-size: 20px; }
.steps p { margin: 0; color: var(--ink-muted, #4E6377); font-size: 17px; }
.section--tint .steps li, .section--tint2 .steps li { border-color: transparent; }
.section--navy .steps li { background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.18); }
.section--navy .steps p { color: #CFDDE7; }
.section--navy .steps li::before { color: #7FD0D6; }
@media (max-width: 560px) {
  .steps li { padding: var(--s3, 24px) var(--s3, 24px) var(--s3, 24px) 60px; }
  .steps li::before { left: var(--s3, 24px); top: var(--s3, 24px); font-size: 21px; }
}

/* ------------------------------------------------------------- pull quote */
.pull {
  font-family: var(--font-head); font-weight: 700;
  font-size: clamp(24px, 3.4vw, 40px); line-height: 1.2; letter-spacing: -0.02em;
  color: var(--navy, #0E2A45); margin: 0; max-width: 22ch;
  text-wrap: balance;
}
.section--navy .pull, .pillar--navy .pull { color: #FFFFFF; }
.pull em { font-style: normal; color: var(--accent-hi, #0B7A82); }
.section--navy .pull em { color: #7FD0D6; }

/* ------------------------------------------------------- the clause sheet
   Ported from the strategic build. Left is the binding language in a document
   face; right is the plain-English gloss. The pairing IS the argument: a
   promise cannot be diffed against an executed agreement, a clause can. */
.clauses { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s5, 48px); }
.clause-pair {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--s5, 48px); align-items: start;
  padding-bottom: var(--s5, 48px); border-bottom: 1px solid var(--rule, #D2DEE7);
}
.clause-pair:last-child { border-bottom: 0; padding-bottom: 0; }
.clause {
  background: var(--tint-1, #F3F7FA);
  border-left: 3px solid var(--navy, #0E2A45);
  padding: var(--s4, 32px);
  font-size: 15.5px; line-height: 1.62; color: var(--ink, #12253A);
  font-variant-numeric: tabular-nums;
}
.clause p { margin: 0 0 var(--s2, 16px); max-width: none; }
.clause p:last-child { margin-bottom: 0; }
.clause .label, .status-note .label {
  display: block; font-family: var(--font-head); font-weight: 700;
  font-size: 13px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent, #07595F); margin-bottom: var(--s2, 16px);
}
.gloss h3 { margin: 0 0 var(--s2, 16px); }
.gloss p { color: var(--ink-muted, #4E6377); margin: 0; }
.section--navy .clause { background: rgba(255,255,255,.06); border-left-color: #7FD0D6; color: #E4EEF4; }
.section--navy .clause .label { color: #7FD0D6; }
@media (max-width: 860px) { .clause-pair { grid-template-columns: 1fr; gap: var(--s3, 24px); } }

/* jurisdiction strip: what is already law, and what is only law because we wrote it */
.jur { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; background: var(--rule, #D2DEE7); border: 1px solid var(--rule, #D2DEE7); }
.jur > span { background: #FFFFFF; padding: var(--s4, 32px); font-size: 16.5px; line-height: 1.5; color: var(--ink-muted, #4E6377); }
.jur > span strong {
  display: block; font-family: var(--font-head); font-size: 19px;
  color: var(--navy, #0E2A45); margin-bottom: 10px;
}
.jur--ca { border-top: 4px solid var(--accent-hi, #0B7A82); }
.jur--rest { border-top: 4px solid var(--gold, #B07A1E); }
@media (max-width: 700px) { .jur { grid-template-columns: 1fr; } }

.status-note {
  background: #F6EDDC; border-left: 4px solid var(--gold, #B07A1E);
  padding: var(--s4, 32px); border-radius: 0 var(--radius, 4px) var(--radius, 4px) 0;
}
.status-note .label { color: var(--gold, #B07A1E); }
.status-note p { margin: 0 0 var(--s2, 16px); font-size: 17px; }
.status-note p:last-child { margin-bottom: 0; }

.changelog, .ledger { width: 100%; border-collapse: collapse; font-size: 17px; }
.changelog th, .ledger th {
  text-align: left; font-family: var(--font-head); font-size: 14px;
  letter-spacing: .06em; text-transform: uppercase; color: var(--accent, #07595F);
  padding: 0 var(--s3, 24px) var(--s2, 16px) 0; border-bottom: 2px solid var(--navy, #0E2A45);
  vertical-align: bottom;
}
.changelog td, .ledger td {
  padding: var(--s3, 24px) var(--s3, 24px) var(--s3, 24px) 0;
  border-bottom: 1px solid var(--rule, #D2DEE7); vertical-align: top; line-height: 1.55;
}
.ledger td:first-child { font-family: var(--font-head); font-weight: 700; color: var(--navy, #0E2A45); width: 34%; }
.ledger td:last-child { color: var(--ink-muted, #4E6377); }
.changelog td:first-child { font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (max-width: 700px) {
  .changelog, .ledger { font-size: 16px; }
  .changelog thead, .ledger thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .changelog tr, .ledger tr { display: block; padding: var(--s3, 24px) 0; border-bottom: 1px solid var(--rule, #D2DEE7); }
  .changelog td, .ledger td { display: block; width: auto; padding: 0 0 8px; border: 0; }
  .ledger td:first-child, .changelog td:first-child { width: auto; margin-bottom: 4px; }
  .changelog td:last-child, .ledger td:last-child { padding-bottom: 0; }
}

/* ------------------------------------------------------------------- FAQ
   <details>, so it works with JavaScript off and every answer is in the DOM
   for a crawler to read. An accordion that hides its answers from a bot is an
   accordion that hides them from search. */
.faq { border-top: 1px solid var(--rule, #D2DEE7); }
.faq details { border-bottom: 1px solid var(--rule, #D2DEE7); }
.faq summary {
  cursor: pointer; list-style: none; padding: var(--s4, 32px) 44px var(--s4, 32px) 0;
  position: relative; font-family: var(--font-head); font-weight: 700;
  font-size: clamp(18px, 2vw, 21px); line-height: 1.35; color: var(--navy, #0E2A45);
  letter-spacing: -0.01em;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; position: absolute; right: 8px; top: calc(var(--s4, 32px) + .5em);
  width: 13px; height: 13px;
  border-right: 2.5px solid var(--accent-hi, #0B7A82);
  border-bottom: 2.5px solid var(--accent-hi, #0B7A82);
  transform: translateY(-40%) rotate(45deg); transition: transform 160ms ease;
}
.faq details[open] summary::after { transform: translateY(-10%) rotate(-135deg); }
.faq summary:hover { color: var(--accent, #07595F); }
.faq .answer { padding: 0 0 var(--s4, 32px); }
.faq .answer p { color: var(--ink-muted, #4E6377); }

/* ------------------------------------------------------------------ flow
   Sections lift in as they arrive. Deliberately small: 14px and 420ms, one
   time only, and completely off under prefers-reduced-motion. Anything larger
   turns a long page into a fairground and pushes CLS. Elements start VISIBLE
   and are hidden by JS only if IntersectionObserver exists, so a failed script
   can never leave the page blank. */
.reveal.is-armed { opacity: 0; transform: translateY(14px); }
.reveal.is-in { opacity: 1; transform: none; transition: opacity 420ms ease, transform 420ms ease; }
@media (prefers-reduced-motion: reduce) {
  .reveal.is-armed { opacity: 1; transform: none; }
  .reveal.is-in { transition: none; }
}

/* -------------------------------------------------------------- back to top */
.totop {
  position: fixed; right: 18px; bottom: 18px; z-index: 55;
  width: 48px; height: 48px; border-radius: 50%;
  background: rgba(10,28,46,.86); color: #FFFFFF;
  border: 1px solid rgba(255,255,255,.2);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  display: none; align-items: center; justify-content: center; cursor: pointer;
  box-shadow: 0 8px 24px rgba(0,0,0,.3);
}
.totop[data-show="true"] { display: inline-flex; }
.totop:hover { background: var(--accent-hi, #0B7A82); }
.totop .ico { width: 20px; height: 20px; }

/* ------------------------------------------------------------------ misc */
.prose > p + p { margin-top: 0; }
.lead-in { max-width: 62ch; }
.rule-soft { border: 0; border-top: 1px solid var(--rule-soft, #E6EDF2); margin: 0; }
.section--tight { padding-block: var(--s6, 64px); }
.tag {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-head); font-weight: 700; font-size: 13px;
  letter-spacing: .06em; text-transform: uppercase;
  background: var(--accent-soft, #D9EDEE); color: var(--accent, #07595F);
  padding: 6px 12px; border-radius: 100px;
}
.tag--gold { background: #F6EDDC; color: var(--gold, #B07A1E); }
.section--navy .tag { background: rgba(127,208,214,.16); color: #7FD0D6; }

/* .bestfor's own heading is an h3 so it does not skip a level over the .card h3
   beneath it. Same size and colour as the h4 it replaced. */
.sitefoot h2 { font-size: 19px; line-height: 1.3; letter-spacing: 0; color: #FFFFFF; margin-bottom: var(--s2, 16px); }
.bestfor h3 { font-size: 19px; line-height: 1.3; letter-spacing: 0; margin-bottom: var(--s3, 24px); display: flex; align-items: center; gap: 10px; color: var(--accent, #07595F); }

/* The `hidden` attribute has to beat a class that sets `display`.
   `.notice { display: flex }` and `.steps { display: grid }` both outrank the UA
   sheet's `[hidden] { display: none }`, so every error box and success panel on
   this site rendered as an empty coloured rectangle at rest. Caught in render at
   1440 on the model gate; it affected the contact form and the booking form too. */
[hidden] { display: none !important; }

/* .bestfor is two columns by default, which is right in a full-width band and
   wrong in a 380px sidebar: the booking aside rendered four words per line. */
.bk-aside .bestfor ul { columns: 1; }

/* ---------------------------------------------------- homepage calculator
   A two-line preview of /model.html, live on the home page. The controls are
   real range inputs so the section is readable with script off; homecalc.js
   flips data-live once its first render succeeds. */

.hc {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, .9fr);
  gap: 2px; margin-top: var(--s6, 64px);
  background: var(--rule, #D2DEE7);
  border: 1px solid var(--rule, #D2DEE7);
  border-top: 5px solid var(--accent, #07595F);
  border-radius: var(--radius, 4px);
  overflow: hidden;
}
@media (max-width: 860px) { .hc { grid-template-columns: 1fr; } }

.hc-inputs { background: #FFFFFF; padding: var(--s5, 48px); }
.hc-inputs .field { margin-bottom: var(--s4, 32px); }
.hc-inputs label {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--s2, 16px); margin-bottom: 10px;
}
.hc-inputs .unit {
  font-family: var(--font-head); font-weight: 800; font-size: 23px;
  color: var(--accent, #07595F); letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* `border: 0` beats .field input, which frames every input with 2px. Without it
   a range renders inside a box and reads as a broken text field. */
.hc-inputs input[type="range"] {
  width: 100%; height: 40px; min-height: 0; margin: 0; padding: 0;
  border: 0; background: transparent; cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.hc-inputs input[type="range"]::-webkit-slider-runnable-track {
  height: 6px; border-radius: 100px; background: var(--rule, #D2DEE7);
}
.hc-inputs input[type="range"]::-moz-range-track {
  height: 6px; border-radius: 100px; background: var(--rule, #D2DEE7);
}
.hc-inputs input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 26px; height: 26px; border-radius: 50%; margin-top: -10px;
  background: var(--accent, #07595F); border: 3px solid #FFFFFF;
  box-shadow: 0 1px 5px rgba(8, 25, 42, .3);
}
.hc-inputs input[type="range"]::-moz-range-thumb {
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--accent, #07595F); border: 3px solid #FFFFFF;
  box-shadow: 0 1px 5px rgba(8, 25, 42, .3);
}

.hc-lab {
  margin: var(--s5, 48px) 0 var(--s2, 16px);
  font-family: var(--font-head); font-weight: 700; font-size: 13px;
  letter-spacing: .06em; text-transform: uppercase; color: var(--accent, #07595F);
}
.hc-presets { display: flex; flex-wrap: wrap; gap: 8px; }
.hc-preset {
  min-width: 0; min-height: 46px; font-size: 15.5px;
  padding-inline: var(--s3, 24px); flex: 1 1 auto;
}
.hc-preset.is-on {
  background: var(--navy, #0E2A45); border-color: var(--navy, #0E2A45); color: #FFFFFF;
}
.hc-inputs .hint { margin-top: var(--s3, 24px); }

.hc-out {
  background: var(--navy, #0E2A45); color: #FFFFFF;
  padding: var(--s5, 48px); display: flex; flex-direction: column;
}
.hc-out-lab {
  margin: 0 0 var(--s2, 16px);
  font-family: var(--font-head); font-weight: 700; font-size: 13px;
  letter-spacing: .06em; text-transform: uppercase; color: #7FD0D6;
}
.hc-out .bignum {
  color: #FFFFFF; font-size: clamp(42px, 6vw, 68px);
  font-variant-numeric: tabular-nums;
}
/* Needs the .hc-out prefix to outrank the white above it, and it carries the same
   green as the full calculator's total so the preview and the page it opens read
   as one number in two places. */
.hc-out .bignum--green { color: var(--green-hi, #34D399); }
.hc-lines { list-style: none; margin: var(--s5, 48px) 0 0; padding: 0; }
.hc-lines li {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--s3, 24px); padding: 13px 0;
  border-bottom: 1px solid rgba(255, 255, 255, .16);
  font-size: 16.5px; color: #CFDDE7;
}
.hc-lines li:last-child { border-bottom: 0; }
.hc-lines b {
  font-family: var(--font-head); font-size: 19px; color: #FFFFFF;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.hc-note {
  margin: var(--s4, 32px) 0 0; font-size: 15px; line-height: 1.55;
  color: #A9C2D3; max-width: none;
}
.hc-out .btn-row { margin-top: var(--s5, 48px); }
/* The two columns are different heights and the navy one is shorter. Stretching the CTA to the
   bottom with margin-top:auto left a 250px band of empty navy between the note and the button
   at 1440, which reads as a missing element rather than as breathing room. */

/* Script off: the sliders are inert, so say so instead of showing a live-looking $0. */
.hc[data-live="false"] .hc-out .bignum,
.hc[data-live="false"] .hc-lines { display: none; }
.hc[data-live="false"] .hc-out-lab::after {
  content: " needs JavaScript"; text-transform: none; letter-spacing: 0; color: #A9C2D3;
}

@media (max-width: 560px) { .hc-inputs, .hc-out { padding: var(--s4, 32px); } }

/* ===========================================================================
   MODULE PAGES + INSTALL  (added 2026-09-02)
   .price is deliberately NOT .bignum. .bignum is clamp(64px,12vw,132px) and is
   reserved for the calculator's single total; three of them in a card row is a
   broken layout. This is the card-scale price.
   =========================================================================== */
.price {
  font-family: var(--font-head); font-weight: 800;
  font-size: clamp(30px, 4.4vw, 42px); line-height: 1;
  letter-spacing: -0.03em; color: var(--navy);
  margin: var(--s3) 0 2px; font-variant-numeric: tabular-nums;
}
.price[data-price="pending"] {
  font-size: clamp(20px, 2.6vw, 26px); color: var(--ink-muted);
  font-style: italic; letter-spacing: -0.01em;
}
.price-cap {
  font-size: 13px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-muted); margin: 0;
}
.card--gold .price { color: var(--gold); }

/* ---- install form ---- */
.install-form { max-width: 760px; }
.install-set { border: 0; padding: 0; margin: 0 0 var(--s5); }
.install-set legend { padding: 0; margin-bottom: var(--s2); }

.install-opt {
  display: grid; grid-template-columns: 22px 1fr auto; gap: var(--s3);
  align-items: start; padding: var(--s3);
  border: 1px solid var(--rule); border-radius: var(--radius);
  margin-bottom: var(--s2); background: var(--bg); cursor: pointer;
}
.install-opt:hover { border-color: var(--accent); }
.install-opt:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.install-opt input { width: 18px; height: 18px; margin-top: 3px; accent-color: var(--accent); }
.install-opt input:disabled { cursor: not-allowed; }
.install-opt:has(input:disabled) { opacity: .62; cursor: not-allowed; background: var(--tint-1); }

.install-opt-body { display: block; }
.install-opt-name { display: block; font-weight: 700; margin-bottom: 3px; }
.install-opt-desc { display: block; color: var(--ink-muted); font-size: 15px; line-height: 1.5; }

.install-opt-price {
  font-family: var(--font-head); font-weight: 800; font-size: 22px;
  color: var(--navy); text-align: right; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.install-opt-price small {
  display: block; font-family: var(--font-body); font-weight: 400;
  font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-muted); margin-top: 2px;
}
.install-opt-price[data-price="pending"] {
  font-size: 15px; font-style: italic; color: var(--ink-muted); font-weight: 600;
}

.install-total {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: var(--s3) 0; border-top: 2px solid var(--navy); margin-bottom: var(--s3);
}
.install-total-lab {
  font-size: 13px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-muted);
}
.install-total-val {
  font-family: var(--font-head); font-weight: 800; font-size: 34px;
  color: var(--navy); font-variant-numeric: tabular-nums; line-height: 1;
}
.install-msg { font-size: 14px; color: var(--ink-muted); margin: var(--s2) 0 0; }

@media (max-width: 640px) {
  .install-opt { grid-template-columns: 22px 1fr; }
  .install-opt-price { grid-column: 2; text-align: left; margin-top: var(--s1); }
}

/* The recurring line under the one-time total. Separate on purpose: folding a
   monthly charge into "due today" misstates what the card is charged now. */
.install-recur {
  margin: calc(-1 * var(--s2)) 0 var(--s3); padding: var(--s2) var(--s3);
  background: var(--tint-2); border-radius: var(--radius);
  font-size: 16px; color: var(--ink); font-weight: 700;
}

/* /mo suffix, and the second price on a module that has both a monthly and a
   one-time. Kept visually subordinate so the headline number stays the monthly. */
.price-per { font-size: .46em; font-weight: 700; letter-spacing: 0; color: var(--ink-muted); }
.price--sub { font-size: clamp(22px, 3vw, 28px); margin-top: var(--s3); color: var(--ink-muted); }
.install-opt-price .plus {
  color: var(--accent); font-weight: 700; text-transform: none; letter-spacing: 0;
  font-size: 13px; margin-top: 4px;
}
