@charset "UTF-8";
/* ══════════════════════════════════════════════════════════════════
   EVERYCALL.CO  —  everycall.css   ·   v1.3   ·   5 Oct 2026
   Harbor palette, lifted from the RenewKit theme table so the token
   names stay familiar. Two faces only: Bebas Neue for display,
   Open Sans (condensed width axis) for everything else.

   The version above is just a label for the changelog. Pages link
   plain everycall.css with no ?v= - .htaccess makes browsers check
   for a newer copy every time, so an upload shows up straight away.

   ── CHANGELOG ──────────────────────────────────────────────────
   v1.3  5 Oct 2026
         · Page headlines 88px → 64px at full width (40px on a phone),
           EveryLocal's size, and every page now takes its headline
           from the one h1 rule: the legal pages (were 60px), the error
           pages (were 84px) and the report page (was 68px, set in the
           page) no longer have sizes of their own. The home page's
           headline is the one exception and stays at 88px.

   v1.2  5 Oct 2026
         · New wordmark, matched to EveryLocal: "Every" bold and "Call"
           light, drawn as shapes (the SVG in each page) rather than set
           in Bebas. Sized here: 29px tall, 20px on a phone - the same
           as EveryLocal's.
         · Speech bubble 55px → 42px (30px on a phone), so it sits
           beside the wordmark the way EveryLocal's pin does, and
           nudged so the wordmark lines up with the bubble's square
           part rather than the whole glyph with its tail.
         · Header held at 74px tall (60px on a phone) - what it was with
           the old logo, and EveryLocal's height - rather than whatever
           the tallest thing in it happens to be.
         · The new footer's pieces, which used to sit in footer.css:
           the small icons beside the Talk to Me lines and the social
           icons. footer.css is no longer needed.

   v1.1  23 Sept 2026
         · A hover hint over each phone - "Click to see the full demo" -
           so the rail reads as six doors rather than six pictures.
         · Phone pan 9s → 11s, so the taller captures (now capped at
           3,800px rather than ~3,000) travel at about the same speed
           they did before - roughly 60 CSS px a second, slow enough to
           read rather than a blur.

   v1.0  23 Sept 2026
         · Demo-rail phones 300px wide → 230px (260 → 200 on phones), so
           the whole row fits a laptop window. Sharpness is unchanged -
           the captures are 780px wide against a 216px screen.
         · Rail speed scaled with them (60s → 46s, 30s → 23s) so it
           travels at the same pixels per second.
         · @charset "UTF-8" on the first line, so the box-drawing rules
           in these comments read properly when the server does not send
           a charset of its own.
   ══════════════════════════════════════════════════════════════════ */

:root {
  /* ── SURFACES ─────────────────────────────────────────────── */
  --bg:          #161d26;
  --surface:     #1c242f;
  --dark2:       #111721;
  --footer-bg:   #1a222c;
  --header-bg:   rgba(28,36,47,0.92);

  /* ── TEXT ─────────────────────────────────────────────────── */
  --text:        #eef2f6;
  --off:         #cdd6e0;
  --muted:       #7d8a99;
  --placeholder: #55606d;

  /* ── ACCENTS ──────────────────────────────────────────────── */
  --accent:      #4fa8e0;
  --accent-rgb:  79,168,224;
  --accent-lt:   #7cc4f0;
  --on-accent:   #161d26;

  --red:         #c9564f;      /* the CTA */
  --red-rgb:     201,86,79;
  --on-red:      #eef2f6;

  --sage:        #3f8a6e;      /* ticks, confirmations */
  --sage-rgb:    63,138,110;

  /* --violet #7b6cd8 exists in Harbor but is deliberately unused
     here — it reads SaaS, and the buyer is a contractor. */

  /* ── LINES ────────────────────────────────────────────────── */
  --border:      rgba(79,168,224,0.16);
  --border-soft: rgba(79,168,224,0.08);

  /* ── TYPE ─────────────────────────────────────────────────── */
  --font-display:   'Bebas Neue', sans-serif;
  --font-condensed: 'Open Sans', sans-serif;
  --font-body:      var(--font-condensed);

  /* ── MEASURE ──────────────────────────────────────────────── */
  --col:      900px;
  --col-tight: 720px;
}

/* ══════════════════════════════════════════════════════════════════
   BASE
   ══════════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }

/* The browser's own [hidden] rule is display:none, but any component
   that sets its own display beats it — .btn is inline-block and
   .btn-row is flex, so el.hidden = true from pricing.js did nothing
   and the Text-to-Pay button showed alongside its own fallback.
   !important because these rules are equal specificity and later in
   the file. Anything with the hidden attribute now actually hides. */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--off);
  font-family: var(--font-body);
  font-stretch: condensed;                 /* this is what makes it condensed */
  font-size: 18px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, .display {
  font-family: var(--font-display);
  font-stretch: normal;
  color: var(--text);
  font-weight: 400;
  letter-spacing: 0.01em;
  line-height: 0.98;
  margin: 0;
  /* Stops a single short word being stranded on its own last line. */
  text-wrap: balance;
}

h1 { font-size: clamp(40px, 5.6vw, 64px); }
/* The home page's "Get found. Get called. Get booked." keeps its full
   size. It's the only headline with two line breaks in it, which lets
   this pick it out without touching index.html. */
.hero h1:has(br ~ br) { font-size: clamp(46px, 7.5vw, 88px); }
h2 { font-size: clamp(34px, 4.6vw, 54px); }
h3 { font-size: clamp(22px, 2.4vw, 28px); }

p { margin: 0 0 1.1em; }
/* Links carry on colour, never on a rule under the word. An underline
   in body copy at this size reads as a footnote and chops the
   descenders; the accent is already doing the work. Hover lifts a
   shade so there's still a state change under the cursor. */
a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-lt); }

/* Emphasis carries on colour as much as weight — only 400 and 500 are
   loaded, so a heavier face isn't available and 700 would be faux-bold. */
strong, b { color: var(--text); font-weight: 500; }

.eyebrow {
  font-family: var(--font-condensed);
  font-stretch: condensed;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 18px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.eyebrow::before {
  content: "";
  /* Thinner and knocked back on purpose. At 2px solid accent this read
     as a second coloured element next to the label rather than a rule
     mark — and on --dark2 the extra contrast made it look heavier than
     the identical mark on --surface. 1px at half opacity evens that out.
     Slightly wider than before because a thin line reads shorter than
     it measures. */
  width: 30px;
  height: 1px;
  background: rgba(var(--accent-rgb), 0.5);
  flex: none;
}

.lede { font-size: 21px; color: var(--off); max-width: 60ch; text-wrap: pretty; }
.small { font-size: 16px; color: var(--muted); }

:focus-visible {
  outline: 2px solid var(--accent-lt);
  outline-offset: 3px;
}

/* ══════════════════════════════════════════════════════════════════
   LAYOUT — full-bleed alternating bands
   ══════════════════════════════════════════════════════════════════ */

.band { padding: 50px 24px; }
.band--surface { background: var(--surface); }
.band--deep    { background: var(--dark2); }

.wrap  { max-width: var(--col); margin: 0 auto; }

/* Narrow-measure sections: the container still lines up with every
   other band, only the content inside is capped. */
.tight { max-width: var(--col); margin: 0 auto; }
.tight > * { max-width: var(--col-tight); }

/* ══════════════════════════════════════════════════════════════════
   HEADER
   ══════════════════════════════════════════════════════════════════ */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--header-bg);
  backdrop-filter: blur(9px);
  border-bottom: 1px solid var(--border);
  padding: 0 24px;
}
.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 0;
  min-height: 74px;   /* v1.2 a set height, not padding round the tallest item */
  max-width: var(--col);
}
.logo {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-display);
  font-size: 30px;
  color: var(--text);
  text-decoration: none;
  letter-spacing: 0.02em;
  line-height: 1;
}
/* CSS beats the SVG's width/height attributes, so size lives here. */
.logo-mark {
  color: var(--accent);
  width: 42px;    /* v1.2 was 55 - sized to sit beside the new wordmark */
  height: 42px;
  flex: none;
  /* The tail hangs below the bubble, so the SVG's box centre sits 4 viewBox
     units below the bubble's. Nudge down so the wordmark lines up with the
     bubble — the part the eye actually reads — not the whole glyph. */
  /* v1.2 The wordmark's capitals sit 2.6px above the middle of its own
     box, and the bubble's square part 3.5px above the middle of its box,
     so 0.9px down puts the two centres level. */
  transform: translateY(0.9px);
  /* And pull the wordmark back in. The viewBox runs to 48 but the artwork
     stops at about 32.7 — the outer arc's rightmost point — so a third of
     the mark's width is empty space travelling with it. At 55px that is
     ~17.5px of invisible padding on top of the 5px gap, which is what made
     the wordmark look adrift. Negative margin rather than a tighter viewBox
     because the SVG is inline in all 46 pages and this is one line.
     -8px, not the -14px the geometry suggests. The arcs are thin strokes,
     so the eye reads the gap from where they visibly end rather than from
     the outermost pixel, and closing the full 32% left them touching the E.
     If the mark is ever resized this wants resizing roughly in proportion. */
  margin-right: -6px;   /* v1.2 was -8 at 55px, scaled to 42 */
}
.logo-word { display: inline-block; }
/* v1.2 The wordmark is an SVG drawing now. 29px is the height of its em
   box, which puts the capitals at the same size as EveryLocal's. */
.logo-word svg { display: block; height: 29px; width: auto; color: var(--text); }

/* Explicit on both halves — nothing inherited, nothing to override. */
.logo-word .lw-a { color: var(--text); }
.logo-word .lw-b { color: var(--accent); }
.logo-word > span:last-child { color: var(--accent); }   /* legacy markup */

/* Footer logo sits a touch smaller */
.site-footer .logo { font-size: 26px; gap: 8px; }
/* Same correction, scaled: 32% of 30px is ~9.6px of built-in space. */
.site-footer .logo-mark { width: 30px; height: 30px; transform: translateY(2.5px);
  margin-right: -7px; }
.nav { display: flex; align-items: center; gap: 28px; }
/* :not(.btn) so these never reach the header CTA. `.nav a` is (0,1,1) and
   `.btn`/`.btn--primary` are (0,1,0), so without the exclusion the nav wins
   and the button silently inherits nav styling: 0.04em tracking instead of
   the button's .08em, and --off instead of --on-red. Both are small enough
   to look like a rendering quirk rather than a cascade problem.

   Excluding at the source rather than patching each property back on the
   button also means any future .btn dropped into the nav is correct by
   default. */
.nav a:not(.btn) {
  color: var(--off);
  text-decoration: none;
  font-size: 15px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 400;
}
.nav a:not(.btn):hover { color: var(--accent-lt); }

/* ══════════════════════════════════════════════════════════════════
   BUTTONS
   ══════════════════════════════════════════════════════════════════ */

