/* ==========================================================================
   Atomx.Pro — shared stylesheet

   Layout language follows the enterprise-agency pattern: a wide 1265px
   container, very heavy (800-900) headings at a large scale, and the page
   built as a stack of full-width bands.

   Colour is balanced roughly in thirds by band, as requested:
     .band-light / .band-white  — white + near-white
     .band-dark                 — black (hero, pipeline, footer)
     .band-red                  — red (stats, closing CTA)

   Contrast rules baked into the scale:
     --red-600 text on white ............ 7.73:1   safe for body text
     --red-600 as a fill under white ..... 7.73:1   safe for buttons
     --red-500 .......................... 6.15:1   borders / icons / large text
     white on --red-700 band ............ 9.96:1   safe
     --red-400 on --ink ................. 5.25:1   the ONLY red for dark bands
   Never use --red-400 on white — it is the dark-background accent.
   ========================================================================== */

:root {
  /* Neutrals */
  --white: #ffffff;
  --bg: #ffffff;
  --bg-soft: #f7f6f6;
  --bg-soft-2: #f1efef;
  --ink: #0e0e10;
  --ink-2: #17171a;
  --ink-soft: #3a3a42;
  --ink-muted: #63636d;
  --line: #e6e4e4;
  --line-strong: #d4d1d1;
  /* text on dark bands */
  --on-dark: #c8c8d0;
  --on-dark-dim: #8e8e99;

  /* Red — deep crimson rather than signal red. The lighter, more saturated
     scale read as "alert" at full-band scale; this one reads as considered,
     which is what a business being evaluated on trust wants.

     --red-400 is the odd one out on purpose: it is the ONLY red used on dark
     backgrounds (hero, dark bands, dark cards), so it stays light while the
     rest of the ramp darkens. Darkening it with the others drops it to
     3.76:1 on --ink and fails AA. */
  --red-50: #fdf2f3;
  --red-100: #f9dadc;
  --red-200: #f0b8bc;
  --red-400: #dd5a62;
  --red-500: #b82a30;
  --red-600: #a11d24;
  --red-700: #861119;
  --red-800: #6d0e14;

  --radius: 12px;
  --radius-lg: 18px;
  --shadow-sm: 0 1px 2px rgba(14, 14, 16, 0.05), 0 4px 12px rgba(14, 14, 16, 0.05);
  --shadow: 0 4px 10px rgba(14, 14, 16, 0.06), 0 18px 44px rgba(14, 14, 16, 0.1);

  /* ---- Widget theming ------------------------------------------------
     chatbot/widget/atomx-chat.js and booking/widget/atomx-booking.js read
     these token names from the host page — that is their theming contract,
     kept generic so both widgets stay reusable for other clients. Mapping
     them here re-themes both without touching widget code. --blue-300 maps
     to a DARK red because in the widgets it colours text and links, which
     sit on a white panel. */
  --bg-alt: #f4f3f3;
  --panel: #ffffff;
  --panel-2: #faf9f9;
  --border: var(--line);
  --text: var(--ink);
  --text-dim: var(--ink-muted);
  /* booking widget reads --text-muted for its field labels; without it they
     fall back to the widget's old blue-grey and drop to 2.5:1 on white */
  --text-muted: var(--ink-muted);
  --blue-100: var(--red-100);
  --blue-300: var(--red-600);
  --blue-400: var(--red-500);
  --blue-500: var(--red-600);
  --blue-600: var(--red-600);
  --blue-700: var(--red-700);

  /* Widget accents that live inside rgba()/box-shadow literals. */
  --axc-glow: rgba(161, 29, 36, 0.3);
  --axc-glow-strong: rgba(161, 29, 36, 0.42);
  --axc-soft: var(--red-50);
  --axc-soft-hover: var(--red-100);
  --axc-line: var(--red-200);
  --axc-ring: rgba(161, 29, 36, 0.16);
  --axc-hover: rgba(14, 14, 16, 0.06);
  --axc-err-bg: var(--red-50);
  --axc-err-line: var(--red-200);
  --axc-err-text: var(--red-700);
  --axc-mark-ring: var(--red-500);
  --axc-mark-arm: var(--red-600);
  --abk-ring: rgba(161, 29, 36, 0.16);
  --axc-online: var(--red-600);
  --axc-online-pulse: rgba(161, 29, 36, 0.45);
  --axc-online-pulse-fade: rgba(161, 29, 36, 0);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  color: var(--ink-soft);
  background: var(--bg);
  font-size: 17px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg { display: block; max-width: 100%; }
a { text-decoration: none; color: inherit; }
ul { list-style: none; }

.container { max-width: 1265px; margin: 0 auto; padding: 0 28px; }

/* ------------------------------------------------------------- typography */
h1, h2, h3, h4 { color: var(--ink); letter-spacing: -0.028em; line-height: 1.1; }
h1 { font-size: clamp(2.3rem, 5.2vw, 3.25rem); font-weight: 900; }
h2 { font-size: clamp(1.85rem, 3.9vw, 2.5rem); font-weight: 900; }
h3 { font-size: 1.16rem; font-weight: 800; letter-spacing: -0.018em; }

.lede { font-size: clamp(1.04rem, 1.7vw, 1.16rem); color: var(--ink-muted); }

.eyebrow-label {
  display: inline-block; font-size: 0.76rem; font-weight: 800;
  letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--red-600); margin-bottom: 14px;
}

/* ------------------------------------------------------------------ bands */
.band { padding: 92px 0; }
.band-white { background: var(--white); }
.band-light { background: var(--bg-soft); }
.band-light-2 { background: var(--bg-soft-2); }

.band-dark { background: var(--ink); color: var(--on-dark); }
.band-dark h1, .band-dark h2, .band-dark h3, .band-dark h4 { color: var(--white); }
.band-dark .lede { color: var(--on-dark); }
.band-dark .eyebrow-label { color: var(--red-400); }

/* Uses red-700, not red-600: white sits at 9.96:1 on 700 versus 7.73:1 on
   600, which is the headroom the tinted-white body copy below needs to
   clear AA. The deeper red also reads less neon at full-band scale. */