.btn {
  display: inline-block;
  font-family: var(--font-condensed);
  font-stretch: condensed;
  font-size: 16px;
  font-weight: 400;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 12px 22px;
  border-radius: 4px;
  line-height: 1;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background .2s, color .2s, border-color .2s, transform .15s;
}
.btn--primary {
  background: var(--red);
  color: var(--on-red);
  border-color: var(--red);
}
/* colour is restated, not inherited. These buttons are <a> elements, so
   the global `a:hover` rule (0,1,1) outranks `.btn--primary` (0,1,0) and
   was repainting the label accent-blue on red the moment the cursor
   landed. Declaring it here takes the hover state to (0,2,0), which wins.
   Same reason it is repeated on .error-cta below.

   The header CTA used to need its own `.nav a.btn--primary` selector on
   top of this, because `.nav a:hover` (0,2,1) outranked (0,2,0). That is
   no longer necessary: `.nav a` now carries :not(.btn), so it never
   touches the button in the first place. */
.btn--primary:hover,
.btn--primary:focus-visible {
  background: #d96a63;
  border-color: #d96a63;
  color: var(--on-red);
  transform: translateY(-2px);
}

/* Header CTA sits shorter than the in-page buttons. */
.site-header .btn {
  font-size: 15px;
  padding: 9px 18px;
  white-space: nowrap;
}

/* The pricing CTA. It sits under ten ticked rows, so the eye arrives in
   skim mode — the gap above it does more work than the size does, and
   both matter more than the colour, which it shares with the header
   button two inches up the page. Full width on a phone: it's the one
   button on the page that should be unmissable with a thumb. */
.btn--xl {
  font-size: 19px;
  padding: 18px 36px;
  letter-spacing: .1em;
}
@media (max-width: 620px) {
  .btn--xl { display: block; width: 100%; text-align: center; padding: 19px 20px; }
}

.btn--ghost {
  background: transparent;
  color: var(--accent-lt);
  border-color: rgba(var(--accent-rgb),0.5);
}
.btn--ghost:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: translateY(-1px);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
  margin-top: 30px;
}

/* A pair of CTAs that should read as one unit. inline-grid with
   fit-content sizes the grid to its content, and two 1fr tracks then
   split that evenly — so both buttons end up as wide as the longer
   label, without stretching across the hero. (max-content tracks
   don't do this: each column would size to its own label.)
   minmax(0,...) because a grid item's floor is min-content, not zero.
   Under 560px they stack full width rather than wrapping ragged. */
.btn-row--even {
  display: inline-grid;
  width: fit-content;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: stretch;
}
.btn-row--even .btn {
  width: 100%;
  text-align: center;
  white-space: nowrap;
}
@media (max-width: 560px) {
  .btn-row--even { grid-template-columns: minmax(0, 1fr); }
}

/* ══════════════════════════════════════════════════════════════════
   HERO
   ══════════════════════════════════════════════════════════════════ */

.hero {
  padding: 50px 24px;
  background:
    radial-gradient(1000px 480px at 78% -10%, rgba(var(--accent-rgb),0.13), transparent 62%),
    var(--bg);
}
.hero .wrap {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(36px, 5vw, 72px);
  align-items: start;
}
.hero h1 span { color: var(--accent); display: block; }
.hero .lede { margin-top: 24px; }

.hero-note {
  margin-top: 26px;
  font-size: 16px;
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
}
.hero-note b { color: var(--off); font-weight: 500; }

/* ── SIGNATURE: the recovery thread ──────────────────────────── */

.thread {
  background: var(--dark2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 16px 18px;
}
.thread-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 11px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--border-soft);
}
.thread-head strong {
  font-family: var(--font-display);
  font-stretch: normal;
  font-size: 19px;
  color: var(--text);
  letter-spacing: 0.02em;
}
.thread-head span {
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}

.ev {
  display: grid;
  grid-template-columns: 52px 1fr;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border-soft);
}
.ev:last-child { border-bottom: 0; padding-bottom: 2px; }
.ev time {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--muted);
  padding-top: 3px;
  font-variant-numeric: tabular-nums;
}
.ev p { margin: 0; font-size: 14.5px; line-height: 1.48; }
.ev .who {
  display: block;
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 500;
  margin-bottom: 3px;
}
.ev--miss  .who { color: var(--red); }
.ev--auto  .who { color: var(--accent); }
.ev--reply .who { color: var(--off); }
.ev--book  .who { color: var(--sage); }
.ev--book p { color: var(--text); font-weight: 500; }

.ev--auto p, .ev--reply p {
  background: var(--surface);
  border-radius: 7px;
  padding: 8px 11px;
  border-left: 2px solid transparent;
}
.ev--auto p  { border-left-color: rgba(var(--accent-rgb),0.55); }
.ev--reply p { border-left-color: rgba(255,255,255,0.14); }

/* ══════════════════════════════════════════════════════════════════
   WHAT'S INCLUDED — five items, rules not boxes
   ══════════════════════════════════════════════════════════════════ */

.stack { margin-top: 42px; }

.item {
  display: grid;
  grid-template-columns: 38px 250px 1fr;
  gap: 22px;
  padding: 24px 0;
  border-top: 1px solid var(--border-soft);
  align-items: start;
}

.item-icon {
  color: var(--accent);
  padding-top: 2px;
}
/* Pages that reuse .item without an icon collapse the gutter. */
.item:not(:has(.item-icon)) { grid-template-columns: 250px 1fr; gap: 30px; }
.item-icon svg { width: 28px; height: 28px; display: block; }
.item:last-child { border-bottom: 1px solid var(--border-soft); }

.item h3 { margin-bottom: 9px; }
.item .tag {
  margin: 0;
  font-size: 16.5px;
  line-height: 1.4;
  color: var(--accent);
}
.item-body p { margin: 0; font-size: 17.5px; }
/* A second paragraph for the specifics, set smaller and quieter than the
   pitch above it. Someone skimming reads the first paragraph and moves
   on; someone who wants to know exactly what he is paying for reads this
   one. Both are served without the section getting longer to look at. */
.item-body .item-detail { margin-top: 14px; font-size: 15.5px;
  line-height: 1.65; color: var(--muted); }
.item-body .item-detail strong { color: var(--off); font-weight: 500; }

/* ══════════════════════════════════════════════════════════════════
   STEPS — a real sequence, so numbering earns its place
   ══════════════════════════════════════════════════════════════════ */

.steps { margin-top: 48px; display: grid; gap: 0; }
.step {
  display: grid;
  grid-template-columns: 42px 1fr;
  gap: 16px;
  padding: 26px 0;
  border-top: 1px solid var(--border-soft);
  align-items: start;
}
.step:last-child { border-bottom: 1px solid var(--border-soft); }
.step .n {
  font-family: var(--font-display);
  font-stretch: normal;
  font-size: 46px;
  line-height: 1;
  color: var(--accent);
}
.step h3 { margin-bottom: 7px; }
.step p { margin: 0; max-width: 62ch; }

/* ══════════════════════════════════════════════════════════════════
   REVIEWS POSITION
   ══════════════════════════════════════════════════════════════════ */

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(32px, 5vw, 66px);
  align-items: start;
  margin-top: 42px;
}
.contrast { border-top: 2px solid var(--border); padding-top: 22px; }
.contrast h3 { font-size: 21px; margin-bottom: 12px; }
.contrast--bad  { border-top-color: rgba(var(--red-rgb),0.55); }
.contrast--good { border-top-color: rgba(var(--sage-rgb),0.7); }
.contrast--bad h3  { color: var(--red); }
.contrast--good h3 { color: var(--sage); }
.contrast p:last-child { margin-bottom: 0; }

/* ══════════════════════════════════════════════════════════════════
   PRICING
   ══════════════════════════════════════════════════════════════════ */

.price-head {
  display: flex;
  align-items: flex-end;
  gap: 16px;
  flex-wrap: wrap;
  /* h2 above carries no bottom margin, so the gap lives here.
     Slightly less than the standard 22px because the figure's
     0.86 line-height already leaves optical space at the cap. */
  margin: 28px 0 4px;
}
.price-figure {
  font-family: var(--font-display);
  font-stretch: normal;
  font-size: clamp(72px, 11vw, 124px);
  line-height: 0.86;
  color: var(--text);
}
.price-per {
  font-size: 19px;
  color: var(--muted);
  letter-spacing: 0.05em;
  padding-bottom: 10px;
}
.price-terms {
  font-size: 15px;
  color: var(--muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 500;
  margin-bottom: 34px;
}

.incl {
  list-style: none;
  margin: 0 0 30px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0,1fr));
  gap: 11px 34px;
}
.incl li {
  position: relative;
  padding-left: 27px;
  font-size: 16.5px;
  color: var(--off);
}
.incl li::before {
  content: "";
  position: absolute;
  left: 0; top: 9px;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--sage);
}

/* ══════════════════════════════════════════════════════════════════
   WHAT'S INCLUDED — the icon grid

   Replaces the bulleted list. Twelve things is too many to read as
   bullets; as labelled rows with an icon each, it scans in a couple of
   seconds and the tick column reads as "all of it, included".

   The icons are inline SVG rather than an icon font or sprite — twelve
   of them cost less than one extra request, and they inherit the accent
   colour without a second stylesheet.
   ══════════════════════════════════════════════════════════════════ */

.incl-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0,1fr));
  gap: 10px;
  margin: 0 0 30px;
}

/* "What every one of these actually does" used to sit directly under
   the price, 6px below the terms line, where two small grey lines ran
   together and the grid then butted straight into them. It belongs
   here instead: it answers the question the ten cards have just
   raised. Sentence case rather than .price-terms' uppercase — under
   the cards it needs to read as a link, not as more small print.
   The negative top pulls it back against the grid's own 30px. */
.incl-more {
  margin: -14px 0 0;
  font-size: 16.5px;
  color: var(--muted);
}
.incl-item {
  display: grid;
  grid-template-columns: 38px minmax(0,1fr) 20px;
  align-items: center;
  gap: 14px;
  background: var(--dark2);
  border: 1px solid var(--border-soft);
  border-radius: 9px;
  padding: 15px 16px;
  transition: opacity .28s ease, transform .28s ease,
              background .28s ease, border-color .28s ease;
  will-change: transform;
}

.incl-i {
  width: 38px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 8px;
  background: rgba(var(--accent-rgb), 0.11);
  color: var(--accent);
  transition: background .28s ease, transform .28s cubic-bezier(.34,1.4,.5,1);
}
.incl-i svg { width: 20px; height: 20px; display: block; }

/* ── Hover: dim the rest, lift the one ────────────────────────────────
   Ten ticked rows read as wallpaper. Fading the others back turns the
   grid into something you scan deliberately instead of skimming past.

   Gated behind hover:hover because on a touchscreen :hover sticks after
   a tap — one card would stay lifted and the other nine stay dimmed
   until you tapped elsewhere. The card is not a link and there is
   nothing to reach, so phones simply get the static version. */
@media (hover: hover) {
  .incl-grid:hover .incl-item { opacity: .45; }

  .incl-grid .incl-item:hover {
    opacity: 1;
    /* Lift, not slide. 8px of translateX inside a two-column grid reads
       as a misalignment rather than a hover. */
    transform: translateY(-3px);
    background: rgba(var(--accent-rgb), 0.06);
    border-color: rgba(var(--accent-rgb), 0.38);
  }
  .incl-item:hover .incl-i {
    background: rgba(var(--accent-rgb), 0.2);
    transform: scale(1.08);
  }
  .incl-item:hover .incl-t { color: var(--accent-lt, var(--accent)); }
  .incl-t { transition: color .28s ease; }
}

@media (prefers-reduced-motion: reduce) {
  .incl-item, .incl-i, .incl-t { transition: none; }
  .incl-grid:hover .incl-item { opacity: 1; }
  .incl-grid .incl-item:hover { transform: none; }
  .incl-item:hover .incl-i { transform: none; }
}

.incl-t {
  font-size: 17px;
  font-weight: 500;
  color: var(--text);
  line-height: 1.25;
}
.incl-s {
  font-size: 15.5px;
  color: var(--muted);
  line-height: 1.4;
  margin-top: 2px;
}
.incl-tick { color: var(--sage); line-height: 0; }
.incl-tick svg { width: 19px; height: 19px; display: block; }

/* An odd number of items would leave a hole in the second column, so
   the last one widens to fill the row. Means rows can be added or
   dropped without the grid looking unfinished. */
.incl-item:last-child:nth-child(odd) { grid-column: 1 / -1; }

@media (max-width: 700px) {
  .incl-grid { grid-template-columns: 1fr; }
  .incl-item { padding: 13px 14px; gap: 12px; }
  .incl-t { font-size: 16px; }
}

.plain {
  border-top: 1px solid var(--border-soft);
  padding-top: 22px;
  font-size: 16.5px;
  color: var(--muted);
}
.plain b { color: var(--off); }

/* ══════════════════════════════════════════════════════════════════
   FAQ
   ══════════════════════════════════════════════════════════════════ */

.faq { margin-top: 60px; }
.faq details {
  border-bottom: 1px solid var(--border-soft);
  padding: 18px 0;
}
.faq summary {
  cursor: pointer;
  list-style: none;
  font-family: var(--font-condensed);
  font-stretch: condensed;
  font-size: 18px;
  font-weight: 500;
  color: var(--text);
  letter-spacing: 0.01em;
  line-height: 1.4;
  display: flex;
  justify-content: space-between;
  gap: 18px;
  align-items: center;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  color: var(--accent);
  font-size: 26px;
  line-height: 1;
  flex: none;
}
.faq details[open] summary::after { content: "–"; }
.faq details p { margin: 14px 0 0; max-width: 74ch; }

/* ══════════════════════════════════════════════════════════════════
   CONTACT
   ══════════════════════════════════════════════════════════════════ */

.form { margin-top: 34px; display: grid; gap: 16px; }
.form .row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.form label {
  display: block;
  font-size: 12.5px;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--muted);
  margin-bottom: 7px;
}
.form input, .form textarea {
  width: 100%;
  background: var(--dark2);
  border: 1px solid var(--border);
  border-radius: 5px;
  color: var(--text);
  font-family: var(--font-condensed);
  font-stretch: condensed;
  font-size: 16px;
  padding: 12px 14px;
}
.form input::placeholder, .form textarea::placeholder { color: var(--placeholder); }
.form input:focus, .form textarea:focus {
  outline: none;
  border-color: var(--accent);
}
.form textarea { resize: vertical; min-height: 108px; }
.consent { font-size: 13.5px; color: var(--muted); line-height: 1.55; }

/* ══════════════════════════════════════════════════════════════════
   INDUSTRY MARQUEE
   ══════════════════════════════════════════════════════════════════ */

.trust-bar {
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  height: 50px;
  overflow: hidden;
  position: relative;
  display: flex;
  align-items: center;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}
.trust-track {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  white-space: nowrap;
  animation: trust-scroll 120s linear infinite;
  will-change: transform;
}
.trust-bar:hover .trust-track { animation-play-state: paused; }
.trust-item {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-condensed);
  font-stretch: condensed;
  font-size: 15px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
  padding: 0 22px;
}
.trust-dot {
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0.55;
  flex-shrink: 0;
}
@keyframes trust-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ══════════════════════════════════════════════════════════════════
   WHO WE WORK WITH
   ══════════════════════════════════════════════════════════════════ */

.who-grid {
  margin-top: 40px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
}
.who-card {
  background: var(--dark2);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  padding: 20px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.who-card h4 {
  font-family: var(--font-display);
  font-stretch: normal;
  font-size: 21px;
  letter-spacing: 0.03em;
  color: var(--text);
  margin: 0 0 9px;
  font-weight: 400;
}
.who-card p {
  margin: 0 0 15px;
  font-size: 16.5px;
  line-height: 1.5;
  color: var(--muted);
}

/* Pill naming why this trade loses calls — varied per card, so it
   carries information rather than repeating one filler label. */
.who-tag {
  display: inline-block;
  border: 1px solid rgba(var(--sage-rgb),0.45);
  border-radius: 3px;
  padding: 4px 10px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sage);
  white-space: nowrap;
}
/* ══════════════════════════════════════════════════════════════════
   SMS OPT-IN

   Deliberately separate from the submit button. Carriers require
   messaging consent to be optional and not a condition of using the
   service, so this is never required and the form submits without it.
   The ticked box is also the only record that consent was given for a
   given number — bundling it into the submit wording leaves nothing to
   point at later.

   Scoped generally rather than to one page so the sales page and the
   contact page cannot drift apart.
   ══════════════════════════════════════════════════════════════════ */

.sms-optin {
  display: grid;
  grid-template-columns: 18px minmax(0,1fr);
  gap: 11px;
  align-items: start;
  margin: 0;
}
/* Drawn rather than native. iOS Safari ignores width and height on a
   checkbox and renders it at whatever size it likes — bigger than the
   18px column it is sitting in, which is why it looked oversized on a
   phone and pushed the label out of line while being fine on desktop.
   appearance:none takes the native control away and the box below is
   ours, so it is the same size everywhere.

   Keep the real input: it is still a checkbox to a screen reader, it
   still toggles on a label click, and it still posts its value. Only the
   drawing changed. */
.sms-optin > input[type="checkbox"] {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  /* THE actual cause of the oversized box. ".form input, .form textarea"
     a few rules up sets padding:12px 14px for every input in the form,
     and the old checkbox rule set width and height but never padding —
     so an 18px box was wearing 26px of vertical padding and rendering
     about 44px square, dragging the label out of line with it. Anything
     that opts out of the standard field shape has to opt out of its
     padding too. */
  padding: 0;
  flex: none;
  margin: 2px 0 0;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--dark2);
  cursor: pointer;
  display: grid;
  place-content: center;
  transition: border-color .15s, background .15s;
}
.sms-optin > input[type="checkbox"]:hover { border-color: var(--accent-lt); }
.sms-optin > input[type="checkbox"]::before {
  content: "";
  width: 10px;
  height: 10px;
  transform: scale(0);
  transition: transform .12s ease-in-out;
  background: var(--accent);
  /* a tick, not a filled square — a square reads as indeterminate */
  clip-path: polygon(14% 46%, 0 60%, 40% 100%, 100% 22%, 86% 8%, 38% 72%);
}
.sms-optin > input[type="checkbox"]:checked {
  border-color: var(--accent);
  background: rgba(var(--accent-rgb), .12);
}
.sms-optin > input[type="checkbox"]:checked::before { transform: scale(1); }
.sms-optin > input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* .form label is styled as a field label — uppercase and letterspaced —
   so it has to be beaten here. */
/* The label is now just the ask — one short line beside the box. The
   disclosure moved below the button as .form-fine. */
.form .sms-optin-text label {
  display: block;
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
  font-size: .95rem;
  line-height: 1.5;
  color: var(--off);
  opacity: 1;
  cursor: pointer;
}
/* Below the button: the carrier checklist, in whole sentences and out
   of the way. Present on the page and next to the consent, which is
   what a verification review looks for. */
/* Centred under a full-width button whose own text is centred. The
   checkbox above stays left — it is a control, and it lines up with
   the fields it sits under. */
.form-fine {
  /* The form grid already contributes 16px between rows, so this is
     zero rather than negative — the visible gap is the grid's. */
  margin: 0;
  font-size: .78rem;
  line-height: 1.55;
  color: var(--placeholder);
  text-align: center;
}
/* No underline, no colour of their own — a policy link in fine print
   is there to be found if looked for, not to be noticed. Hover is the
   only thing that gives them away as links. */
.form-fine a { color: inherit; text-decoration: none; }
.form-fine a:hover { color: var(--accent); }

/* Full width of the form column — one edge with the fields on both
   sides, and a proper tap target on a phone. Taller than a standard
   button: it is the end of the form, and it should look like it. */
.btn--block {
  display: block;
  width: 100%;
  text-align: center;
  padding: 18px 22px;
  font-size: 19px;
  letter-spacing: .1em;
}
.form .sms-optin-text strong {
  font-size: .95rem;
  font-weight: 500;
  color: var(--off);
}
/* The consent links have to be findable — this is the language a carrier
   would read back to us — so they come off the muted grey and onto the
   accent. Colour rather than an underline, same as every other link. */
.form .sms-optin-text a {
  color: var(--accent);
  text-decoration: none;
}
.form .sms-optin-text a:hover { color: var(--accent-lt); }
/* Kept for the contact page, which still renders one. Nothing on the
   sales page uses it — small print stacked around a CTA is what makes
   people abandon a form. */
.sms-optin-note {
  margin: 9px 0 0;
  font-size: .82rem;
  line-height: 1.55;
  opacity: .6;
}

.who-foot {
  margin-top: 26px;
  font-size: 16px;
  color: var(--off);
}
/* Same treatment as .already — colour only, so a link sitting on its
   own under a section doesn't read as a footnote. */
.who-foot a { color: var(--accent); text-decoration: none; }
.who-foot a:hover { color: var(--accent-lt); }

/* ══════════════════════════════════════════════════════════════════
   PRICE BLOCK — "$397/mo, the whole system"
   Lifted out of claim.html so the claim page and /whats-included run
   the same markup off one stylesheet instead of two copies drifting
   apart. The price is the last objection before the ask, so it gets
   to be the size of the thing it is rather than a footnote row.
   ══════════════════════════════════════════════════════════════════ */

.price-block {
  margin-top: 36px;
  padding-top: 28px;
  border-top: 1px solid rgba(255,255,255,.12);
}
.price-line { margin: 0; font-size: 17px; color: var(--muted); }
.price-line b {
  font-size: 26px;
  color: var(--text);
  font-weight: 500;
  letter-spacing: .01em;
}
.price-line span { color: var(--muted); }