.band-red { background: var(--red-700); color: #ffe9e9; }
/* Scoped to direct band content — NOT descendants. The booking widget's
   card title is an <h3>, and a blanket .band-red h3 rule turned it white on
   its own white card. Same reasoning for the dark band below. */
.band-red > .container > h1,
.band-red > .container > h2,
.band-red > .container > h3,
.band-red .band-head h1,
.band-red .band-head h2,
.band-red .band-head h3,
.band-red .stat b { color: var(--white); }
.band-red .lede { color: #ffe0e0; }
.band-red .eyebrow-label { color: #ffd4d4; }

.band-head { max-width: 760px; margin-bottom: 52px; }
.band-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.band-head h2 { margin-bottom: 15px; }

/* ---------------------------------------------------------------- header */
header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(255, 255, 255, 0.93);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
}
.nav { display: flex; align-items: center; justify-content: space-between; padding: 15px 0; }
.brand {
  display: flex; align-items: center; gap: 12px;
  font-weight: 900; font-size: 1.45rem; color: var(--ink); letter-spacing: -0.03em;
}
.brand .mark { width: 42px; height: 42px; }
.brand .pro { color: var(--red-600); }

.nav-links { display: flex; align-items: center; gap: 26px; }
.nav-links a:not(.btn) {
  font-weight: 600; font-size: 0.92rem; color: var(--ink-soft); transition: color 0.18s ease;
}
.nav-links a:not(.btn):hover, .nav-links a[aria-current="page"] { color: var(--red-600); }

.menu-toggle {
  display: none; background: none; border: none; cursor: pointer;
  flex-direction: column; gap: 5px; padding: 6px;
}
.menu-toggle span { width: 24px; height: 2px; background: var(--ink); display: block; border-radius: 2px; }

/* --------------------------------------------------------------- buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 14px 28px; border-radius: 4px;
  font-weight: 700; font-size: 0.95rem; font-family: inherit;
  cursor: pointer; border: 2px solid transparent; white-space: nowrap;
  transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease, transform 0.15s ease;
}
.btn-primary { background: var(--red-600); color: var(--white); }
.btn-primary:hover { background: var(--red-700); transform: translateY(-2px); }
.btn-outline { background: transparent; color: var(--ink); border-color: var(--line-strong); }
.btn-outline:hover { border-color: var(--ink); transform: translateY(-2px); }
.btn-ghost-light { background: transparent; color: var(--white); border-color: rgba(255, 255, 255, 0.45); }
.btn-ghost-light:hover { background: rgba(255, 255, 255, 0.12); border-color: var(--white); transform: translateY(-2px); }
.btn-on-red { background: var(--white); color: var(--red-700); }
.btn-on-red:hover { background: #fff0f0; transform: translateY(-2px); }

/* Tap-to-call, on the dark hero. White fill rather than another red or
   another outline: it has to be obviously separate from the primary CTA
   without competing with it, and this audience scans for a phone number
   before it reads anything. Icon carries the red so the button still
   belongs to the brand. */
.btn-call { background: var(--white); color: var(--ink); }
.btn-call:hover { background: #f1f1f3; transform: translateY(-2px); }
.btn-call svg { width: 17px; height: 17px; stroke: var(--red-600); fill: none; stroke-width: 2.4; }

.btn:active { transform: scale(0.97); }
.nav .btn { padding: 11px 22px; font-size: 0.9rem; }

/* ------------------------------------------------- mobile tap-to-call
   A tradesman reading this is on a phone, on a job, and will call rather
   than fill in a form. Hidden on desktop, where the hero button and the
   contact section already carry the number.

   Bottom LEFT on purpose: the chat widget's launcher is fixed bottom right
   at z-index 2147483000, so anything on that side either collides with it
   or loses to it. Sitting opposite means neither has to win.

   White on --red-600 measures 7.7:1 — comfortably past AA, and past AAA. */
.call-fab { display: none; }

@media (max-width: 700px) {
  .call-fab {
    display: inline-flex; align-items: center; gap: 9px;
    position: fixed; left: 16px; bottom: 20px; z-index: 90;
    background: var(--red-600); color: var(--white);
    padding: 13px 20px; border-radius: 999px;
    font-weight: 700; font-size: 0.95rem; text-decoration: none;
    box-shadow: 0 6px 22px rgba(0, 0, 0, 0.4);
  }
  .call-fab svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2.4; }
  .call-fab:active { transform: scale(0.96); }
}

/* ------------------------------------------- out-of-hours call notice
   Sits above the chat launcher (z-index 2147483000) because it is a modal
   answering a tap the visitor just made — it is the one thing on the page
   that has earned the right to be on top. */
.call-notice {
  position: fixed; inset: 0; z-index: 2147483100;
  display: flex; align-items: center; justify-content: center;
  padding: 24px; background: rgba(8, 8, 10, 0.72);
}
.call-notice-card {
  background: var(--white); color: var(--ink);
  border-radius: var(--radius-lg); padding: 30px 28px;
  max-width: 420px; width: 100%; box-shadow: 0 24px 60px rgba(0, 0, 0, 0.4);
}
.call-notice-card h3 { font-size: 1.22rem; margin-bottom: 12px; color: var(--ink); }
.call-notice-card p { font-size: 0.97rem; line-height: 1.6; color: var(--ink); margin-bottom: 10px; }
/* Over-qualified on purpose. A bare `.call-notice-sub` is 0-1-0 and loses to
   `.call-notice-card p` at 0-1-1, so the muted colour silently never applied —
   the same specificity trap this file already documents for .price-save. */
.call-notice-card p.call-notice-sub { color: var(--ink-muted); }
.call-notice-actions { display: flex; gap: 10px; flex-wrap: wrap; margin: 20px 0 14px; }
.call-notice-actions .btn { padding: 12px 22px; font-size: 0.92rem; }
.call-notice-close {
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: inherit; font-size: 0.88rem; font-weight: 600;
  color: var(--ink-soft, #45454d); text-decoration: underline;
}
.call-notice-close:hover { color: var(--ink); }

/* ------------------------------------------------------------------ hero */
.hero { padding: 96px 0 84px; }

/* Galaxy backdrop. The scrim is deliberately heavy — I can't sample the
   image's pixels to measure contrast, so it's sized for the worst case (a
   bright nebula highlight sitting directly behind body copy). Even at the
   lightest point of the gradient, white clears ~8:1 and the muted grey ~4.8:1.
   background-color stays as the fallback, so a missing file degrades to the
   plain black hero rather than breaking the text. */
/* Was a galaxy photo. It looked like an AI startup, which is precisely the
   wrong signal when the buyer is a plumber deciding whether you understand
   his trade. Replaced with a restrained brand-red wash on near-black: no
   image request, nothing to misread, and ~460KB lighter on a phone with one
   bar of signal. A photograph can be layered back in here if one is ever
   shot on a real job — the rule is that it must look like work, not stock. */
.hero.has-backdrop {
  background-color: var(--ink);
  background-image:
    radial-gradient(1100px 620px at 10% -15%, rgba(161, 29, 36, 0.30), transparent 62%),
    radial-gradient(900px 520px at 96% 4%, rgba(161, 29, 36, 0.12), transparent 58%),
    linear-gradient(180deg, #141417 0%, var(--ink) 58%);
}
/* No responsive variant needed any more: the backdrop is a gradient, so it
   costs nothing to download and scales to any width for free. The pair of
   pre-sized galaxy JPEGs this replaced existed purely to keep the hero from
   costing 462 KB on a phone. */

/* Let a little of the backdrop through the side panel instead of blanking it. */
.hero.has-backdrop .hero-panel {
  background: rgba(23, 23, 26, 0.82);
  backdrop-filter: blur(7px);
}

.hero-tagline {
  display: inline-flex; align-items: center; gap: 9px;
  background: rgba(255, 255, 255, 0.09);
  border: 1px solid rgba(255, 255, 255, 0.22);
  color: var(--white);
  font-weight: 700; font-size: 0.79rem;
  letter-spacing: 0.15em; text-transform: uppercase;
  padding: 8px 18px; border-radius: 999px; margin-bottom: 22px;
  backdrop-filter: blur(4px);
}
.hero-tagline .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--red-400); flex-shrink: 0;
}
.hero-grid { display: grid; grid-template-columns: 1.25fr 0.9fr; gap: 60px; align-items: center; }
/* The mark now sits above the "what you get" panel rather than looming over
   the headline, so it reads as a signature on the card instead of competing
   with the h1 for the first thing the eye lands on. */
.hero-aside { display: flex; flex-direction: column; align-items: center; gap: 24px; }
.hero-mark { width: 132px; height: 132px; color: var(--white); flex-shrink: 0; }
.hero-aside .hero-panel { width: 100%; }
@media (max-width: 900px) { .hero-mark { width: 108px; height: 108px; } }
.hero h1 { margin-bottom: 20px; }
.hero h1 .hl { color: var(--red-400); }
.hero p.subhead { font-size: clamp(1.04rem, 1.8vw, 1.2rem); color: var(--on-dark); margin-bottom: 32px; max-width: 620px; }
.hero-cta { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 26px; }
/* --on-dark rather than --on-dark-dim: the dim grey was the single element
   holding the backdrop scrim dark. Lifting it one step buys ~10% more image
   visibility while still clearing AA over the image's brightest pixel. */
.hero-note { font-size: 0.88rem; color: var(--on-dark); }

/* hero side panel: the "what you get" summary */
.hero-panel {
  background: var(--ink-2); border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: var(--radius-lg); padding: 30px 28px;
}
.hero-panel h4 { color: var(--white); font-size: 0.8rem; letter-spacing: 0.11em; text-transform: uppercase; margin-bottom: 18px; }
.hero-panel ul { display: flex; flex-direction: column; gap: 13px; }
.hero-panel li { display: flex; gap: 11px; align-items: flex-start; font-size: 0.95rem; color: var(--on-dark); }
.hero-panel li svg { width: 17px; height: 17px; flex-shrink: 0; margin-top: 4px; stroke: var(--red-400); fill: none; stroke-width: 2.6; }

/* ------------------------------------------------------------ trust strip */
.trust-strip { border-top: 1px solid rgba(255, 255, 255, 0.14); margin-top: 54px; padding-top: 30px; display: flex; gap: 54px; flex-wrap: wrap; }
.trust-item b { display: block; font-size: 1.55rem; font-weight: 900; color: var(--white); letter-spacing: -0.03em; line-height: 1.2; }
/* Same reason as .hero-note: these sit over the backdrop, so they use the
   brighter grey rather than --on-dark-dim. */
.trust-item span { font-size: 0.85rem; color: var(--on-dark); }

/* --------------------------------------------------- capability categories
   The "how we help" block: a category heading + description on the left,
   and its capabilities listed on the right. */
/* Each category is a single panel: a solid black or red side carrying the
   heading, and white capability cards beside it. The colour blocks are what
   stop the section reading as a page of loose text on white. */
.cap-block {
  display: grid; grid-template-columns: 0.82fr 1.18fr;
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  overflow: hidden; margin-bottom: 22px;
}
.cap-block:last-of-type { margin-bottom: 0; }

.cap-side { padding: 40px 34px; display: flex; flex-direction: column; justify-content: center; }
.cap-side.is-dark { background: var(--ink); }
.cap-side.is-red { background: var(--red-700); }
.cap-num { font-size: 0.78rem; font-weight: 800; letter-spacing: 0.14em; margin-bottom: 12px; }
.cap-side.is-dark .cap-num { color: var(--red-400); }
.cap-side.is-red .cap-num { color: #ffd4d4; }
.cap-side h3 { font-size: clamp(1.35rem, 2.4vw, 1.72rem); font-weight: 900; margin-bottom: 12px; color: var(--white); }
.cap-side p { font-size: 0.99rem; }
.cap-side.is-dark p { color: var(--on-dark); }
.cap-side.is-red p { color: #ffe9e9; }

.cap-items { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; padding: 26px; background: var(--white); }
.cap-item { background: var(--bg-soft); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 18px 20px; }
.cap-item h4 { font-size: 0.99rem; font-weight: 800; margin-bottom: 6px; display: flex; align-items: flex-start; gap: 8px; }
.cap-item h4 svg { width: 17px; height: 17px; stroke: var(--red-600); fill: none; stroke-width: 2.4; flex-shrink: 0; margin-top: 3px; }
.cap-item p { font-size: 0.9rem; color: var(--ink-muted); }

/* A few cards are filled black or red so the grid isn't an unbroken field of
   white boxes. Scattered rather than sequential, so it reads deliberate. */
.auto-card.is-dark { background: var(--ink); border-color: var(--ink); }
.auto-card.is-dark h3 { color: var(--white); }
.auto-card.is-dark p { color: var(--on-dark); }
.auto-card.is-dark .auto-ic { background: rgba(255, 255, 255, 0.09); border-color: rgba(255, 255, 255, 0.2); }
.auto-card.is-dark .auto-ic svg { stroke: var(--red-400); }
.auto-card.is-dark .auto-more { color: var(--red-400); }
.auto-card.is-dark .pill-live { background: var(--red-600); color: var(--white); }
.auto-card.is-dark .pill-soon { background: transparent; color: #fff; border-color: rgba(255,255,255,.5); }

.auto-card.is-red { background: var(--red-700); border-color: var(--red-700); }
.auto-card.is-red h3 { color: var(--white); }
.auto-card.is-red p { color: #ffe9e9; }
.auto-card.is-red .auto-ic { background: rgba(255, 255, 255, 0.14); border-color: rgba(255, 255, 255, 0.28); }
.auto-card.is-red .auto-ic svg { stroke: var(--white); }
.auto-card.is-red .auto-more { color: var(--white); }
.auto-card.is-red .pill-live { background: var(--white); color: var(--red-700); }

.pill {
  display: inline-flex; align-items: center; gap: 6px; align-self: flex-start;
  font-size: 0.68rem; font-weight: 800; letter-spacing: 0.07em; text-transform: uppercase;
  padding: 4px 10px; border-radius: 3px; margin-bottom: 13px;
}
.pill-live { background: var(--red-600); color: var(--white); }
.pill-soon { background: var(--white); color: var(--ink-muted); border: 1px solid var(--line-strong); }
.band-dark .pill-soon, .band-red .pill-soon { background: transparent; color: #fff; border-color: rgba(255,255,255,.5); }
.pill .dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }

/* ------------------------------------------------------------ stats band */
.stats-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 40px; }
.stat b {
  display: block; font-size: clamp(2.4rem, 5.2vw, 3.4rem); font-weight: 900;
  color: var(--white); letter-spacing: -0.04em; line-height: 1.05; margin-bottom: 10px;
}
.stat p { font-size: 0.97rem; color: #ffe0e0; }
.stats-source { margin-top: 40px; font-size: 0.83rem; color: #ffcccc; }
.stats-source a { text-decoration: underline; }

/* --------------------------------------------------------------- pipeline */
.pipeline { display: grid; grid-template-columns: repeat(5, 1fr); gap: 26px; }
.step-num {
  font-size: 2.5rem; font-weight: 900; color: var(--red-400);
  letter-spacing: -0.05em; line-height: 1; margin-bottom: 14px;
  padding-bottom: 14px; border-bottom: 2px solid rgba(255, 255, 255, 0.16);
}
.step h3 { font-size: 1.04rem; margin-bottom: 8px; }
.step p { font-size: 0.92rem; color: var(--on-dark); }

/* ------------------------------------------------------------- principles */
.principle-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); }
.principle { background: var(--white); padding: 34px 32px; }
.principle h3 { margin-bottom: 9px; display: flex; align-items: center; gap: 10px; }
.principle h3 svg { width: 19px; height: 19px; stroke: var(--red-600); fill: none; stroke-width: 2.3; flex-shrink: 0; }
.principle p { font-size: 0.95rem; color: var(--ink-muted); }

/* -------------------------------------------------------------------- FAQ */
.faq { max-width: 880px; margin: 0 auto; border-top: 1px solid var(--line-strong); }
.faq details { border-bottom: 1px solid var(--line-strong); }
.faq summary {
  cursor: pointer; list-style: none; padding: 22px 44px 22px 0; position: relative;
  font-weight: 800; font-size: 1.04rem; color: var(--ink); letter-spacing: -0.015em;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; position: absolute; right: 8px; top: 50%; width: 11px; height: 11px;
  border-right: 2.4px solid var(--red-600); border-bottom: 2.4px solid var(--red-600);
  transform: translateY(-70%) rotate(45deg); transition: transform 0.22s ease;
}
.faq details[open] summary::after { transform: translateY(-30%) rotate(-135deg); }
.faq summary:hover { color: var(--red-600); }
.faq .faq-a { padding: 0 44px 24px 0; color: var(--ink-muted); font-size: 0.98rem; }

/* FAQ sitting on a black band */
.band-dark .faq { border-top-color: rgba(255, 255, 255, 0.18); }
.band-dark .faq details { border-bottom-color: rgba(255, 255, 255, 0.18); }
.band-dark .faq summary { color: var(--white); }
.band-dark .faq summary:hover { color: var(--red-400); }
.band-dark .faq summary::after { border-color: var(--red-400); }
.band-dark .faq .faq-a { color: var(--on-dark); }

/* Principle cards sitting on a red band: keep the cards white so the copy
   stays high-contrast, and drop the grey gutter that would muddy the red.
   The h3 colour MUST be reset — .band-red h3 turns headings white, which on
   a white card is invisible. */
.band-red .principle-grid { background: rgba(255, 255, 255, 0.35); border-color: rgba(255, 255, 255, 0.35); }
.band-red .principle h3 { color: var(--ink); }
.band-red .principle p { color: var(--ink-muted); }

/* --------------------------------------------------------------- booking */
.booking-wrap { display: flex; justify-content: center; }

/* The booking widget renders with a transparent background and relies on
   the host page being light — its labels and hints use muted greys, which
   are unreadable directly on a red band. Give it an explicit white card so
   the widget keeps the light surface it was built for. */
.band-red .booking-wrap > * {
  background: var(--white);
  border-radius: var(--radius-lg);
  padding: 34px 32px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.22);
  width: 100%;
  max-width: 580px;
}
@media (max-width: 560px) { .band-red .booking-wrap > * { padding: 24px 20px; } }

/* --------------------------------------------------------------- contact */
.contact-wrap { display: grid; grid-template-columns: 1fr 1fr; gap: 52px; align-items: start; }
.contact-info h2 { margin-bottom: 15px; }
.contact-info > p { color: var(--ink-muted); margin-bottom: 26px; }
.contact-detail { display: flex; align-items: center; gap: 13px; margin-bottom: 16px; }
.contact-detail .icon {
  width: 40px; height: 40px; border-radius: 9px; background: var(--red-50);
  border: 1px solid var(--red-100);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.contact-detail .icon svg { width: 18px; height: 18px; stroke: var(--red-600); fill: none; stroke-width: 2.2; }
.contact-detail a, .contact-detail .val { color: var(--ink); font-weight: 700; }
.contact-detail a:hover { color: var(--red-600); }
.contact-detail span.label { display: block; font-size: 0.8rem; color: var(--ink-muted); font-weight: 400; }

.contact-form { display: flex; flex-direction: column; gap: 12px; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 32px; }
.contact-form input, .contact-form textarea {
  width: 100%; padding: 13px 15px; border-radius: 6px;
  border: 1px solid var(--line-strong); background: var(--white);
  color: var(--ink); font-family: inherit; font-size: 0.95rem; resize: vertical;
}
.contact-form input::placeholder, .contact-form textarea::placeholder { color: var(--ink-muted); }
.contact-form input:focus, .contact-form textarea:focus {
  outline: none; border-color: var(--red-600); box-shadow: 0 0 0 3px rgba(161, 29, 36, 0.14);
}
.contact-form .btn { align-self: flex-start; }
.form-status { font-size: 0.9rem; min-height: 1.2em; }
/* Success is ink, not red — red means "error" on this palette. */
.form-status.success { color: var(--ink); font-weight: 700; }
.form-status.error { color: var(--red-700); }
.contact-form button[disabled] { opacity: 0.65; cursor: default; transform: none; }

/* ---------------------------------------------------------------- footer */
footer { background: var(--ink); color: var(--on-dark-dim); padding: 66px 0 28px; }
.footer-top { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 40px; margin-bottom: 44px; }
.footer-brand { display: flex; align-items: center; gap: 10px; font-weight: 900; font-size: 1.12rem; color: var(--white); margin-bottom: 12px; }
.footer-brand svg { width: 26px; height: 26px; }
.footer-about { max-width: 300px; font-size: 0.9rem; }
.footer-col h4 { color: var(--white); font-size: 0.78rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.11em; margin-bottom: 15px; }
.footer-col a, .footer-col span.fitem { display: block; font-size: 0.9rem; color: var(--on-dark-dim); margin-bottom: 10px; transition: color 0.18s ease; }
.footer-col a:hover { color: var(--white); }
.footer-bottom {
  border-top: 1px solid rgba(255, 255, 255, 0.12); padding-top: 22px;
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 10px; font-size: 0.85rem;
}

/* ============================ services.html ============================= */
.page-head { padding: 76px 0 0; }
.page-head h1 { margin-bottom: 16px; max-width: 900px; }
.page-head .lede { max-width: 680px; }

.svc { padding: 62px 0; border-top: 1px solid var(--line); scroll-margin-top: 78px; }
/* A service section can sit on any band; these keep its body copy legible
   when that band is black. The .svc-visual stays a light card either way. */
.svc.band-dark { border-top-color: rgba(255, 255, 255, 0.16); }
.svc.band-dark .svc-copy > p { color: var(--on-dark); }
.svc.band-dark .svc-list li { color: var(--on-dark); }
.svc.band-light { border-top-color: var(--line-strong); }
.svc.band-light .svc-visual { background: var(--white); }
.svc.band-red { border-top-color: rgba(255, 255, 255, 0.2); }
.svc.band-red .svc-copy h2 { color: var(--white); }
.svc.band-red .svc-copy > p, .svc.band-red .svc-list li { color: #ffe9e9; }
.svc.band-red .svc-list li svg { stroke: var(--white); }
.svc.band-red .svc-visual { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.28); }
.svc.band-red .vis-note { color: #ffe9e9; }

/* An outline button inherits near-black text, which is invisible on a dark
   or red band. Flip it to the light treatment automatically. */
.band-dark .btn-outline, .band-red .btn-outline {
  color: var(--white); border-color: rgba(255, 255, 255, 0.45); background: transparent;
}
.band-dark .btn-outline:hover, .band-red .btn-outline:hover {
  background: rgba(255, 255, 255, 0.12); border-color: var(--white);
}

/* Muted footnote that has to stay legible on any band. */
.note-muted { color: var(--ink-muted); font-size: 0.94rem; margin-bottom: 22px; }
.band-dark .note-muted, .band-red .note-muted { color: #e9e9ef; }
.svc-inner { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 56px; align-items: center; }
.svc:nth-of-type(even) .svc-copy { order: 2; }
.svc-copy h2 { font-size: clamp(1.6rem, 3.1vw, 2.1rem); margin-bottom: 14px; }
.svc-copy > p { color: var(--ink-muted); font-size: 1.03rem; margin-bottom: 22px; }
.svc-list { display: flex; flex-direction: column; gap: 12px; margin-bottom: 26px; }
.svc-list li { display: flex; align-items: flex-start; gap: 11px; font-size: 0.97rem; color: var(--ink-soft); }
.svc-list li svg { width: 18px; height: 18px; flex-shrink: 0; margin-top: 4px; stroke: var(--red-600); fill: none; stroke-width: 2.6; }

.svc-visual { background: var(--bg-soft); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 30px; display: flex; flex-direction: column; gap: 11px; }
.vis-row {
  background: var(--white); border: 1px solid var(--line); border-radius: 9px;
  padding: 13px 15px; font-size: 0.9rem; color: var(--ink-soft);
  display: flex; align-items: center; gap: 11px; box-shadow: var(--shadow-sm);
}
.vis-row b { color: var(--ink); font-weight: 800; }
.vis-ic { width: 26px; height: 26px; border-radius: 6px; background: var(--red-50); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.vis-ic svg { width: 14px; height: 14px; stroke: var(--red-600); fill: none; stroke-width: 2.6; }
.vis-arrow { display: flex; justify-content: center; color: var(--ink-muted); }
.vis-arrow svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; }
.vis-note { font-size: 0.82rem; color: var(--ink-muted); text-align: center; margin-top: 3px; }

/* ------------------------------------------------------------- animation */
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes electronPulse { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.5); opacity: 0.55; } }
.orbit-rings { transform-box: view-box; transform-origin: 50% 50%; animation: spin 20s linear infinite; }
.orbit-rings ellipse { fill: none; stroke: var(--red-500); stroke-width: 2.5; opacity: 0.95; }
.electron { transform-box: fill-box; transform-origin: 50% 50%; animation: electronPulse 2.6s ease-in-out infinite; }
.electron.e2 { animation-delay: 0.6s; }
.electron.e3 { animation-delay: 1.2s; }

.reveal { opacity: 0; transform: translateY(20px); transition: opacity 0.6s ease, transform 0.6s ease; }
.reveal.visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .orbit-rings, .electron { animation: none; }
  .reveal { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
}

/* ------------------------------------------------------------ responsive */
@media (max-width: 1080px) {
  .auto-grid { grid-template-columns: repeat(2, 1fr); }
  .pipeline { grid-template-columns: repeat(3, 1fr); gap: 32px 26px; }
  .footer-top { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 900px) {
  .hero-grid { grid-template-columns: 1fr; gap: 42px; }
  .cap-block { grid-template-columns: 1fr; gap: 26px; }
  .stats-grid { grid-template-columns: 1fr; gap: 32px; }
  .contact-wrap { grid-template-columns: 1fr; gap: 34px; }
  .svc-inner { grid-template-columns: 1fr; gap: 32px; }
  .svc:nth-of-type(even) .svc-copy { order: 0; }
  .band { padding: 68px 0; }
  .hero { padding: 66px 0 60px; }
}

@media (max-width: 720px) {
  body { font-size: 16px; }
  .auto-grid, .cap-items, .principle-grid, .pipeline { grid-template-columns: 1fr; }
  .principle-grid { gap: 1px; }
  .footer-top { grid-template-columns: 1fr; gap: 30px; }
  .trust-strip { gap: 26px 34px; }
  .nav-links {
    position: absolute; top: 100%; left: 0; right: 0; background: var(--white);
    flex-direction: column; align-items: flex-start; padding: 18px 28px 24px; gap: 16px;
    border-bottom: 1px solid var(--line); box-shadow: var(--shadow); display: none;
  }
  .nav-links.open { display: flex; }
  .nav-links .btn { width: 100%; }
  .menu-toggle { display: flex; }
  .contact-form { padding: 24px; }
}

/* ------------------------------------------------------- legal pages
   privacy.html / terms.html. Long-form prose measure, deliberately
   narrower than .container so lines stay readable. Also the pages an
   A2P 10DLC reviewer lands on, so the SMS callouts need to be obvious. */
.legal { padding: 72px 0 88px; }
.legal-body { max-width: 780px; }
.legal-body h1 { font-size: clamp(2rem, 4vw, 2.7rem); margin-bottom: 10px; }
.legal-body h2 {
  font-size: clamp(1.18rem, 2vw, 1.4rem); margin: 40px 0 14px;
  padding-top: 26px; border-top: 1px solid var(--line);
}
.legal-body .lede { margin-bottom: 8px; }
.legal-body p { color: var(--ink-muted); margin-bottom: 14px; }
.legal-body ul { margin: 0 0 18px; padding-left: 0; }
.legal-body li {
  position: relative; color: var(--ink-muted); padding-left: 22px; margin-bottom: 10px;
}
.legal-body li::before {
  content: ""; position: absolute; left: 4px; top: 0.62em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--red-500);
}
.legal-body strong { color: var(--ink); font-weight: 700; }
.legal-body a { color: var(--red-600); font-weight: 600; }
.legal-body a:hover { text-decoration: underline; }
.legal-meta { font-size: 0.88rem; color: var(--ink-dim, var(--ink-muted)); }

.legal-callout {
  background: var(--white); border: 1px solid var(--line-strong);
  border-left: 4px solid var(--red-500); border-radius: 10px;
  padding: 18px 22px; margin: 0 0 18px;
}
.legal-callout p { margin: 0; }

/* Honeypot field on the contact form — off-screen rather than display:none,
   since some bots skip inputs that are explicitly hidden. */
.hp {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  opacity: 0; pointer-events: none;
}

/* Caveat note inside a service block — used where a service is built but not
   yet deliverable, so the qualification sits with the claim rather than
   hiding in a pill. */
.svc-note {
  border-left: 3px solid var(--red-500);
  padding: 2px 0 2px 14px; margin: 0 0 24px;
  font-size: 0.92rem; line-height: 1.6; color: var(--ink-muted);
}
.svc.band-dark .svc-note, .svc.band-red .svc-note { color: #ffe9e9; }

/* Trades served, in the hero. The whole point is that a plumber landing here
   sees their own trade named within a second — so this sits above the CTA
   rather than further down the page. Chips, not a sentence, so it scans. */
.hero-trades {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin: 22px 0 26px; padding: 0;
}
.hero-trades li {
  font-size: 0.82rem; font-weight: 600; letter-spacing: 0.01em;
  color: var(--white);
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 999px; padding: 5px 13px;
}
@media (max-width: 720px) {
  .hero-trades { gap: 6px; margin: 18px 0 22px; }
  .hero-trades li { font-size: 0.78rem; padding: 4px 11px; }
}

/* ---------------------------------------------------------------- pricing
   Three cards, middle one dark so the eye lands on the £299 rather than
   reading left to right and stopping at the cheapest. */
.price-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px;
  align-items: stretch; margin-bottom: 34px;
}
.price-card {
  position: relative; display: flex; flex-direction: column;
  background: var(--white); border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg); padding: 34px 30px 30px;
  box-shadow: var(--shadow-sm);
}
.price-card h3 { font-size: 1.05rem; letter-spacing: 0.01em; margin-bottom: 14px; }
.price-amount { display: flex; align-items: baseline; gap: 6px; margin-bottom: 6px; }
.price-amount b {
  font-size: 2.6rem; font-weight: 900; letter-spacing: -0.04em;
  color: var(--ink); line-height: 1;
}
.price-amount span { font-size: 0.92rem; font-weight: 600; color: var(--ink-muted); }
.price-sub { font-size: 0.92rem; color: var(--ink-muted); margin-bottom: 22px; }
.price-list { margin: 0 0 26px; padding: 0; flex-grow: 1; }
.price-list li {
  position: relative; padding-left: 24px; margin-bottom: 11px;
  font-size: 0.92rem; line-height: 1.55; color: var(--ink-soft);
}
.price-list li::before {
  content: ""; position: absolute; left: 2px; top: 0.52em;
  width: 8px; height: 8px; border-radius: 50%;
  border: 2px solid var(--red-500);
}
.price-card .btn { width: 100%; text-align: center; }

/* Featured card: dark, so it reads as the recommendation without needing a
   louder colour. Tinted whites rather than pure white for the body copy,
   same approach as the red bands. */
.price-card.is-featured {
  background: var(--ink); border-color: var(--ink);
  box-shadow: var(--shadow); padding-top: 42px;
}
.price-card.is-featured h3,
.price-card.is-featured .price-amount b { color: var(--white); }
.price-card.is-featured .price-amount span,
.price-card.is-featured .price-sub { color: var(--on-dark); }
.price-card.is-featured .price-list li { color: var(--on-dark); }
.price-card.is-featured .price-list li::before { border-color: var(--red-400); }
.price-flag {
  position: absolute; top: 14px; left: 30px;
  font-size: 0.68rem; font-weight: 800; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--red-400);
}

@media (max-width: 900px) {
  .price-grid { grid-template-columns: 1fr; gap: 18px; }
}

/* Free-trial banner. Sits ABOVE the cards on purpose: the objection to
   clear is "what if it doesn't work", not "how much" — answer that before
   showing a single figure. */
.price-banner {
  display: flex; align-items: flex-start; gap: 16px;
  max-width: 860px; margin: 0 auto 38px;
  background: var(--red-50); border: 1px solid var(--red-200);
  border-radius: var(--radius); padding: 20px 26px;
}
.price-banner svg {
  width: 26px; height: 26px; flex-shrink: 0; margin-top: 2px;
  fill: none; stroke: var(--red-600); stroke-width: 2;
}
.price-banner p { margin: 0; font-size: 0.96rem; line-height: 1.62; color: var(--ink-soft); }
.price-banner b { color: var(--ink); font-weight: 800; }

/* The two blocks under the tiers. These were a grey fine-print box and read
   as an afterthought — the website is a real product with a real price, and
   "we'll build you any combination" is a genuine objection-killer. Both now
   get the same card treatment as the tiers themselves. */
.price-extras { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-top: 38px; }
.price-extra {
  display: flex; flex-direction: column;
  background: var(--white); border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg); padding: 30px;
  box-shadow: var(--shadow-sm);
}
.price-extra.is-alt { background: var(--bg-soft); }
.price-extra-label {
  display: inline-block; font-size: 0.68rem; font-weight: 800;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--red-600); margin-bottom: 10px;
}
.price-extra h3 { font-size: 1.22rem; margin-bottom: 16px; }
.price-extra p {
  font-size: 0.94rem; line-height: 1.62; color: var(--ink-muted);
  margin: 0 0 24px; flex-grow: 1;
}
.price-extra p b { color: var(--ink); font-weight: 700; }
.price-extra .btn { align-self: flex-start; }

/* Billing terms under the pricing grid.

   ⚠️ Scoped by the GROUND the text sits on, not by the band. This lives in
   .band-white, so it takes --ink-muted on white — the same pairing as
   .price-extra p. The documented trap in this file is styling by ancestor
   band instead: a blanket rule painted .principle cards white-on-white at
   1.0:1 because they happen to sit inside .band-red.

   Deliberately quiet. It is a disclosure, not a pitch — the pitch is the
   banner above it — but it sits with the prices because that is where
   somebody decides, and because a free-trial-to-paid charge has to be
   disclosed before a card is taken, not buried in a policy page. */
.price-terms {
  max-width: 68ch; margin: 34px auto 0; text-align: center;
  font-size: 0.9rem; line-height: 1.66; color: var(--ink-muted);
  border-top: 1px solid var(--line); padding-top: 26px;
}
.price-terms b { color: var(--ink); font-weight: 700; }
.price-terms-sub {
  display: block; margin-top: 12px;
  font-size: 0.84rem; color: var(--ink-muted);
}
.price-terms-sub a { color: var(--red-600); text-underline-offset: 0.18em; }

.price-extra-amount {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 10px;
  padding-bottom: 18px; margin-bottom: 18px;
  border-bottom: 1px solid var(--line);
}
.pea-part { display: flex; align-items: baseline; gap: 5px; }
.pea-part b {
  font-size: 2.1rem; font-weight: 900; letter-spacing: -0.035em;
  color: var(--ink); line-height: 1;
}
.pea-part span { font-size: 0.88rem; font-weight: 600; color: var(--ink-muted); }
.pea-plus { font-size: 0.85rem; font-weight: 700; color: var(--red-600); text-transform: uppercase; letter-spacing: 0.08em; }

@media (max-width: 900px) {
  .price-banner { flex-direction: column; gap: 12px; padding: 20px; margin-bottom: 28px; }
  .price-extras { grid-template-columns: 1fr; gap: 18px; margin-top: 28px; }
}

/* Setup fee sits directly under the monthly, not buried in the feature list.
   It is the second thing someone needs to know about a package and hiding it
   would be the kind of surprise that kills a deal on day 15. */
.price-setup {
  font-size: 0.85rem; line-height: 1.5; color: var(--ink-muted);
  margin: -2px 0 18px;
}
.price-setup b { color: var(--ink); font-weight: 800; }
.price-setup.is-none { color: var(--red-600); font-weight: 700; }
.price-card.is-featured .price-setup { color: var(--on-dark); }
.price-card.is-featured .price-setup b { color: var(--white); }

/* "from" prefix on the per-automation card, since that one is a range. */
.price-amount .price-from {
  font-size: 0.82rem; font-weight: 700; color: var(--ink-muted);
  text-transform: uppercase; letter-spacing: 0.08em; align-self: center;
}
.price-list li b { color: var(--ink); font-weight: 700; }
.price-card.is-featured .price-list li b { color: var(--white); }

/* Saving badge on the bundle cards. Solid red-600 with white text works on
   both the white cards and the dark featured one at 7.73:1, so one rule
   covers both rather than two variants that have to be kept in step. */
/* Selectors are deliberately over-qualified. `.price-amount span` and
   `.price-card.is-featured .price-amount span` both already match these,
   and both outrank a bare `.price-save` — which silently repainted the
   white pill text grey-on-red at 1.3:1. Specificity has to beat those two,
   not merely tie. Same reason .price-from is qualified below. */
.price-amount .price-save,
.price-card.is-featured .price-amount .price-save {
  display: inline-block; margin-left: 10px; align-self: center;
  background: var(--red-600); color: var(--white);
  font-size: 0.7rem; font-weight: 800; letter-spacing: 0.06em;
  text-transform: uppercase; padding: 4px 9px; border-radius: 999px;
  white-space: nowrap;
}

/* The arithmetic behind the bundle discount, spelled out. Someone will
   always work out that they could buy the three separately — better they
   see here that it costs them more than discover it after asking. */
.price-maths {
  background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 26px 30px; margin-top: 34px;
}
.price-maths h4 { font-size: 1rem; margin-bottom: 18px; }
.price-maths table { width: 100%; border-collapse: collapse; }
.price-maths thead th {
  text-align: left; font-size: 0.72rem; font-weight: 800;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-muted);
  padding-bottom: 10px; border-bottom: 1px solid var(--line-strong);
}
.price-maths tbody th {
  text-align: left; font-size: 0.94rem; font-weight: 700; color: var(--ink);
  padding: 14px 16px 14px 0; vertical-align: top;
}
.price-maths tbody th span {
  display: block; font-size: 0.82rem; font-weight: 400; color: var(--ink-muted);
  margin-top: 3px;
}
.price-maths td {
  padding: 14px 16px 14px 0; font-size: 0.92rem; color: var(--ink-muted);
  vertical-align: top; white-space: nowrap;
}
.price-maths td b { color: var(--ink); font-weight: 800; }
.price-maths td.save, .price-maths td.save b { color: var(--red-600); }
.price-maths tbody tr + tr th, .price-maths tbody tr + tr td { border-top: 1px solid var(--line); }
.price-maths > p {
  margin: 18px 0 0; font-size: 0.92rem; line-height: 1.62; color: var(--ink-muted);
}
.price-maths > p b { color: var(--ink); font-weight: 700; }