/* Two columns of five. Ten stacked would run past the fold on a phone
   and read as a spec sheet; paired, it reads as a receipt. */
.incl-list {
  list-style: none;
  margin: 22px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px 28px;
  max-width: 52ch;
}
.incl-list li {
  position: relative;
  padding-left: 23px;
  font-size: 16.5px;
  color: var(--off);
  line-height: 1.4;
}
.incl-list li::before {
  content: "";
  position: absolute;
  left: 1px;
  top: 7px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

.price-terms { margin: 24px 0 0; font-size: 15px; color: var(--muted); }
.price-terms b { color: var(--off); font-weight: 500; }

@media (max-width: 600px) {
  .incl-list { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  .price-line b { font-size: 23px; }
}

/* ══════════════════════════════════════════════════════════════════
   FOOTER
   ══════════════════════════════════════════════════════════════════ */

.site-footer {
  background: var(--footer-bg);
  border-top: 1px solid var(--border);
  padding: 50px 24px 0;
}
.footer-inner {
  max-width: var(--col);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1.25fr;
  gap: 28px 30px;
  padding-bottom: 34px;
}
.footer-heading {
  font-family: var(--font-display);
  font-stretch: normal;
  font-size: 18px;
  letter-spacing: 0.09em;
  color: var(--text);
  margin-bottom: 10px;
}
.footer-link {
  display: block;
  font-family: var(--font-condensed);
  font-stretch: condensed;
  font-size: 16px;
  line-height: 1.35;
  color: var(--muted);
  text-decoration: none;
  padding: 2px 0;
}
.footer-link:hover { color: var(--accent-lt); }
.footer-connect {
  display: block;
  font-size: 16px;
  color: var(--muted);
  line-height: 1.35;
}
.footer-socials { display: flex; gap: 9px; margin-top: 15px; }
.footer-social-link {
  width: 32px; height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: 50%;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
}
.footer-social-link:hover { color: var(--accent); border-color: var(--accent); }

.footer-bottom {
  max-width: var(--col);
  margin: 0 auto;
  border-top: 1px solid var(--border-soft);
  padding: 18px 0 24px;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 10px 26px;
  font-size: 16px;
  line-height: 1.4;
  color: var(--placeholder);
}
.footer-bottom a { color: var(--muted); text-decoration: none; }
.footer-bottom a:hover { color: var(--accent-lt); }
.footer-bottom-links { display: flex; flex-wrap: wrap; gap: 0 8px; align-items: center; }
.footer-bottom-links a + a::before {
  content: "\00b7";
  color: var(--placeholder);
  margin-right: 8px;
}

/* ══════════════════════════════════════════════════════════════════
   MOTION — one reveal, nothing scattered
   ══════════════════════════════════════════════════════════════════ */

.ev { opacity: 0; transform: translateY(12px); }
.thread.in .ev {
  animation: rise .72s cubic-bezier(.2,.7,.3,1) forwards;
}
/* Gaps widen as the conversation goes on — the reply and the booking
   take longer to arrive than the automatic text does. */
.thread.in .ev:nth-child(2) { animation-delay: .20s; }
.thread.in .ev:nth-child(3) { animation-delay: .95s; }
.thread.in .ev:nth-child(4) { animation-delay: 1.85s; }
.thread.in .ev:nth-child(5) { animation-delay: 2.85s; }

@keyframes rise { to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .ev { opacity: 1; transform: none; }
  .thread.in .ev { animation: none; }
  .trust-track { animation: none; }
  * { transition-duration: .01ms !important; }
}

/* ══════════════════════════════════════════════════════════════════
   RESPONSIVE
   ══════════════════════════════════════════════════════════════════ */

@media (max-width: 940px) {
  .hero .wrap { grid-template-columns: 1fr; }
  .item { grid-template-columns: 38px 1fr; gap: 8px 18px; }
  .item-icon { grid-row: span 2; }
  .split { grid-template-columns: 1fr; }
  .who-grid { grid-template-columns: repeat(2, 1fr); }
  .footer-inner { grid-template-columns: 1fr 1fr; }
  .nav a:not(.btn) { display: none; }
}

@media (max-width: 620px) {
  /* The icon-less .item never collapsed on a phone. `.item` inside the
     940px block is (0,1,0); `.item:not(:has(.item-icon))` up at line ~462
     is (0,2,0) — :not() and :has() take the specificity of their argument,
     and a media query adds none. So the mobile rule lost, and the trade
     pages kept `250px 1fr` all the way down: at 390px that leaves ~70px
     for the body column, which wraps one word per line.

     Restated at matching specificity so it actually binds. Held back to
     620px rather than 940px because the two-column reading is still fine
     on a tablet — it is only narrow phones where the body column starves. */
  .item:not(:has(.item-icon)) { grid-template-columns: 1fr; gap: 6px; }

  body { font-size: 17px; }
  .incl { grid-template-columns: 1fr; }
  .form .row { grid-template-columns: 1fr; }
  .step { grid-template-columns: 32px 1fr; gap: 12px; }
  .step .n { font-size: 34px; }
  .ev { grid-template-columns: 54px 1fr; gap: 11px; }
  .site-header { padding: 0 20px; }
  .site-header .wrap { padding: 0; min-height: 60px; }   /* v1.2 */
  .logo-mark { width: 30px; height: 30px; transform: translateY(0.6px); margin-right: -4px; }
  .logo-word svg { height: 20px; }
  .site-footer { padding-left: 20px; padding-right: 20px; }
  .who-grid { grid-template-columns: 1fr; }
  .footer-inner { grid-template-columns: 1fr; gap: 22px; }
  .band { padding-left: 20px; padding-right: 20px; }
  .hero { padding-left: 20px; padding-right: 20px; }
}

/* ══════════════════════════════════════════════════════════════════
   LEGAL PAGES
   ══════════════════════════════════════════════════════════════════ */


.legal-date {
  font-size: 14px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 16px 0 0;
}

.legal { margin-top: 34px; }
.legal h2 {
  font-size: clamp(22px, 2.5vw, 27px);
  margin: 38px 0 12px;
  color: var(--text);
}
.legal h2:first-child { margin-top: 0; }
.legal p { font-size: 16.5px; }
.legal ul { margin: 0 0 1.1em; padding-left: 20px; }
.legal li { font-size: 16.5px; margin-bottom: 8px; }
.legal strong { color: var(--text); font-weight: 500; }
.legal a { color: var(--accent); }

.legal-contact {
  border-left: 2px solid rgba(var(--accent-rgb),0.45);
  padding-left: 16px;
  color: var(--off);
}

.legal-callout {
  background: var(--dark2);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 20px 22px;
  margin-bottom: 34px;
}
.legal-callout p { margin: 0; }

.legal-sample {
  background: var(--dark2);
  border-left: 2px solid rgba(var(--accent-rgb),0.55);
  border-radius: 0 6px 6px 0;
  padding: 13px 16px;
  font-size: 15.5px;
  color: var(--off);
  margin-bottom: 12px;
}

.legal-keywords {
  font-family: var(--font-display);
  font-stretch: normal;
  font-size: 22px;
  letter-spacing: 0.12em;
  color: var(--accent);
}

/* ══════════════════════════════════════════════════════════════════
   CONTACT PAGE
   ══════════════════════════════════════════════════════════════════ */

.contact-grid {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: clamp(34px, 5vw, 62px);
  margin-top: 44px;
  align-items: start;
}
.contact-block {
  padding-bottom: 20px;
  margin-bottom: 20px;
  border-bottom: 1px solid var(--border-soft);
}
.contact-block:last-child { border-bottom: 0; margin-bottom: 0; padding-bottom: 0; }
.contact-label {
  font-size: 12.5px;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--muted);
  margin-bottom: 8px;
}
.contact-value {
  font-family: var(--font-display);
  font-stretch: normal;
  font-size: 27px;
  letter-spacing: 0.02em;
  color: var(--text);
  text-decoration: none;
  display: block;
  margin-bottom: 8px;
}
.contact-value:hover { color: var(--accent-lt); }
.contact-plain { margin: 0; font-size: 16px; color: var(--off); }
.contact-block .small { margin: 0; }
/* Deliberately NOT a display-font heading. It sits a few inches under the h1
   and in Bebas at heading size the two competed; body font, body colour, a
   step up in weight is enough to label the form without fighting for the eye.
   Size and weight were being overridden by a copy of this rule in contact.html
   — one place now. 500 not 600: only 400 and 500 are loaded, so 600 was a
   faux-bold the browser was synthesising.

   font-stretch: condensed is doing real work here, not tidying up. This
   is an h2, so it picks up font-stretch:normal from the h1/h2/h3 rule —
   fine for Bebas, wrong here, because the only Open Sans instance we load
   is the 75 width axis. Until the webfont arrives the fallback renders at
   normal width and looks right; the moment it lands the browser has to
   reconcile a normal-width request against a condensed-only family, and
   the heading visibly changes a second after the page paints. Every other
   rule that reaches for the body face sets this. This one didn't. */
.contact-form-h {
  margin-bottom: 14px;
  font-family: var(--font-body);
  font-stretch: condensed;
  font-size: 26px;
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1.35;
  color: var(--text);
}

/* ══════════════════════════════════════════════════════════════════
   FAQ PAGE GROUPS
   ══════════════════════════════════════════════════════════════════ */

.faq-group {
  font-size: 17px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  font-family: var(--font-display);
  font-stretch: normal;
  margin: 40px 0 4px;
  padding-bottom: 10px;
}
.faq-group:first-child { margin-top: 0; }

@media (max-width: 940px) {
  .contact-grid { grid-template-columns: 1fr; }
}

/* ══════════════════════════════════════════════════════════════════
   ABOUT PAGE
   ══════════════════════════════════════════════════════════════════ */

.bio-headline {
  text-wrap: balance;
  font-size: clamp(32px, 4.6vw, 54px);
  line-height: 0.98;
  margin-bottom: 34px;
}
.bio-headline span { color: var(--accent); }

.bio {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: clamp(28px, 4vw, 48px);
  align-items: start;
}

.bio-photo {
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--dark2);
}
.bio-photo picture, .bio-photo img { display: block; width: 100%; height: auto; }

.bio-copy p { font-size: 17px; line-height: 1.75; }

/* Credential pills — horizontal, so they cost one or two lines, not six. */
.creds {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 26px 0 4px;
}
.cred {
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 6px 12px;
  font-size: 13.5px;
  letter-spacing: 0.04em;
  color: var(--muted);
  white-space: nowrap;
}

@media (max-width: 780px) {
  .bio { grid-template-columns: 1fr; }
  .bio-photo { max-width: 240px; }
  .cred { white-space: normal; }
}