@media (max-width: 720px) {
  .price-maths { padding: 22px 18px; }

  /* ⚠️ This table is RESTACKED on mobile, not scrolled.
     It previously used `display:block; overflow-x:auto` on the <table>
     itself. That does not work: setting display:block on a table leaves its
     internal row boxes overflowing without establishing a usable scroll
     container, so the Bundled and You-save columns — the whole argument this
     table exists to make — sat off-screen at x=515..672 on a 375px phone,
     with no way to reach them. Measured: 9 of 12 cells unreachable.

     Horizontal scroll would have fixed the clipping, but a four-column
     comparison read through a 375px window is miserable anyway. Each row
     becomes its own block and every cell prints its label from data-label.

     Deliberately NOT display:flex on the cells — a bare text node beside the
     <b> would become two separate flex items and wrap independently, the
     same bug that mangled the hero panel. */
  .price-maths thead { display: none; }
  .price-maths table,
  .price-maths tbody,
  .price-maths tbody tr,
  .price-maths tbody th,
  .price-maths tbody td { display: block; width: auto; }

  .price-maths tbody tr { padding: 16px 0; }
  .price-maths tbody tr + tr { border-top: 1px solid var(--line); }
  /* The generic `tbody tr + tr th/td` border above would draw a line between
     every stacked cell once they are blocks. */
  .price-maths tbody tr + tr th,
  .price-maths tbody tr + tr td { border-top: none; }

  .price-maths tbody th { padding: 0 0 10px; }
  .price-maths tbody td { padding: 3px 0; white-space: normal; }
  .price-maths tbody td::before {
    content: attr(data-label) ": ";
    font-weight: 700; color: var(--ink);
  }
  .price-maths tbody td.save::before { color: var(--red-600); }

  .price-save { margin-left: 0; margin-top: 6px; }
  .price-amount { flex-wrap: wrap; }

  /* --- mobile legibility --------------------------------------------
     Anything under 12px is a squint on a phone held at arm's length on a
     job site. These are all 0.68–0.7rem at desktop sizes. */
  .price-flag,
  .price-extra-label { font-size: 0.76rem; }
  .price-amount .price-save,
  .price-card.is-featured .price-amount .price-save { font-size: 0.75rem; }
}