/* Header phone — visible on every page, click-to-call on mobile */
/* ── PHONE LINKS ──────────────────────────────────────────────────
   A number is one thing, so it breaks as one thing.

   "(888)" at the end of a line and "240-2477" at the start of the next
   is a number somebody has to reassemble before they can dial it, and
   it happens anywhere a phone link sits inside a sentence rather than
   on its own - a paragraph, the footer, a narrow phone. Site-wide
   because it is true site-wide, and because the alternative is finding
   it one page at a time after somebody notices.

   Attribute selector rather than a class, so it covers links that were
   never given one. */
a[href^="tel:"] { white-space: nowrap; }

.nav-phone {
  font-family: var(--font-condensed);
  font-stretch: condensed;
  font-size: 15px;
  font-weight: 400;
  letter-spacing: 0.04em;
  color: var(--text) !important;
  text-decoration: none;
  white-space: nowrap;
}
.nav-phone:hover { color: var(--accent-lt) !important; }

@media (max-width: 940px) {
  .nav a.nav-phone { display: inline-block; }
}
@media (max-width: 520px) {
  .nav a.nav-phone { display: none; }
}

/* Under 520px the written number doesn't fit beside the CTA, so it drops out
   above — but the header is sticky, which makes it the only phone link that
   follows someone down the page. Keep click-to-call as an icon rather than
   losing it entirely. Minimal headers (.site-header--min) are untouched:
   their number sits outside .nav, so it never hides in the first place. */
.nav-call { display: none; }
@media (max-width: 520px) {
  .nav a.nav-call {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    flex: none;
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--text) !important;
  }
  .nav a.nav-call:hover { color: var(--accent-lt) !important; }
  .nav-call svg { width: 18px; height: 18px; display: block; }
  .site-header .wrap { gap: 12px; }

  /* The nav's own 28px gap is a desktop measure for five text links. Under
     520px the nav holds exactly two things — the call icon and the CTA — and
     that gap was never reduced, so it kept 28px of air in the tightest place
     on the page. Combined with a longer CTA label it pushed the button past
     .site-header's 20px padding and up against the screen edge.

     The header cannot shrink to fit on its own: .logo, .nav-call and the
     button are all fixed-width or nowrap, so the overflow lands on whichever
     item is last in the row. Reclaiming it from the gaps is the fix. */
  .nav { gap: 12px; }
  .site-header .btn { padding: 9px 14px; }

  /* "See Your Website" is ~31pt wider than "Your Website" and will not fit
     beside the logo and the call icon at 390px, whatever the gaps do — the
     row needs about 365pt and has 350pt. So one word is markup rather than
     copy, and drops out here:

       <a class="btn btn--primary" href="/#demo">See <span
          class="btn-lead">Your </span>Website</a>

     The word that drops is "Your", not "See". Dropping the verb left the
     button reading "Your Website" on a phone — a noun where an action
     should be, which stops it looking like something you press. "See
     Website" is also a shade narrower than "Your Website" was, so the
     390px row has slightly more slack than before, not less.

     Every page carries the identical header, so this markup has to match
     on all of them or the two versions will drift. The trailing space
     lives INSIDE the span so the short label has no double space. */
  .site-header .btn .btn-lead { display: none; }
}

/* Second step for 375-380px phones (SE, mini, older Androids), where the
   above still leaves only a couple of points of slack. Logo drops a size and
   the CTA loses a point of type — deliberately not applied at 390px, which
   is the common iPhone width and fits at full size. */
@media (max-width: 380px) {
  .logo { font-size: 26px; }
  .site-header .btn { font-size: 14px; padding: 8px 12px; }
}

/* ══════════════════════════════════════════════════════════════════
   BIG STAT COUNTER
   ══════════════════════════════════════════════════════════════════ */

.big-stat { max-width: 100%; }

.big-stat-num {
  display: block;
  font-feature-settings: "tnum" 1;
  min-width: 3ch;
  font-family: var(--font-display);
  font-stretch: normal;
  font-size: clamp(84px, 15vw, 150px);
  line-height: 0.86;
  letter-spacing: 0.01em;
  color: rgba(var(--accent-rgb), 0.38);
  font-variant-numeric: tabular-nums;
  margin-bottom: 14px;
}
.big-stat-num .pct { font-size: 0.62em; }

.big-stat-label {
  /* The line break is in the markup, so balance only has to even out
     the first half when it wraps on a phone. */
  text-wrap: balance;
  /* Deliberately NOT the display face. At h2 size in Bebas this read as
     a second headline and fought the one above it. Open Sans at a fifth
     of the number's size makes it a caption to the stat, which is what
     it is. Condensed so it stays in the same voice as body copy rather
     than adding a third face to the section. Markup is sentence case —
     Bebas hid the casing, this face doesn't. */
  font-family: var(--font-condensed);
  font-stretch: condensed;
  font-weight: 500;
  font-size: clamp(24px, 2.6vw, 32px);
  /* 1.02 was a Bebas value — Open Sans needs room for descenders. */
  line-height: 1.3;
  letter-spacing: 0;
  color: var(--text);
  margin-bottom: 20px;
}
.big-stat-label span { color: var(--accent); }

.big-stat-desc {
  font-size: 17.5px;
  line-height: 1.7;
  max-width: 60ch;
  margin-bottom: 18px;
}

.big-stat-src {
  font-size: 13.5px;
  line-height: 1.6;
  /* --muted, not --placeholder. At 13.5px on the deep band, --placeholder
     lands around 2.9:1 against the background — under half of what AA
     asks for at this size, so the citation read as decoration rather
     than text. --muted clears 5:1 and is still clearly below .big-stat-desc. */
  color: var(--muted);
  max-width: 66ch;
  border-left: 1px solid var(--border-soft);
  padding-left: 14px;
  margin: 0;
}

/* ══════════════════════════════════════════════════════════════════
   SEE IT WORK — interactive flow
   ══════════════════════════════════════════════════════════════════ */

.flow-steps {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 34px 0 36px;
}
.flow-pill {
  font-family: var(--font-condensed);
  font-stretch: condensed;
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 100px;
  padding: 8px 16px;
  cursor: pointer;
  white-space: nowrap;
  transition: color .18s, border-color .18s, background .18s;
}
.flow-pill:hover { color: var(--accent-lt); border-color: rgba(var(--accent-rgb),0.5); }
.flow-pill.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
.flow-arrow { color: var(--placeholder); font-size: 15px; }

.flow-body {
  display: grid;
  grid-template-columns: 300px 1fr;
  gap: clamp(30px, 5vw, 60px);
  align-items: start;
}

/* ── PHONE ──────────────────────────────────────────────────── */

.phone {
  width: 300px;
  background: var(--dark2);
  border: 1px solid var(--border);
  border-radius: 30px;
  padding: 12px;
  position: relative;
}
.phone-notch {
  width: 78px; height: 5px;
  background: var(--placeholder);
  border-radius: 100px;
  margin: 2px auto 12px;
  opacity: 0.5;
}
.phone-screen {
  background: var(--bg);
  border-radius: 20px;
  overflow: hidden;
  min-height: 356px;
  display: flex;
  flex-direction: column;
}
.phone-bar {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  padding: 13px 15px;
  border-bottom: 1px solid var(--border-soft);
}
.phone-who {
  font-family: var(--font-display);
  font-stretch: normal;
  font-size: 17px;
  letter-spacing: 0.02em;
  color: var(--text);
}
.phone-time { font-size: 12px; color: var(--muted); }

.phone-msgs {
  padding: 14px 13px;
  display: flex;
  flex-direction: column;
  gap: 11px;
}

.msg {
  max-width: 88%;
  opacity: 0;
  animation: msg-in .34s cubic-bezier(.2,.7,.3,1) forwards;
}
.msg p {
  margin: 0;
  font-size: 14px;
  line-height: 1.45;
  padding: 9px 12px;
  border-radius: 13px;
}
.msg time {
  display: block;
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--placeholder);
  margin-top: 4px;
  padding: 0 3px;
}

.msg--out { align-self: flex-end; }
.msg--out p { background: rgba(var(--accent-rgb),0.16); color: var(--text); border-bottom-right-radius: 4px; }
.msg--out time { text-align: right; }

.msg--in { align-self: flex-start; }
.msg--in p { background: var(--surface); color: var(--off); border-bottom-left-radius: 4px; }

.msg--miss { align-self: stretch; max-width: 100%; }
.msg--miss p {
  background: rgba(var(--red-rgb),0.12);
  color: var(--red);
  text-align: center;
  font-size: 13px;
  letter-spacing: 0.03em;
}
.msg--miss time { text-align: center; }

.msg--ok { align-self: stretch; max-width: 100%; }
.msg--ok p {
  background: rgba(var(--sage-rgb),0.14);
  color: var(--sage);
  text-align: center;
  font-size: 13px;
  letter-spacing: 0.03em;
}
.msg--ok time { text-align: center; }

@keyframes msg-in {
  from { opacity: 0; transform: translateY(7px); }
  to   { opacity: 1; transform: none; }
}

/* ── COPY ───────────────────────────────────────────────────── */

.flow-copy { padding-top: 6px; }
.flow-copy h3 { margin-bottom: 14px; }
.flow-copy p { font-size: 17px; line-height: 1.7; max-width: 52ch; }
.flow-note {
  font-size: 14.5px !important;
  color: var(--muted);
  border-left: 2px solid rgba(var(--accent-rgb),0.45);
  padding-left: 13px;
  margin-bottom: 0 !important;
}

@media (prefers-reduced-motion: reduce) {
  .msg { opacity: 1; animation: none; }
}

@media (max-width: 820px) {
  .flow-body { grid-template-columns: 1fr; }
  .phone { width: 100%; max-width: 300px; }
  .flow-arrow { display: none; }
}


/* ══════════════════════════════════════════════════════════════════
   ERROR PAGES (401 / 403 / 404)
   ══════════════════════════════════════════════════════════════════ */

.error-page { display: flex; flex-direction: column; min-height: 100vh; }

.error-wrap {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 90px 24px 80px;
}

.error-num {
  font-family: var(--font-display);
  font-stretch: normal;
  font-size: clamp(100px, 20vw, 180px);
  letter-spacing: 0.04em;
  line-height: 1;
  color: #2f6d99;
  font-variant-numeric: tabular-nums;
  animation: err-up .5s ease both;
}

.error-eyebrow {
  font-family: var(--font-condensed);
  font-stretch: condensed;
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 16px;
  animation: err-up .5s .1s ease both;
}

.error-heading {
  margin: 0 0 20px;
  animation: err-up .5s .15s ease both;
}
.error-heading em { color: var(--accent); font-style: normal; display: block; }

.error-sub {
  font-size: 17px;
  color: var(--muted);
  line-height: 1.7;
  max-width: 460px;
  margin: 0 auto 36px;
  animation: err-up .5s .2s ease both;
}
.error-sub strong { color: var(--text); font-weight: 500; }