/* --- touch targets and iOS zoom -------------------------------------
   Separate block from the layout media query above because it is about
   input ergonomics rather than layout, and it applies at the same
   breakpoint the mobile nav appears. */
@media (max-width: 900px) {
  /* Was 36x28. WCAG 2.5.5 and Apple's HIG both want 44x44, and this is the
     only way to open the menu on a phone. */
  .menu-toggle {
    min-width: 44px; min-height: 44px;
    align-items: center; justify-content: center; padding: 0;
  }

  /* Was 24px tall. These are the primary navigation once the menu is open. */
  .nav-links a:not(.btn) {
    display: block; width: 100%; padding: 11px 0;
  }
  .nav-links { gap: 2px; }

  /* ⚠️ 16px is not a style choice. iOS Safari zooms the whole page in when a
     focused input's font-size is below 16px, and then leaves the visitor
     zoomed and scrolled sideways on a form they were trying to fill in.
     Every field here measured 15.2px. */
  input, select, textarea,
  .abk-card input, .abk-card select, .abk-card textarea,
  .contact-form input, .contact-form textarea { font-size: 16px; }

  /* Footer links measured 23px tall and sat 10px apart — under even the
     relaxed 24x24 minimum, and close enough together that a thumb hits the
     wrong one. Padding rather than font-size, so the footer still reads as
     small print but is comfortably tappable. */
  .footer-col a,
  .footer-col span.fitem { padding: 9px 0; margin-bottom: 0; }
  .footer-bottom { gap: 4px 18px; }
  .footer-bottom a { display: inline-block; padding: 8px 0; }
}