.error-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--red);
  color: var(--on-red);
  font-family: var(--font-condensed);
  font-stretch: condensed;
  font-size: 16px;
  font-weight: 400;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 14px 32px;
  border-radius: 4px;
  text-decoration: none;
  margin-bottom: 48px;
  transition: background .2s, transform .15s;
  animation: err-up .5s .25s ease both;
}
/* color restated to beat the global `a:hover` — see .btn--primary:hover. */
.error-cta:hover,
.error-cta:focus-visible { background: #d96a63; color: var(--on-red); transform: translateY(-2px); }

.quick-links {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  animation: err-up .5s .3s ease both;
}
.quick-links-label {
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}
.quick-links-row { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }

.quick-link {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 15px 20px;
  text-decoration: none;
  text-align: left;
  min-width: 168px;
  transition: border-color .2s, transform .15s;
}
.quick-link:hover {
  border-color: rgba(var(--accent-rgb),0.45);
  transform: translateY(-2px);
}
.quick-link-arrow {
  display: block;
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 5px;
}
.quick-link-label {
  display: block;
  font-family: var(--font-display);
  font-stretch: normal;
  font-size: 17px;
  letter-spacing: 0.05em;
  color: var(--text);
}

@keyframes err-up {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .error-num, .error-eyebrow, .error-heading,
  .error-sub, .error-cta, .quick-links { animation: none; opacity: 1; }
}

@media (max-width: 480px) {
  .quick-links-row { flex-direction: column; align-items: stretch; width: 100%; max-width: 280px; }
  .error-wrap { padding-top: 60px; }
}

/* ══════════════════════════════════════════════════════════════════
   SECTION SUBHEADINGS
   Open Sans Condensed rather than Bebas — these are sentence-case
   labels sitting next to body copy, and all-caps display type reads
   too loud at that size.
   ══════════════════════════════════════════════════════════════════ */

.item h3,
.contrast h3,
.step h3,
.flow-copy h3 {
  font-family: var(--font-condensed);
  font-stretch: condensed;
  font-weight: 500;
  font-size: 22px;
  line-height: 1.3;
  letter-spacing: 0.005em;
}
.contrast h3 { font-size: 22px; }

/* ── Thank-you page: secondary self-book option ─────────────── */
.book-alt {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  padding: 20px 24px;
  margin: 0 auto 44px;
  max-width: 430px;
}
.book-alt-label {
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 10px;
}
.book-alt-link {
  font-family: var(--font-display);
  font-stretch: normal;
  font-size: 24px;
  letter-spacing: 0.03em;
  color: var(--accent);
  text-decoration: none;
  display: inline-block;
}
.book-alt-link:hover { color: var(--accent-lt); }
.book-alt-note {
  font-size: 14px;
  line-height: 1.55;
  color: var(--muted);
  margin: 10px 0 0;
}

/* ══════════════════════════════════════════════════════════════════
   BOOKING PAGE — Cal.com inline embed
   ══════════════════════════════════════════════════════════════════ */

.cal-wrap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  position: relative;
  margin-top: 8px;
}
.cal-header {
  padding: 22px 26px;
  border-bottom: 1px solid var(--border);
}
.cal-header h2 { font-size: 30px; margin-bottom: 4px; }
.cal-header p { margin: 0; font-size: 15.5px; color: var(--muted); }

.cal-embed {
  width: 100%;
  min-height: 620px;
  overflow: auto;
  padding: 24px 32px;
}

/* Masks Cal's own branding strip at the foot of the embed. */
.cal-brand-cover {
  position: absolute;
  left: 1px; right: 1px; bottom: 0;
  height: 68px;
  background: var(--surface);
  pointer-events: none;
  z-index: 2;
}

.cal-alt {
  margin: 22px 0 0;
  font-size: 15.5px;
  color: var(--muted);
}

@media (max-width: 620px) {
  .cal-embed { padding: 16px 10px; min-height: 560px; }
  .cal-header { padding: 18px 20px; }
  .cal-brand-cover { height: 56px; }
}

/* Quiet line under pricing — for someone who's already seen their demo
   and just wants the payment link. Deliberately not a button. */
.already {
  /* Sits under the enlarged pricing CTA — 20px left it clinging to the
     button's bottom edge once that grew. */
  margin: 30px 0 0;
  /* Secondary on purpose — it is for the handful who have already seen
     their demo — but 15px muted was quiet enough to miss. Up one step,
     and off the muted grey onto body colour. */
  font-size: 16px;
  color: var(--off);
}
.already a { color: var(--accent); text-decoration: none; }
.already a:hover { color: var(--accent-lt); }

/* ══════════════════════════════════════════════════════════════════
   PAYMENT PAGE
   ══════════════════════════════════════════════════════════════════ */

.pay-grid {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: clamp(30px, 5vw, 56px);
  align-items: start;
  margin-top: 30px;
}

.btn--pay {
  font-size: 19px;
  padding: 17px 34px;
  margin-top: 26px;
}

.pay-secure {
  margin: 14px 0 0;
  font-size: 13.5px;
  letter-spacing: 0.05em;
  color: var(--muted);
}

.pay-card {
  background: var(--dark2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 24px 24px 26px;
}
.pay-card-head {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  margin-bottom: 4px;
}
.pay-figure {
  font-family: var(--font-display);
  font-stretch: normal;
  font-size: 58px;
  line-height: 0.9;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.pay-per { font-size: 15px; color: var(--muted); padding-bottom: 5px; }
.pay-card-sub {
  margin: 0 0 18px;
  font-size: 14.5px;
  color: var(--muted);
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border-soft);
}
.pay-incl {
  grid-template-columns: 1fr;
  gap: 10px;
  margin-bottom: 0;
}
.pay-incl li { font-size: 15.5px; }

@media (max-width: 820px) {
  .pay-grid { grid-template-columns: 1fr; }
  .pay-card { max-width: 380px; }
}

/* ══════════════════════════════════════════════════════════════════
   SENTENCE-CASE LABELS → OPEN SANS CONDENSED
   Bebas is caps-only, so anything written in sentence case loses its
   casing and reads as shouting. These are all phrases, not headlines
   or category labels, so they belong in the body face.
   ══════════════════════════════════════════════════════════════════ */

.quick-link-label,      /* "What's included", "Talk to Erik" — 401/403/404 */
.book-alt-link,         /* "Book a 15-minute call →" — thanks page */
.contact-value,         /* phone number and email address — contact page */
.thread-head strong,    /* "A Tuesday afternoon" — hero panel */
.phone-who {            /* "Ridgeline Plumbing" — flow phone mockup */
  font-family: var(--font-condensed);
  font-stretch: condensed;
  font-weight: 500;
  letter-spacing: 0.01em;
}

.quick-link-label { font-size: 16px; line-height: 1.3; }
.book-alt-link    { font-size: 19px; }
.contact-value    { font-size: 22px; line-height: 1.3; }
.thread-head strong { font-size: 17px; }
.phone-who        { font-size: 15px; }

/* Industry cards are links once the per-trade pages exist. */
a.who-card { text-decoration: none; transition: border-color .18s, transform .15s; }
a.who-card:hover {
  border-color: rgba(var(--accent-rgb),0.4);
  transform: translateY(-2px);
}
a.who-card:hover h4 { color: var(--accent-lt); }

/* ══════════════════════════════════════════════════════════════════
   COOKIE CONSENT BAR
   ══════════════════════════════════════════════════════════════════ */

.cookie-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 200;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding: 16px 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 24px;
  box-shadow: 0 -8px 32px rgba(0,0,0,0.4);
  opacity: 0;
  transform: translateY(100%);
  transition: opacity .26s ease, transform .3s cubic-bezier(.2,.7,.3,1);
}
.cookie-bar.is-in { opacity: 1; transform: none; }

.cookie-copy {
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--off);
  flex: 0 1 auto;
}
.cookie-copy a { color: var(--accent); }

.cookie-actions {
  display: flex;
  gap: 10px;
  flex: none;
}
.cookie-actions .btn { font-size: 14px; padding: 10px 18px; }

@media (prefers-reduced-motion: reduce) {
  .cookie-bar { transition: none; opacity: 1; transform: none; }
}

@media (max-width: 900px) {
  .cookie-bar {
    flex-direction: column;
    align-items: stretch;
    gap: 14px;
    padding: 16px 20px;
    text-align: left;
  }
  .cookie-actions .btn { flex: 1; text-align: center; }
}

/* Explains the Lead Frog name on the Stripe checkout before they see it. */
.pay-note {
  margin: 16px 0 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--muted);
  border-left: 2px solid var(--border);
  padding-left: 14px;
  max-width: 52ch;
}

/* ══════════════════════════════════════════════════════════════════
   MINIMAL CHROME — checkout and post-payment pages
   Nav removed so the only forward action is the payment button.
   ══════════════════════════════════════════════════════════════════ */

.site-header--min .wrap {
  justify-content: space-between;
}
.site-header--min .nav-phone {
  font-size: 16px;
  color: var(--off) !important;
}
.site-header--min .nav-phone:hover { color: var(--accent-lt) !important; }

/* No column grid above it, so the divider has nothing to divide. */
.site-footer--min {
  padding-top: 0;
  border-top: 0;          /* the rule above the footer itself */
}
.site-footer--min .footer-bottom {
  border-top: 0;          /* the rule above the copyright row */
  padding-top: 34px;
}

/* Second line of a headline in accent — used on the payment page. */
.accent-line { color: var(--accent); }

/* ══════════════════════════════════════════════════════════════════
   DEMO BUILDS — scrolling rail
   Same pattern as the ConsultKit theme rail: it pauses on hover so a
   cell can be aimed at, and on keyboard focus so it can be tabbed to.
   ══════════════════════════════════════════════════════════════════ */

.demo-marquee {
  position: relative;
  overflow: hidden;
  margin-top: 24px;
  /* overflow:hidden clips vertically too, so the hover lift and the phone's
     drop shadow need room inside the box or they get sheared off. */
  padding: 14px 0 30px;
  /* Fades the slice through whichever phone is straddling the boundary.
     Vertical stops are opaque so the mask never eats the hover lift or the
     drop shadow the padding above just made room for. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}

.demo-track {
  display: flex;
  gap: 20px;
  width: max-content;
  animation: demoscroll 46s linear infinite;   /* scaled with --pw, so the rail keeps the same pixels per second */
}

/* :focus-visible rather than :focus-within — a click leaves focus on the
   link in the tab behind, which would pause the rail permanently with
   nothing hovered and no way to see why. */
.demo-marquee:hover .demo-track,
.demo-marquee:has(:focus-visible) .demo-track { animation-play-state: paused; }

@keyframes demoscroll {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-50% - 10px)); }
}

/* --pw drives every dimension of the device chrome — bezel, corner radii,
   island, buttons are all calc()'d off it, so changing the cell width at a
   breakpoint rescales the whole phone in proportion. Change it in ONE place. */
.demo-cell {
  /* 230, not 300. At 300 the rail of phones was taller than a laptop
     window, so the row could not be seen whole. Sharpness is unaffected:
     the captures are 780px wide and the screen inside the phone is 216
     CSS px at this size, which is 3.6x the pixels it needs - MORE
     oversampled than before, not less. */
  --pw: 230px;
  flex: 0 0 var(--pw);
  display: block;
  position: relative;   /* v1.1 - for the hover hint below */
  text-decoration: none;
  transition: transform .25s ease;
}
.demo-cell:hover { transform: translateY(-4px); }

/* v1.1 A hint over the screen, so it is obvious the phone is a door and
   not a picture. Drawn with ::after rather than markup, because the rail
   duplicates its cells to loop and any element added would be added
   twice. pointer-events:none so it never eats the click it is inviting,
   and hover-only, which on a touch screen means it simply never shows -
   there a tap opens the demo anyway. */
.demo-cell::after {
  content: "Click to see the full demo";
  position: absolute;
  left: 50%;
  top: calc(var(--pw) * 1.05);
  transform: translate(-50%, 6px);
  padding: 7px 13px;
  border-radius: 999px;
  background: rgba(12, 17, 24, 0.9);
  border: 1px solid rgba(var(--accent-rgb), 0.5);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 12.5px;
  letter-spacing: .03em;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease, transform .2s ease;
  z-index: 4;
}
.demo-cell:hover::after,
.demo-cell:focus-visible::after { opacity: 1; transform: translate(-50%, 0); }

@media (prefers-reduced-motion: reduce) {
  .demo-cell::after { transition: none; }
}

/* A real device shell rather than a rounded rectangle with a notch: 19.5:9
   screen, titanium rail, Dynamic Island, side buttons. The screen is a real
   phone screen, so the hover pan now reads as scrolling a phone. Note that
   overflow is VISIBLE — the side buttons have to sit outside the body, and
   the screen clips itself on the img's own border-radius instead. */
.demo-cell .phone-frame {
  position: relative;
  aspect-ratio: 71.6 / 147.6;
  border-radius: calc(var(--pw) * 0.145);
  padding: calc(var(--pw) * 0.030);
  background:
    linear-gradient(145deg, #6d7278 0%, #2f3338 18%, #43484e 42%, #24272b 68%, #5a5f65 100%);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.16),
    0 18px 40px rgba(0, 0, 0, 0.55);
  transition: box-shadow .25s ease;
}
.demo-cell:hover .phone-frame {
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.16),
    0 0 0 2px rgba(var(--accent-rgb), 0.45),
    0 18px 40px rgba(0, 0, 0, 0.55);
}

/* Left rail: action button, then volume up and volume down. One pseudo-element
   drawing three bars via box-shadow offsets, so no extra markup. */
.demo-cell .phone-frame::before {
  content: "";
  position: absolute;
  left: calc(var(--pw) * -0.008);
  top: calc(var(--pw) * 0.175);
  width: calc(var(--pw) * 0.011);
  height: calc(var(--pw) * 0.055);
  border-radius: calc(var(--pw) * 0.006) 0 0 calc(var(--pw) * 0.006);
  background: linear-gradient(90deg, #23262a, #55595f);
  box-shadow:
    0 calc(var(--pw) * 0.105) #3a3e43,
    0 calc(var(--pw) * 0.200) #3a3e43;
}
/* Right rail: power button, longer and lower than the volume pair. */
.demo-cell .phone-frame::after {
  content: "";
  position: absolute;
  right: calc(var(--pw) * -0.008);
  top: calc(var(--pw) * 0.250);
  width: calc(var(--pw) * 0.011);
  height: calc(var(--pw) * 0.105);
  border-radius: 0 calc(var(--pw) * 0.006) calc(var(--pw) * 0.006) 0;
  background: linear-gradient(270deg, #23262a, #55595f);
}

/* Safari chrome. The screenshots are page captures with no browser UI, so the
   status bar, address bar and toolbar are drawn here and the capture sits in
   the gap between them — which is exactly where a real viewport lives. Chrome
   covers the screen's rounded corners top and bottom, so the img itself can be
   square-cornered and still look clipped. Every size is a fraction of --pw. */
.demo-cell .phone-ui,
.demo-cell .phone-toolbar {
  position: absolute;
  left: calc(var(--pw) * 0.030);
  width: calc(100% - var(--pw) * 0.060);
  background: #2c2c2e;
  z-index: 2;
}
.demo-cell .phone-ui {
  top: calc(var(--pw) * 0.030);
  height: calc(var(--pw) * 0.250);
  border-radius: calc(var(--pw) * 0.115) calc(var(--pw) * 0.115) 0 0;
}
.demo-cell .phone-toolbar {
  bottom: calc(var(--pw) * 0.030);
  height: calc(var(--pw) * 0.122);
  border-radius: 0 0 calc(var(--pw) * 0.115) calc(var(--pw) * 0.115);
}
.demo-cell .phone-toolbar::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: calc(var(--pw) * 0.022);
  transform: translateX(-50%);
  width: 34%;
  height: calc(var(--pw) * 0.011);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.55);
}
/* Back / forward / share / tabs, as four dots — at this scale real glyphs
   would be mush, and four evenly spaced marks read as a toolbar anyway. */
.demo-cell .phone-toolbar::before {
  content: "";
  position: absolute;
  left: 18%;
  top: calc(var(--pw) * 0.038);
  width: calc(var(--pw) * 0.022);
  height: calc(var(--pw) * 0.022);
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.34);
  box-shadow:
    calc(var(--pw) * 0.140) 0 rgba(255, 255, 255, 0.34),
    calc(var(--pw) * 0.280) 0 rgba(255, 255, 255, 0.34),
    calc(var(--pw) * 0.420) 0 rgba(255, 255, 255, 0.34);
}
.demo-cell .phone-status {
  position: absolute;
  top: calc(var(--pw) * 0.020);
  left: 0; right: 0;
  height: calc(var(--pw) * 0.115);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 calc(var(--pw) * 0.058);
}
.demo-cell .phone-time {
  color: #fff;
  font-size: calc(var(--pw) * 0.042);
  /* 600 isn't loaded — the browser was smearing a synthetic bold onto
     the 500 at 8px, which is where it shows worst. */
  font-weight: 500;
  letter-spacing: .01em;
  line-height: 1;
}
/* Signal, wifi and battery as three small blocks. */
.demo-cell .phone-icons {
  width: calc(var(--pw) * 0.028);
  height: calc(var(--pw) * 0.020);
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.85);
  box-shadow:
    calc(var(--pw) * -0.042) 0 rgba(255, 255, 255, 0.85),
    calc(var(--pw) * -0.084) 0 rgba(255, 255, 255, 0.85);
}
.demo-cell .phone-url {
  position: absolute;
  left: calc(var(--pw) * 0.040);
  right: calc(var(--pw) * 0.040);
  bottom: calc(var(--pw) * 0.026);
  height: calc(var(--pw) * 0.090);
  border-radius: 999px;
  background: #4a4a4d;
  display: flex;
  align-items: center;
  justify-content: center;
}
.demo-cell .phone-url span {
  color: #f2f2f5;
  font-size: calc(var(--pw) * 0.040);
  line-height: 1;
  letter-spacing: .01em;
}

.demo-cell .phone-frame img {
  position: absolute;
  top: calc(var(--pw) * 0.280);
  left: calc(var(--pw) * 0.030);
  width: calc(100% - var(--pw) * 0.060);
  height: calc(100% - var(--pw) * 0.432);
  display: block;
  border: 0;
  background: var(--dark2);
  object-fit: cover;
  object-position: top center;
  /* Panning walks the preview down the page. The rail is already paused by
     then, so the two behaviours cooperate: stop, then look. Feed it the FULL
     page capture, not a cropped one — the crop is what there is to scroll
     through.

     .is-panning is set by script, not :hover, for two reasons: only one card
     may pan at a time, and a card only qualifies if it is WHOLLY inside the
     marquee — panning a phone that is half past the edge shows a scroll you
     cannot follow. The release below is deliberately quick: on a slow return
     the card you just left is still moving while the new one starts, which
     reads as two things scrolling at once. */
  transition: object-position .45s ease-out;
}
.demo-cell.is-panning .phone-frame img {
  object-position: bottom center;
  transition-duration: 11s;   /* v1.1 - matched to the taller 3,800px captures */
  transition-timing-function: ease-in-out;
}

/* Dynamic Island — floats on the screen rather than cutting into the bezel,
   which is what actually distinguishes it from the old notch. Sits inside the
   Safari status bar, where a real one does. */
.demo-cell .phone-notch {
  position: absolute;
  top: calc(var(--pw) * 0.075);
  left: 50%;
  transform: translateX(-50%);
  width: calc(var(--pw) * 0.285);
  height: calc(var(--pw) * 0.082);
  background: #000;
  border-radius: 999px;
  z-index: 3;
}

.demo-name {
  font-size: 16.5px;
  font-weight: 500;
  color: var(--text);
  text-align: center;
  margin-top: 12px;
  transition: color .25s ease;
}
.demo-cell:hover .demo-name { color: var(--accent-lt); }

.demo-trade {
  font-size: 12.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: center;
  margin-top: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .demo-track { animation: none; flex-wrap: wrap; width: auto; justify-content: center; }
  .demo-cell[aria-hidden="true"] { display: none; }
  .demo-cell .phone-frame img,
  .demo-cell.is-panning .phone-frame img { transition: none; object-position: top center; }
}

@media (max-width: 620px) {
  .demo-cell { --pw: 200px; }
  /* Narrower cells mean a shorter track, so the same duration crawls here.
     Scale the duration down to keep the rail at the same pixels-per-second
     it runs at on desktop. */
  .demo-track { animation-duration: 23s; }
  .demo-marquee { margin-top: 18px; }
}

/* ══════════════════════════════════════════════════════════════════
   ADD-ON CARD
   Deliberately quieter than the pricing band above it — a contained
   card, no big figure, no h2. There is one price on this page and it
   is $397; this is an aside.
   ══════════════════════════════════════════════════════════════════ */

.addon {
  background: var(--dark2);
  border: 1px solid var(--border-soft);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  padding: 30px 34px 32px;
}

.addon-tag {
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 12px;
}

.addon-h {
  font-family: var(--font-display);
  font-stretch: normal;
  font-size: 34px;
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--text);
  margin: 0 0 14px;
}

.addon-lede {
  font-size: 18px;
  line-height: 1.65;
  color: var(--off);
  margin: 0 0 18px;
  max-width: 60ch;
}

.addon-list {
  list-style: none;
  margin: 0 0 20px;
  padding: 0;
  display: grid;
  gap: 11px;
}
.addon-list li {
  position: relative;
  padding-left: 22px;
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--muted);
  max-width: 66ch;
}
.addon-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 9px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

.addon-price {
  margin: 0;
  padding-top: 18px;
  border-top: 1px solid var(--border-soft);
  font-size: 15.5px;
  line-height: 1.65;
  color: var(--muted);
  max-width: 66ch;
}
.addon-price strong { color: var(--text); }