/* The capability cards are now the automation list — one place naming the
   seven, grouped by the problem each solves, instead of a flat grid
   repeating what the blocks above already said. Each is a link through to
   its section on the services page. */
a.cap-item {
  display: flex; flex-direction: column; color: inherit;
  transition: border-color 0.18s ease, background 0.18s ease,
              transform 0.18s ease, box-shadow 0.18s ease;
}
a.cap-item:hover {
  background: var(--white); border-color: var(--red-500);
  transform: translateY(-2px); box-shadow: var(--shadow-sm);
}
a.cap-item p { flex-grow: 1; }
.cap-more {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 12px;
  font-size: 0.8rem; font-weight: 800; letter-spacing: 0.01em;
  color: var(--red-600);
}
.cap-more svg {
  width: 14px; height: 14px; stroke: currentColor; fill: none;
  stroke-width: 2.6; transition: transform 0.18s ease;
}
a.cap-item:hover .cap-more svg { transform: translateX(3px); }

/* ------------------------------------------------------------ emphasis
   Bold has to earn its place on every background, not just white. Body
   copy sits at --ink-soft/--ink-muted, so a <b> that only changes weight
   barely reads; these lift it to full --ink (or white on dark) so the
   phrase a skimmer must not miss actually separates from the sentence
   around it. Scoped per surface because each one has a different ground. */
/* Grouped by the surface the text actually sits on, NOT by which band the
   markup lives inside. `.principle` cards are white but sit in the red
   band, so a blanket `.band-red p b` painted them white-on-white — the
   same trap already documented above for `.band-red h3`. Check the ground,
   not the ancestor. */

/* --- light ground: white cards and light bands --- */
.band-white .lede b,
.band-light .lede b,
.cap-item p b,
.principle p b,
.svc-copy p b,
.price-extra p b { color: var(--ink); font-weight: 700; }

/* --- near-black ground: hero, pipeline, FAQ, dark panels --- */
.band-dark .lede b,
.hero p.subhead b,
.hero-panel li b,
.cap-side.is-dark p b,
.step p b,
.faq-a b { color: var(--white); font-weight: 700; }

/* --- red ground: stats and the closing band. Scoped to direct band
       content so cards sitting on top keep their own treatment. --- */
.band-red > .container > .band-head .lede b,
.cap-side.is-red p b,
.stat p b { color: var(--white); font-weight: 700; }

/* Service sections on services.html alternate white / light / dark / red,
   so .svc-copy has no single ground. The dark and red variants need the
   same lift the light ones don't. */
.svc.band-dark .svc-copy p b,
.svc.band-red .svc-copy p b { color: var(--white); font-weight: 700; }