@media (max-width: 620px) {
  .addon { padding: 24px 20px 26px; border-left-width: 2px; }
  .addon-h { font-size: 29px; }
}

/* ══════════════════════════════════════════════════════════════════
   HERO WATERMARK  —  opt in with  <section class="band band--mark">

   The mark sits in the right-hand gutter, outside the 720px content
   column, anchored to the TOP of the band. Top-anchored on purpose:
   on /privacy and /contact the first band holds the whole page, so
   anything centred vertically would end up floating in the middle of
   the legal text.

   The glyph is a data URI rather than a file for three reasons: no
   extra request, no hotlink rule to trip over on client domains, and
   everycall.css already revalidates on every request — so an edit
   here takes effect immediately, where an .svg would sit in a
   one-year cache (see the mod_expires block in .htaccess).

   viewBox is 2 7 36 36, not the header's 0 0 48 48. The header glyph
   carries empty space on the right that the wordmark needs and a
   watermark does not; this one is cropped to the artwork.

   Colour is baked to #4fa8e0 — a background-image can't read
   currentColor. If a light-background band ever needs this, add a
   second rule with #161d26 in the fill and opacity around .05.
   ══════════════════════════════════════════════════════════════════ */

.band--mark { position: relative; overflow: hidden; }

/* lift the real content above the watermark */
.band--mark > * { position: relative; z-index: 1; }

.band--mark::after {
  content: "";
  position: absolute;
  z-index: 0;
  top: 30px;
  /* always 120px right of the 900px wrap's right edge, at any width */
  right: calc(50% - var(--col) / 2 - 120px);
  width: min(30vw, 340px);
  aspect-ratio: 1 / 1;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='2 7 36 36'%3E%3Cmask id='m'%3E%3Crect x='2' y='7' width='36' height='36' fill='%23000'/%3E%3Crect x='2' y='7' width='36' height='26' rx='8' fill='%23fff'/%3E%3Cpath d='M11 31 L11 43 L22 31 Z' fill='%23fff'/%3E%3Ccircle cx='9.2' cy='20' r='3.1' fill='%23000'/%3E%3Ccircle cx='17.2' cy='20' r='3.1' fill='%23000'/%3E%3Cpath d='M26.45 15.24 A5.5 5.5 0 0 1 26.45 24.76' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round'/%3E%3Cpath d='M28.20 12.21 A9 9 0 0 1 28.20 27.79' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round'/%3E%3C/mask%3E%3Crect x='2' y='7' width='36' height='36' fill='%234fa8e0' mask='url(%23m)'/%3E%3C/svg%3E") no-repeat center / contain;
  opacity: .075;
  pointer-events: none;
}

/* the darker the band, the more the mark needs to carry */
.band--mark.band--surface::after { opacity: .085; }
.band--mark.band--deep::after    { opacity: .095; }

/* Below ~1040px the gutter is gone and the mark would land on the
   headline. Nothing to salvage at that width — hide it. */
@media (max-width: 1040px) {
  .band--mark::after { display: none; }
}

/* ══════════════════════════════════════════════════════════════════
   MOCKS — the ten parts, drawn

   Every competitor selling this shows a picture of each part; we were
   showing ten icons and a paragraph. These are inline SVG rather than
   screenshots on purpose: nothing new to host, no version bump on an
   image, sharp at any width, and every fill is a palette var so they
   recolour with the site instead of drifting from it.

   They live inside .item-body, under the paragraph, so the .item grid
   above is untouched and the 940px/620px collapses still apply.
   ══════════════════════════════════════════════════════════════════ */

.mock { margin-top: 20px; }
.mock svg { width: 100%; height: auto; display: block; }

/* Type inside the drawings is set here, not as SVG attributes, so the
   faces live with the rest of the site's type and not in the markup. */
.mock text      { font-family: var(--font-condensed); font-size: 11.5px; fill: var(--off); }
.mock .mk-hd    { font-size: 12px; font-weight: 500; fill: var(--text); }
.mock .mk-dim   { font-size: 10.8px; fill: var(--muted); }
.mock .mk-ac    { fill: var(--accent); }
.mock .mk-sg    { fill: var(--sage); }

/* Surfaces. The band behind these is --surface, so the "screen" drops
   to --dark2 and the cards sitting on it come back up to --surface. */
.mock .mk-scr   { fill: var(--dark2); stroke: var(--border); stroke-width: 1; }
.mock .mk-card  { fill: var(--surface); }
.mock .mk-in    { fill: var(--surface); }
.mock .mk-out   { fill: rgba(var(--accent-rgb), 0.16); stroke: rgba(var(--accent-rgb), 0.34); stroke-width: 1; }
.mock .mk-rule  { stroke: var(--border-soft); stroke-width: 1; }
.mock .mk-bar   { fill: rgba(var(--accent-rgb), 0.14); }   /* stand-in for text */
.mock .mk-cta   { fill: rgba(var(--red-rgb), 0.9); }
.mock .mk-dot   { fill: var(--placeholder); }
.mock .mk-fill  { fill: var(--accent); }
.mock .mk-line  { fill: none; stroke: var(--accent); stroke-width: 1.5;
                  stroke-linecap: round; stroke-linejoin: round; }
.mock .mk-line-sg { fill: none; stroke: var(--sage); stroke-width: 1.6;
                  stroke-linecap: round; stroke-linejoin: round; }

/* Review stars are the one warm value on the site and they earn it —
   blue stars don't read as Google. Kept local, deliberately out of
   :root so it can't leak into the palette. */
.mock .mk-star  { fill: #d9a441; }
.mock .mk-star-o{ fill: none; stroke: #d9a441; stroke-width: 1.2; }

@media (max-width: 940px) {
  /* Once .item collapses to `38px 1fr` the drawing is stuck in the
     narrow column with the icon gutter beside it. Pulling it back over
     that gutter is worth about 13% more width, which matters more here
     than any font-size bump: the whole drawing scales with its box. */
  .mock { margin-left: -56px; }
}

@media (max-width: 620px) {
  /* A phone still renders these at roughly 0.85 of the desktop size, so
     the internal type goes up again to compensate. They bottom out at
     about 12px on screen — which is what phone UI looks like on a phone,
     and these are drawings of phone UI, so that reads as intended
     rather than as small text. */
  .mock { margin-top: 16px; }
  .mock text    { font-size: 13px; }
  .mock .mk-hd  { font-size: 13.5px; }
  .mock .mk-dim { font-size: 12.2px; }
}

/* ══════════════════════════════════════════════════════════════════
   SHIFT — the same week, twice

   Two columns that line up pair by pair: the moment on the left with
   what currently happens, the same moment on the right with what
   happens instead. Sits between the 85% stat and the price, so the
   reader has seen the cost and the change before the number.

   On a phone the pairs stack. The column headings drop out and each
   cell grows its own label from data-label, so a stacked pair still
   says which side it is without duplicating the words in the markup.
   ══════════════════════════════════════════════════════════════════ */

.shift {
  margin-top: 40px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 30px;
}

.shift-head {
  font-family: var(--font-display);
  font-size: 23px;
  letter-spacing: .03em;
  /* Top padding on both heads, not just the tinted one: the panel needs
     air above "WITH EVERYCALL", and if only the right cell grew, the two
     headings would sit at different baselines and their rules wouldn't
     line up across the gutter. */
  padding: 20px 0 12px;
  border-bottom: 1px solid var(--border);
}
.shift-head--a { color: var(--muted); }
.shift-head--b { color: var(--accent); }

.shift-a, .shift-b {
  margin: 0;
  padding: 18px 0;
  /* Was 16px, which sat below the 17px body base — these rows are the
     substance of the section, not a caption, so they shouldn't be the
     smallest text on screen. */
  font-size: 17.5px;
  line-height: 1.52;
  border-bottom: 1px solid var(--border-soft);
}
.shift-a { color: var(--muted); }

/* The right column is one continuous panel, not six tinted rows: the
   grid has no row gap, so consecutive cells sit flush and the fill
   joins up by itself. The heading rounds the top, the last row rounds
   the bottom and drops its rule so the panel closes on itself.

   The tint is accent at 7% over --bg, which lands a shade cooler than
   --surface — deliberately, so it doesn't read as just another card. */
.shift-b {
  color: var(--off);
  position: relative;
  padding: 18px 22px 18px 42px;
  background: rgba(var(--accent-rgb), 0.07);
}
.shift-head--b {
  padding: 20px 22px 12px 42px;
  background: rgba(var(--accent-rgb), 0.07);
  border-radius: 10px 10px 0 0;
}
.shift-b:last-child {
  border-bottom: 0;
  padding-bottom: 22px;
  border-radius: 0 0 10px 10px;
}

/* Per-row tick. The panel says which column is the good one; the tick
   marks each answer inside it, which is a different job. */
.shift-b::after {
  content: "";
  position: absolute;
  left: 18px; top: 25px;
  width: 12px; height: 7px;
  border-left: 2px solid var(--sage);
  border-bottom: 2px solid var(--sage);
  transform: rotate(-45deg);
}

/* The moment itself, stated once on the left and answered on the right. */
.shift-when {
  display: block;
  color: var(--text);
  font-weight: 500;
  margin-bottom: 6px;
}

.shift-a::before, .shift-b::before { display: none; }

.shift-note {
  margin-top: 26px;
  margin-bottom: 0;
  color: var(--muted);
  font-size: 16.5px;
}

@media (max-width: 760px) {
  .shift { grid-template-columns: 1fr; gap: 0; }
  .shift-head { display: none; }

  /* Stacked, the column can't be a column, so each answer becomes its
     own tinted card sitting under the moment it answers. The tick goes:
     on a card this small the fill and the label already say which half
     this is, and a third marker is just noise. */
  .shift-a { padding: 22px 0 12px; border-bottom: 0; }
  .shift-b {
    padding: 14px 18px 16px;
    border-bottom: 0;
    border-radius: 10px;
  }
  .shift-b:last-child { padding-bottom: 16px; border-radius: 10px; }
  .shift-b::after { display: none; }

  .shift-a::before, .shift-b::before {
    display: block;
    content: attr(data-label);
    font-family: var(--font-display);
    font-size: 15px;
    letter-spacing: .06em;
    margin-bottom: 7px;
  }
  .shift-a::before { color: var(--muted); }
  .shift-b::before { color: var(--accent); }
}

@media print {
  .band--mark::after { display: none; }
}


/* ══════════════════════════════════════════════════════════════════
   FOOTER ADDITIONS  (v1.2, 5 Oct 2026 - were footer.css)
   ══════════════════════════════════════════════════════════════════ */

/* Talk to Me: phone, email, book a call, see your website. Ordinary
   footer links - same colour and spacing as the other columns - with a
   small icon in front that takes the link's colour. */
.footer-line svg { width: 18px; height: 18px; }

/* Social icons in the circles that held "ig fb yt". */
.footer-socials { margin-top: 18px; }
.footer-social-link svg { width: 18px; height: 18px; display: block; }
