/* ===== Self-hosted fonts (were Google Fonts CDN — render-blocking). =====
   Latin subsets only. Regenerate via the selfhost-fonts script if weights change. */
@font-face{font-family:'Baloo 2';font-style:normal;font-weight:700;font-display:swap;src:url("fonts/baloo-2-700.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Baloo 2';font-style:normal;font-weight:800;font-display:swap;src:url("fonts/baloo-2-800.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url("fonts/inter-400.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url("fonts/inter-500.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url("fonts/inter-600.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;src:url("fonts/inter-700.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Plus Jakarta Sans';font-style:normal;font-weight:600;font-display:swap;src:url("fonts/plus-jakarta-sans-600.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Plus Jakarta Sans';font-style:normal;font-weight:700;font-display:swap;src:url("fonts/plus-jakarta-sans-700.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Plus Jakarta Sans';font-style:normal;font-weight:800;font-display:swap;src:url("fonts/plus-jakarta-sans-800.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}

/* ===== Bang For Ya Buck — black + orange =====
   Same token names as the Kapow sheet it was forked from, so every rule below
   carries over untouched; only the values change. --blue is the primary dark
   (here: near-black) and --yellow the bright accent (here: BFYB orange), which
   is why those names still read oddly. Orange is #FF9933, taken from the
   logo and the invoice/report PDFs so print and web match.
   --orange-ink is the darkened orange for accent text on white — #FF9933 on
   white is only ~2:1 and fails WCAG for body-size text. */
:root {
  /* BFYB BRAND ORDER, Pearce 28/09/2026:
       1. ORANGE  #FF9933 — the primary. Hero, accents, every price, the
                            "both" strip, every filled button that matters.
       2. BLUE    #2489EC — the second colour. Off the truck (see --bar).
       3. BLACK   #141414 — the third. Dark panels and body copy.
       4. WHITE   #ffffff — the fourth. Cards and page ground.
     Rank is not area: orange leads, blue is what gets reached for when a
     second colour is needed, black is a surface rather than a statement.

     BLUE IS THE TOP BAR. THAT IS ALL.
     Pearce, 28/09/2026 — first "BFYB second colour is blue... black is 3rd,
     and not bold, or a lot", then, seeing it applied to every dark surface
     on the site: "okay, let's change back the blue, this is A LOT. Make the
     top bar this blue, that's fine, the rest no."
     He is right, and it is the "not a lot" half of his own rule: a saturated
     blue behind every band, panel and button turned the accent into the
     wallpaper. So the deep SURFACE colour goes back to near-black, and the
     blue lives in --bar alone, where one strip of it at the top of the page
     reads as brand rather than as a theme.
     The blue itself is still measured, not chosen — see --bar below. */
  /* ============================================================
     THE BRAND PALETTE — SAMPLED. NEVER INVENTED.
     ============================================================
     Pearce, 01/10/2026, after I had guessed three times: "I don't know where
     you're getting these colours... I need to make you ONLY SELECT ON BRAND
     COLOURS FROM NOW." He then sent the truck wrap, and finally a 30x29 crop
     of the blue itself with "this one".

     THE BLUE, measured off that crop — every pixel in it, no interpretation:
         mode  #076EB8     mean  #0E6EB4
         hue 205   lightness 37-38%   saturation ~93%
     That is the blue on the polo shirts and the swoosh on the ute. It is a
     BRIGHT blue, and that is the point: my three earlier attempts all failed
     by being too dark — #2A1E17 (not on the vehicle at all), #0E2038 (right
     hue, 14% lightness against the real 38%), #2D5082 (sampled from the
     trailer in shade, so the daylight had been taken out of it).

     THE ORANGE, from the same photographs:
         hue 23-25    #C6601E deep -> #E4874B mid -> #EAA24E light

     THE RULE: any colour added to this site is sampled from a photograph of
     the vehicle or the uniforms first. If it cannot be found there, it is not
     a BFYB colour, however well it goes with these. Black is excluded by
     Pearce explicitly; it survives only as --ink, which is heading TEXT on
     cream and not a brand colour at all.
     ============================================================ */
  --blue: #076EB8;        /* THE brand blue, straight off the uniform */
  --blue-d: #065E9E;
  --blue-dk: #054E85;     /* the footer — same blue, deep enough for small text */
  --blue-bright: #1E8AD8;
  --blue-pill: #3AA0E8;
  /* A wash of the SAME measured blue (#076EB8), for a selected surface.
     Not a new colour — the brand blue with the daylight left in. */
  --blue-soft: #eaf3fb;
  --deep: #076EB8;        /* alias, for rules that mean "the dark panel" */
  --yellow: #FF9933;      /* BFYB orange accent */
  /* THE TOP BAR — the one place the brand blue lives.
     Pearce, 28/09/2026: "change the top bar colour, black is wrong", then
     "get the HEX code from the truck and use it", then "slightly more sky".
     #0060D0 is the dominant pixel of the blue swoosh on the cab door in
     assets/img/bfyb-truck-new.jpg — the photograph of the actual wrapped
     ute. This is that hue opened up toward sky, one notch short of where
     white text stops being readable on it. */
  --bar: #FF9933;        /* the top bar — orange, Pearce 29/09/2026 */
  --bar-line: rgba(20,18,16,.18);
  --yellow-d: #e07f1d;
  --yellow-soft: #ffeeda;
  /* ACCENT ORANGE ON LIGHT GROUNDS — the wrap's deep orange.
     Pearce, 01/10/2026, sent a swatch of the wrap's LIGHT orange (#EA9F55,
     hue 30) and asked for "Armidale" to be that: on brand and brighter.
     On brand it is — it is straight off the vehicle. But on the cream hero it
     measures 2.07:1, where large headline text needs 3:1, so the word would
     be noticeably harder to read than the words either side of it. A headline
     you have to squint at is not a brand win.
     #C6601E is the same vehicle, the DEEP orange from the wrap at hue 24. It
     is brighter and far more saturated than the #b35c00 it replaces (which
     was never sampled from anything), and it clears 3.89:1 on cream.
     The light orange is not wasted — it is correct anywhere it sits on the
     blue or on a dark ground, where the contrast runs the other way. */
  /* ---- GRADIENTS (Option A, chosen 01/10/2026) --------------------------
     Pearce: "all the colours used are solid one colour. KAPOW is gradient
     everywhere." Measured from Kapow's stylesheet: 28 linear gradients and 12
     radial, and the signature one is a diagonal three-stop WITHIN a colour —
     lighter at one corner, deeper at the other. Not a second colour, just
     depth. Same palette, so nothing on brand changes; the surfaces simply
     stop being flat.
     Applied to the LARGE surfaces only. On a 30px circle a three-stop is
     invisible noise, and 40 of them would be 40 chances for one to drift. */
  /* AMPLIFIED 01/10/2026 — Pearce: "I can see a SMALL change, but it needs to
     be amplified, more obvious."
     The spread is deliberately LOPSIDED, because that is where the room is.
     White text on the light end of the blue already measures 3.70:1 and large
     text needs 3:1, so lightening it further breaks the stat band's labels —
     #3AA3E8 would land at 2.77:1. The dark end has all the headroom going:
     #033052 carries white at 13.6:1. So the light end stays put and the dark
     end goes much deeper, which roughly doubles the visible travel without
     costing a single contrast point.
     The midpoint also moves from 52% to 40%, so the dark half occupies more of
     the surface and the sweep is something you see rather than suspect.
     The orange has headroom at BOTH ends because its text is near-black. */
  --grad-blue: linear-gradient(100deg, #1E8AD8 0%, var(--blue) 40%, #033052 100%);
  --grad-blue-deep: linear-gradient(170deg, #0C73BD 0%, #02233C 85%);
  --grad-blue-btn: linear-gradient(100deg, #2B95DE 0%, #054E85 100%);
  --grad-orange: linear-gradient(100deg, #FFC98A 0%, var(--yellow) 45%, #D96908 100%);
  --orange-ink: #CB601F;
  /* Same hue, dark enough for SMALL uppercase labels: 5.6:1 on cream where
     --orange-ink is only 3.8:1. Headings keep --orange-ink. */
  --orange-ink-d: #A8431A;  /* Pearce's swatch, 01/10 — hue 23, 3.8:1 on cream */
  --orange-bright: #EA9F55; /* wrap light orange — for DARK grounds only */
  --grass: #FF9933;       /* kept in the orange family */
  --grass-d: #e07f1d;
  --red: #E63946;
  --ink: #141414;         /* near-black headings */
  --body: #46443f;
  --muted: #6f6c66;
  --line: #e9e6e1;
  --cream: #faf8f5;       /* warm off-white */
  --cream2: #f2ede6;      /* warm light sand */
  --white: #ffffff;

  /* aliases kept so forked rules keep resolving */
  --navy: #076EB8;
  --navy-d: #065E9E;
  --navy-dk: #054E85;
  --green: #141414;
  --green-d: #000000;
  --green-dk: #0a0a0a;
  --leaf: #333333;

  --radius: 14px;
  --radius-lg: 22px;
  --radius-xl: 34px;
  --shadow: 0 14px 34px rgba(0, 0, 0, 0.16);
  --shadow-lg: 0 28px 64px rgba(0, 0, 0, 0.28);
  --ring: 0 0 0 4px rgba(255, 153, 51, 0.45);
  --maxw: 1240px;
  --font: "Inter", system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  --head: "Plus Jakarta Sans", "Inter", system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  --brand: "Baloo 2", "Plus Jakarta Sans", system-ui, sans-serif;
  --splat-mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20200%20200'%3E%3Cg%20fill='%23fff'%3E%3Ccircle%20cx='100'%20cy='100'%20r='80'/%3E%3Ccircle%20cx='45'%20cy='62'%20r='40'/%3E%3Ccircle%20cx='158'%20cy='55'%20r='44'/%3E%3Ccircle%20cx='165'%20cy='142'%20r='40'/%3E%3Ccircle%20cx='55'%20cy='150'%20r='42'/%3E%3Ccircle%20cx='100'%20cy='38'%20r='34'/%3E%3Ccircle%20cx='100'%20cy='168'%20r='32'/%3E%3Ccircle%20cx='34'%20cy='112'%20r='32'/%3E%3Ccircle%20cx='172'%20cy='100'%20r='30'/%3E%3Ccircle%20cx='188'%20cy='28'%20r='8'/%3E%3Ccircle%20cx='18'%20cy='176'%20r='9'/%3E%3C/g%3E%3C/svg%3E");
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { margin: 0; font-family: var(--font); color: var(--body); background: var(--white); line-height: 1.6; -webkit-font-smoothing: antialiased; overflow-x: hidden; }
h1, h2, h3, h4, h5 { font-family: var(--head); color: var(--ink); line-height: 1.1; margin: 0 0 .5em; letter-spacing: -.025em; font-weight: 800; }
h1 { font-size: clamp(2.6rem, 6.2vw, 4.6rem); }
h2 { font-size: clamp(1.9rem, 4vw, 2.9rem); }
h3 { font-size: 1.2rem; font-weight: 700; letter-spacing: -.015em; }
p { margin: 0 0 1rem; }
a { color: var(--blue); text-decoration: none; }
img { max-width: 100%; display: block; }
/* Light grounds get the deeper orange — --yellow on cream is 2.1:1, which is
   below the bar even for display type. The dark panels override back to yellow
   below (.ctaband, .priceblock__intro, .pricepanel__pitch), and the interior
   hero sets its own brand blue. */
.hl { color: var(--orange-ink); }
.hl-b { color: var(--blue); }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }
.wrap--narrow { max-width: 860px; }

/* ===== Icons ===== */
.ico { width: 1.15em; height: 1.15em; display: inline-block; vertical-align: -0.18em; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.ibadge { display: inline-grid; place-items: center; width: 64px; height: 64px; border-radius: 50%; color: var(--blue); background: var(--yellow); box-shadow: 0 12px 24px rgba(255,153,51,.35); flex: none; transition: transform .25s ease; }
.ibadge .ico { width: 30px; height: 30px; }
.ibadge--blue, .ibadge--amber { background: var(--yellow); color: var(--blue); }
.ibadge--violet, .ibadge--teal { background: var(--blue); color: var(--yellow); }
.ibadge--ghost { background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.2); box-shadow: none; color: var(--yellow); }

/* ===== Buttons ===== */
.btn { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: .5em; font-family: var(--head); font-weight: 700; font-size: 1rem; padding: .95rem 1.7rem; border-radius: 10px; border: 2px solid transparent; cursor: pointer; transition: transform .14s ease, box-shadow .2s ease, background .2s ease; text-align: center; line-height: 1; letter-spacing: -.01em; }
.btn .ico { width: 1.05em; height: 1.05em; transition: transform .2s ease; }
.btn:hover .ico { transform: translateX(3px); }
.btn:active { transform: translateY(1px) scale(.99); }
/* ORANGE BUTTON, NEAR-BLACK LABEL.
   10/10/2026. This said `color: var(--blue)` — the brand blue, #076EB8,
   on the orange gradient. That measures 2.8:1, where even large bold
   text needs 3:1 and a button label of this size needs 4.5:1, and it
   was the label on the primary call to action of all eight service
   pages ("See my price & book"). On a phone held outdoors it read as
   a smudge.
   #141414 on the same orange is 8.9:1, and it is what every other
   orange control on the site already uses — the sticky bar, the carpet
   builder button, the end-of-lease band. Nothing changes colour here;
   the text simply becomes readable. */
.btn--accent { background: var(--grad-orange); color: var(--ink); box-shadow: 0 10px 22px rgba(255,153,51,.4); }
.btn--accent:hover { background: var(--yellow-d); transform: translateY(-3px); box-shadow: 0 16px 30px rgba(255,153,51,.5); }
.btn--green { background: var(--blue); color: #fff; }
.btn--green:hover { background: var(--blue-d); transform: translateY(-3px); }
.btn--ghost { background: transparent; color: #fff; border-color: rgba(255,255,255,.7); }
.btn--ghost:hover { background: rgba(255,255,255,.14); transform: translateY(-3px); }
.btn--outline { background: #fff; color: var(--blue); border-color: var(--line); }
.btn--outline:hover { border-color: var(--yellow); box-shadow: var(--shadow); transform: translateY(-3px); }
.btn--lg { padding: 1.1rem 2rem; font-size: 1.05rem; }
.btn--sm { padding: .6rem 1.15rem; font-size: .9rem; }
.btn--block { width: 100%; }

/* ===== Eyebrow ===== */
.eyebrow { display: inline-flex; align-items: center; gap: .7em; font-family: var(--head); font-weight: 700; font-size: .78rem; letter-spacing: .18em; text-transform: uppercase; color: var(--blue); background: none; padding: 0; border-radius: 0; margin-bottom: 1.1rem; }
.eyebrow::before { content: ""; width: 28px; height: 2px; background: var(--yellow-d); border-radius: 2px; flex: none; }
.eyebrow .ico { display: none; }
.eyebrow--light { background: none; color: #FDE3CA; }
.eyebrow--light::before { background: var(--yellow); }
.section__head { text-align: center; max-width: 800px; margin: 0 auto 3rem; }
.section__head .eyebrow { display: inline-flex; }
.section__lead { color: var(--muted); font-size: 1.12rem; }
.on-dark { color: #fff; }

/* ===== Reveal ===== */
.reveal { opacity: 0; transform: translateY(24px); transition: opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1); }
.reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; transform: none; transition: none; } }

/* ===== Header (all blue) ===== */
.topbadge { background: var(--blue); color: #fff; }
.topbadge__inner { display: flex; align-items: center; gap: 2.4rem; padding: .7rem 24px; }
.topbadge__item { display: inline-flex; align-items: center; gap: .8em; font-size: .82rem; color: #FEEFE0; }
.topbadge__item .ico { color: var(--yellow); width: 42px; height: 42px; stroke-width: 1.7; flex: none; }
.topbadge__item b { font-family: var(--head); color: #fff; display: block; font-size: .95rem; text-transform: uppercase; letter-spacing: .04em; font-weight: 800; }
.topbadge__item span { display: block; line-height: 1.15; }
.topbadge__spacer { margin-left: auto; }

.header { position: sticky; top: 0; z-index: 50; background: var(--grad-orange); }
.header__inner { display: flex; align-items: center; gap: 1.5rem; padding: .65rem 24px; }
.header__badges { display: flex; gap: 2.2rem; flex: 1; justify-content: center; }
/* The header sits on ORANGE now, so everything in it is dark ink rather than
   the white it used to be on a dark bar. */
.hbadge { display: inline-flex; align-items: center; gap: .7em; color: #4a3008; }
.hbadge > .ico { color: #141414; width: 42px; height: 42px; flex: none; stroke-width: 1.7; }
.hbadge__txt b { display: block; font-family: var(--head); font-weight: 800; color: #141414; text-transform: uppercase; letter-spacing: .03em; font-size: .92rem; }
.hbadge__txt span { display: block; font-size: .76rem; line-height: 1.15; color: #5a3a12; }
/* Both badges are links now (Pearce, 01/10/2026) and have to LOOK tappable
   without becoming two more buttons in a header that already has four. So:
   no new colour, no border at rest — just a hit area, a hand cursor, and the
   title underlining on hover and keyboard focus. */
.hbadge--link { text-decoration: none; cursor: pointer; border-radius: 12px;
  padding: .3rem .45rem; margin: -.3rem -.45rem; transition: background .15s ease; }
.hbadge--link:hover, .hbadge--link:focus-visible { background: rgba(255,255,255,.26); }
.hbadge--link:hover .hbadge__txt b, .hbadge--link:focus-visible .hbadge__txt b { text-decoration: underline; text-underline-offset: 2px; }
.hbadge--link:focus-visible { outline: 2px solid #141414; outline-offset: 1px; }
.brand { display: inline-flex; align-items: center; background: none; padding: 0; box-shadow: none; transition: transform .15s ease; }
.brand:hover { transform: translateY(-1px) rotate(-1.5deg); }
.logo { display: inline-flex; flex-direction: column; align-items: flex-start; line-height: 1; }
.logo__word { font-family: "Baloo 2", "Montserrat", sans-serif; font-weight: 800; font-size: 2.7rem; color: #fff; letter-spacing: .005em; display: inline-flex; align-items: center; line-height: .9; }
.logo__o { display: inline-block; width: .92em; height: .92em; margin: 0 .005em; position: relative; top: .05em; }
.logo__splat { width: 100%; height: 100%; display: block; filter: drop-shadow(0 2px 4px rgba(0,0,0,.25)); }
.logo__sub { font-family: "Baloo 2", "Montserrat", sans-serif; font-weight: 700; font-size: .74rem; letter-spacing: .36em; color: var(--yellow); text-transform: uppercase; margin-top: .05em; padding-left: .18em; }
.header__cta { display: flex; align-items: center; gap: .7rem; flex: none; }
/* WHITE, NOT YELLOW. This pill used to be yellow text on a black ground, which
   was fine. When --deep became the brand blue, yellow on it fell to 2.5:1 —
   under half of what 16px text needs — and it is the phone number, the single
   most important thing in the header. White on the brand blue is 5.3:1 and is
   the same treatment the footer already uses. The icon keeps the yellow: it is
   a decorative glyph beside a label, not the text being read. */
.header__phone { font-family: var(--head); font-weight: 800; color: #fff; background: var(--deep); padding: .55rem 1rem; border-radius: 8px; display: inline-flex; align-items: center; gap: .4em; }
.header__phone .ico { color: var(--yellow); }
.header__phone:hover { color: var(--yellow); }
.header__nums { display: flex; flex-direction: column; align-items: stretch; gap: .3rem; }
.header__sms { font-family: var(--head); font-weight: 700; font-size: .76rem; color: #241a10; background: rgba(255,255,255,.4); border: 1px solid rgba(20,18,16,.3); padding: .28rem .7rem; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; gap: .35em; white-space: nowrap; }
.header__sms .ico { width: 13px; height: 13px; color: #141414; }
@media (max-width: 560px) { .header__sms { font-size: .68rem; padding: .22rem .5rem; } .header__sms > span { display: none; } }

/* Nav bar */
/* top is the HEADER's height, not 0 — at 0 the two sticky bars pin to the same
   line and the taller header simply covers the nav. --hdr-h is measured on load
   and on resize in the shared script; the 95px fallback is the desktop height
   if that script has not run yet. */
.navbar { background: var(--grad-blue); position: sticky; top: var(--hdr-h, 95px); z-index: 49; }
/* IN-PAGE ANCHORS LAND BELOW THE STICKY BARS, NOT BEHIND THEM.
   Pearce, 01/10/2026, following the new "15 years local" badge to #why: "click
   this and its cut off." The browser had done exactly what it was asked — put
   the heading at y=0 — which is underneath a sticky header AND a sticky navbar.
   --stick-h is both of them, measured in build-common.cjs; the fallback covers
   the moment before that script runs. Applied to every element with an id so
   footer links, the badges and any anchor added later all behave, and set with
   scroll-margin rather than padding so nothing about the layout moves. */
[id] { scroll-margin-top: calc(var(--stick-h, 160px) + 14px); }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
.navbar__inner { display: flex; align-items: stretch; gap: .1rem; padding: 0 24px; }
.navitem { position: relative; }
.navitem > a { display: flex; align-items: center; gap: .4em; padding: .9rem 1.05rem; color: #FEF6ED; font-family: var(--head); font-weight: 600; font-size: .93rem; }
.navitem > a .ico { width: .85em; height: .85em; opacity: .8; }
.navitem:hover > a, .navitem > a:hover { color: var(--yellow); }
.navitem__panel { position: absolute; top: 100%; left: 0; background: #fff; border-radius: 0 0 14px 14px; box-shadow: var(--shadow-lg); padding: 1.2rem; min-width: 640px; display: grid; grid-template-columns: repeat(4, 1fr); gap: .15rem 1.2rem; opacity: 0; visibility: hidden; transform: translateY(8px); transition: all .18s ease; z-index: 60; }
.navitem:hover .navitem__panel { opacity: 1; visibility: visible; transform: translateY(0); }
.navitem__panel a { display: block; padding: .42rem .5rem; color: var(--body); font-size: .88rem; border-radius: 8px; }
.navitem__panel a:hover { background: var(--cream2); color: var(--blue); }
.navitem__col-h { grid-column: 1/-1; font-family: var(--head); font-weight: 700; color: var(--blue); text-transform: uppercase; letter-spacing: .08em; font-size: .72rem; padding: .2rem .5rem .4rem; }
.navbar__book { margin-left: auto; align-self: center; }
.navbar__social { margin-left: auto; display: flex; align-items: center; gap: 1.1rem; padding-left: 1rem; }
.navbar__social a { color: #fff; display: inline-flex; transition: color .15s, transform .15s; }
.navbar__social a:hover { color: var(--yellow); transform: translateY(-2px); }
.navbar__social .ico { width: 20px; height: 20px; }

/* ===== Hero (solid blue + stats panel) ===== */
/* Original team photo anchored to the RIGHT edge at full hero height; the
   left side is a solid-to-clear overlay the headline sits on. The gradient
   stays ~opaque past the image's left edge at any viewport width, so the
   square photo blends in with no visible seam. */
/* THE HERO IS ORANGE.
 *
 * Pearce, 28/09/2026: "PLEASE CHANGE THE HERO colours, i HATE THE BLACK."
 * It was a near-black gradient with a hint of orange glow — correct to the
 * palette, and indistinguishable from every other trade site in the country.
 * The brand colour now carries the whole band and the type goes black on it,
 * which is the pairing with the most contrast BFYB owns (#141414 on #FF9933
 * is 8.4:1, better than the white-on-black it replaces).
 *
 * Black has not left the site — it still runs the header, the stat band, the
 * footer and every primary button. It is no longer the first thing anyone
 * sees.
 */
/* THE PHOTO IS THE BACKDROP, NOT A CARD.
 *
 * Pearce, 28/09/2026, pointing at Kapow's homepage: "see how the hero and pic
 * is blended, LOOKS MINT. Need BFYB the same."
 *
 * Kapow runs one full-bleed photo under a brand-colour gradient that is solid
 * where the words are and gone by the time it reaches the subject. BFYB was
 * putting its truck in a rounded box on the right — a stock-photo layout. Now
 * the truck IS the hero and the orange lies over it.
 *
 * The gradient stops are what make it read as blended rather than as a photo
 * with a panel stuck on: solid to 40%, most of the way gone by 64%, fully
 * clear by 80%. `background-position: right center` keeps the cab and the door
 * logo in the clear part — the tray logo sits under the orange, which is fine,
 * because the door one is sharper anyway.
 */
/* THE PHOTO RUNS THE WHOLE WIDTH. NOTHING IS WASHED OUT.
   Pearce, 01/10/2026: "i hate the white on the left, give me a preview with
   the photo going through the white instead", then, of three previews, "C" —
   "i love C".

   The history this replaces: the hero was a full field of #FF9933, which was
   cut back to a white ground in September because the brand colour was doing
   the job of a background. That fixed the glare and created this: a white
   wash over the left 56% that ate the house, the plants and half the ute, so
   the photograph only really existed on the right-hand side.

   Now the photo is the background, at full strength, edge to edge — and the
   copy sits on a frosted card of its own (.hero__copy below). That is the
   trade: the readability no longer comes from bleaching the picture, it comes
   from giving the text its own surface. Do not reintroduce a gradient over
   the photo; the card is what makes this legible.

   The earlier note about the fade clearing before their faces is obsolete —
   there is no fade. The warm radial in .hero::before is kept but it is well
   under 12% and sits where nobody is standing. */
/* THE DARK OVERLAY, LEFT TO RIGHT. Pearce, 01/10/2026: "dark overlay from left
   to right."
   It runs heavy on the left, where the card and the copy sit, and is gone by
   the right-hand third — so it never touches the two of them or the ute, which
   is the half of the photo that is actually selling anything. That is the same
   rule the old orange wash was written to (clear before the people, not over
   them); what changed is that the left side is now dark instead of white.
   #0A1622 rather than black: a cold near-navy sits with the brand blue, where
   pure black goes muddy against the warm evening light in this photo. */
.hero { position: relative; color: #141414; overflow: hidden;
  background:
    linear-gradient(90deg,
      rgba(10,22,34,.88) 0%, rgba(10,22,34,.82) 26%, rgba(10,22,34,.62) 44%,
      rgba(10,22,34,.34) 62%, rgba(10,22,34,.10) 82%, rgba(10,22,34,0) 100%),
    url("img/hero-team-ai.jpg");
  background-size: cover, cover;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
  background-color: #0A1622; }

/* THE FROSTED CARD. This is the whole of option C.
   backdrop-filter is a progressive enhancement: where it is unsupported the
   card is still 90% white and the text is still readable, just without the
   blur. The @supports block below raises the opacity for exactly that case,
   so no browser gets grey text on a photograph. */
.hero:not(.hero--plain) .hero__copy {
  background: rgba(255,255,255,.86);
  backdrop-filter: blur(7px) saturate(1.05);
  -webkit-backdrop-filter: blur(7px) saturate(1.05);
  border-radius: 22px;
  padding: 20px 24px 22px;
  box-shadow: 0 18px 50px rgba(2,35,60,.20);
}
@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .hero:not(.hero--plain) .hero__copy { background: rgba(255,255,255,.95); }
}
/* PHONES KEEP THE SAME IDEA, with two adjustments.
   The photo is framed to the RIGHT of centre, because at 390px wide a centred
   crop of a landscape shot puts the ute's door in the middle and loses both
   people. And the card tightens its padding and corner so it does not eat the
   whole screen. The blur stays — it is cheap on a modern phone and it is what
   keeps the text off the picture. */
@media (max-width: 860px) {
  /* On a phone the copy sits over the MIDDLE of the frame, not the left of it,
     so a left-to-right scrim would miss what it is there to darken. Same
     overlay, turned to run top-to-bottom instead. */
  .hero { background:
    linear-gradient(180deg,
      rgba(10,22,34,.84) 0%, rgba(10,22,34,.74) 34%, rgba(10,22,34,.52) 58%,
      rgba(10,22,34,.22) 82%, rgba(10,22,34,.04) 100%),
    url("img/hero-team-ai.jpg");
    background-size: cover, cover;
    background-position: center, 68% center; }
  .hero:not(.hero--plain) .hero__copy { padding: 20px 18px 24px; border-radius: 18px;
    background: rgba(255,255,255,.90); }
}
/* No shadow: black type on orange needs none, and a drop shadow on a light
   ground is what makes a page look homemade. The photo side keeps one. */
.hero h1, .hero__lead { text-shadow: none; }
/* The warm radial used to be centred at 68% — directly under the two of them
   — so it put a brown cast over their legs and torsos that the linear
   gradient had already been blamed for. It now sits under the copy column
   where it belongs, and lighter. */
.hero::before { content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0; background:
    radial-gradient(700px 460px at 86% 3%, rgba(255,153,51,.10), transparent 62%),
    radial-gradient(620px 420px at 30% 106%, rgba(255,153,51,.08), transparent 62%); }
/* Comic halftone dot texture (top-left).
   Pearce, 01/10/2026: "these orange dots, increase the orange obviousness by
   20% please." Done on the LAYER opacity rather than on the dot colour, in all
   three places the motif appears (.hero, .ctaband, .bk-upsell), so the texture
   stays one consistent thing across the site and the orange stays the sampled
   #FF9933 rather than drifting to a brighter one. .5 -> .6 here. */
.hero::after { content: ""; position: absolute; top: 0; left: 0; width: 48%; height: 78%; pointer-events: none; z-index: 0;
    background-image: radial-gradient(rgba(255,153,51,.55) 2px, transparent 2.6px); background-size: 17px 17px;
    -webkit-mask-image: linear-gradient(135deg, #000 0%, transparent 62%); mask-image: linear-gradient(135deg, #000 0%, transparent 62%); opacity: .6; }

/* Right column: comic burst stacked over the stats */
.hero__right { display: flex; flex-direction: column; align-items: center; gap: 1.3rem; position: relative; z-index: 1; }
/* The HOME hero's photo moved to its background, so the boxed copy of it on the
   right was the same picture twice — hidden, not deleted.
   That rule was written as `.hero .hero__right`, which also caught every
   interior hero, because those are `.hero.hero--plain`. They have no background
   photo, so it left the whole right half of carpet, pest, termites and flood as
   dead orange space. Scoped to the home hero only. */
.hero:not(.hero--plain) .hero__right { display: none; }
.hero:not(.hero--plain) .hero__inner { grid-template-columns: minmax(0, 1fr); }
.hero .hero__copy { max-width: 36rem; }
@media (min-width: 861px) { .hero .hero__copy { max-width: 36rem; } }

/* Splat promo badge (replaces comic burst) */
@keyframes splatIn {
  0%   { transform: scale(0) rotate(var(--r,0deg)); opacity: 0; }
  55%  { transform: scale(1.18) rotate(calc(var(--r,0deg) + 6deg)); opacity: var(--o,1); }
  78%  { transform: scale(.93) rotate(var(--r,0deg)); }
  100% { transform: scale(1) rotate(var(--r,0deg)); opacity: var(--o,1); }
}
.splatbadge { position: relative; width: 212px; height: 198px; display: grid; place-items: center; --o: 1; animation: splatIn .7s .05s cubic-bezier(.2,1.5,.5,1) both; }
.splatbadge__shape { position: absolute; inset: 0; width: 100%; height: 100%; filter: drop-shadow(0 8px 18px rgba(0,0,0,.4)); }
.splatbadge__txt { position: relative; z-index: 2; text-align: center; color: #0a0a0a; font-family: "Baloo 2","Montserrat",sans-serif; line-height: .92; transform: rotate(-6deg); }
.splatbadge__txt b { display: block; font-size: 2.9rem; font-weight: 800; }
.splatbadge__txt span { display: block; font-size: .78rem; font-weight: 800; text-transform: uppercase; letter-spacing: .14em; }
@media (prefers-reduced-motion: reduce) { .splatbadge { animation: none; } }

/* Splat-the-bug mini game */
.bughunt { position: relative; width: 100%; max-width: 320px; height: 200px; border: 3px dashed rgba(255,153,51,.55); border-radius: 18px; background: rgba(255,255,255,.06); overflow: hidden; }
.bughunt__hint { position: absolute; top: 12px; left: 0; right: 0; text-align: center; font-family: "Baloo 2","Montserrat",sans-serif; font-weight: 700; font-size: .92rem; color: #fff; z-index: 1; pointer-events: none; }
.bughunt__hint b { color: var(--yellow); }
.bughunt__bug { position: absolute; top: 0; left: 0; width: 46px; height: 46px; padding: 6px; border: none; background: none; cursor: pointer; transform: translate(135px, 90px); transition: transform .8s cubic-bezier(.5,.05,.5,1); z-index: 2; }
.bughunt__bug svg { width: 100%; height: 100%; fill: none; stroke: var(--yellow); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; filter: drop-shadow(0 2px 3px rgba(0,0,0,.35)); }
.bughunt__bug:hover svg { stroke: #fff; }
.bughunt__win[hidden] { display: none; }
.bughunt__win { position: absolute; inset: 0; z-index: 4; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .3rem; text-align: center; background: var(--blue-dk); border-radius: 15px; padding: .9rem; animation: splatIn .55s cubic-bezier(.2,1.5,.5,1) both; }
.bughunt__splat { display: block; width: 56px; height: 48px; margin: 0 auto .15rem; }
.bughunt__splat svg { width: 100%; height: 100%; display: block; }
.bughunt__win strong { font-family: "Baloo 2","Montserrat",sans-serif; color: #fff; font-size: 1.1rem; }
.bughunt__codeline { color: #FEEEDD; font-size: .9rem; }
.bughunt__codeline code { background: var(--yellow); color: #0a0a0a; font-family: "Baloo 2","Montserrat",sans-serif; font-weight: 800; padding: .2rem .6rem; border-radius: 8px; letter-spacing: .08em; }
.bughunt__btns { display: flex; gap: .5rem; margin-top: .4rem; }
.bughunt__copy, .bughunt__book { background: var(--yellow); color: #0a0a0a; border: none; border-radius: 8px; padding: .45rem .9rem; font-family: "Baloo 2","Montserrat",sans-serif; font-weight: 800; cursor: pointer; font-size: .9rem; }
.bughunt__book { background: #fff; }
.bughunt__copy:hover, .bughunt__book:hover { transform: translateY(-1px); }
/* Decorative bug-splats */
.splatdeco { position: absolute; pointer-events: none; z-index: 0; line-height: 0; opacity: var(--o, .8); }
.splatdeco .ico { fill: var(--yellow); stroke: none; display: block; width: 100%; height: 100%; }
.splatdeco--1 { top: -40px; right: 4%; width: 175px; height: 175px; --o: .9; --r: 18deg; --d: .12s; animation: splatIn .7s var(--d) cubic-bezier(.2,1.5,.5,1) both, floaty 7s calc(var(--d) + .8s) ease-in-out infinite; }
.splatdeco--2 { bottom: -55px; left: 1%; width: 150px; height: 150px; --o: .85; --r: -12deg; --d: .26s; animation: splatIn .7s var(--d) cubic-bezier(.2,1.5,.5,1) both, floaty 9s calc(var(--d) + .8s) ease-in-out infinite; }
.splatdeco--3 { top: 40%; left: 47%; width: 95px; height: 95px; --o: .5; --r: 6deg; --d: .4s; animation: splatIn .7s var(--d) cubic-bezier(.2,1.5,.5,1) both, floaty 8s calc(var(--d) + .8s) ease-in-out infinite; }

/* ===== Motion (restrained) ===== */
@keyframes floaty { 0%,100% { transform: translateY(0) rotate(var(--r,0deg)); } 50% { transform: translateY(-14px) rotate(calc(var(--r,0deg) + 4deg)); } }

/* Navbar */
.navbar { background: var(--grad-blue); border-bottom: 1px solid rgba(255,255,255,.08); }
.navitem > a { position: relative; transition: color .15s ease; }
.navitem > a::before { content: ""; position: absolute; left: 16px; right: 16px; bottom: 8px; height: 2px; background: var(--yellow); border-radius: 2px; transform: scaleX(0); transform-origin: left; transition: transform .22s ease; }
.navitem:hover > a { color: var(--yellow); }
.navitem:hover > a::before { transform: scaleX(1); }
.navbar__social a { transition: color .15s ease, transform .15s ease; }

/* Subtle, consistent lift on interactive surfaces */
.tcard, .misspill, .eco-pill, .bookchip { transition: transform .18s ease, box-shadow .18s ease; }
.tcard:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.misspill:hover { transform: translateX(4px); }

@media (prefers-reduced-motion: reduce) {
  .splatdeco--1, .splatdeco--2, .splatdeco--3 { animation: none !important; }
}
/* Tightened 02/10/2026 so the enlarged hero still clears the fold — the old
   3.2/4.8rem was 128px of padding on a card that was already 335px too tall. */
.hero__inner { position: relative; z-index: 1; display: grid; grid-template-columns: 1.25fr .75fr; gap: 3rem; align-items: center; padding: 1.7rem 24px 3.3rem; min-height: 0; }
/* Splat decorations removed site-wide (distracting). */
.splatdeco, .hero__emblem { display: none !important; }
.hero__curve { position: absolute; left: 0; right: 0; bottom: -1px; width: 100%; height: clamp(44px, 5.5vw, 84px); display: block; z-index: 3; pointer-events: none; }
.hero__curve path { fill: var(--cream); }
/* BIGGER, 02/10/2026. Pearce, with the Kapow home page open beside this one:
   "everything in the second pic is actually bigger then BFYB has. BFYB needs
   it made bigger to match." The headroom came from moving the lane picker out
   of the hero (see build-home.cjs) — about 250px that was sitting above this
   heading. 3.3rem -> 4rem at the top end, and the line-height tightened with
   it so the extra size does not just become extra leading. */
.hero h1 { color: #141414; text-transform: none; line-height: 1.03; font-size: clamp(2.3rem, 4.1vw, 4rem); letter-spacing: -.022em; margin-bottom: .45rem; }
/* The place name was orange on black. On orange it becomes white — still the
   one word that jumps, still only one colour away from the rest. */
/* "Armidale" in --yellow, the same orange as the pest card.
   Pearce, 01/10/2026: "the orange in his, make Armidale, so it matches." He
   has now seen three versions of this word on the live page and picked by
   eye each time, which is the right way round — the point of the headline is
   that the word matches the cards below it, so the page reads as one thing.
   Measured, it is 2.0:1 on cream against the 3:1 large text normally wants,
   and that is a real cost he has chosen knowingly. It survives better than
   the number suggests because the type is ~56px at 800 weight and sits hard
   against solid black on the line above.
   Scoped to the HERO H1 and nowhere else. Every small orange label, link and
   button on a light ground stays on --orange-ink (#CB601F, his own swatch),
   where this colour genuinely would be unreadable. */
/* "ARMIDALE" WAS INVISIBLE. The interior heroes sit on the orange gradient, and
   --yellow on that ground is orange on orange — the word was there and could not
   be seen. Brand blue on the orange is 4:1 and is straight off the truck wrap. */
.hero h1 .hl { color: var(--blue-dk); text-shadow: none; display: inline; }
.hero__lead { font-size: 1.18rem; line-height: 1.5; color: var(--body); max-width: 32rem; margin-top: .55rem; margin-bottom: .75rem; }
/* SHORT SCREENS GET A SHORTER HERO. The enlargement above clears the fold on
   a 1920x920 window, but a 1440x800 laptop has 120px less to play with and
   was still cutting the Request a quote button off. Keyed to HEIGHT rather
   than width, because height is the actual constraint — a wide short window
   has the same problem as a narrow one. */
@media (min-width: 861px) and (max-height: 880px) {
  .hero__inner { padding-top: 1.1rem; padding-bottom: 2.4rem; }
  .hero h1 { font-size: clamp(2.1rem, 3.4vw, 3.1rem); }
  .hero__lead { font-size: 1.06rem; margin-bottom: .55rem; }
  .hero:not(.hero--plain) .hero__copy { padding: 16px 20px 18px; }
  .heroprice { padding: .4rem .65rem; }
  .heroprice__p { font-size: 1.04rem; }
}
.hero__eyebrow { display: inline-flex; align-items: center; gap: .55em; font-family: var(--head); font-weight: 700; font-size: .8rem; letter-spacing: .08em; text-transform: uppercase; color: var(--yellow); background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.18); padding: .5rem 1.05rem; border-radius: 999px; margin-bottom: 1.2rem; }
.hero__eyebrow .ico { width: 1em; height: 1em; color: var(--yellow); }
.hero__cta { display: flex; gap: .8rem; flex-wrap: wrap; margin: 1.1rem 0 0; }
.hero__stats { background: rgba(255,255,255,.10); border: 1px solid rgba(255,255,255,.16); border-radius: var(--radius-lg); padding: 2rem 1.6rem; display: grid; gap: 1.4rem; backdrop-filter: blur(4px); align-self: stretch; }
.hero__stat { display: flex; align-items: center; gap: 1.15rem; }
.hero__stat-ico { width: 64px; height: 64px; color: var(--yellow); display: grid; place-items: center; flex: none; }
.hero__stat-ico .ico { width: 56px; height: 56px; fill: var(--yellow); stroke: none; }
.hero__stat-num { font-family: var(--head); font-weight: 800; font-size: 3.6rem; color: var(--yellow); line-height: .85; flex: none; width: 64px; text-align: center; }
.hero__stat-txt b { font-family: var(--head); color: var(--yellow); font-size: 1.55rem; display: block; line-height: 1; text-transform: uppercase; letter-spacing: .01em; font-weight: 800; }
.hero__stat-txt span { color: #fff; font-size: 1.02rem; text-transform: uppercase; font-weight: 700; letter-spacing: .03em; }

/* ===== Sections ===== */
.section { padding: 5rem 0; }
.section--cream { background: var(--cream); }
.section--lav { background: #F8EBDD; }  /* soft lime band — brings the splat-green in as a section */

/* Plain hero (interior pages). The ute photo is anchored bottom-right and
   sized by HEIGHT (auto 118%) so the whole vehicle always sits in frame —
   `cover` in a wide, short hero sliced the car through the middle at desktop
   widths and the curve chopped the wheels. Slight top overscan crops sky only. */
/* MORE VOLUME IN THE ORANGE. Pearce, 01/10/2026: "the orange gradient needs more
   volume, it almost seems the same orange."
   He was looking at a gradient whose first 52% was one flat colour and whose
   whole range was 0.13 in luminance — so for half the banner there was nothing
   to see. These stops run 0.65 down to 0.19, about three and a half times the
   depth, and every one of them is in the wrap's own orange family: #FFC98A is
   the light stop already in --grad-orange, #FF9933 is the top bar, and the deep
   end is --orange-ink taken a shade further.
   The angle matters as much as the colours. 115deg puts the LIGHT end top-left,
   under the heading and the body copy, and the deep end bottom-right behind the
   video — so the extra contrast lands where there is no text to read. */
.hero--plain { background:
    linear-gradient(115deg, #FFC98A 0%, #FFAD55 24%, #FF9933 48%, #E07C14 78%, #C05A09 100%);
  background-color: #FF9933; }
@media (max-width: 760px) {
  .hero--plain { background:
    linear-gradient(170deg, #FFC98A 0%, #FF9933 45%, #E07C14 82%, #C05A09 100%);
    background-color: #ffffff; } }
/* Slimmer curve on interior heroes so it doesn't swallow the bottom of the photo */
.hero--plain .hero__curve { height: clamp(22px, 2.4vw, 42px); }
/* Newcastle suburb pages: team-at-the-beach photo hero */
.hero--nc { background:
    linear-gradient(104deg, #FF9933 0%, #FF9933 46%, #f8912c 66%, #e07f1d 100%);
  background-color: #FF9933; }
@media (max-width: 760px) {
  .hero--nc { background:
    linear-gradient(180deg, #FF9933 0%, #FF9933 58%, #e07f1d 100%); } }
.hero--plain h1 { font-size: clamp(2.3rem, 4.8vw, 3.7rem); line-height: 1; }
/* The right column carries the hero clip on carpet and the photo on the other
   three, so it gets real room — 1.1fr rather than the .75fr the base grid gives.
   Without this the 16:9 panel is only ~430px wide and looks like a thumbnail. */
.hero--plain .hero__inner { grid-template-columns: 1fr 1.1fr; min-height: clamp(300px, 30vw, 520px); padding: 4.5rem 24px 6.5rem; align-items: center; }
/* The single-column mobile rule further down is only `.hero__inner`, so the
   two-column rule above out-specifies it and the grid stayed split on a phone —
   a 137px-wide video. Same specificity here, so the stack wins where it should. */
@media (max-width: 860px) { .hero--plain .hero__inner { grid-template-columns: 1fr; } }
/* PHOTO HEROES MATCH VIDEO HEROES. Pearce, 01/10/2026: "the picture is too
   small, all needs to match."
   The video pages (carpet, termites, flood) render a 599x337 panel; the photo
   pages (pest, commercial) were capped at 380px — so the same slot was two
   different sizes depending on which page you landed on. Same width cap and the
   same 16:9 as .herovid now, and both hero source images are cut at 1400x788 to
   suit it. */
.hero__media { max-width: 620px; width: 100%; }
.hero__media .split__img { aspect-ratio: 16 / 9; }

/* A LOOPING HERO CLIP. Pearce, 01/10/2026.
   Sized and cropped by the box, not by the file, so a clip shot in any aspect
   still fills the frame instead of letterboxing. */
/* 9:16, uncropped. Pearce, 01/10/2026: "I'm hoping the entire video can be used
   on this banner? helps people see first hand, machine, and cleaning." It was
   shot on a phone in portrait, so the frame stays portrait — cropping it to a
   letterbox would throw away the ute and the technician, which are two of the
   four things it shows. */
/* THE WHOLE CARD HAS TO FIT ON THE SCREEN. That is the rule this setting
   exists to enforce, and it took four goes to land on it.
   The history, so nobody re-breaks it: 320px wide was fine but small; doubling
   it was good; tripling the WIDTH (720 x 1280) was "horrible" — the heading slid
   down and the quote button fell under the fold; tripling the HEIGHT as a 2:5
   strip then ran the card off the bottom of the window, which is what Pearce
   meant by "the video is still wrong, should be within the size of my second
   pic." A 9:16 phone clip costs 1.78px of height for every px of width, so the
   only sane constraint is the VIEWPORT HEIGHT.
   WHERE IT LANDED: a WIDE 16:9 panel filling the right column.
   Pearce drew it (01/10/2026) after I had twice read his "length" as height and
   built tall strips. He meant the box keeps its height and doubles in WIDTH.

   The clip is 608 x 1080 — shot portrait on a phone — so a 16:9 window keeps
   only the middle 32% of each frame. That sounds ruinous and is not, which is
   worth recording because it is counter-intuitive: a phone video's top third is
   sky or ceiling and its bottom third is floor, and the subject lives in the
   middle. Cropped this way the branded ute fills the panel and the wordmark is
   finally readable; in the portrait version it was a sliver with the logo cut
   at both edges. The wand shots gain for the same reason.

   object-position stays centred — the wand, hose and machine all sit mid-frame.
   The right column was widened from .75fr to 1.1fr to give this room; that is
   the companion change and the two belong together. */
.herovid { width: 100%; max-width: 620px; aspect-ratio: 16 / 9;
  border-radius: 24px; overflow: hidden;
  box-shadow: 0 28px 60px rgba(0,0,0,.34); background: var(--blue-dk);
  border: 4px solid rgba(255,255,255,.6); }
.herovid__el { display: block; width: 100%; height: 100%; object-fit: cover; }
/* Reduced motion: hold the poster, never play. A hero that moves on its own is
   exactly the thing that setting is for. */
@media (prefers-reduced-motion: reduce) {
  .herovid__el { animation: none !important; }
}
/* Phones keep the same 16:9 window rather than switching shape — one crop across
   every screen, so the clip is framed the same wherever it is watched. */
@media (max-width: 860px) { .herovid { width: 100%; max-width: 100%; margin: 0 auto; } }
.hero__emblem { position: relative; width: clamp(210px, 30vw, 300px); aspect-ratio: 1/1; margin: 0 auto; display: grid; place-items: center; filter: drop-shadow(0 16px 26px rgba(0,0,0,.32)); }
.hero__emblem-splat { position: absolute; inset: 0; width: 100%; height: 100%; }
.hero__emblem-ico { position: relative; width: 40%; height: 40%; color: #0a0a0a; stroke-width: 1.7; }
.herochips { display: flex; flex-wrap: wrap; gap: .55rem; margin-top: 1.4rem; }
.herochip { display: inline-flex; align-items: center; gap: .45em; background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.2); color: #fff; font-family: var(--head); font-weight: 600; padding: .5rem 1rem; border-radius: 999px; font-size: .9rem; }
.herochip .ico { color: var(--yellow); width: 1.05em; height: 1.05em; }
/* On the orange hero the chips and the outline button invert: a translucent
   WHITE pill reads as a hole punched in the orange, which is muddy. Scoped to
   .hero so the same chip on a dark band elsewhere is untouched. */
.hero .herochip { background: rgba(20,20,20,.09); border-color: rgba(20,20,20,.26); color: #141414; }
.hero .herochip .ico { color: #141414; }
.hero .btn--accent { background: var(--grad-blue-btn); color: #fff; box-shadow: 0 10px 22px rgba(0,0,0,.22); }
.hero .btn--accent:hover { background: var(--blue-d); box-shadow: 0 16px 30px rgba(0,0,0,.3); }
/* The orange splats vanish on an orange ground. Deeper orange keeps them. */
.hero .splatdeco .ico { fill: rgba(150,72,0,.34); }
.hero__eyebrow { background: rgba(20,20,20,.10); border-color: rgba(20,20,20,.24); color: #141414; }
.hero__eyebrow .ico { color: #141414; }
.hero__stats { background: rgba(255,255,255,.28); border-color: rgba(255,255,255,.5); }
.hero__stat-ico { color: #141414; }
.hero__stat-ico .ico { fill: #141414; }
.hero__stat-num, .hero__stat-txt b { color: #141414; }
.hero__stat-txt span { color: #3a2a15; }

/* Interior page breadcrumb */
.crumbs { font-size: .85rem; color: var(--muted); padding: 1.1rem 0 0; }
.crumbs a { color: var(--blue); font-weight: 600; }
.crumbs span { color: var(--muted); margin: 0 .4em; }
.section--blue, .section--navy, .section--green { background: var(--grad-blue); color: #fff; position: relative; overflow: hidden; }
.section--blue::before, .section--navy::before { content: ""; position: absolute; inset: 0; background: radial-gradient(800px 460px at 85% 0%, rgba(255,255,255,.08), transparent 60%); }
.section--book { background: var(--cream); }
.section--blue .eyebrow, .section--navy .eyebrow { background: rgba(255,255,255,.14); color: var(--yellow); }
.section--blue h2, .section--navy h2, .section--blue h3, .section--blue p, .section--navy p { color: #fff; }

.grid { display: grid; gap: 1.6rem; }
.grid--4 { grid-template-columns: repeat(4, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }

/* Eco band (white, green pills) */
.eco-bar { background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow); display: flex; align-items: center; flex-wrap: wrap; gap: 1.2rem 2rem; padding: 1.4rem 2rem; }
.eco-bar__lead { display: flex; align-items: center; gap: .8rem; font-family: var(--head); font-weight: 700; color: var(--ink); font-size: 1.15rem; }
.eco-bar__leaf { width: 44px; height: 44px; border-radius: 50%; background: #e7f7ec; color: var(--grass); display: grid; place-items: center; flex: none; }
.eco-bar__leaf .ico { width: 24px; height: 24px; }
.eco-bar__pills { display: flex; gap: .8rem; margin-left: auto; flex-wrap: wrap; }
.eco-pill { display: inline-flex; align-items: center; gap: .5em; background: var(--grass); color: #fff; font-family: var(--head); font-weight: 700; padding: .7rem 1.3rem; border-radius: 10px; font-size: 1rem; }
.eco-pill .ico { width: 1.1em; height: 1.1em; }

/* Pest price cards */
.pestcard { position: relative; background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; transition: transform .22s ease, box-shadow .22s ease; display: flex; flex-direction: column; }
.pestcard:hover { transform: translateY(-8px); box-shadow: var(--shadow-lg); }
.pestcard__media { position: relative; aspect-ratio: 16/10; background: var(--blue); overflow: hidden; }
.pestcard__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .3s ease; }
.pestcard:hover .pestcard__media img { transform: scale(1.06); }
.pestcard__icon { position: absolute; bottom: -26px; left: 20px; width: 56px; height: 56px; border-radius: 14px; background: var(--yellow); color: var(--blue); display: grid; place-items: center; box-shadow: var(--shadow); }
.pestcard__icon .ico { width: 28px; height: 28px; }
.pestcard__body { padding: 2rem 1.4rem 1.4rem; display: flex; flex-direction: column; flex: 1; }
.pestcard__name { font-family: var(--head); font-weight: 800; text-transform: uppercase; letter-spacing: .04em; color: var(--ink); font-size: 1.05rem; }
.pestcard__price { font-family: var(--head); font-weight: 800; color: var(--blue); font-size: 1.5rem; margin: .2rem 0 1rem; }
.pestcard__price span { font-size: .8rem; color: var(--muted); font-weight: 600; }
.pestcard__save { position: absolute; top: 12px; right: 12px; background: var(--yellow); color: var(--blue); font-family: var(--head); font-weight: 800; font-size: .72rem; padding: .3rem .6rem; border-radius: 6px; letter-spacing: .03em; z-index: 2; }
.pestcard .btn { margin-top: auto; }
.fineprint { text-align: center; color: var(--muted); font-size: .92rem; margin-top: 2rem; }

/* Two-col content */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 3.5rem; align-items: center; }
.split + .split { margin-top: 4.5rem; }
.split--flip .split__media { order: 2; }
.split__img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; border-radius: 16px; }
.split__video { display: block; width: 100%; aspect-ratio: 16/10; object-fit: cover; border-radius: 20px; background: var(--blue-dk); }
.split h2 { margin-bottom: .6rem; }
.split ul { list-style: none; padding: 0; margin: 1.2rem 0 1.6rem; display: grid; gap: .7rem; }
.split ul li { display: flex; align-items: flex-start; gap: .6em; font-weight: 500; }
.split ul li .ico { color: var(--yellow-d); margin-top: .15em; flex: none; }
.section--blue .split ul li .ico { color: var(--yellow); }

/* Affordable excellence block */
.afford { display: grid; grid-template-columns: 1fr 1.05fr; gap: 3rem; align-items: center; position: relative; z-index: 1; }
.afford h2 { font-size: clamp(2.4rem, 5vw, 3.6rem); color: var(--yellow); line-height: .98; text-transform: uppercase; }
.afford__sub { font-family: var(--head); font-weight: 700; color: #fff; letter-spacing: .12em; text-transform: uppercase; font-size: .9rem; margin: .4rem 0 1.2rem; }
.afford p { color: #FDECDB; }
.misspills { display: grid; gap: .8rem; }
.misspill { display: flex; align-items: center; gap: 1rem; background: var(--blue-pill); border: 1px solid rgba(255,255,255,.14); border-radius: 999px; padding: .9rem 1.3rem; color: #fff; font-weight: 500; }
.misspill__tick { width: 30px; height: 30px; border-radius: 50%; background: var(--yellow); color: var(--blue); display: grid; place-items: center; flex: none; }
.misspill__tick .ico { width: 17px; height: 17px; stroke-width: 3; }

/* Pest chips */
.chips { display: flex; flex-wrap: wrap; gap: .6rem; justify-content: center; }
.chip { display: inline-flex; align-items: center; gap: .4em; background: #fff; border: 1px solid var(--line); border-radius: 999px; padding: .55rem 1.1rem; font-weight: 600; color: var(--blue); font-size: .92rem; transition: all .15s; }
.chip:hover { background: var(--yellow); border-color: var(--yellow); color: var(--blue); transform: translateY(-2px); }
.chip .ico { width: 1.1em; height: 1.1em; color: var(--yellow-d); }
.chip:hover .ico { color: var(--blue); }

/* Pest picker tiles */
.pestpick { display: grid; grid-template-columns: repeat(8, 1fr); gap: .9rem; }
.pesttile { display: flex; flex-direction: column; align-items: center; gap: .7rem; background: #fff; border: 2px solid var(--line); border-radius: 16px; padding: 1.4rem .6rem; text-align: center; transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease, background .16s ease; }
.pesttile:hover { border-color: var(--yellow); background: var(--yellow-soft); transform: translateY(-4px); box-shadow: var(--shadow); }
.pesttile__ico { width: 58px; height: 58px; display: grid; place-items: center; color: var(--blue); }
.pesttile__ico .ico { width: 44px; height: 44px; stroke-width: 1.7; }
.pesttile__name { font-family: var(--head); font-weight: 700; color: var(--ink); font-size: .86rem; }

/* Booking page chips */
.bookchips { display: flex; flex-wrap: wrap; justify-content: center; gap: .7rem; margin-top: 1.7rem; }
.bookchip { display: inline-flex; align-items: center; gap: .5em; background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.2); color: #fff; font-family: var(--head); font-weight: 600; padding: .65rem 1.15rem; border-radius: 999px; font-size: .95rem; }
.bookchip .ico { color: var(--yellow); width: 1.15em; height: 1.15em; }

/* Steps */
.steps .step { position: relative; background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 2rem 1.6rem; transition: transform .2s ease, box-shadow .2s ease; }
.steps .step:hover { transform: translateY(-6px); box-shadow: var(--shadow); }
.step__num { display: grid; place-items: center; width: 52px; height: 52px; border-radius: 14px; background: var(--yellow); color: var(--blue); font-family: var(--head); font-weight: 800; font-size: 1.5rem; margin-bottom: 1rem; }
.step h3 { margin-bottom: .3rem; }
.step p { color: var(--muted); margin: 0; }
.how__cta { text-align: center; margin-top: 2.8rem; }

/* Logo strips */
.logos { display: flex; flex-wrap: wrap; gap: 1rem; justify-content: center; align-items: center; }
.logos__item { width: 140px; height: 76px; background: #fff; border: 1px solid var(--line); border-radius: 12px; display: grid; place-items: center; color: var(--muted); font-family: var(--head); font-weight: 700; font-size: .8rem; text-align: center; padding: .5rem; }
.section--blue .logos__item, .section--navy .logos__item { background: #fff; border: none; }

/* Testimonials */
.tcard { background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 2rem; box-shadow: var(--shadow); }
.tcard__stars { display: inline-flex; gap: 2px; color: var(--yellow); margin-bottom: .8rem; }
.tcard__stars .ico { fill: var(--yellow); stroke: var(--yellow); width: 1.2em; height: 1.2em; }
.tcard p { color: var(--ink); font-size: 1.02rem; }
.tcard__by { display: flex; align-items: center; gap: .7rem; margin-top: 1.2rem; }
.tcard__avatar { width: 44px; height: 44px; border-radius: 50%; background: var(--blue); color: var(--yellow); display: grid; place-items: center; font-family: var(--head); font-weight: 800; }
.tcard__name { font-family: var(--head); font-weight: 700; color: var(--ink); }
.tcard__loc { color: var(--muted); font-size: .85rem; }

/* FAQ block (two-column, shared accordion style) */
.faqblock { display: grid; grid-template-columns: .8fr 1.2fr; gap: 2.8rem; align-items: start; }
.faqblock__intro { position: sticky; top: 92px; }
.faqblock__intro h2 { margin-bottom: .6rem; }
.faqblock__intro p { color: var(--muted); font-size: 1.06rem; margin-bottom: 1.6rem; }
.faqblock__cta { display: flex; flex-wrap: wrap; gap: .7rem; }
.faqlist { display: flex; flex-direction: column; gap: .85rem; }

/* FAQ */
.faq { background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 1.1rem 1.4rem; margin-bottom: .8rem; }
.faq[open] { box-shadow: var(--shadow); }
.faq summary { font-family: var(--head); font-weight: 700; color: var(--ink); cursor: pointer; list-style: none; display: flex; justify-content: space-between; align-items: center; gap: 1rem; font-size: 1.05rem; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-size: 1.6rem; color: var(--yellow-d); }
.faq[open] summary::after { content: "−"; }
.faq p { margin: .8rem 0 .2rem; color: var(--muted); }

/* CTA band — ON BRAND BLUE. Pearce, 01/10/2026: "the blacks back."
   This was the last charcoal-to-black panel on the interior pages. Same
   structure, same orange glow in the corner, brand blue underneath. */
.ctaband { position: relative; overflow: hidden; border-radius: 16px; padding: 2.4rem 2.2rem; text-align: center; box-shadow: var(--shadow-lg);
  background: radial-gradient(520px 260px at 86% 0%, rgba(255,153,51,.20), transparent 60%), var(--grad-blue-deep); }
.ctaband::before { content: ""; position: absolute; top: 0; right: 0; width: 48%; height: 82%; pointer-events: none; z-index: 0;
  background-image: radial-gradient(rgba(255,153,51,.5) 1.7px, transparent 2.3px); background-size: 15px 15px;
  -webkit-mask-image: linear-gradient(225deg, #000 0%, transparent 62%); mask-image: linear-gradient(225deg, #000 0%, transparent 62%); opacity: .18; }
.ctaband > * { position: relative; z-index: 1; }
.ctaband .splatdeco { position: absolute; opacity: .85; }
.ctaband .splatdeco--1 { top: -28px; right: -18px; width: 96px; height: 96px; }
.ctaband .splatdeco--2 { bottom: -30px; left: -16px; width: 84px; height: 84px; }
.ctaband h2 { color: #fff; font-size: clamp(1.55rem, 2.8vw, 2.1rem); margin-bottom: .5rem; }
.ctaband h2 .hl { color: var(--yellow); }
.ctaband p { color: #F0E0CF; max-width: 520px; margin: 0 auto 1.4rem; font-size: 1.02rem; }
/* THE BUTTONS GO UNDER THE MIDDLE OF THE SENTENCE THEY BELONG TO.
   Pearce, 11/10/2026: "centure the secont pictue, the need to be moved to the
   right." The band is text-align:center, but .hero__cta is a flex row and a
   flex row ignores text-align — so the heading and the lead sat centred with
   the buttons hard against the left edge. The suburb pages had already been
   patched with an inline justify-content; this does it once, everywhere a CTA
   band appears, and the inline patch comes out. */
.ctaband .hero__cta { justify-content: center; }

/* ===== Assurance / trust cards ===== */
.assure { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.2rem; }
.acard { background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 1.9rem 1.6rem; transition: transform .18s ease, box-shadow .18s ease; }
.acard:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.acard__ico { width: 52px; height: 52px; border-radius: 14px; background: var(--cream2); color: var(--blue); display: grid; place-items: center; margin-bottom: 1.1rem; }
.acard__ico .ico { width: 26px; height: 26px; }
.acard h3 { margin-bottom: .35rem; }
.acard p { color: var(--muted); margin: 0; font-size: .95rem; }

/* ===== Stat / credentials band ===== */
/* THE STAT BAND, KAPOW-STYLE. Pearce, 02/10/2026, sending Kapow's strip:
   "put this on BFYB homepage too, i like it and this also applies."
   Three changes to match what he liked about it: the numbers are much bigger,
   each one carries its own colour instead of four identical orange figures,
   and the whole band moved up to sit directly under the hero — on Kapow it is
   the first thing after the fold, which is the point of it.
   The box, border and dividing rules are gone: Kapow's reads as numbers
   floating on the band, and the frame was doing nothing but shrinking them. */
.statband { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.2rem; padding: .6rem 0; }
.statband__item { text-align: center; padding: .4rem .6rem; }
.statband__num { display: block; font-family: var(--head); font-weight: 800;
  font-size: clamp(2.4rem, 5vw, 3.6rem); line-height: 1; letter-spacing: -.02em; color: var(--yellow); }
/* Each figure its own colour, all four sampled from the brand — orange, the
   uniform blue opened up for a dark ground, white, orange again. Never a
   colour that is not on the truck. */
.statband__item:nth-child(2) .statband__num { color: #7FC4F5; }
.statband__item:nth-child(3) .statband__num { color: #fff; }
.statband__item:nth-child(4) .statband__num { color: var(--yellow); }
.statband__txt { display: block; margin-top: .55rem; color: rgba(255,255,255,.88);
  font-size: .95rem; font-weight: 700; line-height: 1.3; }
@media (max-width: 680px) { .statband { grid-template-columns: repeat(2, 1fr); gap: 1.6rem .8rem; } }
.statband__note { margin: .9rem 0 0; text-align: center; color: rgba(255,255,255,.52); font-size: .78rem; font-weight: 500; }

/* ===== Mobile sticky book bar ===== */
.bookbar { display: none; }

/* ===== Splat decorations (reusable, section-level) ===== */
.splatdeco--sm { width: 70px; height: 70px; }
.splatdeco--md { width: 110px; height: 110px; }
.splatdeco--lg { width: 170px; height: 170px; }
.splatdeco--tl { top: -28px; left: -28px; }
.splatdeco--tr { top: -30px; right: 3%; }
.splatdeco--br { bottom: -34px; right: 4%; }
.splatdeco--bl { bottom: -36px; left: 2%; }
.splatdeco--soft { opacity: .14; }
.splatdeco--g .ico { fill: var(--grass); }
.section { position: relative; }
.section--cream, .section--blue { overflow: hidden; }

/* ===== Split media (splat-masked photo) ===== */
.split__media { position: relative; z-index: 1; filter: drop-shadow(0 16px 26px rgba(0,0,0,.26)); }

/* ===== Price block (interactive price list) ===== */
.priceblock__grid { display: grid; grid-template-columns: .85fr 1.15fr; gap: 2.6rem; align-items: start; }
.priceblock__intro { position: sticky; top: 92px; background: var(--grad-blue-deep); color: #fff; border-radius: var(--radius-lg); padding: 2.5rem 2.2rem; overflow: hidden; box-shadow: var(--shadow); }
.priceblock__intro h2 { color: #fff; margin-bottom: .6rem; }
.priceblock__intro h2 .hl { color: var(--yellow); }
.priceblock__intro p { color: #F0E0CF; margin: 0; }
.priceblock__points { list-style: none; padding: 0; margin: 1.3rem 0 1.7rem; display: grid; gap: .65rem; }
.priceblock__points li { display: flex; align-items: center; gap: .6em; font-weight: 500; font-size: .96rem; }
.priceblock__points .ico { color: var(--yellow); width: 1.1em; height: 1.1em; flex: none; }
.priceblock__intro .splatdeco { position: absolute; z-index: 0; }
.priceblock__intro > * { position: relative; z-index: 1; }

.pricelist { display: flex; flex-direction: column; gap: .85rem; }
.pricerow { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; transition: box-shadow .2s ease, border-color .2s ease, transform .18s ease; }
.pricerow:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.pricerow[open] { box-shadow: var(--shadow); border-color: var(--cream2); }
.pricerow > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 1rem; padding: 1.15rem 1.3rem; }
.pricerow > summary::-webkit-details-marker { display: none; }
.pricerow__ico { width: 46px; height: 46px; border-radius: 12px; background: var(--cream2); color: var(--blue); display: grid; place-items: center; flex: none; transition: background .2s ease, color .2s ease; }
.pricerow__ico .ico { width: 24px; height: 24px; }
.pricerow[open] .pricerow__ico { background: var(--blue); color: var(--yellow); }
.pricerow__head { flex: 1; min-width: 0; }
.pricerow__name { font-family: var(--head); font-weight: 700; color: var(--ink); font-size: 1.08rem; display: block; line-height: 1.2; }
.pricerow__tag { color: var(--muted); font-size: .85rem; display: block; }
.pricerow__price { font-family: var(--head); font-weight: 800; color: var(--blue); font-size: 1.2rem; white-space: nowrap; line-height: 1; }
.pricerow__price span { display: block; font-size: .62rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); text-align: right; margin-bottom: .2rem; }
/* "from" is a <small>, not the <span> above, so it was picking up no rule at
   all and rendering as "from$289". Pearce, 01/10/2026. */
.pricerow__price small { font-size: .64rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); margin-right: .45em; }
.pricerow__toggle { width: 30px; height: 30px; border-radius: 50%; border: 2px solid var(--line); color: var(--blue); flex: none; position: relative; transition: all .2s ease; }
.pricerow__toggle::before, .pricerow__toggle::after { content: ""; position: absolute; top: 50%; left: 50%; background: currentColor; border-radius: 2px; transform: translate(-50%, -50%); }
.pricerow__toggle::before { width: 12px; height: 2px; }
.pricerow__toggle::after { width: 2px; height: 12px; transition: transform .2s ease; }
.pricerow[open] .pricerow__toggle { background: var(--yellow); border-color: var(--yellow); color: var(--blue); }
.pricerow[open] .pricerow__toggle::after { transform: translate(-50%, -50%) scaleY(0); }
.pricerow__body { padding: 0 1.3rem 1.4rem; }
.pricerow__body p { color: var(--body); margin: 0 0 1rem; }
.pricerow__incl { list-style: none; padding: 0; margin: 0 0 1.3rem; display: grid; gap: .5rem; }
.pricerow__incl li { display: flex; align-items: center; gap: .55em; color: var(--ink); font-size: .93rem; font-weight: 500; }
.pricerow__incl .ico { color: var(--grass); width: 1.1em; height: 1.1em; flex: none; stroke-width: 2.4; }

/* ===== How it works + Why (side by side) ===== */
.howwhy { display: grid; grid-template-columns: 1fr 1fr; gap: 0; }
.howwhy__col:first-child { padding-right: 3.2rem; }
.howwhy__col:last-child { padding-left: 3.2rem; border-left: 1px solid rgba(255,255,255,.15); }
.howwhy__col h2 { color: #fff; margin-bottom: .6rem; }
.howwhy__col > p { color: #F0E0CF; margin: 0; }
.howwhy__photo { margin-bottom: 1.6rem; }
.howwhy__photo img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; border-radius: 16px; box-shadow: 0 16px 30px rgba(0,0,0,.20); }
.flowv { list-style: none; padding: 0; margin: 1.5rem 0 0; display: grid; gap: 1.2rem; }
.flowv__step { display: flex; gap: 1rem; align-items: flex-start; }
.flowv__num { width: 42px; height: 42px; border-radius: 50%; background: var(--yellow); color: var(--blue); font-family: var(--head); font-weight: 800; font-size: 1.15rem; display: grid; place-items: center; flex: none; box-shadow: 0 8px 16px rgba(255,153,51,.32); }
.flowv__step h3 { color: #fff; margin: 0 0 .15rem; font-size: 1.06rem; }
.flowv__step p { color: #E8D5C3; margin: 0; font-size: .92rem; }
.checklist { list-style: none; padding: 0; margin: 1.5rem 0 0; display: grid; gap: .75rem; }
/* SIX INVISIBLE BULLET POINTS ON THE HOME PAGE.
   This was hard-coded white, which is right inside the .section--blue "Why
   BFYB" panel on the four interior pages — and wrong on the home page, where
   the same list sits in a plain white section. The text was in the HTML the
   whole time; it was white on white. Pearce spotted it on 01/10/2026: six ticks
   and nothing beside them.
   Default is now body ink, and white is applied only where the ground is dark. */
.checklist li { display: flex; align-items: flex-start; gap: .6em; color: var(--body); font-weight: 500; }
.section--blue .checklist li, .heatband .checklist li, .prevacbuy .checklist li { color: rgba(255,255,255,.92); }
.checklist li b { color: var(--ink); }
.section--blue .checklist li b { color: #fff; }
.checklist li .ico { color: var(--yellow); margin-top: .2em; flex: none; }

/* ===== Reviews rating summary ===== */
.revsum { display: flex; align-items: center; justify-content: center; gap: 1.4rem; flex-wrap: wrap; background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow); padding: 1.3rem 1.8rem; max-width: 620px; margin: 0 auto 2.6rem; }
.revsum__score { font-family: var(--head); font-weight: 800; font-size: 3rem; color: var(--ink); line-height: 1; }
.revsum__stars { display: inline-flex; gap: 2px; }
.revsum__stars .ico { width: 1.25em; height: 1.25em; fill: var(--yellow); stroke: var(--yellow); }
.revsum__meta { color: var(--muted); font-size: .92rem; }
.revsum__meta b { color: var(--ink); font-family: var(--head); }
.revsum__div { width: 1px; align-self: stretch; background: var(--line); }
.revsum__google { display: inline-flex; align-items: center; gap: .45em; font-family: var(--head); font-weight: 700; color: var(--ink); }
.revsum__google .ico { width: 1.3em; height: 1.3em; }

/* ===== Footer ===== */
.footer { background: var(--grad-blue-deep); color: #F0D4B9; }
.footer__top { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 2rem; padding: 3.5rem 24px; }
.footer__brand p { max-width: 24rem; margin-top: 1rem; }
.footer__col h4 { color: #fff; font-size: .95rem; margin-bottom: 1rem; text-transform: uppercase; letter-spacing: .06em; }
.footer__col a, .footer__col span { display: block; color: #F0D4B9; margin-bottom: .5rem; font-size: .9rem; }
.footer__col a:hover { color: var(--yellow); }
.footer__contact { display: flex; align-items: center; gap: .5em; }
.footer__contact .ico { color: var(--yellow); width: 1em; height: 1em; }
.footer__base { border-top: 1px solid rgba(255,255,255,.12); font-size: .85rem; padding: 1.2rem 0; color: #D6AD84; text-align: center; }
/* The Terms link had no colour of its own, so it inherited the global
   link colour — which is set for light grounds. On a dark footer that is
   dark-on-dark and all but invisible, and it was invisible on the old
   black footer too. The one link in the legal line should be readable. */
.footer__base a { color: var(--yellow); text-decoration: underline; text-underline-offset: 2px; }
.footer__base a:hover { color: #fff; }

/* ===== Booking widget (themed) ===== */
.booking { background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); overflow: hidden; max-width: 960px; margin: 0 auto; }
.booking__noscript { padding: 2rem; text-align: center; }
.bk-steps { display: flex; background: var(--cream); border-bottom: 1px solid var(--line); }
.bk-step { flex: 1; display: flex; align-items: center; justify-content: center; gap: .45em; padding: 1rem .5rem; font-family: var(--head); font-weight: 700; font-size: .82rem; color: var(--muted); }
.bk-step__dot { display: inline-grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: #EAD8C7; color: #fff; font-size: .85rem; transition: background .2s ease, transform .2s ease; }
.bk-step__dot .ico { width: 14px; height: 14px; stroke-width: 3; }
.bk-step.is-active { color: var(--blue); }
.bk-step.is-active .bk-step__dot { background: var(--yellow); color: var(--blue); transform: scale(1.1); }
.bk-step.is-done { color: var(--blue); }
.bk-step.is-done .bk-step__dot { background: var(--blue); }
.bk-body { padding: 2.2rem; }
.bk-pane h3 { font-size: 1.5rem; margin-bottom: .3rem; }
.bk-pane__sub { color: var(--muted); margin-bottom: 1.5rem; }
.bk-info { display: flex; gap: .6em; align-items: flex-start; background: var(--green-s, #e9f8ef); border: 1px solid #cdeccf; border-radius: 12px; padding: .85rem 1rem; margin: 0 0 1.5rem; font-size: .93rem; color: var(--ink); line-height: 1.5; }
.bk-info .ico { color: #16a34a; flex: none; width: 1.2em; height: 1.2em; margin-top: .12em; }
/* Bundle upsell card — brand purple band with lime accents, sized to pop */
.bk-upsell { position: relative; overflow: hidden; display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap; background: linear-gradient(115deg, #0C73BD 0%, #054E85 55%, #02233C 100%); border: none; border-radius: 16px; padding: 1.2rem 1.3rem; margin: 0 0 1.2rem; box-shadow: 0 8px 22px rgba(0,0,0, .28); }
.bk-upsell::after { content: ""; position: absolute; top: -30%; right: -6%; width: 46%; height: 160%; pointer-events: none; background-image: radial-gradient(rgba(255,153,51,.5) 2px, transparent 2.6px); background-size: 15px 15px; -webkit-mask-image: linear-gradient(245deg, #000 0%, transparent 60%); mask-image: linear-gradient(245deg, #000 0%, transparent 60%); opacity: .3; }
.bk-upsell__body { flex: 1 1 280px; position: relative; z-index: 1; }
.bk-upsell__tag { display: inline-flex; align-items: center; gap: .38em; background: #FF9933; color: #0a0a0a; font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; border-radius: 999px; padding: .3rem .75rem; margin-bottom: .5rem; }
.bk-upsell__tag .ico { width: 1em; height: 1em; }
.bk-upsell__body > b { display: block; color: #fff; font-size: 1.12rem; line-height: 1.3; margin-bottom: .3rem; font-family: 'Baloo 2', 'Plus Jakarta Sans', sans-serif; }
.bk-upsell__body p { margin: 0; font-size: .9rem; line-height: 1.55; color: rgba(255,255,255,.82); }
.bk-upsell__body p b { color: #FF9933; }
.bk-upsell > button { position: relative; z-index: 1; flex: none; background: #FF9933; color: #0a0a0a; border: none; border-radius: 13px; font-weight: 800; font-size: 1rem; padding: .95rem 1.35rem; cursor: pointer; display: inline-flex; align-items: center; gap: .5em; box-shadow: 0 4px 0 rgba(0,0,0,.35); transition: transform .12s, box-shadow .12s; }
.bk-upsell > button:hover { transform: translateY(-2px); box-shadow: 0 6px 0 rgba(0,0,0,.35); }
/* Phones: upsell buttons (bundle, half-price, extended warranty) go full-width
   and centred — intrinsic-width lime buttons were poking out of the card. */
@media (max-width: 640px) {
  .bk-upsell > button { width: 100%; justify-content: center; box-sizing: border-box; white-space: normal; font-size: .95rem; padding: .85rem 1rem; }
}
.bk-upsell > button .ico { width: 1.05em; height: 1.05em; }

/* Collapsible "What's included" per service */
.bk-incl { border: 2px solid rgba(20,20,20, .3); border-radius: 12px; margin: 0 0 1.1rem; background: #fff; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0, .07); }
.bk-incl summary { display: flex; align-items: center; gap: .65em; padding: .9rem 1rem; cursor: pointer; font-weight: 800; color: var(--deep, #0a0a0a); font-size: 1rem; list-style: none; user-select: none; background: #FCF6F1; transition: background .15s; }
.bk-incl summary:hover { background: #FAF0E6; }
.bk-incl summary::-webkit-details-marker { display: none; }
.bk-incl summary .ico { background: #FF9933; color: #0a0a0a; border-radius: 50%; padding: .28em; width: 1.65em; height: 1.65em; flex: none; box-sizing: border-box; }
.bk-incl__hint { margin-left: auto; font-weight: 600; font-size: .8rem; color: #B35C00; }
.bk-incl__chev { width: .55em; height: .55em; border-right: 2.5px solid #B35C00; border-bottom: 2.5px solid #B35C00; transform: rotate(45deg); transition: transform .18s; flex: none; margin-left: .5em; margin-top: -.25em; }
.bk-incl[open] .bk-incl__chev { transform: rotate(-135deg); margin-top: .25em; }
.bk-incl[open] summary { border-bottom: 1px solid var(--line, #EFE8E2); }
.bk-incl__body { padding: .85rem 1rem .95rem; font-size: .9rem; line-height: 1.55; color: var(--ink, #211F1D); }
.bk-incl__body > p { margin: .1rem 0 .7rem; }
.bk-incl__body ul { list-style: none; margin: 0 0 .7rem; padding: 0; display: grid; gap: .45rem; }
.bk-incl__body li { display: flex; gap: .55em; align-items: flex-start; }
.bk-incl__body li .ico { color: #16a34a; flex: none; width: 1.05em; height: 1.05em; margin-top: .16em; }
.bk-incl__best { margin: 0; color: var(--mute, #6b6580); font-size: .87rem; }
.bk-incl__best b { color: var(--deep, #0a0a0a); }
.bk-incl--addon { border-color: rgba(101, 163, 13, .55); animation: bkAddonIn .25s ease; }
.bk-incl--addon summary { background: #FBF0E4; }
.bk-incl--addon summary:hover { background: #F7E5D3; }
.bk-incl--addon summary .ico { background: #A3580D; color: #fff; }
@keyframes bkAddonIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.bk-locked { display: flex; align-items: center; gap: .55rem; border: 2px solid var(--blue); background: #FCF5EE; border-radius: 12px; padding: .8rem 1rem; margin: 0 0 1rem; font-family: var(--head); font-weight: 700; color: var(--ink); }
.bk-locked .ico { color: var(--blue); flex: none; width: 1.15em; height: 1.15em; }
.bk-locked strong { margin-left: .35em; color: var(--blue); }
.bk-locked em { margin-left: auto; font-style: normal; font-size: .68rem; text-transform: uppercase; letter-spacing: .07em; background: var(--blue); color: #fff; padding: .25em .65em; border-radius: 999px; }
.bk-services { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.bk-choice { text-align: left; background: #fff; border: 2px solid var(--line); border-radius: var(--radius); padding: 0; overflow: hidden; cursor: pointer; transition: border-color .15s, box-shadow .15s, transform .15s; display: flex; gap: 0; align-items: stretch; }
.bk-choice:hover { border-color: var(--yellow); box-shadow: var(--shadow); transform: translateY(-2px); }
.bk-choice.is-selected { border-color: var(--yellow); box-shadow: var(--ring); }
.bk-choice .ibadge { width: 48px; height: 48px; border-radius: 12px; flex: none; }
.bk-choice .ibadge .ico { width: 24px; height: 24px; }
.bk-choice__main { display: flex; gap: .9rem; align-items: flex-start; padding: 1.05rem 1rem; flex: 1; min-width: 0; }
.bk-choice__body { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.bk-choice__name { font-family: var(--head); font-weight: 800; color: var(--ink); display: block; margin-bottom: .2rem; line-height: 1.25; }
.bk-choice__tag { color: var(--muted); font-size: .88rem; line-height: 1.4; }
.bk-choice__price { flex: 0 0 27%; min-width: 78px; background: linear-gradient(158deg, #D96908 0%, #054E85 100%); color: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: .5rem .4rem; gap: .04rem; font-family: var(--head); }
.bk-choice__price small { font-size: .6rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; opacity: .82; }
.bk-choice__price b { font-size: 1.2rem; font-weight: 800; line-height: 1.04; }
.bk-choice__pop { display: inline-flex; align-items: center; gap: .25em; background: var(--yellow); color: var(--blue); font-size: .64rem; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; padding: .14rem .5rem; border-radius: 999px; margin-left: .4rem; vertical-align: middle; }
.bk-choice__pop .ico { fill: var(--blue); stroke: var(--blue); }
/* Featured "Most Popular" service (General Pest), centred under a banner */
.bk-feature { max-width: 720px; margin: 0 auto 2rem; border: 2px solid var(--blue); border-radius: 18px; overflow: hidden; box-shadow: 0 12px 28px rgba(0,0,0,.16); }
.bk-feature__banner { display: flex; align-items: center; justify-content: center; gap: .45em; background: linear-gradient(95deg, var(--blue-bright) 0%, var(--blue) 52%, var(--blue-dk) 100%); color: #fff; font-family: var(--head); font-weight: 800; text-transform: uppercase; letter-spacing: .11em; font-size: .82rem; padding: .6rem 1rem; }
.bk-feature__banner .ico { width: 1.12em; height: 1.12em; fill: var(--yellow); stroke: var(--yellow); }
.bk-feature__row { display: grid; grid-template-columns: 1fr 1fr; gap: .75rem; padding: .75rem; }
.bk-feature__row .bk-choice { border-radius: 12px; }
.bk-choice--feature .bk-choice__main { padding: 1.05rem 1rem; }
.bk-choice--feature .bk-choice__name { font-size: 1rem; }
.bk-choice--feature .bk-choice__price b { font-size: 1.3rem; }
.bk-field { margin-bottom: 1.35rem; }
.bk-field > label { display: block; font-family: var(--head); font-weight: 700; color: var(--ink); margin-bottom: .55rem; }
.bk-hint { color: var(--muted); font-weight: 400; font-size: .88rem; }
.bk-options { display: flex; flex-wrap: wrap; gap: .55rem; }
.bk-pill { border: 2px solid var(--line); background: #fff; border-radius: 999px; padding: .58rem 1.05rem; font-weight: 700; font-family: var(--head); color: var(--body); cursor: pointer; transition: all .15s; }
.bk-pill:hover { border-color: var(--yellow); transform: translateY(-1px); }
.bk-pill.is-selected { background: var(--blue); border-color: var(--blue); color: #fff; }
.bk-checks { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: .6rem; }
.bk-check { display: flex; gap: .6rem; align-items: flex-start; border: 2px solid var(--line); border-radius: 12px; padding: .8rem 1rem; cursor: pointer; transition: border-color .15s, background .15s; }
.bk-check.is-selected { border-color: var(--yellow); background: var(--yellow-soft); }
.bk-check input { margin-top: .25rem; accent-color: var(--blue); }
.bk-input, .bk-textarea { width: 100%; border: 2px solid var(--line); border-radius: 12px; padding: .85rem 1rem; font: inherit; color: var(--ink); transition: border-color .15s, box-shadow .15s; background: #fff; }
.bk-input:focus, .bk-textarea:focus { outline: none; border-color: var(--yellow); box-shadow: var(--ring); }
.bk-input.is-error, .bk-textarea.is-error { border-color: var(--red); }
.bk-err { color: var(--red); font-size: .85rem; margin-top: .3rem; }
.bk-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.bk-quote { position: sticky; bottom: 0; display: flex; align-items: center; justify-content: space-between; gap: 1rem; background: var(--grad-blue); color: #fff; padding: 1.05rem 1.4rem; border-radius: 14px; margin-top: 1.7rem; box-shadow: 0 14px 30px rgba(0,0,0,.3); }
.bk-quote__label { font-size: .82rem; color: #F5DDC5; display: flex; align-items: center; gap: .4em; }
.bk-quote__label .ico { width: 1em; height: 1em; color: var(--yellow); }
.bk-quote__amount { font-family: var(--head); font-weight: 800; font-size: 2rem; line-height: 1; color: var(--yellow); }
.bk-quote__lines { font-size: .78rem; color: #EFD2B6; margin-top: .25rem; }
.bk-cal { display: grid; grid-template-columns: 240px 1fr; gap: 1.5rem; }
.bk-dates { max-height: 380px; overflow-y: auto; border: 1px solid var(--line); border-radius: 16px; padding: .5rem; }
.bk-date { display: flex; justify-content: space-between; align-items: center; width: 100%; text-align: left; background: #fff; border: none; border-radius: 11px; padding: .72rem .85rem; cursor: pointer; font: inherit; color: var(--ink); transition: background .15s; }
.bk-date:hover { background: var(--cream); }
.bk-date.is-selected { background: var(--blue); color: #fff; }
.bk-date.is-selected .bk-date__open { color: #FDE7D1; }
.bk-date__day { font-family: var(--head); font-weight: 700; }
.bk-date__open { font-size: .76rem; color: var(--blue); font-weight: 700; }
.bk-date.is-full { opacity: .42; cursor: not-allowed; }
.bk-date.is-full .bk-date__open { color: var(--muted); }
.bk-slots { display: grid; grid-template-columns: 1fr 1fr; gap: .7rem; align-content: start; }
.bk-slot { border: 2px solid var(--line); background: #fff; border-radius: 12px; padding: .95rem; font-family: var(--head); font-weight: 700; color: var(--ink); cursor: pointer; transition: all .15s; }
.bk-slot:hover:not(:disabled) { border-color: var(--yellow); transform: translateY(-2px); }
.bk-slot.is-selected { background: var(--yellow); border-color: var(--yellow); color: var(--blue); }
.bk-slot:disabled { opacity: .35; cursor: not-allowed; text-decoration: line-through; }
.bk-slots__empty { color: var(--muted); grid-column: 1/-1; padding: 1.5rem; text-align: center; }
.bk-foot { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin-top: 1.9rem; }
.bk-back { background: none; border: none; color: var(--muted); font-family: var(--head); font-weight: 700; cursor: pointer; padding: .8rem; }
.bk-back:hover { color: var(--ink); }
.bk-foot .btn--accent { background: var(--yellow); color: var(--ink); } /* was --blue on orange: 2.8:1 */
.bk-foot .btn--accent:hover { background: var(--yellow-d); }
.bk-review { display: grid; gap: .6rem; background: var(--cream); border-radius: 16px; padding: 1.3rem 1.5rem; margin-bottom: 1.2rem; }
.bk-review__row { display: flex; justify-content: space-between; gap: 1rem; }
.bk-review__row span:first-child { color: var(--muted); }
.bk-review__row span:last-child { font-weight: 700; color: var(--ink); text-align: right; }
.bk-review__total { border-top: 1px dashed #EAD8C7; padding-top: .75rem; margin-top: .4rem; }
.bk-review__total span:last-child { color: var(--blue); font-family: var(--head); font-weight: 800; font-size: 1.4rem; }
.bk-success { text-align: center; padding: 1.2rem; }
.bk-success__tick { width: 88px; height: 88px; border-radius: 50%; background: var(--yellow); color: var(--blue); display: grid; place-items: center; margin: 0 auto 1.1rem; box-shadow: 0 16px 34px rgba(255,153,51,.45); animation: pop .5s cubic-bezier(.16,1.3,.5,1); }
.bk-success__tick .ico { width: 44px; height: 44px; stroke-width: 3; }
@keyframes pop { 0% { transform: scale(0); } 100% { transform: scale(1); } }
.bk-success__ref { display: inline-block; background: var(--cream2); color: var(--blue); font-family: var(--head); font-weight: 800; letter-spacing: .05em; padding: .55rem 1.1rem; border-radius: 11px; margin: .6rem 0 1.3rem; }
.bk-loading, .bk-error-msg { padding: 3rem; text-align: center; color: var(--muted); }
.bk-spinner { width: 40px; height: 40px; border: 4px solid var(--line); border-top-color: var(--yellow); border-radius: 50%; margin: 0 auto 1rem; animation: spin 1s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.is-hidden { display: none !important; }

/* ===== Responsive ===== */
@media (max-width: 1024px) {
  .navbar { display: none; }
  .topbadge { display: none; }
}
@media (max-width: 980px) {
  .hero__inner { grid-template-columns: 1fr; padding-top: 3rem; }
  .grid--4 { grid-template-columns: 1fr 1fr; }
  .grid--3 { grid-template-columns: 1fr; }
  .split, .split--flip .split__media, .afford { grid-template-columns: 1fr; }
  .split--flip .split__media { order: -1; }
  .bk-cal { grid-template-columns: 1fr; }
  .bk-dates { max-height: 210px; }
  .footer__top { grid-template-columns: 1fr 1fr; }
  .pestpick { grid-template-columns: repeat(4, 1fr); }
  .eco-bar { flex-direction: column; align-items: flex-start; }
  .eco-bar__pills { margin-left: 0; }
  .assure { grid-template-columns: 1fr 1fr; }
  .statband { grid-template-columns: 1fr 1fr; gap: 1.6rem 1rem; }
  .statband__item:nth-child(odd)::before { display: none; }
  .priceblock__grid { grid-template-columns: 1fr; gap: 1.6rem; }
  .priceblock__intro { position: static; }
  .howwhy { grid-template-columns: 1fr; gap: 2.6rem; }
  .howwhy__col:first-child { padding-right: 0; }
  .howwhy__col:last-child { padding-left: 0; border-left: none; }
  .faqblock { grid-template-columns: 1fr; gap: 1.6rem; }
  .faqblock__intro { position: static; }
}
@media (max-width: 560px) {
  .grid--4, .grid--2, .bk-services, .bk-checks, .bk-slots, .bk-row, .bk-feature__row { grid-template-columns: 1fr; }
  .footer__top { grid-template-columns: 1fr; }
  .pestpick { grid-template-columns: repeat(2, 1fr); }
  .assure { grid-template-columns: 1fr; }
  .revsum { gap: 1rem; padding: 1.1rem 1.2rem; }
  .revsum__div { display: none; }
  .bk-step__label { display: none; }
  .bk-body { padding: 1.4rem; }
  .hero__cta { flex-direction: column; }
  .hero__cta .btn { width: 100%; }
  .ctaband { padding: 2rem 1.4rem; }
  .header__phone span { display: none; }
  /* Sticky instant-book bar on phones */
  .bookbar { display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 60; gap: .6rem; padding: .6rem .8rem calc(.6rem + env(safe-area-inset-bottom)); background: rgba(0,0,0,.97); backdrop-filter: blur(6px); border-top: 1px solid rgba(255,255,255,.12); }
  .bookbar .btn { flex: 1; padding: .85rem 1rem; }
  .bookbar__call { flex: none; width: 52px; padding: 0; }
  body { padding-bottom: 72px; }
}

/* ===== SEO blocks: internal-link clouds, quick-answer callout, local context ===== */
.linkcloud{display:flex;flex-wrap:wrap;gap:.55rem;margin-top:1rem}
.linkcloud a{display:inline-block;padding:.5rem .95rem;border-radius:999px;border:1.5px solid rgba(0,0,0,.16);
  background:#fff;color:#0a0a0a;text-decoration:none;font-weight:600;font-size:.92rem;transition:border-color .15s,color .15s}
.linkcloud a:hover{border-color:#B35C00;color:#B35C00}
.linkcloud a.is-strong{background:var(--deep);color:#fff;border-color:var(--deep)}
.linkcloud a.is-strong:hover{background:#B35C00;border-color:#B35C00;color:#fff}
.linksub-h{margin:1.8rem 0 .2rem;font-size:1.05rem;color:#0a0a0a;text-align:center}
.qa{background:#FEF6ED;border-left:4px solid #B35C00;border-radius:0 14px 14px 0;padding:1rem 1.25rem;
  margin:0 auto 1.4rem;max-width:760px;text-align:left;font-size:1.02rem;line-height:1.55}
.qa b{color:#0a0a0a}
.localfacts{display:flex;flex-wrap:wrap;gap:.6rem;justify-content:center;margin:1.2rem 0 .2rem;padding:0;list-style:none}
.localfacts li{display:inline-flex;align-items:center;gap:.4rem;background:#fff;border:1px solid rgba(0,0,0,.12);
  border-radius:999px;padding:.4rem .85rem;font-size:.9rem;font-weight:600;color:#0a0a0a}
.localfacts .ico{width:1.05em;height:1.05em}

/* Breadcrumbs + clickable pest cards (suburb pages).
   These sit inside the hero, which is orange now — white-on-orange was the
   one thing left on the band that couldn't be read. */
.crumbs{font-size:.85rem;color:rgba(20,20,20,.62);margin-bottom:.9rem}
.crumbs a{color:#141414;text-decoration:none;font-weight:600}
.crumbs a:hover{color:#ffffff}
.crumbs span{color:rgba(20,20,20,.45)}
.acard--link{text-decoration:none;color:inherit;display:block;transition:transform .15s,box-shadow .15s}
.acard--link:hover{transform:translateY(-3px);box-shadow:0 12px 30px rgba(0,0,0,.12)}
.acard--link h3{color:#0a0a0a}

/* Long-form guide articles */
.prose{max-width:760px;margin:0 auto;text-align:left}
.prose h2{margin-top:2.2rem}
.prose h3{margin-top:1.5rem}
.prose p,.prose li{font-size:1.04rem;line-height:1.72;color:#312E2C}
.prose ul,.prose ol{padding-left:1.2rem}
.prose li{margin:.35rem 0}
.prose a{color:#B35C00;font-weight:600}
.ptable{width:100%;border-collapse:collapse;margin:1.3rem 0;font-size:.98rem}
.ptable th,.ptable td{text-align:left;padding:.65rem .8rem;border-bottom:1px solid rgba(0,0,0,.12);vertical-align:top}
.ptable th{background:#FEF6ED;color:#0a0a0a}
.guidegrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:1.2rem;margin-top:1.4rem}
.guidecard{display:block;text-decoration:none;color:inherit;background:#fff;border:1px solid rgba(0,0,0,.1);
  border-radius:16px;padding:1.4rem;transition:transform .15s,box-shadow .15s}
.guidecard:hover{transform:translateY(-3px);box-shadow:0 12px 30px rgba(0,0,0,.12)}
.guidecard h3{color:#0a0a0a;margin:.2rem 0 .4rem}
.guidecard span{color:#B35C00;font-weight:700;font-size:.9rem}

/* Areas directory (region-grouped suburb lists — replaces pill clouds) */
/* Pearce, 11/10/2026: "can you center the info to the middle of the page."
   auto-fill laid five 200px tracks across the wrap and then filled only the
   first two, so a pair of groups hugged the left edge underneath a centred
   heading. These directory lists are ALWAYS two groups wide -- two service
   groups, two regions -- so they are a centred row, not a grid of mostly
   empty tracks. The columns themselves stay left-aligned; it is the block
   that centres. */
.arealist{display:flex;flex-wrap:wrap;justify-content:center;gap:1.8rem 3rem;margin-top:1.4rem;text-align:left}
.arealist__group{flex:0 1 230px;min-width:190px}
.arealist__group h3{font-size:.82rem;text-transform:uppercase;letter-spacing:.08em;color:#B35C00;margin:0 0 .7rem;padding-bottom:.45rem;border-bottom:1px solid rgba(0,0,0,.14)}
.arealist__group ul{list-style:none;margin:0;padding:0}
.arealist__group li{margin:.32rem 0}
.arealist__group a{color:#0a0a0a;text-decoration:none;font-weight:500;font-size:.98rem}
.arealist__group a:hover{color:#B35C00;text-decoration:underline}
.arealist--light .arealist__group h3{color:#FF9933;border-bottom-color:rgba(255,255,255,.18)}
.arealist--light .arealist__group a{color:#F7F0EA}
.arealist--light .arealist__group a:hover{color:#fff}
.areas-more{margin-top:2.2rem;text-align:center}

/* ===== Splat-backed feature items (replaces the generic icon-on-card grid) ===== */
.featgrid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2.6rem 1.9rem; }
.feat { position: relative; }
.feat__art { position: relative; width: 92px; height: 92px; margin-bottom: 1.15rem; display: grid; place-items: center; }
.feat__art::before { content: ""; position: absolute; inset: 0; background: var(--yellow);
  -webkit-mask: var(--splat-mask) center / contain no-repeat; mask: var(--splat-mask) center / contain no-repeat;
  filter: drop-shadow(0 10px 16px rgba(0,0,0,.18)); }
.feat__ico { position: relative; z-index: 1; width: 42px; height: 42px; fill: none; stroke: var(--blue-dk); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.feat h3 { margin-bottom: .35rem; font-size: 1.14rem; }
.feat p { color: var(--muted); margin: 0; font-size: .96rem; line-height: 1.55; }
/* alternate colours (clean) + organic angles (varied) so it reads hand-made, not templated */
.feat:nth-child(odd) .feat__art::before { background: var(--yellow); }
.feat:nth-child(even) .feat__art::before { background: var(--blue); }
.feat:nth-child(even) .feat__ico { stroke: var(--yellow); }
.feat:nth-child(4n+1) .feat__art::before { transform: rotate(-8deg); }
.feat:nth-child(4n+2) .feat__art::before { transform: rotate(7deg); }
.feat:nth-child(4n+3) .feat__art::before { transform: rotate(-4deg); }
.feat:nth-child(4n+4) .feat__art::before { transform: rotate(11deg); }
/* playful vertical stagger on wide screens */
/* The every-other-card drop was a rhythm trick for a full four-column row.
   Pearce, 01/10/2026: "why are there off centre?" — and he is right, because
   with an odd number of cards it does not read as rhythm, it reads as a card
   that has slipped. The splat shapes behind the icons already rotate at four
   different angles, so the row has plenty of movement without it. */
/* clickable variant (suburb "common pests") */
a.feat--link { display: block; text-decoration: none; color: inherit; }
a.feat--link h3 { color: var(--blue-dk); transition: color .15s ease; }
a.feat--link:hover h3 { color: var(--blue); }
a.feat--link .feat__art { transition: transform .25s ease; }
a.feat--link:hover .feat__art { transform: scale(1.07) rotate(-3deg); }
.feat__more { display: inline-flex; align-items: center; gap: .35em; margin-top: .55rem; color: var(--blue); font-family: var(--head); font-weight: 700; font-size: .9rem; }
.feat__more .ico { width: 1em; height: 1em; transition: transform .2s ease; }
a.feat--link:hover .feat__more .ico { transform: translateX(4px); }
@media (max-width: 880px) { .featgrid { grid-template-columns: 1fr 1fr; gap: 2.2rem 1.6rem; } }
@media (max-width: 540px) {
  .featgrid { grid-template-columns: 1fr; gap: 1.6rem; }
  .feat { display: grid; grid-template-columns: 64px 1fr; column-gap: 1.1rem; align-items: start; }
  .feat:nth-child(2n) { margin-top: 0; }
  .feat__art { width: 64px; height: 64px; margin-bottom: 0; }
  .feat__ico { width: 30px; height: 30px; }
  /* THE PARAGRAPH WAS SETTING ONE WORD PER LINE. Found 10/10/2026.
     This card is a flat list of children — icon, heading, paragraph (and on
     the suburb pages a "Learn more") — dropped into a two-column grid. Auto
     placement put the icon at 1/1, the heading at 1/2 and then wrapped the
     PARAGRAPH back to 2/1, the 64px icon column. "Hot water extraction that
     reaches the base of the pile" came out as fourteen lines of one word.
     Every one of these on the home page and the seven suburb pages, on every
     phone, since the card was given its side-by-side phone layout.
     Everything after the icon now belongs to the second column. */
  .feat > :not(.feat__art) { grid-column: 2; }
}

/* ===== Steps ("how we treat") — splat-backed numbers, no card boxes ===== */
.steps .step { background: none; border: none; padding: 0; }
.steps .step:hover { transform: none; box-shadow: none; }
.step__num { position: relative; z-index: 0; width: 74px; height: 74px; border-radius: 0; background: none;
  display: grid; place-items: center; font-family: var(--head); font-weight: 800; font-size: 1.9rem;
  color: var(--blue-dk); margin-bottom: 1rem; }
.step__num::before { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--yellow);
  -webkit-mask: var(--splat-mask) center / contain no-repeat; mask: var(--splat-mask) center / contain no-repeat;
  filter: drop-shadow(0 8px 14px rgba(0,0,0,.16)); }
.steps .step:nth-child(even) .step__num::before { background: var(--blue); }
.steps .step:nth-child(even) .step__num { color: var(--yellow); }
.steps .step:nth-child(4n+1) .step__num::before { transform: rotate(-7deg); }
.steps .step:nth-child(4n+2) .step__num::before { transform: rotate(8deg); }
.steps .step:nth-child(4n+3) .step__num::before { transform: rotate(-5deg); }
.steps .step:nth-child(4n+4) .step__num::before { transform: rotate(10deg); }
@media (min-width: 920px) { .steps .step:nth-child(even) { margin-top: 1.8rem; } }

/* ===== Homepage price-list icons — splat motif instead of faded-purple square ===== */
.pricerow__ico { position: relative; z-index: 0; width: 54px; height: 54px; border-radius: 0; background: none; color: var(--blue-dk); }
.pricerow__ico::before { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--yellow);
  -webkit-mask: var(--splat-mask) center / contain no-repeat; mask: var(--splat-mask) center / contain no-repeat;
  transform: rotate(-6deg); transition: transform .25s ease, background .2s ease; filter: drop-shadow(0 6px 12px rgba(0,0,0,.16)); }
.pricerow__ico .ico { position: relative; width: 27px; height: 27px; stroke-width: 2.5; }
.pricerow[open] .pricerow__ico { background: none; color: var(--yellow); }
.pricerow[open] .pricerow__ico::before { background: var(--blue); transform: rotate(7deg); }
.pricerow:hover .pricerow__ico::before { transform: rotate(2deg) scale(1.05); }

/* ===== Dark brand header + image logo ===== */
.header { background: var(--bar); border-bottom: 1px solid var(--bar-line); }
.header__inner { padding: .5rem 24px; }
/* The logo file is the white version, made for a dark bar. On orange it has
   almost no contrast, so it is knocked to solid black rather than swapped for
   a second file that would have to be kept in step. */
/* No filter any more — the header now uses a logo built for an orange ground
   (black B, white FYB, black tagline), so nothing has to be knocked to black.
   Bigger too: 46px was small for the one element that gets people home.
   THEN 40% SMALLER AGAIN. Pearce, 01/10/2026, sending a screenshot of the
   header: "BFYB make it 40% smaller." 62px -> 37px desktop, 52px -> 31px
   mobile. At 62 the mark was taller than the two stat blocks beside it and
   was setting the height of the whole orange band; at 37 the band tightens
   and the logo sits level with the rest of the row.
   AND 20% SMALLER AGAIN. Pearce, 01/10/2026: "make BFYB 20% smaller."
   37px -> 30px desktop, 31px -> 25px mobile.

   AND BACK UP, 04/10/2026. Pearce, on the header: "why have you changed
   this? it was bigger and said home — revert it back."
   Two rounds of shrinking took it to 30px, and the logo file is the full
   lockup: the BFYB mark with BANG FOR YA BUCK set underneath it. At 30px
   that wordmark is four pixels tall and reads as a smudge, so the header was
   carrying a logo nobody could actually read. 46px is where it sat before the
   October shrinking, and it is the smallest size the wordmark survives. */
.brand { flex-direction: column; align-items: flex-start; gap: .12rem; }
.brand__logo { height: 46px; width: auto; display: block; }
/* "Home" under the mark, so it reads as a way back and not just a badge.
   Dropped with the mark — .66rem under a 37px logo was competing with it. */
.brand__home { font-family: var(--head); font-weight: 800; font-size: .58rem;
  letter-spacing: .18em; text-transform: uppercase; color: #3d2607; opacity: .78;
  padding-left: .12rem; }
.brand:hover .brand__home { opacity: 1; }
.header__cta .btn--ghost { color: #141414; border-color: rgba(20,18,16,.38); background: rgba(255,255,255,.28); }
.header__cta .btn--ghost:hover { border-color: #141414; background: rgba(255,255,255,.6); }
.navtoggle span { background: #fff; }

/* ===== Mobile nav: hamburger -> right slide-in drawer ===== */
.navtoggle { display: none; flex-direction: column; justify-content: center; align-items: center; gap: 5px;
  width: 46px; height: 46px; padding: 9px; border: none; background: var(--yellow); border-radius: 12px;
  box-shadow: 0 3px 0 rgba(0,0,0, .55); cursor: pointer; flex: none; }
.navtoggle span { display: block; width: 28px; height: 3px; background: #fff; border-radius: 3px; transition: transform .25s ease, opacity .2s ease; }
.navtoggle.on span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.navtoggle.on span:nth-child(2) { opacity: 0; }
.navtoggle.on span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

.m-overlay { display: none; position: fixed; inset: 0; z-index: 90; background: rgba(20,0,40,.5);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); opacity: 0; visibility: hidden; pointer-events: none; transition: opacity .3s ease, visibility .3s ease; }
.m-overlay.show { opacity: 1; visibility: visible; pointer-events: auto; }

.m-drawer { display: none; position: fixed; top: 0; left: 0; right: 0; z-index: 95; width: 100%; max-height: 100dvh;
  flex-direction: column; background: linear-gradient(175deg, #35322F 0%, var(--blue-dk) 62%);
  box-shadow: 0 16px 50px rgba(0,0,0,.36); transform: translateY(-100%); transition: transform .32s cubic-bezier(.4,0,.2,1); }
.m-drawer.open { transform: translateY(0); }
.m-drawer__logo img { height: 40px; width: auto; display: block; }
.m-drawer__group { display: block; padding: 1.05rem 1.5rem .3rem; font-family: var(--head); font-weight: 800; font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--yellow); }
.m-drawer__links > .m-drawer__group:first-child { padding-top: .55rem; }
.m-drawer__head { display: flex; align-items: center; justify-content: space-between; padding: 1.05rem 1.4rem; border-bottom: 1px solid rgba(255,255,255,.14); }
.m-drawer__brand { font-family: "Baloo 2","Montserrat",sans-serif; font-weight: 800; font-size: 1.5rem; color: #fff; line-height: 1; }
.m-drawer__brand .o { color: var(--yellow); }
.m-drawer__brand small { display: block; font-size: .5rem; letter-spacing: .34em; color: var(--yellow); text-transform: uppercase; font-weight: 700; margin-top: .25em; }
.m-drawer__close { width: 42px; height: 42px; flex: none; border: none; background: rgba(255,255,255,.12); color: #fff; font-size: 1.7rem; line-height: 1; border-radius: 11px; cursor: pointer; }
.m-drawer__close:hover { background: rgba(255,255,255,.22); }
.m-drawer__links { display: flex; flex-direction: column; overflow-y: auto; flex: 1; padding: .4rem 0; }
.m-drawer__links a { display: flex; align-items: center; gap: .7em; padding: .7rem 1.5rem; font-family: var(--head); font-weight: 600; font-size: 1.02rem; color: rgba(255,255,255,.92); border-bottom: 1px solid rgba(255,255,255,.06); }
.m-drawer__links a:active, .m-drawer__links a:hover { background: rgba(255,255,255,.07); color: var(--yellow); }
.m-drawer__cta { padding: 1.1rem 1.4rem calc(1.4rem + env(safe-area-inset-bottom)); border-top: 1px solid rgba(255,255,255,.12); display: flex; flex-direction: column; gap: .7rem; }
.m-drawer__cta .mn-primary { background: var(--yellow); color: #0a0a0a; text-align: center; padding: 1rem; border-radius: 12px; font-family: var(--head); font-weight: 800; font-size: 1.05rem; }
.m-drawer__cta .mn-phone { display: flex; align-items: center; justify-content: center; gap: .45em; color: var(--yellow); font-family: var(--head); font-weight: 700; font-size: 1.05rem; }
.m-drawer__cta .mn-phone .ico { width: 1.05em; height: 1.05em; }

@media (max-width: 1024px) {
  .header .header__inner { padding: .95rem 22px; min-height: 76px; }
  .navtoggle { display: flex; margin-left: auto; }
  .m-drawer { display: flex; }
  .m-overlay { display: block; }
  .navbar { display: none; }
  .header__badges { display: none; }
  .header__cta { display: none; }
}
@media (max-width: 600px) {
  .header .header__inner { gap: .7rem; padding: 1rem 18px; min-height: 62px; }
  .brand__logo { height: 36px; }
  .logo__word { font-size: 2.1rem; }
  .section { padding: 3rem 0; }
  .wrap { padding: 0 18px; }
  .ptable { font-size: .82rem; }
  .ptable th, .ptable td { padding: .5rem .45rem; }
  .drawer { width: 100%; }
}

/* ===== Booking form — new elements for the full pricing engine ===== */
.bk-cat { font-family: var(--head); font-weight: 800; text-transform: uppercase; letter-spacing: .08em; font-size: .74rem; color: #B35C00; margin: 1.4rem 0 .6rem; }
.bk-cat:first-child { margin-top: 0; }
.bk-options--col { flex-direction: column; align-items: stretch; }
.bk-options--col .bk-pill { text-align: left; justify-content: space-between; display: flex; }
.bk-pill strong { color: #0a0a0a; font-weight: 800; margin-left: .6rem; }
.bk-pill.is-selected strong { color: var(--yellow); }
.bk-num { display: flex; align-items: center; gap: .8rem; }
.bk-num__btn { width: 44px; height: 44px; border-radius: 12px; border: 1.5px solid #F0E3D6; background: #fff; font-size: 1.4rem; font-weight: 700; color: #0a0a0a; cursor: pointer; line-height: 1; }
.bk-num__btn:hover { border-color: #B35C00; }
.bk-num__v { font-family: var(--head); font-weight: 800; font-size: 1.5rem; min-width: 2ch; text-align: center; color: #0a0a0a; }
.bk-num__hint { color: #7E6D5B; font-size: .9rem; }
.bk-note { display: flex; align-items: flex-start; gap: .6em; background: #FEF6ED; border: 1px solid #F7E4D2; border-radius: 12px; padding: .85rem 1rem; margin: 1rem 0; font-size: .94rem; color: #3B3734; }
.bk-note .ico { color: #B35C00; flex: none; margin-top: .1em; }
.bk-note a { color: #B35C00; font-weight: 700; }
.bk-note--ok { background: #eafbe9; border-color: #c7e8c2; }
.bk-note--ok .ico { color: #1f8a4c; }
.bk-note--warn { background: #fff4e2; border-color: #f3dcb4; }
.bk-note--warn .ico { color: #c98a00; }
.bk-slot__sur { display: inline-block; margin-left: .4em; font-size: .72rem; font-weight: 700; color: #c98a00; }
.bk-quote--q { background: #FEF6ED; }
.bk-quote--q .bk-quote__label { color: #B35C00; }

/* ===== Auth + client portal ===== */
.authwrap { max-width: 460px; margin: 0 auto; padding: 3rem 20px 4rem; min-height: 68vh; }
.authcard { background: #fff; border: 1px solid var(--line); border-radius: 18px; padding: 2rem 1.8rem; box-shadow: 0 10px 40px rgba(0,0,0,.07); }
.authcard__h { font-family: var(--head); font-size: 1.8rem; color: var(--blue-dk); margin: 0 0 .3rem; }
.authcard__sub { color: var(--muted); margin: 0 0 1.4rem; font-size: .95rem; }
.auth-tabs { display: flex; gap: .4rem; background: #FEF6ED; border-radius: 12px; padding: .3rem; margin-bottom: 1.3rem; }
.auth-tab { flex: 1; border: none; background: none; padding: .6rem; border-radius: 9px; font-weight: 700; color: #8D7C6B; cursor: pointer; font-family: var(--head); font-size: .95rem; }
.auth-tab.is-on { background: #fff; color: var(--blue-dk); box-shadow: 0 2px 8px rgba(0,0,0,.1); }
.auth-form { display: flex; flex-direction: column; gap: .9rem; }
.auth-field { display: flex; flex-direction: column; gap: .35rem; }
.auth-field span { font-size: .82rem; font-weight: 600; color: var(--blue-dk); }
.auth-alt { text-align: center; margin: 1.1rem 0 0; font-size: .9rem; color: var(--muted); }
.auth-alt a { color: #B35C00; font-weight: 700; }
.auth-note { background: #eafbe9; border: 1px solid #c7e8c2; color: #1f6b3a; border-radius: 10px; padding: .7rem .9rem; font-size: .9rem; margin-bottom: 1rem; }
.authwrap__foot { text-align: center; margin-top: 1.4rem; }
.authwrap__foot a { color: var(--muted); font-size: .9rem; }

.acctwrap { max-width: 840px; margin: 0 auto; padding: 2.4rem 20px 4rem; min-height: 60vh; }
.acct-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.4rem; }
.acct-head h1 { font-family: var(--head); font-size: 2rem; color: var(--blue-dk); margin: 0; }
.acct-head__act { display: flex; gap: .6rem; flex-wrap: wrap; }
.acct-cta { display: flex; justify-content: space-between; align-items: center; gap: 1rem; background: var(--grad-blue-deep); color: #fff; border-radius: 16px; padding: 1.2rem 1.4rem; margin-bottom: 1.4rem; flex-wrap: wrap; }
.acct-cta strong { display: block; font-family: var(--head); font-size: 1.1rem; }
.acct-cta span { color: #ECDFD2; font-size: .9rem; }
.acct-h2 { font-family: var(--head); color: var(--blue-dk); font-size: 1.2rem; margin: 1.6rem 0 .8rem; }
.acct-empty { padding: .2rem 0 1rem; }
.acct-list { display: grid; grid-template-columns: repeat(auto-fill,minmax(240px,1fr)); gap: 1rem; }
.acct-card { border: 1px solid var(--line); border-radius: 14px; padding: 1.1rem; background: #fff; }
.acct-card__top { display: flex; justify-content: space-between; align-items: flex-start; gap: .5rem; margin-bottom: .5rem; }
.acct-card__svc { font-weight: 800; font-family: var(--head); color: var(--blue-dk); line-height: 1.2; }
.acct-badge { font-size: .68rem; font-weight: 700; padding: .2rem .55rem; border-radius: 20px; white-space: nowrap; }
.acct-card__meta { color: var(--muted); font-size: .9rem; display: flex; align-items: center; gap: .35rem; margin-bottom: .8rem; }
.acct-card__meta .ico { width: 1em; height: 1em; flex: none; }
.acct-card__foot { display: flex; justify-content: space-between; align-items: center; border-top: 1px solid var(--line); padding-top: .7rem; }
.acct-card__price { font-weight: 700; color: var(--blue-dk); font-size: .92rem; }
.acct-rebook { color: #B35C00; font-weight: 700; font-size: .88rem; display: inline-flex; align-items: center; gap: .2em; }
.acct-rebook .ico { width: .9em; height: .9em; }
.acct-card__ref { font-size: .68rem; color: #C7B9AB; margin-top: .5rem; letter-spacing: .03em; }
.acctwrap .btn--ghost { background: transparent; color: var(--blue-dk); border: 1px solid var(--line); }
.nav__login { font-weight: 700; color: var(--blue-dk); display: inline-flex; align-items: center; gap: .3em; }

/* Discreet admin login link in the footer base */
.footer__admin { color: inherit; opacity: .5; text-decoration: underline; }
.footer__admin:hover { opacity: .95; }

/* ===================== Comic-book personality layer (v1) ===================== */
/* Sticker-style primary buttons: bold outline + hard offset shadow that
   presses into place on hover/click. */
.btn--accent, .btn--green { border-color: var(--blue-dk); box-shadow: 5px 5px 0 var(--blue-dk); }
.btn--accent:hover { transform: translate(2px, 2px); box-shadow: 3px 3px 0 var(--blue-dk); }
.btn--green:hover { transform: translate(2px, 2px); box-shadow: 3px 3px 0 var(--blue-dk); }
.btn--accent:active, .btn--green:active { transform: translate(5px, 5px); box-shadow: 0 0 0 var(--blue-dk); }

/* Comic-panel cards: chunky outline + hard offset shadow that pops on hover. */
.pestcard, .tcard { border: 2.5px solid var(--blue-dk); box-shadow: 6px 6px 0 var(--blue-dk); }
.pestcard:hover, .tcard:hover { transform: translate(-3px, -3px); box-shadow: 9px 9px 0 var(--blue-dk); }
.bk-feature { border-width: 3px; box-shadow: 7px 7px 0 var(--blue-dk); }
.bk-choice { border-width: 2.5px; }
.bk-choice.is-selected { box-shadow: 5px 5px 0 var(--yellow-d); }

/* Splats turned up — let the brand show. */
.splatdeco { opacity: 1; }
.splatdeco--1 { --o: 1; }
.splatdeco--2 { --o: .95; }
.splatdeco--3 { --o: .6; }

/* ----- Comic layer v2: halftone + hero burst ----- */
/* Ben-Day halftone dots over the deep-purple sections (kept faint, on the same
   layer as the existing glow so it stays behind content). */
.section--blue::before, .section--navy::before, .section--green::before {
  background:
    radial-gradient(rgba(255,255,255,.06) 1.3px, transparent 1.4px) 0 0 / 14px 14px,
    radial-gradient(820px 480px at 85% 0%, rgba(255,255,255,.08), transparent 60%);
}
/* Faint lime splat bursting behind the hero headline. */
.splatdeco--hero { top: 5%; left: 0%; width: 270px; height: 270px; --o: .2; --r: -8deg;
  animation: splatIn .8s .15s cubic-bezier(.2,1.5,.5,1) both, floaty 11s 1s ease-in-out infinite; }
@media (max-width: 880px) { .splatdeco--hero { display: none; } }

/* ----- Homepage hero: branded ute/house photo under a purple overlay ----- */
.hero--main { color: #fff;
  background:
    linear-gradient(100deg, rgba(0,0,0,.93) 0%, rgba(0,0,0,.80) 30%, rgba(0,0,0,.42) 58%, rgba(0,0,0,.16) 100%);
  background-color: var(--blue-dk); }
@media (max-width: 760px) {
  /* Full-bleed image covering the whole hero */
  .hero--main { background:
    linear-gradient(180deg, rgba(0,0,0,.90) 0%, rgba(0,0,0,.72) 32%, rgba(0,0,0,.48) 62%, rgba(0,0,0,.66) 100%),
    var(--blue-dk); }
  /* Top-align the copy so the CTA buttons clear the bottom curve */
  .hero--main .hero__inner { min-height: 64vh; padding-top: 2.4rem; padding-bottom: 4rem; align-content: start; align-items: start; }
  .hero--main h1 { font-size: clamp(2.1rem, 8vw, 3rem); }
}

/* ----- Mobile: centre the main content ----- */
@media (max-width: 760px) {
  .hero__copy { text-align: center; }
  .hero__cta, .herochips { justify-content: center; }
  .split, .priceblock__intro, .howwhy__col, .faqblock__intro { text-align: center; }
  .split .hero__cta { justify-content: center; }
  /* keep list rows left-aligned, but centre the list block itself */
  .priceblock__points, .checklist, .split ul { display: inline-grid; text-align: left; }
}

/* Hero secondary ("Call us") button. This rule sits after the .hero block
   above and beats it on source order, so it is the one that decides — a
   second copy up there just fights it. White on orange is unreadable; black
   on orange is 8.4:1 and matches the chips beside it. */
.hero .btn--ghost { background: #fff; color: #141414; border-color: rgba(20,20,20,.5); }
.hero .btn--ghost:hover { background: var(--cream2); color: #141414; border-color: #141414; }

/* Booking add-on: best-value highlight */
.bk-check--best { border-color: var(--yellow); background: rgba(255,153,51,.09); box-shadow: 0 0 0 1px var(--yellow) inset; }
.bk-best { display: inline-block; background: var(--yellow); color: var(--blue-dk); font-style: normal; font-weight: 800; font-size: .6rem; letter-spacing: .04em; text-transform: uppercase; padding: .12em .55em; border-radius: 999px; margin-left: .35em; vertical-align: middle; }

/* ----- Nav-links bar: white background, purple text + leading icons ----- */
.navbar { background: #fff; border-bottom: 1px solid rgba(0,0,0,.10); box-shadow: 0 1px 6px rgba(0,0,0,.05); }
.navitem > a { color: var(--ink); padding-top: 1.2rem; padding-bottom: 1.2rem; }
.navitem__lead { width: 1.1em !important; height: 1.1em !important; color: var(--blue); opacity: 1 !important; }
.navitem > a::before { background: var(--blue); }
.navitem:hover > a, .navitem > a:hover { color: var(--blue); }

/* Mobile: lead with the headline, put the video below + make it shorter */
@media (max-width: 980px) {
  .split--videobottom .split__media { order: 2; }
  .split--videobottom .split__video { aspect-ratio: 16 / 9; }
}

/* ----- Booking: Mapbox address autocomplete ----- */
.bk-mb { position: relative; }
.bk-mb-list { position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 30; margin: 0; padding: .3rem; list-style: none; background: #fff; border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow-lg); max-height: 264px; overflow-y: auto; }
.bk-mb-list li { display: flex; align-items: flex-start; gap: .5em; padding: .6rem .7rem; border-radius: 8px; cursor: pointer; font-size: .92rem; color: var(--ink); line-height: 1.3; }
.bk-mb-list li:hover { background: var(--cream2); }
.bk-mb-list li .ico { color: var(--blue); margin-top: .1em; flex: none; width: 16px; height: 16px; }
.bk-mb-chosen { display: flex; align-items: center; gap: .45em; margin: .6rem 0 0; color: var(--blue-dk); font-size: .92rem; }
.bk-mb-chosen .ico { color: var(--blue); width: 18px; height: 18px; }
.bk-link { display: inline-block; background: none; border: none; padding: .5rem 0 0; color: var(--blue); font-weight: 600; font-size: .88rem; cursor: pointer; text-decoration: underline; }
.bk-link:hover { color: var(--blue-dk); }

/* ----- Mobile drawer: tap-to-expand accordions ----- */
.m-acc__head { display: flex; align-items: center; justify-content: space-between; gap: .7em; width: 100%; padding: .95rem 1.5rem; background: none; border: none; border-bottom: 1px solid rgba(255,255,255,.09); font-family: var(--head); font-weight: 700; font-size: 1.08rem; color: #fff; cursor: pointer; text-align: left; }
.m-acc__chev { width: .8em; height: .8em; flex: none; color: var(--yellow); transition: transform .25s ease; }
.m-acc.is-open .m-acc__chev { transform: rotate(180deg); }
.m-acc__body { max-height: 0; overflow: hidden; transition: max-height .32s ease; background: rgba(0,0,0,.16); }
.m-acc__body a { display: block; padding: .62rem 1.5rem .62rem 2.1rem; font-family: var(--head); font-weight: 600; font-size: .98rem; color: rgba(255,255,255,.86); border-bottom: 1px solid rgba(255,255,255,.05); }
.m-acc__body a:active, .m-acc__body a:hover { background: rgba(255,255,255,.08); color: var(--yellow); }

/* ----- The sticky book / call bar (phones) -----
   Re-coloured 10/10/2026. This block was forked from Kapow and still
   carried Kapow's deep blue: a blue bar, a blue button border, blue
   label text and a blue handset, on a site whose top bar has been
   orange since 29/09 and whose brand order Pearce set as orange,
   blue, black, white — with blue reserved, in his words, for the top
   bar and nothing else.

   Worse than off-brand, it was unreadable: --blue (#076EB8) label
   text on the orange gradient measures about 1.9:1, where small bold
   text needs 4.5:1. The one control on the site that must be legible
   at a glance, in sunlight, one-handed, was the one set in a colour
   that disappears into its own button.

   Near-black ground, orange hairline, near-black label on the orange
   button, and the call button in white with a near-black rule. */
.bookbar { background: #141414; border-top: 3px solid var(--yellow);
  box-shadow: 0 -6px 20px rgba(0,0,0,.42); }
.bookbar .btn--accent { position: relative; overflow: hidden; color: var(--ink);
  border: 2.5px solid #000; box-shadow: 0 3px 0 #000, 0 6px 14px rgba(0,0,0,.4);
  font-family: var(--head); font-weight: 800; text-transform: uppercase;
  letter-spacing: .005em; font-size: .95rem; display: inline-flex;
  align-items: center; justify-content: center; gap: .45em; }
.bookbar .btn--accent .ico { color: var(--ink); width: 1.15em; height: 1.15em; }
.bookbar .btn--accent::after { content: ""; position: absolute; top: 0; left: -60%; width: 38%; height: 100%; background: linear-gradient(100deg, transparent, rgba(255,255,255,.6), transparent); transform: skewX(-18deg); animation: bookshine 3.6s ease-in-out infinite; pointer-events: none; }
.bookbar .btn--accent:active { transform: translateY(3px); box-shadow: 0 0 0 #000; }
/* The call button says "Call". A bare handset glyph is a guess, and the
   one thing on this bar nobody should have to guess at is how to reach
   a person. Fixed width so Book always reads as the primary. */
.bookbar .bookbar__call { flex: none; width: auto; min-width: 112px; padding: .7rem .9rem;
  background: #fff; border: 2.5px solid #000; color: var(--ink);
  font-family: var(--head); font-weight: 800; font-size: .95rem;
  box-shadow: 0 3px 0 #000; border-radius: 12px; gap: .4em; }
.bookbar .bookbar__call .ico { color: var(--orange-ink); width: 1.15em; height: 1.15em; }
.bookbar .bookbar__call:active { transform: translateY(3px); box-shadow: 0 0 0 #000; }
@keyframes bookshine { 0%, 58% { left: -60%; } 80%, 100% { left: 130%; } }
@media (prefers-reduced-motion: reduce) { .bookbar .btn--accent::after { display: none; } }

/* Booking: advance-date picker (bright CTA below the schedule) */
.bk-adv-btn { display: flex; align-items: center; justify-content: center; gap: .55em; width: 100%; margin: 1.2rem 0 .2rem; padding: 1rem 1.1rem; border: 2.5px solid var(--blue-dk); border-radius: 14px; background: var(--yellow); color: var(--blue-dk); font-family: var(--head); font-weight: 800; font-size: 1.02rem; cursor: pointer; box-shadow: 0 4px 0 var(--blue-dk); transition: transform .12s ease, box-shadow .12s ease; }
.bk-adv-btn .ico { width: 1.25em; height: 1.25em; color: var(--blue-dk); }
.bk-adv-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 0 var(--blue-dk); }
.bk-adv-btn:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--blue-dk); }
.bk-adv { margin: 1.2rem 0 .2rem; padding: 1rem 1.1rem; background: #FBEAD9; border: 2px solid var(--yellow); border-radius: 14px; }
.bk-adv label { display: flex; align-items: center; gap: .4em; font-family: var(--head); font-weight: 800; color: var(--blue-dk); font-size: .98rem; margin-bottom: .5rem; }
.bk-adv label .ico { width: 1.1em; height: 1.1em; color: var(--blue); }
.bk-adv__chosen { display: flex; align-items: center; gap: .4em; margin: .6rem 0 0; color: var(--blue-dk); font-size: .92rem; }
.bk-adv__chosen .ico { color: var(--blue); }

/* Booking: pay-method choice (card / cash) */
.bk-pay { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; }
.bk-pay__opt { display: flex; align-items: center; justify-content: center; gap: .4em; padding: .85rem .6rem; border: 2px solid var(--line); border-radius: 12px; background: #fff; font-family: var(--head); font-weight: 700; font-size: .92rem; color: var(--ink); cursor: pointer; text-align: center; }
.bk-pay__opt .ico { color: var(--blue); width: 18px; height: 18px; }
.bk-pay__opt.is-on { border-color: var(--blue); background: rgba(20,20,20,.07); color: var(--blue); }
@media (max-width: 480px) { .bk-pay { grid-template-columns: 1fr; } }
/* Seam wrapper: pill straddles the hero-curve / statbar boundary */
.emailcta-seam { position: relative; z-index: 5; height: 0; text-align: center; }
/* Full-width CTA blended into the cream curve band — no pill, no colour seam. */
.emailcta-seam .emailcta { position: absolute; left: 0; right: 0; bottom: 7px; display: flex; justify-content: center; align-items: center; gap: .6rem; background: transparent; box-shadow: none; border-radius: 0; padding: .45rem 1rem; font-size: 1.25rem; font-weight: 800; transform: none; }
.emailcta-seam .emailcta:hover b { text-decoration: underline; }
.emailcta-seam .emailcta .ico { width: 20px; height: 20px; }
@media (max-width: 600px) {
  /* Taller lime band on phones so the email CTA has room to breathe */
  .hero__curve--cta { height: 82px; }
  .hero .hero__inner { padding-bottom: 5.2rem; }
  .emailcta-seam .emailcta { font-size: 1rem; padding: .3rem .8rem; bottom: 14px; }
}
/* Email-us pill (homepage hero + /book strip) */
.emailcta { display: inline-flex; align-items: center; gap: .5rem; background: #fff; color: #0a0a0a; font-family: "Baloo 2", sans-serif; font-weight: 700; font-size: .9rem; padding: .55rem 1.15rem; border-radius: 999px; text-decoration: none; box-shadow: 0 5px 16px rgba(0,0,0,.3); max-width: 100%; }
.emailcta .ico { width: 16px; height: 16px; color: #141414; flex: none; }
.emailcta b { color: #141414; white-space: nowrap; }
.emailcta__qs { display: none; }
@media (max-width: 600px) {
  .emailcta { font-size: .84rem; padding: .5rem 1rem; }
  .emailcta__q { display: none; }
  .emailcta__qs { display: inline; }
}
/* Wizard sticky action bar — phones only; mirrors the pane's primary button
   so price + CTA stay visible on the long panes (details / review & pay). */
.bk-sticky { display: none; }
@media (max-width: 760px) {
  .bk-sticky { display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 70; align-items: center; gap: .8rem; padding: .6rem .9rem calc(.6rem + env(safe-area-inset-bottom)); background: rgba(0,0,0,.97); backdrop-filter: blur(6px); border-top: 1px solid rgba(255,255,255,.14); }
  .bk-sticky__price { color: #FF9933; font-family: "Baloo 2", sans-serif; font-weight: 800; font-size: 1.25rem; line-height: 1.1; }
  .bk-sticky__price small { display: block; color: rgba(255,255,255,.75); font-size: .68rem; font-weight: 600; font-family: "Plus Jakarta Sans", sans-serif; }
  .bk-sticky .btn { flex: 1; justify-content: center; padding: .8rem 1rem; }
  body.bk-stickyon { padding-bottom: 76px; }
  /* the in-pane price bar also sticks to the viewport bottom — with the
     fixed action bar present that stacks two bars over the content, so on
     phones the pane bar becomes static and the action bar owns the bottom */
  body.bk-stickyon .bk-quote { position: static; }
}

/* Booking: "Before we arrive" sub-section */
.bk-subhead { font-family: var(--head); font-weight: 800; color: var(--ink); font-size: 1.05rem; margin: 1.5rem 0 .3rem; padding-top: 1.1rem; border-top: 1px solid var(--line); }
.bk-subhead .bk-hint { font-weight: 500; }


/* ===== BFYB contrast corrections =====
   #FF9933 on white is ~2.1:1 — below the 3:1 WCAG threshold even for large
   text and icons. Anywhere the accent lands on a light ground it uses
   --orange-ink instead. The accent on black is unchanged. */
.navbar { background: #fff; }
.navitem > a { color: var(--ink); }
.navitem:hover > a, .navitem > a:hover { color: var(--orange-ink); }
.navitem__panel a:hover { color: var(--orange-ink); }
.hl-b { color: var(--orange-ink); }

/* ===== Booking flow (.bkq__*) =================================================
 * Its own namespace rather than the .bk-* block inherited from Kapow: that one
 * is wired to Kapow's markup and I am not going to half-match it. These use the
 * BFYB tokens, so the flow is black-and-orange without a single hex here.
 * Generated markup lives in assets/booking.js.
 * ========================================================================== */
/* ============================================================
   THE QUESTION RAIL — one question per screen, numbered.
   ============================================================
   Pearce, 02/10/2026: "there is SOOO MUCH scrolling to do... it should be
   question 1/8 so the person doesn't need to scroll."
   The row of thin progress dashes it replaces told you how far along you
   were and nothing else. This names every question, ticks the ones that are
   answered, shows what was said, and lets any of them be reopened — so a
   customer who wonders whether they said two bedrooms or three can look
   instead of guessing, and fix it in one click.

   ON A PHONE it turns into a horizontal strip of numbers above the question:
   the labels would eat the screen, which is the thing we are trying to give
   back. The number and the tick survive, because those are what tell you
   where you are. */
.bkq__layout { display: grid; grid-template-columns: 236px minmax(0, 1fr); gap: 26px; align-items: start; }
/* No rail on the service picker — the column would sit empty beside it. */
.bkq__layout:has(> #bkq-steps[hidden]) { grid-template-columns: minmax(0, 1fr); }
.bkq__steps[hidden] { display: none; }
.bkq__steps { display: flex; flex-direction: column; gap: 2px; position: sticky; top: var(--stick-h, 160px); }
.bkq__rail { display: flex; gap: 10px; align-items: flex-start; width: 100%; text-align: left;
  background: none; border: 0; padding: 8px 10px; border-radius: 11px; cursor: pointer; }
.bkq__rail:disabled { cursor: default; }
.bkq__railn { flex: none; width: 24px; height: 24px; border-radius: 50%; background: var(--cream2);
  color: var(--muted); display: grid; place-items: center; font-family: var(--head);
  font-weight: 800; font-size: .76rem; line-height: 1; }
.bkq__raill { flex: 1; min-width: 0; }
.bkq__raill b { display: block; font-family: var(--head); font-weight: 700; font-size: .88rem;
  color: var(--muted); line-height: 1.25; }
.bkq__raill span { display: block; font-size: .76rem; color: var(--orange-ink-d); font-weight: 600;
  margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bkq__rail.done .bkq__railn { background: var(--yellow-d); color: #fff; }
.bkq__rail.done .bkq__raill b { color: var(--ink); }
.bkq__rail.done:hover { background: var(--cream); }
.bkq__rail.on { background: var(--white); box-shadow: 0 2px 12px rgba(0,0,0,.08); }
.bkq__rail.on .bkq__railn { background: var(--yellow); color: var(--ink); }
.bkq__rail.on .bkq__raill b { color: var(--ink); }
.bkq__rail--end { margin-top: 4px; border-top: 1px solid var(--line); padding-top: 12px; }
.bkq__rail--end .bkq__railn { background: var(--cream2); color: var(--muted); }
.bkq__rail--end.on .bkq__railn { background: var(--ink); color: #fff; }
/* ============================================================
   THE CARPET LANE'S PICKER — TWO CARDS AND A "BOTH" BAR.
   ============================================================
   Pearce, 02/10/2026, choosing this of six layouts: carpet left, upholstery
   right, both underneath. The two-row list it replaces gave equal billing to
   a $289 job almost everyone wants and a $97-a-seat job most people add, and
   read like a menu rather than a decision.
   The both bar is BLUE on purpose — it is the one thing on the screen that is
   neither of the two cards, and the second brand colour marks it as the
   different kind of answer rather than a third equal option. */
.bkq__pick2grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.bkq__pick2 { display: flex; flex-direction: column; gap: 7px; text-align: left; cursor: pointer;
  background: var(--white); border: 2px solid var(--line); border-radius: 16px; padding: 18px 16px;
  font: inherit; color: inherit; transition: border-color .14s, box-shadow .14s, transform .14s; }
.bkq__pick2:hover { border-color: var(--yellow); box-shadow: 0 10px 26px rgba(0,0,0,.09); transform: translateY(-1px); }
.bkq__pick2ic { width: 42px; height: 42px; border-radius: 13px; background: var(--yellow);
  display: grid; place-items: center; }
.bkq__pick2ic .ico { width: 23px; height: 23px; color: #fff; }
.bkq__pick2n { font-family: var(--head); font-weight: 800; font-size: 1.1rem; color: var(--ink); line-height: 1.2; }
.bkq__pick2t { font-size: .83rem; color: var(--muted); flex: 1; line-height: 1.45; }
.bkq__pick2r { display: flex; align-items: flex-end; justify-content: space-between; gap: 10px; margin-top: 6px; }
.bkq__pick2p { font-family: var(--head); font-weight: 800; font-size: 1.35rem; color: var(--orange-ink-d);
  font-variant-numeric: tabular-nums; line-height: 1.1; }
.bkq__pick2p small { display: block; font-size: .6rem; letter-spacing: .09em; text-transform: uppercase;
  color: var(--muted); font-weight: 800; }
.bkq__pick2go { background: var(--yellow); color: var(--ink); border-radius: 10px; padding: 9px 16px;
  font-family: var(--head); font-weight: 800; font-size: .86rem; }

.bkq__pickboth { display: flex; align-items: center; gap: 13px; width: 100%; text-align: left; cursor: pointer;
  margin-top: 12px; background: var(--blue-soft); border: 1.5px solid rgba(7,110,184,.32);
  border-radius: 14px; padding: 14px 15px; font: inherit; color: inherit; transition: border-color .14s, box-shadow .14s; }
.bkq__pickboth:hover { border-color: var(--blue); box-shadow: 0 8px 22px rgba(7,110,184,.16); }
.bkq__pickbothic { flex: none; width: 32px; height: 32px; border-radius: 10px; background: var(--blue);
  display: grid; place-items: center; }
.bkq__pickbothic .ico { width: 18px; height: 18px; color: #fff; }
.bkq__pickbotht { flex: 1; min-width: 0; }
.bkq__pickbotht b { display: block; font-family: var(--head); font-weight: 800; font-size: .95rem; color: var(--ink); }
.bkq__pickbotht span { display: block; font-size: .81rem; color: var(--body); line-height: 1.45; margin-top: 2px; }
.bkq__pickbothgo { flex: none; background: var(--blue); color: #fff; border-radius: 10px; padding: 10px 16px;
  font-family: var(--head); font-weight: 800; font-size: .86rem; white-space: nowrap; }
/* ======================================================================
   THE SECOND JOB ON THE SAME VISIT.
   ======================================================================
   Pearce, 03/10/2026: "how can the client do the carpets with the pest? It
   seems one or the other after clicking." The rows are tickable rather than
   one-of, because an end-of-lease customer often wants the carpets, the fleas
   and the spiders in one visit. Selected is the brand orange, same as the
   room chips in the carpet builder — the colour means "you picked this"
   everywhere in this flow and nowhere else. */
.bkq__alsolist { display: grid; gap: 8px; margin-top: 12px; }
.bkq__also { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left; cursor: pointer;
  background: #fff; border: 1.5px solid var(--line); border-radius: 13px; padding: 12px 14px;
  font: inherit; color: inherit; transition: border-color .14s, background .14s, box-shadow .14s; }
.bkq__also:hover:not([disabled]) { border-color: var(--yellow); box-shadow: 0 6px 16px rgba(255,153,51,.16); }
.bkq__also[disabled] { opacity: .5; cursor: default; }
.bkq__also.sel { background: var(--yellow-soft); border-color: var(--yellow);
  box-shadow: inset 0 0 0 1.5px var(--yellow); }
.bkq__alsobox { flex: none; width: 22px; height: 22px; border-radius: 7px; display: grid; place-items: center;
  border: 1.5px solid var(--line); background: #fff; font-weight: 800; font-size: .8rem; color: var(--orange-ink-d); }
.bkq__also.sel .bkq__alsobox { background: var(--yellow); border-color: var(--yellow); color: var(--ink); }
.bkq__alsot { flex: 1; min-width: 0; }
.bkq__alsot b { display: block; font-family: var(--head); font-weight: 700; font-size: .92rem; color: var(--ink); }
.bkq__alsot span { display: block; font-size: .8rem; color: var(--muted); line-height: 1.45; margin-top: 2px; }
.bkq__alsop { flex: none; text-align: right; font-family: var(--head); font-weight: 800; font-size: 1.05rem;
  color: var(--ink); font-variant-numeric: tabular-nums; }
/* The saving sits under the price, in the brand orange, because it is the
   reason this row is worth reading. */
.bkq__alsop small { display: block; font-size: .64rem; font-weight: 800; letter-spacing: .04em;
  text-transform: uppercase; color: var(--orange-ink-d); margin-top: 1px; }
/* The pest-to-carpet card is a single offer rather than one of a list, so it
   gets the blue treatment the other "do both" offers use. */
.bkq__also--big { background: var(--blue-soft); border-color: rgba(7,110,184,.32); align-items: flex-start; }
.bkq__also--big:hover { border-color: var(--blue); box-shadow: 0 8px 22px rgba(7,110,184,.16); }
.bkq__alsoic { flex: none; width: 32px; height: 32px; border-radius: 10px; background: var(--blue);
  display: grid; place-items: center; }
.bkq__alsoic .ico { width: 18px; height: 18px; color: #fff; }
.bkq__alsogo { flex: none; background: var(--blue); color: #fff; border-radius: 10px; padding: 10px 16px;
  font-family: var(--head); font-weight: 800; font-size: .86rem; white-space: nowrap; }
/* THE FLEA CARD. Its own space, at the top, visibly not one of the list.
   Pearce, 04/10/2026: "bigger, obvious, bold." Orange because it is the one
   thing on this screen we are actively recommending, and the only one with a
   real saving on it. */
/* The flag rides on the card's top edge, so it reads as a label ON the offer
   rather than another line inside it. The card gets its top margin back as
   padding so nothing shifts underneath. */
.bkq__flea { position: relative; }
.bkq__fleaflag { position: absolute; top: -11px; left: 18px; background: var(--ink); color: #fff;
  font-family: var(--head); font-weight: 800; font-size: .64rem; letter-spacing: .1em;
  text-transform: uppercase; padding: 4px 11px; border-radius: 7px; white-space: nowrap;
  box-shadow: 0 3px 10px rgba(20,18,16,.22); }
/* BLOCK, NOT FLEX. It was a single button laid out as a row; it is now a panel
   holding a header row, two priced choices and a remove link. Left as a flex
   row, those three sections became three columns and every word wrapped on
   its own line. 04/10/2026. */
.bkq__flea { display: block; width: 100%; text-align: left;
  margin-top: 24px; background: var(--yellow-soft);
  border: 2px solid var(--yellow); border-radius: 15px; padding: 16px 18px; font: inherit; color: inherit;
  box-shadow: 0 6px 20px rgba(255,153,51,.22); transition: box-shadow .14s, transform .14s, background .14s; }
.bkq__fp:hover { transform: translateY(-1px); }
.bkq__flea.sel { background: #fff; box-shadow: inset 0 0 0 2px var(--yellow), 0 6px 20px rgba(255,153,51,.22); }
.bkq__fleabox { flex: none; width: 28px; height: 28px; border-radius: 9px; display: grid; place-items: center;
  border: 2px solid var(--yellow); background: #fff; font-weight: 800; font-size: .95rem; color: var(--orange-ink-d); }
.bkq__flea.sel .bkq__fleabox { background: var(--yellow); color: var(--ink); }
.bkq__fleat { flex: 1; min-width: 0; }
.bkq__fleat b { display: block; font-family: var(--head); font-weight: 800; font-size: 1.08rem; color: var(--ink); }
.bkq__fleat span { display: block; font-size: .84rem; color: var(--body); line-height: 1.5; margin-top: 3px; }
.bkq__fleap { flex: none; text-align: right; font-family: var(--head); font-weight: 800; font-size: 1.6rem;
  color: var(--ink); font-variant-numeric: tabular-nums; line-height: 1.1; }
.bkq__fleap small { display: block; font-size: .64rem; font-weight: 800; letter-spacing: .04em;
  text-transform: uppercase; color: var(--orange-ink-d); margin-top: 2px; }
.bkq__fleap i { display: inline-block; font-style: normal; margin-top: 8px; background: var(--yellow);
  color: var(--ink); border-radius: 9px; padding: 7px 13px; font-size: .8rem; white-space: nowrap; }
@media (max-width: 620px) {
  .bkq__flea { flex-wrap: wrap; }
  .bkq__fleap { width: 100%; text-align: left; margin-left: 42px; }
}
/* THE COCKROACH CARD. The same shape as the flea one at lower weight: white
   rather than filled, a thinner edge, a smaller number and a plain Add chip
   instead of a filled button. Second-most-likely, not equal-first — if both
   cards shouted, neither would. */
.bkq__roach { display: flex; align-items: center; gap: 13px; width: 100%; text-align: left;
  cursor: pointer; margin-top: 10px; background: #fff;
  border: 1.5px solid var(--yellow); border-radius: 13px; padding: 13px 15px; font: inherit; color: inherit;
  box-shadow: 0 4px 12px rgba(255,153,51,.13); transition: box-shadow .14s, transform .14s, background .14s; }
.bkq__roach:hover { transform: translateY(-1px); box-shadow: 0 8px 20px rgba(255,153,51,.22); }
.bkq__roach.sel { background: var(--yellow-soft); box-shadow: inset 0 0 0 1.5px var(--yellow); }
.bkq__roachbox { flex: none; width: 24px; height: 24px; border-radius: 8px; display: grid; place-items: center;
  border: 1.5px solid var(--yellow); background: #fff; font-weight: 800; font-size: .82rem; color: var(--orange-ink-d); }
.bkq__roach.sel .bkq__roachbox { background: var(--yellow); color: var(--ink); }
.bkq__roacht { flex: 1; min-width: 0; }
.bkq__roacht b { display: block; font-family: var(--head); font-weight: 800; font-size: .96rem; color: var(--ink); }
.bkq__roacht span { display: block; font-size: .8rem; color: var(--body); line-height: 1.45; margin-top: 2px; }
.bkq__roachp { flex: none; text-align: right; font-family: var(--head); font-weight: 800; font-size: 1.22rem;
  color: var(--ink); font-variant-numeric: tabular-nums; line-height: 1.1; }
.bkq__roachp i { display: block; font-style: normal; margin-top: 6px; background: #fff; color: var(--orange-ink-d);
  border: 1.5px solid var(--yellow); border-radius: 8px; padding: 4px 11px; font-size: .74rem; white-space: nowrap; }
.bkq__roach.sel .bkq__roachp i { background: var(--yellow); color: var(--ink); }
@media (max-width: 620px) {
  .bkq__roach { flex-wrap: wrap; }
  .bkq__roachp { width: 100%; text-align: left; margin-left: 37px; }
}
/* The "2 of 4 - Rooms" line inside an active grouped rail step. */
.bkq__railsub { display: block; font-style: normal; font-family: var(--head); font-weight: 800;
  font-size: .64rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--orange-ink-d); margin-top: 1px; }
/* The follow-up that unfolds under a bad answer. Indented and rule-marked so
   it reads as a consequence of the answer above it, not a new question. */
.bkq__fu { margin: 12px 0 0 0; padding: 11px 0 0 14px; border-left: 3px solid var(--yellow); }
.bkq__fuq { margin: 0 0 8px; font-family: var(--head); font-weight: 700; font-size: .88rem; color: var(--ink); }
/* ============================================================
   THE CARPET HERO ON THE "WHICH ONE FIRST?" SCREEN.
   ============================================================
   Full width above both columns, because carpet is half the business and was
   reading as one row in eleven. Orange and filled: the only thing on the
   screen at this weight, so there is no competition for the eye. */
.bkq__hero { display: flex; align-items: center; gap: 16px; width: 100%; text-align: left;
  cursor: pointer; margin: 4px 0 16px; background: var(--yellow-soft);
  border: 2px solid var(--yellow); border-radius: 16px; padding: 18px 20px; font: inherit; color: inherit;
  box-shadow: 0 8px 24px rgba(255,153,51,.24); transition: transform .14s, box-shadow .14s; }
.bkq__hero:hover { transform: translateY(-2px); box-shadow: 0 14px 32px rgba(255,153,51,.34); }
.bkq__heroic { flex: none; width: 46px; height: 46px; border-radius: 13px; background: var(--yellow);
  display: grid; place-items: center; }
.bkq__heroic .ico { width: 25px; height: 25px; color: var(--ink); }
.bkq__herot { flex: 1; min-width: 0; }
.bkq__herot b { display: block; font-family: var(--head); font-weight: 800; font-size: 1.3rem; color: var(--ink);
  line-height: 1.15; }
.bkq__herot > span { display: block; font-size: .9rem; color: var(--body); margin-top: 3px; }
.bkq__herot i { display: block; font-style: normal; font-size: .8rem; color: var(--orange-ink-d);
  font-weight: 600; margin-top: 6px; }
.bkq__herop { flex: none; text-align: right; font-family: var(--head); font-weight: 800; font-size: 2rem;
  color: var(--ink); font-variant-numeric: tabular-nums; line-height: 1; }
.bkq__herop small { display: block; font-size: .56rem; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: var(--orange-ink); margin-bottom: 2px; }
.bkq__herop em { display: block; font-style: normal; margin-top: 10px; background: var(--yellow);
  color: var(--ink); border-radius: 10px; padding: 9px 16px; font-size: .88rem; white-space: nowrap; }
@media (max-width: 620px) {
  .bkq__hero { flex-wrap: wrap; gap: 12px; padding: 15px 16px; }
  .bkq__herop { width: 100%; text-align: left; font-size: 1.7rem; }
}
/* The double-storey stairs question, asked on the rooms screen. */
.bkq__note--ask { background: var(--blue-soft); border-color: rgba(7,110,184,.3); }
.bkq__note--ask > b { background: var(--blue) !important; color: #fff !important; }
.bkq__askbtns { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.bkq__askyes, .bkq__askno { font: inherit; cursor: pointer; border-radius: 9px; padding: 8px 14px;
  font-family: var(--head); font-weight: 800; font-size: .83rem; }
.bkq__askyes { background: var(--yellow); color: var(--ink); border: 0; }
.bkq__askno { background: #fff; color: var(--body); border: 1.5px solid var(--line); }
/* ============================================================
   THE RECOMMENDED ADD-ONS — LAYOUT B, NOTHING PRE-TICKED.
   ============================================================
   Cards rather than rows, filled only once the customer adds one, so the
   screen never looks like it has decided for them. Pearce, 04/10/2026:
   "these are add-ons, not mandatory — the idea is to explain WHY." */
.bkq__recs { display: grid; gap: 12px; }
.bkq__rc { border: 1.5px solid var(--line); border-radius: 13px; padding: 15px 16px; background: #fff; }
.bkq__rc.on { border-color: var(--yellow); background: var(--yellow-soft);
  box-shadow: inset 0 0 0 1.5px var(--yellow); }
.bkq__rctop { display: flex; align-items: flex-start; gap: 12px; }
.bkq__rcn { flex: 1; min-width: 0; }
.bkq__rcn b { font-family: var(--head); font-weight: 800; font-size: 1.04rem; color: var(--ink); }
.bkq__rcn span { display: block; font-size: .8rem; color: var(--muted); margin-top: 2px; line-height: 1.45; }
.bkq__rctag { font-style: normal; font-size: .6rem; font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; background: var(--yellow); color: var(--ink); border-radius: 5px; padding: 2px 7px; }
.bkq__rcp { flex: none; font-family: var(--head); font-weight: 800; font-size: 1.3rem; color: var(--ink);
  font-variant-numeric: tabular-nums; }
.bkq__rcwhy { margin-top: 9px; display: grid; gap: 6px; }
.bkq__rcwhy span { display: block; font-size: .82rem; line-height: 1.5; color: var(--body);
  border-left: 3px solid var(--yellow); padding-left: 11px; }
.bkq__rcmore { display: inline-block; margin-top: 10px; background: none; border: 0; padding: 0;
  font: inherit; font-size: .79rem; font-weight: 700; color: var(--blue); cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px; }
.bkq__rcx { margin-top: 10px; background: var(--cream); border-radius: 10px; padding: 12px 14px; }
.bkq__rcx p { margin: 0 0 9px; font-size: .83rem; line-height: 1.55; color: var(--body); }
.bkq__rcx p:last-child { margin-bottom: 0; }
.bkq__rcx b { display: block; font-family: var(--head); font-weight: 800; font-size: .68rem;
  letter-spacing: .08em; text-transform: uppercase; color: var(--orange-ink-d); margin-bottom: 2px; }
.bkq__rcadd { display: block; width: 100%; margin-top: 12px; cursor: pointer; font: inherit;
  font-family: var(--head); font-weight: 800; font-size: .88rem; border-radius: 10px; padding: 11px 14px;
  background: var(--yellow); color: var(--ink); border: 0; }
.bkq__rcadd.on { background: #fff; color: var(--orange-ink-d); border: 1.5px solid var(--yellow); }
.bkq__recsum { margin: 14px 0 0; font-size: .9rem; color: var(--ink); }
.bkq__recsum b { font-family: var(--head); font-weight: 800; font-variant-numeric: tabular-nums; }
.bkq__recwarn { margin: 10px 0 0; font-size: .8rem; line-height: 1.55; color: var(--body);
  background: var(--blue-soft); border-radius: 10px; padding: 11px 13px; }
/* The fields that hang off an access answer — which agency, the key-safe
   spot and code, who is meeting us and on what number. Indented under the
   answer they belong to, the same way the stains follow-up is. */
.bkq__ef { margin: -2px 0 10px 0; padding: 12px 0 2px 14px; border-left: 3px solid var(--yellow);
  display: grid; gap: 10px; }
.bkq__eflab { display: block; font-family: var(--head); font-weight: 700; font-size: .83rem; color: var(--ink); }
.bkq__eflab i { font-style: normal; font-weight: 400; color: var(--muted); font-size: .76rem; }
.bkq__eflab input { display: block; width: 100%; margin-top: 5px; font: inherit; font-weight: 400;
  font-size: .9rem; padding: 10px 12px; border: 1.5px solid var(--line); border-radius: 9px;
  background: #fff; color: var(--ink); }
.bkq__eflab input:focus { outline: 0; border-color: var(--yellow); box-shadow: 0 0 0 3px rgba(255,153,51,.2); }
.bkq__eflab input[aria-invalid="true"] { border-color: rgba(194,86,31,.5); }
.bkq__efnote { display: block; margin-top: 4px; font-weight: 400; font-size: .76rem; color: var(--muted); }
/* The flea card is no longer one big button — it holds a choice between two
   genuinely different jobs, so the top is a header and the two jobs sit under
   it as the things you actually press. */
.bkq__fleatop { display: flex; align-items: center; gap: 14px; }
.bkq__fleapick { display: grid; gap: 9px; margin-top: 13px; }
.bkq__fp { display: flex; align-items: flex-start; gap: 12px; width: 100%; text-align: left; cursor: pointer;
  background: #fff; border: 1.5px solid var(--line); border-radius: 11px; padding: 12px 14px; font: inherit; color: inherit; }
.bkq__fp:hover { border-color: var(--yellow); }
.bkq__fp.sel { border-color: var(--yellow); background: #fff; box-shadow: inset 0 0 0 1.5px var(--yellow); }
.bkq__fpn { flex: 1; min-width: 0; }
.bkq__fpn b { display: block; font-family: var(--head); font-weight: 800; font-size: .94rem; color: var(--ink); }
.bkq__fpn span { display: block; font-size: .79rem; color: var(--body); line-height: 1.5; margin-top: 2px; }
.bkq__fpp { flex: none; text-align: right; font-family: var(--head); font-weight: 800; font-size: 1.15rem;
  color: var(--ink); font-variant-numeric: tabular-nums; }
.bkq__fpp small { display: block; font-size: .62rem; font-weight: 700; letter-spacing: .03em;
  text-transform: uppercase; color: var(--muted); margin-top: 2px; }
.bkq__fleaoff { display: block; margin: 11px auto 0; background: none; border: 0; font: inherit;
  font-size: .79rem; font-weight: 700; color: var(--body); text-decoration: underline;
  text-underline-offset: 2px; cursor: pointer; }

/* ---------- ASK FIRST, THEN SHOW ONE JOB ----------
   Pearce, 04/10/2026: "instead of having both listed, there should have been a
   question, then it gives based on the question. This is busy and I don't know
   what to click."
   The header is now plain text, not a tickbox — there is nothing to tick until
   the question is answered, so a tickbox there was a third thing to press that
   did a fourth thing. The question is the only interactive element on a fresh
   card, and the answer replaces it with exactly one priced job. */
.bkq__fleahead b { display: block; font-family: var(--head); font-weight: 800; font-size: 1.08rem;
  color: var(--ink); }
.bkq__fleahead span { display: block; font-size: .84rem; color: var(--body); line-height: 1.55; margin-top: 4px; }
.bkq__fleaask { margin-top: 15px; background: #fff; border: 1.5px solid var(--line);
  border-radius: 12px; padding: 14px 15px; }
.bkq__fleaask b { display: block; font-family: var(--head); font-weight: 800; font-size: .98rem; color: var(--ink); }
.bkq__fleaask > span { display: block; font-size: .79rem; color: var(--muted); line-height: 1.5; margin-top: 3px; }
.bkq__fleaans { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 12px; }
/* Each answer carries its own price. Pearce, 04/10/2026: "the no should list
   the price, the yes should list the price, within each bubble." Stacked
   rather than side by side inside the button, so the label reads first and the
   number reads as its consequence. */
.bkq__fa { flex: 1 1 180px; cursor: pointer; font: inherit; font-weight: 700; font-size: .88rem;
  color: var(--ink); background: var(--paper); border: 1.5px solid var(--line); border-radius: 10px;
  padding: 12px 14px; text-align: center; transition: border-color .14s, background .14s;
  display: flex; flex-direction: column; align-items: center; gap: 7px; }
.bkq__fa:hover { border-color: var(--yellow); background: #fff; }
.bkq__fan { display: block; line-height: 1.35; }
.bkq__fap { display: block; font-family: var(--head); font-weight: 800; font-size: 1.3rem;
  color: var(--ink); font-variant-numeric: tabular-nums; line-height: 1.1; }
.bkq__fap small { display: block; font-size: .6rem; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted); margin-top: 3px; }
.bkq__fleares { margin-top: 15px; background: #fff; border: 1.5px solid var(--line);
  border-radius: 12px; padding: 14px 15px; }
.bkq__fleares.sel { border-color: var(--yellow); box-shadow: inset 0 0 0 1.5px var(--yellow); }
.bkq__frtop { display: flex; align-items: flex-start; gap: 14px; }
.bkq__frt { flex: 1; min-width: 0; }
.bkq__frt b { display: block; font-family: var(--head); font-weight: 800; font-size: .98rem; color: var(--ink); }
.bkq__frt span { display: block; font-size: .81rem; color: var(--body); line-height: 1.5; margin-top: 3px; }
.bkq__frp { flex: none; text-align: right; font-family: var(--head); font-weight: 800; font-size: 1.45rem;
  color: var(--ink); font-variant-numeric: tabular-nums; line-height: 1.1; }
.bkq__frp small { display: block; font-size: .62rem; font-weight: 800; letter-spacing: .04em;
  text-transform: uppercase; color: var(--muted); margin-top: 3px; }
.bkq__frwhy { margin: 11px 0 0; font-size: .79rem; color: var(--body); line-height: 1.55;
  background: var(--paper); border-radius: 9px; padding: 10px 12px; }
.bkq__frwhy b { color: var(--ink); }
.bkq__fradd { display: block; width: 100%; margin-top: 13px; cursor: pointer; font: inherit;
  font-family: var(--head); font-weight: 800; font-size: .92rem; color: var(--ink);
  background: var(--yellow); border: 0; border-radius: 10px; padding: 12px 14px; }
.bkq__fradd.sel { background: #fff; color: var(--body); box-shadow: inset 0 0 0 1.5px var(--line); }
@media (max-width: 560px) {
  .bkq__frtop { flex-wrap: wrap; }
  .bkq__frp { width: 100%; text-align: left; font-size: 1.3rem; }
}
/* The answers echoed back on the review page. A follow-up answer is indented
   under the question it hangs off, so "pet urine" reads as part of the stains
   answer rather than as its own question. */
.bkq__sublines > span { padding-left: 2px; color: var(--muted); }
.bkq__also--no { margin-top: 10px; justify-content: center; }
.bkq__also--no .bkq__alsot { flex: 0 1 auto; }
.bkq__also--no .bkq__alsot b { font-weight: 600; color: var(--body); }
.bkq__note--save b { background: var(--yellow) !important; color: var(--ink) !important; }
/* The review: two job cards, then one number under both. */
.bkq__card--also { border-color: rgba(255,153,51,.45); }
.bkq__saved { font-style: normal; font-size: .72rem; font-weight: 800; letter-spacing: .03em;
  text-transform: uppercase; color: var(--orange-ink-d); background: var(--yellow-soft);
  border-radius: 6px; padding: 1px 6px; margin-left: 6px; white-space: nowrap; }
.bkq__grand { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: 12px 0 4px; background: var(--ink); color: #fff; border-radius: 13px; padding: 14px 16px; }
.bkq__grand span { font-family: var(--head); font-weight: 700; font-size: .9rem; }
.bkq__grand b { font-family: var(--head); font-weight: 800; font-size: 1.5rem;
  font-variant-numeric: tabular-nums; }
@media (max-width: 620px) {
  .bkq__pick2grid { grid-template-columns: 1fr; }
  .bkq__pickboth { flex-wrap: wrap; }
  .bkq__pickbothgo { margin-left: 45px; }
  .bkq__also--big { flex-wrap: wrap; }
  .bkq__alsogo { margin-left: 44px; }
  .bkq__grand b { font-size: 1.3rem; }
}

/* RESTART QUOTE — quiet, at the foot of the rail, and it asks first.
   Deliberately the least prominent control on the screen: it is useful once
   in a while and destructive every time, so it does not compete with
   Continue. The confirm happens in place because the artifact viewer blocks
   confirm() and a half-built modal for one button is not worth it. */
.bkq__restart { display: block; width: 100%; margin-top: 14px; padding: 9px 10px;
  background: none; border: 1px dashed var(--line); border-radius: 10px; cursor: pointer;
  font-family: var(--head); font-weight: 700; font-size: .78rem; color: var(--muted); text-align: left; }
.bkq__restart:hover { border-color: var(--yellow); color: var(--orange-ink-d); }
.bkq__restart--ask { border-style: solid; border-color: var(--yellow); background: var(--yellow-soft);
  padding: 11px 12px; cursor: default; }
.bkq__restart--ask p { margin: 0 0 9px; font-family: var(--font); font-weight: 400;
  font-size: .78rem; line-height: 1.45; color: var(--body); }
.bkq__restart-yes, .bkq__restart-no { border: 0; border-radius: 8px; padding: 7px 11px; cursor: pointer;
  font-family: var(--head); font-weight: 800; font-size: .76rem; }
.bkq__restart-yes { background: var(--ink); color: #fff; margin-right: 6px; }
.bkq__restart-no { background: none; color: var(--muted); }
.bkq__restart-no:hover { color: var(--ink); }
@media (max-width: 860px) {
  .bkq__restart { width: auto; flex: none; margin-top: 0; margin-left: 6px; white-space: nowrap; }
  .bkq__restart--ask { white-space: normal; max-width: 260px; }
}
/* NOT A BUG — AND MY FIRST FIX FOR IT WAS ONE. 10/10/2026.
   An automated check flagged this button's right edge at 450px on a 393px
   phone and I widened it to 100% and let it wrap. That was wrong. It is the
   last item in .bkq__steps, the numbered step rail, which is display:flex
   with overflow:auto — a strip you swipe sideways. Items in it are SUPPOSED
   to sit past the edge of the screen; that is what makes the rail scroll.
   Setting width:100% made it claim the whole rail and shove the step chips
   out of the way. The 860px rule above is correct and stays. Noted here so
   the next sweep that flags it does not "fix" it again. */

.bkq__sronly { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }
.bkq__linkish { background: none; border: 0; padding: 0; color: var(--blue); font: inherit;
  font-size: inherit; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.bkq__lines--plain li b { font-weight: 600; font-family: var(--font); font-size: .86rem; }

@media (max-width: 860px) {
  .bkq__layout { grid-template-columns: 1fr; gap: 14px; }
  .bkq__steps { flex-direction: row; gap: 5px; position: static; overflow-x: auto;
    padding-bottom: 4px; scrollbar-width: none; }
  .bkq__steps::-webkit-scrollbar { display: none; }
  .bkq__rail { width: auto; flex: none; padding: 5px; }
  .bkq__raill { display: none; }
  .bkq__rail.on { box-shadow: none; }
  .bkq__rail.on .bkq__railn { box-shadow: 0 0 0 3px rgba(255,153,51,.35); }
  .bkq__rail--end { margin-top: 0; border-top: 0; border-left: 1px solid var(--line);
    padding-top: 5px; padding-left: 9px; margin-left: 4px; }
}

.bkq__kick { font-size: .72rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--orange-ink); margin: 18px 0 6px; }
.bkq__lead { color: var(--muted); font-size: .95rem; margin: 0 0 18px; }

/* THE LANE CHOOSER — the first thing the booking flow asks.
   Pest and carpet are half the business each, so the two sit side by side at
   equal weight and "Both" runs full width underneath: it is an answer in its
   own right, not an afterthought squeezed into a third column. */
.bkq__lanes { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 18px; }
.bkq__lane { grid-column: span 1; display: flex; flex-direction: column; gap: 6px; text-align: left; width: 100%; cursor: pointer;
  background: var(--white); border: 1.5px solid var(--line); border-radius: var(--radius-lg); padding: 20px 20px 18px;
  font: inherit; color: inherit; transition: border-color .15s, transform .15s, box-shadow .15s; }
.bkq__lane:hover { border-color: var(--yellow); transform: translateY(-2px); box-shadow: 0 10px 26px rgba(20,18,16,.09); }
.bkq__laneico { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 12px;
  background: linear-gradient(140deg, #ffb45f, #ff9933); color: #241a10; margin-bottom: 6px; }
.bkq__laneico .ico { width: 21px; height: 21px; }
.bkq__lane b { font-family: var(--head); font-size: 1.22rem; font-weight: 800; color: var(--ink); line-height: 1.15; }
.bkq__lane > span { font-size: .87rem; color: var(--muted); line-height: 1.45; }
.bkq__lane > span em { font-style: normal; font-weight: 700; color: var(--ink); }
.bkq__lane > em { font-style: normal; font-family: var(--head); font-weight: 800; font-size: .74rem; letter-spacing: .07em;
  text-transform: uppercase; color: var(--orange-ink); margin-top: 8px; }
.bkq__lane--both { grid-column: 1 / -1; flex-direction: row; align-items: center; flex-wrap: nowrap; gap: 0 16px; padding: 15px 20px; }
.bkq__lane--both .bkq__laneico { flex: 0 0 auto; width: 38px; height: 38px; margin-bottom: 0; }
.bkq__lane--both b { flex: 0 0 auto; font-size: 1.12rem; }
.bkq__lane--both > span { flex: 1 1 auto; min-width: 0; }
.bkq__lane--both > em { display: none; }
@media (max-width: 600px) {
  .bkq__lanes { grid-template-columns: 1fr; }
  .bkq__lane--both { flex-direction: column; align-items: flex-start; gap: 6px; padding: 18px 20px; }
  .bkq__lane--both .bkq__laneico { margin-bottom: 4px; }
}

/* SERVICE ROWS — the list you choose from.
   These replaced a grid of flat cards that nobody could tell were buttons.
   A row is wide, has a price hard right, and ends in a filled "+" circle;
   the whole row is the hit target, and on hover the "+" fills orange so the
   affordance is unmistakable on desktop too. */
.bkq__rows { display: grid; gap: 8px; margin-bottom: 4px; }
.bkq__row { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left; cursor: pointer;
  background: var(--white); border: 1.5px solid var(--line); border-radius: var(--radius); padding: 13px 14px;
  font: inherit; color: inherit; transition: border-color .15s, transform .15s, box-shadow .15s; }
.bkq__row:hover { border-color: var(--yellow); transform: translateY(-1px); box-shadow: 0 6px 18px rgba(20,18,16,.07); }
.bkq__rowt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.bkq__rowt b { font-family: var(--head); font-size: .96rem; font-weight: 700; color: var(--ink);
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.bkq__rowt > span { font-size: .8rem; color: var(--muted); line-height: 1.4; }
.bkq__rowp { flex: 0 0 auto; font-family: var(--head); font-weight: 800; font-size: 1.04rem;
  color: var(--orange-ink); font-variant-numeric: tabular-nums; text-align: right; }
.bkq__rowp small { display: block; font-weight: 600; color: var(--muted); font-size: .64rem;
  letter-spacing: .08em; text-transform: uppercase; }
.bkq__rowgo { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%; border: 1.5px solid var(--line);
  font-family: var(--head); font-weight: 800; font-size: 1.15rem; line-height: 1; color: var(--orange-ink);
  transition: background .15s, color .15s, border-color .15s; }
.bkq__row:hover .bkq__rowgo { background: var(--yellow); border-color: var(--yellow); color: var(--blue); }

/* THE 50/50 "BOTH" SCREEN. Carpet left, pest right, equal columns. */
.bkq__two { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 6px; }
.bkq__panel { min-width: 0; }
.bkq__panelhead { display: flex; align-items: center; gap: 9px; margin: 0 0 10px;
  font-family: var(--head); font-weight: 800; font-size: .82rem; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink); }
.bkq__panelico { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px;
  border-radius: 8px; background: linear-gradient(140deg, #ffb45f, #ff9933); color: #241a10; }
.bkq__panelico .ico { width: 14px; height: 14px; }
@media (max-width: 680px) {
  .bkq__two { grid-template-columns: 1fr; gap: 20px; }
  .bkq__rowt > span { display: none; }
}

.bkq__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 10px; }
.bkq__svc { display: flex; flex-direction: column; gap: 4px; text-align: left; width: 100%; cursor: pointer;
  background: var(--white); border: 1.5px solid var(--line); border-radius: var(--radius); padding: 14px 15px;
  font: inherit; color: inherit; transition: border-color .15s, transform .15s; }
.bkq__svc:hover { border-color: var(--yellow); transform: translateY(-1px); }
.bkq__svc b { font-family: var(--head); font-size: .98rem; color: var(--ink); font-weight: 700; display: flex; align-items: center; gap: 7px; }
.bkq__svc span { font-size: .82rem; color: var(--muted); line-height: 1.4; }
.bkq__svc em { font-style: normal; font-family: var(--head); font-weight: 800; color: var(--orange-ink); font-size: 1.02rem; margin-top: 6px; font-variant-numeric: tabular-nums; }
.bkq__svc em small { font-weight: 600; color: var(--muted); font-size: .72rem; margin-right: 3px; }
.bkq__pop { font-size: .6rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; background: var(--yellow); color: var(--blue); border-radius: 99px; padding: 2px 7px; }
.bkq__cathead { font-family: var(--head); font-weight: 800; font-size: .74rem; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); margin: 22px 0 9px; }

.bkq__card { background: var(--white); border: 1.5px solid var(--line); border-radius: var(--radius-lg); padding: 16px; margin-bottom: 12px; }
.bkq__q { font-family: var(--head); font-weight: 700; color: var(--ink); font-size: .92rem; margin: 0 0 9px; }
.bkq__sub { font-size: .8rem; line-height: 1.5; color: var(--muted); margin: -4px 0 11px; }

/* ---- THE THREE CONDITION LEVELS, ALL PRICED AT ONCE ----
   Deliberately not the .bkq__opt row the rest of this step uses. A radio row
   shows one price at a time; this card's entire purpose is that the customer
   can see what all three cost before they choose, so nothing can move on them
   later. See the note in booking.js.
   Three across on desktop, stacked on a phone. The price is the biggest thing
   in each card because it is the thing being compared. */
/* THE THREE PACKAGES — ON BRAND.
   Pearce, 02/10/2026: "make the three packages more on brand, they are off."
   He was right and the fault was mine: the prices were set in --blue. Blue is
   the SECOND brand colour and he has already ruled on where it may appear —
   28/09/2026, "make the top bar this blue, that's fine, the rest no." Orange
   leads, and every price on this site is orange. Three blue numbers in the
   middle of an orange page read as another company's card dropped into ours.
   So: the price takes --orange-ink-d (the sampled wrap orange, and the only
   one of the family that clears 4.5:1 on cream), the ladder is legible as a
   ladder through a weighted top rule rather than a third colour, and the one
   that is chosen is the only one that is filled. */
.bklv { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.bklv__o { display: grid; align-content: start; gap: 3px; text-align: left; cursor: pointer;
  background: var(--white); border: 1.5px solid var(--line); border-radius: 14px;
  padding: 0 13px 14px; transition: .15s; font: inherit; color: inherit;
  position: relative; overflow: hidden; }
/* The rung. Three weights of the same orange, so the ladder reads at a glance
   without introducing a colour that is not on the truck. */
.bklv__o::before { content: ""; display: block; height: 4px; margin: 0 -13px 12px;
  background: var(--yellow); opacity: .35; }
.bklv__o:nth-child(2)::before { opacity: .65; }
.bklv__o:nth-child(3)::before { opacity: 1; }
.bklv__o:hover { border-color: var(--yellow); box-shadow: 0 6px 18px rgba(0,0,0,.07); }
.bklv__o.sel { border-color: var(--yellow); background: var(--yellow-soft);
  box-shadow: 0 0 0 3px rgba(255, 153, 51, .3); }
.bklv__o.sel::before { opacity: 1; }
.bklv__lvl { font-family: var(--head); font-weight: 800; font-size: .58rem; letter-spacing: .13em;
  text-transform: uppercase; color: var(--muted); }
.bklv__o.sel .bklv__lvl { color: var(--orange-ink-d); }
.bklv__nm { font-family: var(--head); font-weight: 800; font-size: .95rem; line-height: 1.2; color: var(--ink); }
.bklv__pr { font-family: var(--head); font-weight: 800; font-size: 1.55rem; line-height: 1.1;
  color: var(--orange-ink-d); font-variant-numeric: tabular-nums; margin: .18rem 0 .12rem; }
.bklv__bl { font-size: .76rem; line-height: 1.45; color: var(--body); }
@media (max-width: 560px) { .bklv { grid-template-columns: 1fr; }
  .bklv__o::before { height: 3px; margin-bottom: 10px; } }

.bkq__opts { display: flex; flex-direction: column; gap: 8px; }
.bkq__opt { display: flex; align-items: center; gap: 11px; cursor: pointer; background: var(--cream2); border: 1.5px solid transparent;
  border-radius: 12px; padding: 11px 13px; transition: .15s; width: 100%; text-align: left; font: inherit; color: inherit; }
.bkq__opt:hover { border-color: var(--yellow); }
.bkq__opt.sel { border-color: var(--yellow); background: var(--yellow-soft); }
.bkq__opt .bkq__dot { width: 17px; height: 17px; border-radius: 50%; border: 2px solid var(--muted); flex: none; position: relative; }
.bkq__opt.sel .bkq__dot { border-color: var(--yellow-d); }
.bkq__opt.sel .bkq__dot::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--yellow-d); }
.bkq__opt .bkq__sq { border-radius: 5px; }
.bkq__opt.sel .bkq__sq::after { border-radius: 2px; }
.bkq__opt .bkq__t { flex: 1; min-width: 0; }
.bkq__opt .bkq__t b { display: block; font-family: var(--head); font-weight: 600; color: var(--ink); font-size: .9rem; }
.bkq__opt .bkq__t span { display: block; font-size: .78rem; color: var(--muted); }
.bkq__opt .bkq__p { font-family: var(--head); font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; font-size: .94rem; }

.bkq__chips { display: flex; gap: 7px; flex-wrap: wrap; }
.bkq__chip { cursor: pointer; background: var(--cream2); border: 1.5px solid transparent; border-radius: 10px; padding: 8px 15px;
  font: inherit; font-family: var(--head); font-weight: 700; font-size: .88rem; color: var(--body); }
.bkq__chip.sel { border-color: var(--yellow); background: var(--yellow-soft); color: var(--ink); }

/* A TIME THAT IS ALREADY TAKEN, SHOWN RATHER THAN HIDDEN.
   Dropping booked slots off the list makes a busy Tuesday look like a short
   day. Striking them through says "that one has gone" and makes the days
   with room obvious by contrast. Not a button any more, so no hover and no
   pointer. Added 09/10/2026 with live availability. */
.bkq__chip[disabled] { opacity: .38; cursor: not-allowed; text-decoration: line-through; }

/* "NOT GUARANTEED", ON THE DAY ITSELF.
   Pearce, 09/10/2026: Thursdays and Fridays are "no guaranteed booking ...
   select and the office will confirm if avalible". That has to be legible
   BEFORE the time is picked, not in the confirmation afterwards, so it sits
   on the day heading in brand orange. */
.bkq__tag { display: inline-block; vertical-align: middle; margin-left: 7px;
  background: var(--yellow-soft); color: var(--ink); border: 1px solid var(--yellow);
  border-radius: 999px; padding: 2px 9px; font-size: .68rem; font-weight: 700;
  letter-spacing: .02em; text-transform: uppercase; }

/* ============================================================
   THE ROOM GRID — LEFT TO RIGHT, NOT UP AND DOWN.
   ============================================================
   Pearce, 02/10/2026: "i dont like the volume of scrolling... I feel like it
   should be left to right not up and down", then, shown three layouts at 100%
   zoom, the tile grid.

   Twelve stacked rows meant eleven scrolls past rooms that are nearly all
   zero, and the minimum-price note — the one thing on that screen a customer
   needs to read — sat below all of them. Four across is three rows, and the
   whole question fits the window the page opens at. The breakpoint is 720px
   rather than 860 on purpose: at 860 a laptop sized a notch below full width
   dropped to three across and the grid went back to four rows, which is the
   exact thing being fixed.

   The size caveat is folded away under the grid. It still matters, but it is
   reassurance rather than a question, and open it was what pushed the last row
   off the bottom of a 100% window. */
.bkq__rmgrid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.bkq__rm { display: flex; flex-direction: column; align-items: center; gap: 2px; text-align: center;
  background: var(--white); border: 1.5px solid var(--line); border-radius: 12px;
  padding: 8px 6px 7px; transition: border-color .13s, background .13s; min-width: 0; }
.bkq__rm:hover { border-color: #ddd5c9; }
/* SELECTED IS ORANGE — #FF9933, the primary, which Pearce sent as a swatch on
   02/10/2026 ("instead of blue, make it the orange on brand, this one").
   We tried blue here for an hour and he reversed it; orange is the brand's
   lead colour and selection is the most important state on the screen, so
   that is the right call even though it costs some contrast against the
   orange badges. The contrast is bought back three other ways instead of with
   a second hue: the badge DEEPENS to the sampled wrap orange, the tile fills,
   and a ring is thrown around the whole thing. Together they are louder than
   a colour change on its own was. */
.bkq__rm.has { border-color: var(--yellow); background: var(--yellow-soft);
  box-shadow: 0 0 0 3px rgba(255, 153, 51, .28); }
.bkq__rmbadge { width: 34px; height: 34px; border-radius: 10px; background: var(--yellow);
  display: grid; place-items: center; flex: none; transition: background .13s; }
.bkq__rm.has .bkq__rmbadge { background: var(--orange-ink-d); }
.bkq__rm.has b { color: var(--orange-ink-d); }
.bkq__rm.has .bkq__n { color: var(--orange-ink-d); }
.bkq__rm.has .bkq__step button { border-color: rgba(255, 153, 51, .55); background: #fff; }
.bkq__rmic { width: 20px; height: 20px; color: #fff; flex: none; }
.bkq__rm b { font-family: var(--head); font-weight: 700; font-size: .77rem; color: var(--ink);
  line-height: 1.18; }
.bkq__rm span { font-size: .65rem; color: var(--muted); line-height: 1.3; }
.bkq__rm .bkq__step { margin-top: 3px; }
.bkq__rm .bkq__step button { width: 25px; height: 25px; }
@media (max-width: 720px) { .bkq__rmgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 520px) { .bkq__rmgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* On the shortest laptops the heading block gives up a little too, so the
   last row of tiles and the minimum-price note clear the sticky bar. */
@media (min-width: 721px) and (max-height: 800px) {
  #bkq-app h2 { font-size: 1.28rem; }
  #bkq-app .bkq__lead { font-size: .84rem; margin-bottom: 10px; }
  #bkq-app .bkq__kick { margin-bottom: 2px; }
}

/* THE SHORT-SCREEN VARIANT — TIGHTER, NOT SIDEWAYS.
   The first attempt turned each tile into a row with the icon beside the
   label. It fitted, and it looked broken: four across inside a 760px column
   leaves about 65px for the text, so "up to 4 × 4 m" wrapped onto three lines
   and every tile was a different height. The centred tile is the right shape
   at this width; it just has to give up a few pixels on a short window. */
@media (min-width: 721px) and (max-height: 820px) {
  .bkq__rmgrid { gap: 6px; }
  .bkq__rm { padding: 6px 5px 6px; gap: 1px; }
  .bkq__rmbadge { width: 28px; height: 28px; border-radius: 9px; }
  .bkq__rmic { width: 17px; height: 17px; }
  .bkq__rm b { font-size: .74rem; }
  .bkq__rm span { font-size: .63rem; }
  .bkq__rm .bkq__step { margin-top: 2px; }
  .bkq__rm .bkq__step button { width: 22px; height: 22px; }
  .bkq__rmgrid { gap: 5px; }
  .bkq__rm { padding: 5px 4px; }
  .bkq__rm span { font-size: .62rem; }
  #bkq-app .bkq__lead { font-size: .81rem; margin-bottom: 9px; line-height: 1.45; }
  .bkq__rmgrid { gap: 4px; }
  .bkq__rm .bkq__n { font-size: .85rem; }
  /* the card and the note give up the last 30px between them */
  #bkq-app .bkq__card { padding: 12px; }
  .bkq__note--tight { margin-top: 7px; padding-block: 6px; font-size: .75rem; }
  .bkq__fold--tight { margin-top: 7px; }
}
/* The one phrase in the lead that is doing work rather than explaining. */
.bkq__leadnudge { color: var(--orange-ink-d); font-weight: 700; }
.bkq__note--tight { margin-top: 8px; padding-block: 7px; font-size: .78rem; line-height: 1.4; }
.bkq__fold--tight { margin-top: 9px; }
.bkq__fold--tight > summary { font-size: .8rem; }

.bkq__room { display: flex; align-items: center; gap: 11px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.bkq__room:last-child { border-bottom: 0; }
.bkq__room .bkq__t { flex: 1; min-width: 0; }
.bkq__room .bkq__t b { display: block; font-family: var(--head); font-weight: 600; color: var(--ink); font-size: .9rem; }
.bkq__room .bkq__t span { display: block; font-size: .74rem; color: var(--muted); }
.bkq__room .bkq__pr { font-family: var(--head); font-weight: 700; color: var(--muted); font-size: .82rem; font-variant-numeric: tabular-nums; min-width: 38px; text-align: right; }
.bkq__step { display: flex; align-items: center; gap: 2px; flex: none; }
.bkq__step button { width: 44px; height: 44px; border-radius: 9px; border: 1.5px solid var(--line); background: var(--white);
  color: var(--ink); font-size: 1.1rem; font-weight: 700; cursor: pointer; line-height: 1; display: flex; align-items: center; justify-content: center; font-family: var(--head); }
.bkq__step button:hover:not(:disabled) { border-color: var(--yellow); color: var(--orange-ink); }
.bkq__step button:disabled { opacity: .3; cursor: default; }
.bkq__step .bkq__n { width: 30px; text-align: center; font-family: var(--head); font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; font-size: 1rem; }
.bkq__room.has .bkq__n { color: var(--orange-ink); }

.bkq__note { display: flex; gap: 9px; background: var(--yellow-soft); border: 1px solid rgba(255,153,51,.32); border-radius: 12px;
  padding: 11px 13px; font-size: .82rem; color: var(--body); margin-top: 12px; line-height: 1.5; }
.bkq__note b { color: var(--orange-ink); }

.bkq__lines { margin: 0; padding: 0; list-style: none; }
.bkq__lines li { display: flex; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--line); font-size: .88rem; }
.bkq__lines li:last-child { border-bottom: 0; }
.bkq__lines li span { flex: 1; }
.bkq__lines li b { font-family: var(--head); font-variant-numeric: tabular-nums; color: var(--ink); }
.bkq__tot { display: flex; gap: 12px; align-items: baseline; margin-top: 12px; padding-top: 12px; border-top: 2px solid var(--ink); }
.bkq__tot span { flex: 1; font-family: var(--head); font-weight: 700; color: var(--ink); }
.bkq__tot b { font-family: var(--head); font-weight: 800; font-size: 1.5rem; color: var(--ink); font-variant-numeric: tabular-nums; }

/* ============================================================
   THE ACTION ROW — UNDER THE QUESTION, NOT PINNED TO THE WINDOW.
   ============================================================
   Pearce, 02/10/2026: "frankly i hate the bottom bar... you have to move the
   mouse so far down to click continue, then all the way back up."
   A control pinned to the bottom of the window is a control a long way from
   whatever you just clicked. Every question cost two full-height mouse
   journeys, which on a two-option screen was most of the work. This row sits
   directly beneath the last option, and the price travels with it so the
   number is beside the thing that changed it.
   The .bkq__bar rules below are kept because the markup may still exist in a
   cached book.html; the bar itself is no longer rendered. */
/* ============================================================
   WHAT WE'D RECOMMEND — AND WHY.
   ============================================================
   Pearce, 02/10/2026: "right now, upsells nobody would select, nothing has
   told them otherwise or why they are important."
   The recommended add-ons are set apart from the rest of the list, each
   carrying the reason the customer's own answers produced. The reason is the
   point, so it gets real type rather than being squeezed in as fine print,
   and the block is tinted so the eye lands on it before the plain list. */
.bkq__card--rec { border-color: var(--yellow); background: linear-gradient(180deg, var(--yellow-soft) 0%, #fff 70%); }
.bkq__rechead { display: flex; align-items: center; gap: 8px; margin: 0 0 10px;
  font-family: var(--head); font-weight: 800; font-size: .92rem; color: var(--ink); }
.bkq__recpip { flex: none; width: 20px; height: 20px; border-radius: 50%; background: var(--yellow);
  color: var(--ink); display: grid; place-items: center; font-size: .66rem; font-weight: 800; }
.bkq__opt--rec { align-items: flex-start; }
.bkq__why { display: block; margin-top: 6px; font-size: .79rem; line-height: 1.5; color: var(--body);
  padding-left: 10px; border-left: 2px solid var(--yellow); }
.bkq__note--rec { border-left-color: var(--yellow); background: var(--yellow-soft); }
.bkq__card--q { padding-block: 12px; }
.bkq__card--q + .bkq__card--q { margin-top: 8px; }

/* The level the answers point at. A tag and a ring, not a selection — the
   customer still picks, and all three prices stay on screen. */
/* THREE STATES, NOT ONE. A single highlighted card at the top of the range
   reads as an upsell; the honest picture is a range with a floor. See
   levelAdvice() in booking.js — the suggested level is marked, the one below
   is marked as possibly enough, and anything two levels or more below is
   ruled out and not selectable, because the grading promise only ever moves a
   customer DOWN and a locked-in Standard on a neglected carpet is a job we
   cannot do at that price. */
.bklv__o.sugg { border-color: var(--yellow); box-shadow: 0 0 0 3px rgba(255,153,51,.22); }
.bklv__o.mayb { border-color: rgba(255,153,51,.5); }
.bklv__o.mayb .bklv__tag { background: var(--yellow-soft); color: var(--orange-ink-d); }
.bklv__o.out { opacity: .5; cursor: not-allowed; border-style: dashed; }
.bklv__o.out:hover { border-color: var(--line); box-shadow: none; }
.bklv__o.out .bklv__tag { background: var(--cream2); color: var(--muted); }
.bklv__o.out .bklv__pr { color: var(--muted); text-decoration: line-through; }
.bklv__o.out::before { opacity: .25; }
.bklv__tag { display: block; margin: 0 -13px 8px; padding: 4px 13px; background: var(--yellow);
  color: var(--ink); font-family: var(--head); font-weight: 800; font-size: .62rem;
  letter-spacing: .08em; text-transform: uppercase; }
.bklv__o.sugg::before { opacity: 1; }

.bkq__act { display: flex; align-items: center; gap: 14px; margin: 18px 0 8px;
  padding-top: 16px; border-top: 1px solid var(--line); }
.bkq__act-sp { flex: 1; }
.bkq__act-back { flex: none; background: none; border: 0; cursor: pointer; padding: 10px 2px;
  font-family: var(--head); font-weight: 700; font-size: .88rem; color: var(--muted); }
.bkq__act-back:hover { color: var(--ink); }
.bkq__act-amt { flex: 1; text-align: right; line-height: 1.12; }
.bkq__act-amt small { display: block; color: var(--muted); font-size: .68rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; }
.bkq__act-amt b { font-family: var(--head); font-weight: 800; font-size: 1.3rem; color: var(--ink);
  font-variant-numeric: tabular-nums; display: block; }
.bkq__act .bkq__go--inline { flex: none; margin: 0; }
@media (max-width: 520px) {
  .bkq__act { gap: 9px; }
  .bkq__act-amt b { font-size: 1.12rem; }
  .bkq__act .bkq__go--inline { padding: 14px 20px; font-size: .95rem; }
}
/* THE ACTION ROW ON A PHONE: the price gets its own line.
   Back, a running price and Continue cannot share 393px without one of them
   being squeezed, and the one that was losing is the price — the single most
   important number on the page. It goes above, full width and left-aligned
   so it reads as a statement rather than a label hanging off a button, and
   Back and Continue share the line underneath with Continue taking the room
   that is left. */
@media (max-width: 560px) {
  .bkq__act { flex-wrap: wrap; row-gap: 10px; }
  .bkq__act-amt { flex: 1 1 100%; order: -1; text-align: left; }
  .bkq__act-amt b { display: inline; }
  .bkq__act-amt small { display: inline; margin-right: .4em; }
  .bkq__act-back { flex: 0 0 auto; }
  .bkq__act-sp { flex: 1 1 auto; }
  .bkq__act .bkq__go--inline { flex: 1 1 auto; width: auto; min-width: 0; }
}

.bkq__bar[hidden] { display: none; }
/* THE BAR IS BLUE. LEAVE IT BLUE.
   I changed it to near-black on 02/10/2026, reasoning from the "blue is the
   top bar and that is all" rule, and Pearce reversed it the same day: "change
   the blue back, the black is not on brand as i have previously said."
   He is right and I had the rule backwards. BLACK IS NOT A BFYB COLOUR — it
   is excluded by name (see the palette note at the top of this file: it
   survives only as --ink, which is heading text on cream). The 28/09 ruling
   was about not flooding the site with blue surfaces, not about banning the
   one dark surface the flow has. This bar is the exception that ruling always
   allowed, and the orange price and orange button read fine against it.
   DO NOT "fix" this to black again. */
.bkq__bar { position: fixed; left: 0; right: 0; bottom: 0; background: var(--grad-blue); color: #fff;
  padding: 13px 16px; padding-bottom: calc(13px + env(safe-area-inset-bottom, 0px));
  z-index: 40; box-shadow: 0 -10px 30px rgba(0,0,0,.2); }
/* Matches the 780px column the flow itself uses, so the price sits directly
   under the thing that changed it rather than out at the window edge. */
.bkq__barin { max-width: 780px; margin: 0 auto; display: flex; align-items: center; gap: 12px; }
.bkq__bar .bkq__amt { flex: 1; min-width: 0; text-align: right; padding-right: 4px; }
/* THE PRICE ANNOUNCES ITSELF WHEN IT MOVES.
   A number that changes silently at the edge of the screen is a number
   nobody notices. One short pulse on change puts it in the corner of the
   eye without being a distraction, and it is skipped for anyone who has
   asked their system for less motion. */
@keyframes bkqbump { 0% { transform: scale(1); } 34% { transform: scale(1.13); } 100% { transform: scale(1); } }
.bkq__bar .bkq__amt b.bump { animation: bkqbump .34s ease-out; }
@media (prefers-reduced-motion: reduce) { .bkq__bar .bkq__amt b.bump { animation: none; } }
.bkq__bar .bkq__amt small { display: block; color: rgba(255,255,255,.55); font-size: .7rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }
.bkq__bar .bkq__amt b { font-family: var(--head); font-weight: 800; font-size: 1.32rem; color: var(--yellow); font-variant-numeric: tabular-nums; line-height: 1.1; display: block; }
.bkq__go { background: var(--yellow); color: var(--blue); border: 0; border-radius: 11px; padding: 13px 20px; cursor: pointer;
  font-family: var(--head); font-weight: 800; font-size: .95rem; white-space: nowrap; min-height: 44px; }
.bkq__go:hover { background: var(--yellow-d); }
.bkq__go:disabled { opacity: .4; cursor: default; }

/* STEP 1'S CONTINUE LIVES IN THE FLOW, NOT IN THE STICKY BAR.
   Pearce, 01/10/2026: "NO to the next in the bottom bar, it should be below the
   actual street address section." The bar's yellow-on-blue fill is built for a
   dark bar; dropped onto the cream page it has nothing to sit against, so the
   inline one wears the site's primary blue — the same button as "Request a
   quote" everywhere else. */
.bkq__gowrap { display: flex; justify-content: flex-end; margin: 16px 0 6px; }  /* unused since the action row landed */
.bkq__go--inline { background: var(--grad-blue-btn); color: #fff; padding: 15px 32px; font-size: 1.04rem;
  box-shadow: 0 10px 22px rgba(7,110,184,.26); transition: transform .16s ease, box-shadow .16s ease; }
.bkq__go--inline:hover:not(:disabled) { background: var(--grad-blue-btn); transform: translateY(-1px);
  box-shadow: 0 14px 28px rgba(7,110,184,.34); }
.bkq__go--inline:disabled { background: #E4DFD6; color: #6A6158; opacity: 1; box-shadow: none; transform: none; }
@media (prefers-reduced-motion: reduce) { .bkq__go--inline:hover:not(:disabled) { transform: none; } }
/* SCOPED. Found 10/10/2026 from photographs of the real booking flow on a
   phone: "ADD A ROOM TO SEE YOUR PRICE" was setting one word per line in a
   column about 60px wide, and the Continue button ran off the right edge of
   the screen with the whole page scrolling sideways.

   Both came from this one rule. It sets width:100% on EVERY .bkq__go--inline
   below 560px, and the Continue button in the action row is one of those —
   sitting in a flex row next to Back and the running price, with flex:none.
   A flex:none item asked for 100% takes the whole row: the price label
   (flex:1) collapses to its narrowest possible width, which is one word, and
   the row overflows the viewport.

   The rule was written for .bkq__gowrap, a container that no longer appears
   anywhere in assets/booking.js. Scoping it to that container leaves it
   harmless if the markup ever comes back, and takes it off the action row,
   which lays itself out properly below. */
@media (max-width: 560px) { .bkq__gowrap { justify-content: stretch; } .bkq__gowrap .bkq__go--inline { width: 100%; } }

.bkq__back { background: transparent; border: 1.5px solid rgba(255,255,255,.28); color: #fff; border-radius: 11px; padding: 12px 15px;
  cursor: pointer; font-family: var(--head); font-weight: 700; font-size: .9rem; white-space: nowrap; flex: none; min-height: 44px; }
.bkq__back:hover { border-color: var(--yellow); color: var(--yellow); }
/* The same class is used inside the blue bar AND at the top of each step. In
   the flow it was white-on-white — there, but invisible. That mattered little
   while the bar carried a second Back; now that step 1 has no bar, it is the
   only way back. */
#bkq-app .bkq__back { background: #fff; border-color: rgba(7,110,184,.32); color: var(--blue); margin-bottom: 16px; }
#bkq-app .bkq__back:hover { border-color: var(--blue); color: var(--blue-d); background: var(--cream2); }

.bkq__slots { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.bkq__warr { display: flex; gap: 9px; align-items: flex-start; font-size: .84rem; color: var(--body); margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
.bkq__tick { color: var(--yellow-d); font-weight: 800; flex: none; }
.bkq__fine { font-size: .76rem; color: var(--muted); margin-top: 14px; line-height: 1.55; }
.bkq__caveat { background: var(--cream2); border-left: 3px solid var(--yellow); border-radius: 0 12px 12px 0; padding: 12px 14px; font-size: .82rem; margin-top: 14px; line-height: 1.55; }
.bkq__caveat b { color: var(--ink); font-family: var(--head); }

/* The flow owns the bottom of the screen; the site's own book bar would sit on
   top of the price. */
body:has(.bkq__bar) .bookbar { display: none; }
/* Only reserve room for the bar on the steps that actually have one — step 1
   runs its Continue inline, so 96px there is just a hole above the footer. */
main:has(#bkq-app) { padding-bottom: 28px; }
body:has(.bkq__bar:not([hidden])) main:has(#bkq-app) { padding-bottom: 96px; }

/* Booking: the details form on the last step. */
.bkq__form { display: grid; grid-template-columns: 1fr 1fr; gap: 11px; }
.bkq__form .bkq__wide { grid-column: 1 / -1; }
.bkq__form label { display: flex; flex-direction: column; gap: 5px; font-family: var(--head);
  font-weight: 600; font-size: .82rem; color: var(--ink); min-width: 0; }
.bkq__form input, .bkq__form textarea { font: inherit; font-family: var(--font); font-weight: 400;
  font-size: 1rem; color: var(--ink); background: var(--white); border: 1.5px solid var(--line);
  border-radius: 10px; padding: 11px 12px; min-height: 44px; width: 100%; }
.bkq__form input:focus, .bkq__form textarea:focus { outline: none; border-color: var(--yellow); box-shadow: var(--ring); }
.bkq__form textarea { resize: vertical; min-height: 66px; }
@media (max-width: 560px) { .bkq__form { grid-template-columns: 1fr; } }

/* The price pill above the hero headline. Kapow's "FROM just $175!" — the
   first thing anyone reads, because it is the only question they have yet. */
.heropill { display: inline-flex; align-items: center; gap: .4em; background: var(--grad-blue); color: var(--yellow);
  font-family: var(--brand); font-weight: 800; font-size: 1.02rem; letter-spacing: .01em;
  padding: .42rem 1.1rem .5rem; border-radius: 999px; margin: 0 0 1rem;
  box-shadow: 0 6px 16px rgba(0,0,0,.18); }
@media (max-width: 860px) { .heropill { font-size: .94rem; } }

/* Quote form */
.qform__know { display: flex; gap: .7rem; align-items: flex-start; background: var(--yellow-soft);
  border: 1px solid rgba(255,153,51,.32); border-radius: var(--radius); padding: 13px 15px;
  font-size: .9rem; margin-bottom: 1.4rem; line-height: 1.55; }
.qform__know .ico { color: var(--orange-ink); flex: none; margin-top: .15em; }

/* ---- UPSELLS INSIDE A PRICE ROW ----
   Pearce, 01/10/2026: "go see KAPOW, each is listed better, with upsell
   options, we are the same so go copy them."
   Set apart from the row's body copy with a tint and a rule, so it reads as a
   menu rather than as more prose. The paired spray gets the orange left edge
   because it is the one upsell that is genuinely worth the customer's time. */
.upsell { background: var(--cream2); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 12px 14px 10px; margin: 14px 0; }
.upsell__h { display: block; font-family: var(--head); font-weight: 800; font-size: .62rem;
  letter-spacing: .13em; text-transform: uppercase; color: var(--orange-ink-d); margin-bottom: 8px; }
.upsell__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.upsell__i { display: flex; align-items: baseline; justify-content: space-between; gap: .8rem;
  background: var(--white); border: 1px solid var(--line); border-radius: 9px; padding: 8px 11px; }
.upsell__i--pair { border-color: rgba(255,153,51,.5); border-left: 4px solid var(--yellow); }
.upsell__l { min-width: 0; display: grid; gap: 1px; }
.upsell__l b { font-size: .86rem; font-weight: 700; color: var(--ink); line-height: 1.3; }
.upsell__l span { font-size: .76rem; color: var(--muted); line-height: 1.4; }
.upsell__p { flex: none; font-family: var(--head); font-weight: 800; font-size: .92rem;
  color: var(--orange-ink-d); font-variant-numeric: tabular-nums; }
.upsell__p small { font-weight: 700; font-size: .68rem; color: var(--muted); }
.upsell__note { font-size: .76rem; line-height: 1.45; color: var(--muted); margin: 9px 0 0; }

/* ---- "WELCOME BACK" — remembered contact details ----
   Pearce, 02/10/2026: "BFYB needs pre-memory, so when a customer begins to
   type their details, options that pre fill it happen too."
   Shown above the form only when this browser has sent an enquiry before.
   Deliberately a soft offer, not a banner: it sits in the page flow, states
   what it knows, and carries its own way out. */
.qfmem { margin: 0 0 16px; }
.qfmem__in { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  background: var(--yellow-soft); border: 1.5px solid rgba(255,153,51,.42);
  border-radius: var(--radius-lg); padding: 13px 15px; }
.qfmem__in > .ico { width: 24px; height: 24px; flex: none; color: var(--orange-ink-d); }
.qfmem__t { flex: 1 1 14rem; min-width: 0; display: grid; gap: 1px; }
.qfmem__t b { font-family: var(--head); font-weight: 800; font-size: .95rem; color: var(--ink); }
.qfmem__t span { font-size: .84rem; line-height: 1.4; color: var(--body); }
.qfmem__acts { display: flex; align-items: center; gap: 10px; flex: none; }
.qfmem__no { font: inherit; font-size: .82rem; font-weight: 600; color: var(--muted);
  background: none; border: none; cursor: pointer; text-decoration: underline;
  text-underline-offset: 2px; padding: 4px; }
.qfmem__no:hover { color: var(--ink); }
@media (max-width: 520px) { .qfmem__acts { flex: 1 1 100%; } }

/* ---- THE PRICING PAGE'S OWN DOOR ----
   Pearce, 01/10/2026: "when you click pricing, it should ask, what service, or
   both carpet/pest as it starts at pest. we wil lloose people wanting just
   carpet."
   Three cards, above the fold, each carrying its real "from". Equal height by
   grid, with the price pinned to the bottom of each so the three numbers sit
   on one line and can be compared at a glance. */
/* The three doors have to be ON SCREEN when the page opens, or they are not
   asking anything — which was the whole complaint. So the pricing hero is
   shortened and the cards sit tight under it. */
.hero--pick .hero__inner { padding: 2.2rem 24px 3rem; }
.hero--pick h1 { font-size: clamp(1.9rem, 4vw, 2.9rem); }
.pickprice { padding: 1.4rem 0 0; }
.pickprice__q { font-family: var(--head); font-weight: 800; font-size: .92rem; color: var(--ink);
  margin: 0 0 12px; }
.pickprice__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.pickprice__b { display: grid; grid-template-rows: auto auto 1fr auto; gap: 4px;
  text-decoration: none; color: inherit; background: var(--white);
  border: 2px solid var(--line); border-radius: 16px; padding: 18px 18px 16px;
  transition: .15s; box-shadow: 0 3px 12px rgba(20,18,16,.06); }
.pickprice__b .ico { width: 30px; height: 30px; color: var(--blue); }
.pickprice__b b { font-family: var(--head); font-weight: 800; font-size: 1.14rem; color: var(--ink); }
.pickprice__b span { font-size: .84rem; line-height: 1.45; color: var(--muted); }
.pickprice__b em { font-family: var(--head); font-style: normal; font-weight: 800; font-size: 1.05rem;
  color: var(--orange-ink-d); margin-top: 8px; }
.pickprice__b:hover { border-color: var(--yellow); transform: translateY(-2px);
  box-shadow: 0 12px 26px rgba(255,153,51,.26); }
.pickprice__b--both { background: var(--yellow-soft); border-color: rgba(255,153,51,.42); }
.pickprice__b--both .ico { color: var(--orange-ink-d); }
@media (max-width: 760px) { .pickprice__grid { grid-template-columns: 1fr; } }

/* ---- THE SERVICE PICKER, FIRST THING ON THE QUOTE FORM ----
   Pearce, 01/10/2026: "this request a quote isnt helpful needs al lthe
   questions we ask carpet for BFYB, and KAPOW pest." The questions were
   already built; they were invisible because the service was a <select> under
   the address, so nothing ever revealed them. Tiles, at the top, and the
   questions appear under the tile that was just tapped.
   .qfpick__fallback is the real <select>, hidden by script once the tiles are
   working — so a browser with JS off still gets a usable dropdown. */
/* UNANSWERED, THE PICKER IS THE WHOLE FORM. Pearce, 02/10/2026: the service
   "should be asked first, like it takes over the screen to ask." Nothing else
   is rendered until it is answered (see quote-form.js), so the tiles are sized
   to be the only thing on the screen — big targets, generous spacing, a real
   question above them. Once answered the block collapses to .qfpick--chosen
   and gets out of the way of the questions it just revealed. */
.qfpick { margin: 0 0 16px; }
.qfpick__q { font-family: var(--head); font-weight: 800; font-size: 1.35rem; line-height: 1.2;
  color: var(--ink); margin: 0 0 4px; }
.qfpick__sub { font-size: .92rem; line-height: 1.5; color: var(--muted); margin: 0 0 16px; }
.qfpick__grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 9px; }
/* Answered: half the padding, smaller type, and a line under it so it reads as
   a setting that can be changed rather than a question still being asked. */
.qfpick--chosen { border-bottom: 1px solid var(--line); padding-bottom: 14px; }
.qfpick--chosen .qfpick__q { font-size: .92rem; margin-bottom: 8px; }
.qfpick--chosen .qfpick__sub { display: none; }
.qfpick--chosen .qfpick__b { padding: 9px 11px; }
.qfpick--chosen .qfpick__b .ico { width: 20px; height: 20px; }
.qfpick--chosen .qfpick__b b { font-size: .88rem; }
.qfpick--chosen .qfpick__b span { display: none; }
.qfpick--chosen .qfpick__b:not(.on) { opacity: .62; }
.qfpick--chosen .qfpick__b:not(.on):hover { opacity: 1; }
.qfpick__b { display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto auto;
  column-gap: 11px; row-gap: 2px; align-items: center; text-align: left; cursor: pointer;
  font: inherit; color: inherit; background: var(--white);
  border: 2px solid var(--line); border-radius: 14px; padding: 13px 14px; transition: .15s; }
.qfpick__b .ico { grid-row: 1 / 3; width: 26px; height: 26px; color: var(--blue); }
.qfpick__b b { font-family: var(--head); font-weight: 800; font-size: 1rem; color: var(--ink); line-height: 1.2; }
.qfpick__b span { font-size: .78rem; line-height: 1.35; color: var(--muted); }
.qfpick__b:hover { border-color: var(--yellow); }
.qfpick__b.on { border-color: var(--yellow); background: var(--yellow-soft); }
.qfpick__b.on .ico { color: var(--orange-ink-d); }
@media (max-width: 560px) { .qfpick__grid { grid-template-columns: 1fr; } }
/* A plain sub-heading inside the form, for the details block at the foot. */
.qfq__h--std { font-family: var(--head); font-weight: 800; font-size: .74rem; letter-spacing: .13em;
  text-transform: uppercase; color: var(--orange-ink-d); margin: 20px 0 10px; }

/* ---- THE CONDITIONAL QUESTION BLOCKS ----
   Pearce, 01/10/2026: ask pest or carpet or both, then ask based on the
   answer, using the CRM's own carpet questions "so there isn't a need for a
   customer to type."
   Tap targets, not dropdowns, for the same reason the CRM uses buttons: every
   answer is visible at once and takes one tap. 44px minimum height so they
   work with a thumb. The block is tinted and inset so it reads as "this part
   appeared because of what you just picked" rather than as more form. */
.qfq { background: var(--cream2); border: 1.5px solid var(--line); border-radius: var(--radius-lg);
  padding: 15px 16px 4px; margin: 0 0 14px; }
.qfq__h { font-family: var(--head); font-weight: 800; font-size: .74rem; letter-spacing: .13em;
  text-transform: uppercase; color: var(--orange-ink-d); margin: 0 0 12px; }
.qfq__row { margin: 0 0 14px; }
.qfq__l { display: block; font-family: var(--head); font-weight: 700; font-size: .88rem;
  color: var(--ink); margin-bottom: 8px; line-height: 1.35; }
.qfq__opts { display: flex; flex-wrap: wrap; gap: 7px; }
.qfq__b { font: inherit; font-size: .86rem; font-weight: 600; color: var(--ink); cursor: pointer;
  background: var(--white); border: 1.5px solid var(--line); border-radius: 10px;
  padding: 10px 14px; min-height: 44px; transition: .14s; }
.qfq__b:hover { border-color: var(--yellow); }
.qfq__b.on { border-color: var(--yellow); background: var(--yellow-soft); font-weight: 800; }
.qfq__in { font: inherit; font-size: .92rem; width: 100%; margin-top: 8px; color: var(--ink);
  background: var(--white); border: 1.5px solid var(--line); border-radius: 10px; padding: 10px 12px; }
/* The not-a-standard-clean warning. Said to the customer in plain terms,
   rather than kept for the office — this is the number moving, and the whole
   argument for showing all three level prices applies here too. */
.qfq__flag { font-size: .88rem; line-height: 1.55; color: #1d1508; margin: 0 0 14px;
  background: rgba(255,153,51,.15); border-left: 4px solid var(--yellow);
  border-radius: 0 var(--radius) var(--radius) 0; padding: 11px 13px; }
/* A sub-heading inside a block that already has one — the pest panel runs
   three groups (the job, the safety declaration, access and pets), which is
   how Kapow's flow splits them. */
.qfq__h--2 { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.qfq__p--sm { font-size: .82rem; color: var(--muted); margin: -8px 0 12px; }
/* Property type carries a subtitle, as it does on Kapow — "house" and "unit"
   are not as obvious as they look once a townhouse or a villa is involved. */
.qfq__b--sub { text-align: left; white-space: normal; line-height: 1.25; max-width: 17rem; padding: 9px 13px; }
.qfq__b--sub span { display: block; font-weight: 500; font-size: .74rem; line-height: 1.35;
  color: var(--muted); margin-top: 3px; }
.qfq__b--sub.on span { color: #6b4a16; }
.qfq--urgent { background: var(--yellow-soft); border-color: rgba(255,153,51,.4); padding-bottom: 15px; }
.qfq__p { font-size: .92rem; line-height: 1.6; color: var(--body); margin: 0 0 12px; }
.qfq__acts { display: flex; flex-wrap: wrap; gap: 9px; }
.qform select { font: inherit; font-family: var(--font); font-size: 1rem; color: var(--ink);
  background: var(--white); border: 1.5px solid var(--line); border-radius: 10px; padding: 11px 12px;
  min-height: 44px; width: 100%; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%236f6c66' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center; background-size: 12px; padding-right: 36px; }
.qform select:focus, .qform input:focus, .qform textarea:focus { outline: none; border-color: var(--yellow); box-shadow: var(--ring); }
.qform input[readonly] { background: var(--cream2); color: var(--muted); }
.qform__done { background: var(--white); border: 1.5px solid var(--line); border-radius: var(--radius-lg);
  padding: 30px 22px; text-align: center; }
.qform__done h2 { margin: 0 0 8px; }

/* ===== Prices in the hero ==================================================
 * Two columns, two chips each: pest on the left, carpet on the right, equal
 * weight. BFYB is half carpet and half pest, and the layout has to say so
 * before a word is read. See the note in build-home.cjs.
 * ======================================================================== */
.heropair { display: grid; grid-template-columns: 1fr 1fr; gap: .55rem .8rem; margin: 1.1rem 0 .7rem; max-width: 33rem; }
/* ============================================================
   LAYOUT C — A LIST ON THE LEFT, A TOOL ON THE RIGHT.
   ============================================================
   Pearce, 03/10/2026, of six layouts. The two halves are not the same kind of
   thing: pest is a catalogue you pick from, carpet is a quote you build, and
   two matching price lists made the builder look like a four-item menu. The
   left column keeps its rows; the right becomes the thing it actually is.
   A little wider than the old pair, because the builder needs room to show
   what it does. */
.herobuild { display: flex; flex-direction: column; gap: .4rem; min-width: 0; flex: 1;
  background: #fff; border: 2px solid var(--yellow); border-radius: 13px; padding: .7rem .75rem .75rem;
  box-shadow: 0 6px 18px rgba(255,153,51,.18); }
.herobuild__h { font-family: var(--head); font-weight: 800; font-size: .74rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--orange-ink-d); }
/* The carpet heading is a sibling of the pest heading now, not a child of
   the orange card, so the two sit on the same baseline. */
.heropair--c > .heropairwrap > .heropair__h,
.heropair--c > .herobuildwrap > .herobuild__h { display: block; margin-bottom: .34rem; line-height: 1.2; }
/* Both sides are now heading-then-box. The pest box is the same box as the
   carpet one with its border made invisible, so the rows inside start on the
   same line on both sides by construction. */
.heropairwrap { display: flex; flex-direction: column; min-width: 0; }
.herobuildwrap { display: flex; flex-direction: column; min-width: 0; }
.herobuild__p { margin: 0; font-size: .76rem; line-height: 1.45; color: var(--body); }
/* The room names. Decoration doing a job: they are what makes the column read
   as a tool you use rather than a second button. */
.herobuild__rooms { display: flex; flex-wrap: wrap; gap: .25rem; }
.herobuild__rooms i { font-style: normal; background: var(--cream2); border: 1px solid var(--line);
  border-radius: 7px; padding: .18rem .42rem; font-size: .66rem; font-weight: 600; color: var(--body); }
.herobuild__more { background: var(--yellow-soft) !important; border-color: rgba(255,153,51,.4) !important;
  color: var(--orange-ink-d) !important; }
.herobuild__btn { display: flex; align-items: center; justify-content: center; gap: .45em;
  margin-top: auto; background: var(--yellow); color: var(--ink); border-radius: 10px;
  padding: .62rem .7rem; font-family: var(--head); font-weight: 800; font-size: .84rem;
  text-decoration: none; text-align: center; line-height: 1.25;
  box-shadow: 0 6px 16px rgba(255,153,51,.4); transition: transform .14s, box-shadow .14s; }
.herobuild__btn:hover { transform: translateY(-1px); box-shadow: 0 9px 22px rgba(255,153,51,.5); }
.herobuild__btn .ico { width: .85em; height: .85em; flex: none; }
@media (max-width: 760px) { .heropair--c { grid-template-columns: 1fr; max-width: 33rem; } }

/* SHORT SCREENS GIVE UP THE EXPLAINING, NOT THE CHOICES.
   Pearce has said twice that the landing page has to work at 100% on his own
   screen, and layout C is the tallest of the six: at 1366×768 the Request a
   quote button finished 120px under the fold. Keyed to window HEIGHT rather
   than width, because the problem is the vertical room a laptop has, not how
   wide it is. What goes is prose the chips and the button already say; what
   stays is every price and every door. */
@media (min-width: 761px) and (max-height: 850px) {
  .hero__copy h1 { font-size: 2.35rem; }
  .hero__lead { font-size: .88rem; margin-bottom: .55rem; }
  .heropair--c { margin: .75rem 0 .5rem; gap: .5rem .8rem; }
  .herobuild,
  .heropair--c .heropair__col { padding: .6rem .65rem .65rem; gap: .35rem; }
  .herobuild__p { display: none; }
  .herobuild__rooms i { font-size: .63rem; padding: .14rem .36rem; }
  .heroprice { padding-block: .3rem; }
  .heroboth { margin-top: .4rem; padding: calc(.45rem + 3px) calc(.8rem + 3px); }
  .heroboth__txt > span { font-size: .73rem; }
  .heropill { margin-bottom: .35rem; }
  /* the last dozen pixels */
  .hero:not(.hero--plain) .hero__copy { padding-block: 1.15rem; }
  .hero__cta { margin-top: .35rem; }
  .hero__cta .btn--lg { padding-block: .72rem; font-size: .95rem; }
  /* The line under the buttons goes too, by this block's own rule: it is
     prose the button it sits under already says. The quote door stays in
     the header, the nav, the footer and the closing band. */
  .hero__alt { display: none; }
  .heropair--c { margin-bottom: .42rem; }
}
/* THE TWO COLUMNS RUN FULL HEIGHT so their buttons line up. Pearce,
   01/10/2026: "they need to be the same size." "Build your carpet quote" wraps
   to two lines where "Book pest control" does not, so with align-content:start
   one button finished a line lower than the other and they read as two
   different controls. The columns now stretch, the button is pushed to the
   bottom of its column with margin-top:auto, and both carry the same
   min-height — so they are the same size whether a label wraps or not. */
.heropair__col { display: grid; gap: .34rem; align-content: start; min-width: 0;
  grid-template-rows: auto auto auto 1fr; }
/* Price chips sized up with the rest of the hero, 02/10/2026 — on Kapow these
   are the second thing the eye lands on after the headline, and at .74/.96rem
   ours were reading as footnotes. */
.heropair__h { font-family: var(--head); font-weight: 800; font-size: .74rem; letter-spacing: .1em;
  text-transform: uppercase; color: #6b4a1e; }
.heroprice { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem;
  /* Was translucent white, which simply vanished once the ground went
     white. A warm tint with a real border keeps them reading as chips. */
  background: var(--yellow-soft); border: 1.5px solid rgba(255,153,51,.42); border-radius: 10px;
  padding: .5rem .75rem; text-decoration: none; transition: background .14s, transform .14s, border-color .14s; }
.heroprice:hover { background: #fff; border-color: var(--yellow); transform: translateY(-1px); }
.heroprice__n { font-family: var(--head); font-weight: 600; font-size: .84rem; color: var(--ink); min-width: 0; }
.heroprice__p { font-family: var(--head); font-weight: 800; font-size: 1.14rem; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.heroprice__p small { font-weight: 700; font-size: .56rem; letter-spacing: .07em; text-transform: uppercase;
  color: var(--orange-ink); margin-right: .3em; }
/* One button under each column. Same weight on both sides — the page does not
   get to have an opinion about whether you came for pest or carpet. */
/* WHITE WITH AN ORANGE OUTLINE, NOT A FOURTH BLACK SLAB.
   Pearce, 28/09/2026: "there's too many black buttons, can we mix it up with
   different colour/style buttons? White with orange outlines?"
   The hero had four solid black blocks stacked down the left — two column
   buttons, the "both" strip and Request a quote — so nothing in it read as
   the main action. These two are the SECONDARY pair (one per service, equal
   weight to each other), so they go white with an orange edge: the fourth
   brand colour doing real work, and black is left to the one button that
   should own the eye. Filling orange on hover keeps the press obvious. */
/* THE TWO BUTTONS THAT MATTER, AT THE SIZE THEY MATTER.
   Pearce, 01/10/2026: "make BOOK PEST CONTROL and BUILD YOUR CARPETS QUOTE the
   same size as the request a quote please they are not obvious and i have read
   past them heaps."
   He wrote this page and he was still skimming past its two primary doors, so
   a customer had no chance. They were .84rem on a half-rem of padding —
   smaller than the price rows directly above them — which read as a caption
   under the prices rather than as the thing to press.
   They now match .btn--lg (1.05rem, 1.1rem/2rem padding) and go full width of
   their column, so each one is the biggest thing in it. The colours stay as
   they were: white with an orange rule, because two solid orange blocks here
   would fight the Request a quote button below and the orange band above. */
.heropair__btn { display: flex; width: 100%; align-items: center; justify-content: center; gap: .5em;
  background: #fff; color: var(--orange-ink); border: 2px solid var(--yellow);
  border-radius: 10px; padding: calc(.85rem - 2px) calc(1rem - 2px); margin-top: auto;
  min-height: 3.5rem; text-align: center;
  font-family: var(--head); font-weight: 800; font-size: 1.05rem; line-height: 1.15; text-decoration: none;
  box-shadow: 0 4px 14px rgba(20,18,16,.14);
  transition: background .14s, color .14s, transform .14s, box-shadow .14s; }
.heropair__btn:hover { background: var(--yellow); color: var(--ink); border-color: var(--yellow);
  transform: translateY(-1px); box-shadow: 0 10px 22px rgba(255,153,51,.40); }
.heropair__btn .ico { width: .9em; height: .9em; }
/* HALF HEIGHT IN LAYOUT C. Pearce, 03/10/2026: "I think All pest prices is
   too big, cut it in half." It was sized back when it was one of a matched
   PAIR of column buttons and had to balance the carpet one. In layout C the
   carpet side ends in its own smaller orange button, so this one at 3.5rem
   and 1.05rem was the loudest thing in the hero while being the least
   important — it is the "show me the rest" link, not the action. Halved, it
   matches .herobuild__btn, which also levels the two columns. */
/* align-self:end is the half of this that actually did the work. The button
   is the last child of a stretching grid column, so whatever the carpet card
   was taller by got poured into the button's height — it was 56px tall
   because the card next to it was 25px taller, not because anything asked for
   56px. Pinning it to the bottom at its own size is what makes "cut it in
   half" hold at every width instead of only at the one I measured. */
.heropair--c .heropair__btn { min-height: 0; font-size: .84rem;
  padding: calc(.62rem - 2px) calc(.7rem - 2px); border-radius: 10px;
  align-self: end; line-height: 1.25;
  box-shadow: 0 3px 10px rgba(20,18,16,.10); }
/* The height the button is no longer swallowing goes back into the three
   price rows instead, so the pest column fills its side honestly and the two
   columns finish level — "move the carpet bubble down in alignment".
   Three 1fr rows rather than a padding number, because the carpet card's
   height changes with the viewport (its paragraph is dropped on short
   screens), so any fixed padding would only be right at one size. The chips
   divide whatever the card is tall, at every width, by themselves. */
/* THREE EQUAL ROWS THAT FILL THE COLUMN, which is the version Pearce picked.
   Pearce, 03/10/2026, of the compact one: "this isn't the display I picked —
   it was this, but I said light them up better."
   I had moved them to natural height chasing row-for-row alignment with the
   carpet card. It bought a tidier second row and cost the thing the column is
   for: three chips of equal weight filling their side, instead of three small
   ones with a hole underneath. The tops still line up, the buttons still line
   up, and the columns still finish level — that was always the alignment that
   mattered. */
.heropair--c .heropair__col { grid-template-rows: 1fr 1fr 1fr auto; flex: 1;
  gap: .4rem; padding: .7rem .75rem .75rem;
  border: 2px solid transparent; border-radius: 13px; }
.heropair--c .heropair__col .heroprice { align-items: center; }
/* LIT UP. The carpet side has a white card, a full-strength orange edge and a
   warm shadow; the pest chips had a 42%-alpha border and nothing else, so on a
   photographic background they sat back while the carpet half came forward —
   on a business that is half pest, half carpet. Full orange edge, the warm
   drop shadow, and a white inner line so each chip reads as a raised object
   rather than a tint. Same brand orange, nothing invented. */
.heropair--c .heroprice { border-color: var(--yellow);
  box-shadow: 0 4px 12px rgba(255,153,51,.22), inset 0 1px 0 rgba(255,255,255,.75); }
.heropair--c .heroprice:hover { box-shadow: 0 8px 20px rgba(255,153,51,.34), inset 0 1px 0 #fff; }
.heropair--c .heropair__btn .ico { width: .85em; height: .85em; }
/* At phone width the two sit side by side in narrow columns, so the label has
   to be allowed to wrap rather than overflow. */
@media (max-width: 560px) {
  .heropair__btn { font-size: .9rem; padding: calc(.75rem - 2px) calc(.5rem - 2px);
    min-height: 3.1rem; line-height: 1.2; }
}
/* KEEP THE TWO COLUMNS ON A PHONE.
   Stacking them made the hero 989px — a whole screen of pest before carpet
   even appeared, which is the opposite of what the split is for. Side by side
   the price drops under the name instead, and both services stay visible in
   one glance. */
@media (max-width: 620px) {
  .heropair { gap: .5rem .55rem; max-width: none; }
  .heroprice { flex-direction: column; align-items: flex-start; gap: 0; padding: .4rem .55rem; }
  .heroprice__n { font-size: .7rem; line-height: 1.2; }
  .heroprice__p { font-size: .94rem; }
  .heropair__h { font-size: .62rem; }
  .heropair__btn { font-size: .78rem; padding: .5rem .6rem; }
  .heromore { gap: .5rem; }
  .heromore__txt { min-width: 100%; font-size: .76rem; }
}

.pricepanel { display: grid; grid-template-columns: minmax(0, 360px) minmax(0, 1fr); gap: 1.6rem; align-items: start; }
.pricepanel__pitch { background: var(--grad-blue); color: #fff; border-radius: var(--radius-xl); padding: 2rem 1.7rem; position: sticky; top: 100px; }
.pricepanel__pitch h2 { color: #fff; font-size: 1.72rem; margin: 0 0 .7rem; }
.pricepanel__pitch h2 .hl { color: var(--yellow); }
.pricepanel__pitch > p { color: rgba(255,255,255,.80); font-size: .94rem; margin: 0 0 1.2rem; }
.pricepanel__pitch ul { list-style: none; margin: 0 0 1.5rem; padding: 0; display: grid; gap: .6rem; }
.pricepanel__pitch li { display: flex; gap: .6rem; align-items: flex-start; font-size: .9rem; color: rgba(255,255,255,.92); }
.pricepanel__pitch li .ico { color: var(--yellow); flex: none; margin-top: .15em; }
.pricepanel__list { min-width: 0; display: grid; gap: .55rem; }
.pricepanel__all { display: inline-flex; align-items: center; gap: .4em; font-family: var(--head); font-weight: 700;
  font-size: .9rem; color: var(--orange-ink); text-decoration: none; margin-top: .5rem; }
.pricepanel__all:hover { text-decoration: underline; }
@media (max-width: 900px) { .pricepanel { grid-template-columns: 1fr; } .pricepanel__pitch { position: static; } }

.buildprice { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 340px); gap: 2.2rem; align-items: center; }
.buildprice__kick { font-family: var(--head); font-weight: 800; font-size: .74rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--orange-ink); display: block; margin-bottom: .4rem; }
.buildprice__copy h2 { font-size: clamp(1.6rem, 3vw, 2.1rem); margin: 0 0 .7rem; }
.buildprice__copy > p { color: var(--muted); margin: 0 0 1.1rem; max-width: 38rem; }
.buildprice__list { list-style: none; margin: 0 0 1.5rem; padding: 0; display: grid; gap: .55rem; }
.buildprice__list li { display: flex; gap: .6rem; align-items: flex-start; font-size: .92rem; }
.buildprice__list .ico { color: var(--yellow-d); flex: none; margin-top: .15em; }
.buildprice__card { background: var(--grad-blue); color: #fff; border-radius: var(--radius-xl); padding: 1.9rem 1.6rem; text-align: center; }
.buildprice__from { display: block; font-size: .78rem; letter-spacing: .08em; text-transform: uppercase; color: rgba(255,255,255,.6); font-weight: 700; }
.buildprice__num { display: block; font-family: var(--head); font-weight: 800; font-size: 3.4rem; color: var(--yellow); line-height: 1.05; margin: .1rem 0 .3rem; }
.buildprice__sub { display: block; font-size: .84rem; color: rgba(255,255,255,.72); line-height: 1.5; margin-bottom: 1.3rem; }
.buildprice__steps { list-style: none; margin: 0; padding: 1.2rem 0 0; border-top: 1px solid rgba(255,255,255,.18); display: grid; gap: .7rem; text-align: left; }
.buildprice__steps li { display: flex; gap: .7rem; align-items: center; font-size: .88rem; color: rgba(255,255,255,.9); }
.buildprice__steps span { width: 24px; height: 24px; border-radius: 50%; background: var(--yellow); color: var(--blue);
  font-family: var(--head); font-weight: 800; font-size: .78rem; display: grid; place-items: center; flex: none; }
@media (max-width: 860px) { .buildprice { grid-template-columns: 1fr; gap: 1.6rem; } }



/* Flood restoration: one strip under the three service cards, not a fourth
   card. It is under a tenth of the business (Pearce, 28/09/2026) and a quarter
   of the service row was saying otherwise. */
.floodstrip { display: flex; align-items: center; gap: 1.1rem; margin-top: 1.6rem; padding: 1.1rem 1.4rem;
  background: var(--blue); color: #fff; border-radius: var(--radius-lg); text-decoration: none;
  transition: transform .15s, box-shadow .15s; }
.floodstrip:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.floodstrip__ico { width: 44px; height: 44px; border-radius: 12px; background: rgba(255,153,51,.18);
  display: grid; place-items: center; flex: none; }
.floodstrip__ico .ico { color: var(--yellow); width: 22px; height: 22px; }
.floodstrip__txt { flex: 1; min-width: 0; }
.floodstrip__txt b { display: block; font-family: var(--head); font-size: 1rem; color: #fff; }
.floodstrip__txt span { display: block; font-size: .87rem; color: rgba(255,255,255,.74); line-height: 1.5; margin-top: .15rem; }
.floodstrip__go { display: inline-flex; align-items: center; gap: .4em; font-family: var(--head); font-weight: 700;
  font-size: .88rem; color: var(--yellow); white-space: nowrap; flex: none; }
@media (max-width: 720px) {
  .floodstrip { flex-direction: column; align-items: flex-start; gap: .8rem; }
  .floodstrip__go { margin-left: 56px; }
}

/* "We also do…" — the line that stops four chips reading as four services.
   Names, not a number: someone scanning for "cockroaches" has to see the
   word. The count is what makes them click. */
/* THE THIRD DOOR, WITH A LIGHT CHASING ROUND IT.
   Pearce, 28/09/2026: "make this a moving border highlight that's obvious."
   The strip sits between two black buttons on an orange hero, so a static
   black bar with orange text disappears into the stack — it reads as a
   caption rather than a third option. A band of light travelling round the
   edge is the one thing on the page that moves, so the eye finds it without
   the strip having to shout in size or colour.

   How it works: a conic-gradient square, larger than the strip, spins behind
   it; a solid inset panel covers all but a 2px rim, so what survives is a
   highlight running round the border. Clipped by overflow + radius. */
/* THE BOTH PANEL CARRIES A NUMBER NOW, so it needs two lines and an icon
   rather than one short sentence. "One visit, one invoice" is a convenience
   claim; "$182 instead of $219 and one invoice for your agent" is a reason.
   Same spinning rim — it earns its keep on a panel people were walking past. */
.heroboth { position: relative; isolation: isolate; overflow: hidden;
  display: flex; align-items: center; justify-content: space-between; gap: .7rem; flex-wrap: nowrap;
  margin-top: .55rem; max-width: 38rem; background: transparent; border-radius: 12px;
  padding: calc(.6rem + 3px) calc(.85rem + 3px); text-decoration: none;
  transition: transform .14s, box-shadow .14s; }
.heroboth__ic { position: relative; z-index: 2; flex: none; width: 30px; height: 30px; border-radius: 9px;
  background: var(--yellow); display: grid; place-items: center; }
.heroboth__ic .ico { width: 17px; height: 17px; color: var(--ink); }
.heroboth__txt b { display: block; }
.heroboth__txt > span { display: block; margin-top: .1rem; font-size: .76rem; color: rgba(255,255,255,.8); }
.heroboth::before { content: ""; position: absolute; z-index: 0; left: 50%; top: 50%;
  width: 170%; aspect-ratio: 1; translate: -50% -50%;
  /* The rim's RESTING colour is dark, not transparent. Transparent let the
     orange hero show through the whole rim, so an orange light chasing round
     an orange rim was invisible from a metre away — which is the only
     distance that matters. Dark base, white-hot band: the contrast is the
     point. */
  background: conic-gradient(from 0turn,
    #2b2118 0turn .46turn,
    #ff9933 .57turn, #ffe2b8 .655turn, #ffffff .685turn, #ffe2b8 .715turn, #ff9933 .80turn,
    #2b2118 .91turn 1turn);
  animation: herobothspin 2.6s linear infinite; }
.heroboth::after { content: ""; position: absolute; z-index: 1; inset: 3px; border-radius: 9px;
  background: var(--deep); }
.heroboth:hover { transform: translateY(-1px); box-shadow: 0 8px 20px rgba(20,18,16,.22); }
.heroboth__txt { position: relative; z-index: 2; flex: 1 1 auto; min-width: 0; font-size: .83rem;
  color: rgba(255,255,255,.82); line-height: 1.4; }
.heroboth__txt b { font-weight: 800; color: #fff; }
.heroboth__go { position: relative; z-index: 2; display: inline-flex; align-items: center; gap: .35em;
  font-family: var(--head); font-weight: 800; font-size: .78rem; color: var(--yellow); white-space: nowrap; }
.heroboth__go .ico { width: .82em; height: .82em; }
@keyframes herobothspin { to { rotate: 1turn; } }
/* Someone who has asked their system to stop animations gets a plain bright
   rim instead of a moving one — still obvious, just not in motion. */
@media (prefers-reduced-motion: reduce) {
  .heroboth::before { animation: none; background: linear-gradient(100deg, #ffb45f, #ff9933); }
}

/* Moved out of the hero card into the lane band, 02/10/2026. It has the full
   page width there instead of a 33rem column beside a headline, so the cap
   comes off and it sits on one or two lines instead of three. */
.heromore { display: flex; align-items: center; gap: .9rem; flex-wrap: wrap; margin-top: 1.2rem; max-width: none;
  background: var(--white); border: 1px dashed rgba(255,153,51,.5); border-radius: 12px;
  padding: .7rem 1rem; text-decoration: none; transition: background .14s; }
.heromore:hover { background: var(--yellow-soft); }
.heromore__txt { flex: 1; min-width: 12rem; font-size: .8rem; color: #4a3520; line-height: 1.45; }
.heromore__txt b { font-weight: 700; color: var(--ink); }
.heromore__go { display: inline-flex; align-items: center; gap: .35em; font-family: var(--head); font-weight: 800;
  font-size: .78rem; color: var(--ink); white-space: nowrap; }
.heromore__go .ico { width: .82em; height: .82em; }

/* ============================================================
   SPLIT PICKER — the two halves of the business, under the hero
   ============================================================
   Pearce, 28/09/2026: "left side is pest control, right hand side can be
   carpet cleaning, alternating colours."

   Equal columns, no size trick favouring one — the layout is the argument
   that this is a 50/50 business. The dark/light alternation is what makes
   the split legible at a glance while you are still scrolling past. */
.splitpick__kick { font-family: var(--head); font-weight: 800; font-size: .74rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); text-align: center; margin: 0 0 1rem; }
.splitpick { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; align-items: stretch; }
.splitpick__side { display: flex; flex-direction: column; gap: .55rem; text-decoration: none;
  border-radius: var(--radius-lg); padding: 1.7rem 1.7rem 1.4rem; position: relative; overflow: hidden;
  transition: transform .16s, box-shadow .16s; }
.splitpick__side:hover { transform: translateY(-3px); box-shadow: 0 16px 38px rgba(20,18,16,.16); }

/* 13 -> ORANGE. Pearce, 29/09/2026. Its contents were written for white on
   near-black, so every one of them flips to dark ink; the accents that were
   orange go white, so they still separate from the ground they sit on. */
.splitpick__side--dark { background: var(--grad-orange); color: #141414; }
.splitpick__side--light { background: var(--white); color: var(--ink); border: 1.5px solid var(--line); }
/* The light half still has to read as BFYB, not as an empty card. */
.splitpick__side--light::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 5px;
  background: linear-gradient(90deg, #ffb45f, #ff9933); }

.splitpick__ico { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px;
  border-radius: 13px; background: linear-gradient(140deg, #ffb45f, #ff9933); color: #241a10; margin-bottom: .2rem; }
/* On the orange card the orange tile disappears, so it inverts. */
.splitpick__side--dark .splitpick__ico { background: var(--blue); color: #fff; }
.splitpick__ico .ico { width: 23px; height: 23px; }

.splitpick__h { font-family: var(--head); font-weight: 800; font-size: clamp(1.35rem, 2.3vw, 1.75rem);
  line-height: 1.12; text-wrap: balance; }
.splitpick__side--dark .splitpick__h b { color: #fff; font-weight: 800; }
.splitpick__side--light .splitpick__h b { color: var(--orange-ink); font-weight: 800; }

.splitpick__lead { font-size: .92rem; line-height: 1.5; }
.splitpick__side--dark .splitpick__lead { color: rgba(20,18,16,.8); }
.splitpick__side--light .splitpick__lead { color: var(--muted); }

.splitpick__list { list-style: none; margin: .35rem 0 0; padding: 0; display: grid; gap: .4rem; }
.splitpick__list li { display: flex; align-items: flex-start; gap: .5rem; font-size: .87rem; line-height: 1.4; }
.splitpick__list .ico { width: .95em; height: .95em; flex: 0 0 auto; margin-top: .2em; color: var(--yellow); }
.splitpick__side--light .splitpick__list .ico { color: var(--orange-ink); }
.splitpick__side--dark .splitpick__list li { color: #141414; }
.splitpick__side--dark .splitpick__list .ico { color: #141414; }

/* The price and the action share a baseline, so the two halves line up with
   each other however long the copy above them runs. */
.splitpick__foot { margin-top: auto; padding-top: 1.1rem; display: flex; align-items: center;
  justify-content: space-between; gap: .8rem; flex-wrap: wrap; }
.splitpick__from { font-family: var(--head); font-weight: 800; font-size: 1.6rem; font-variant-numeric: tabular-nums; }
.splitpick__from small { display: block; font-size: .62rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; opacity: .6; }
.splitpick__side--dark .splitpick__from { color: #141414; }
/* The price on the carpet card in the brand blue, not orange. The card is
   already orange-accented top to bottom — icon, ticks, heading — so an orange
   price was one more orange thing rather than the thing you look at. Blue is
   the other half of the wrap and it is the only element on that card wearing
   it, so the number is now the first thing the eye lands on. 5.3:1 on white. */
.splitpick__side--light .splitpick__from { color: var(--blue); }
.splitpick__go { display: inline-flex; align-items: center; gap: .4em; font-family: var(--head); font-weight: 800;
  font-size: .88rem; border-radius: 99px; padding: .6rem 1.05rem; white-space: nowrap; }
.splitpick__side--dark .splitpick__go { background: var(--grad-blue-btn); color: #fff; }
.splitpick__side--light .splitpick__go { background: var(--grad-blue-btn); color: #fff; }
.splitpick__go .ico { width: .85em; height: .85em; }

/* THE SECOND ROW OF THE CHOOSER — "both" and the emergency.
 *
 * Two cards that are deliberately SHORTER than the carpet and pest doors
 * above them. They are real choices, not equals: the weight on the page
 * should match the weight in the business, and these two together are a
 * fraction of what the top row carries.
 *
 * The emergency card is a <div>, not an <a>. Someone standing in water needs
 * the phone, so the whole card is not one big link to a page they will not
 * read — the number is the button and "how it works" is the quiet option.
 */
.splitpick__pair { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 1rem;
  align-items: stretch; }
.splitpick__mini { display: flex; align-items: center; gap: .9rem; flex-wrap: wrap;
  padding: .95rem 1.15rem; border-radius: var(--radius-lg); text-decoration: none;
  transition: transform .16s, box-shadow .16s; }
.splitpick__mini__ico { display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; flex: 0 0 38px; border-radius: 11px; }
.splitpick__mini__ico .ico { width: 19px; height: 19px; }
.splitpick__mini__txt { flex: 1; min-width: 0; }
.splitpick__mini__txt b { display: block; font-family: var(--head); font-weight: 800; font-size: 1.02rem; }
.splitpick__mini__txt > span { display: block; font-size: .86rem; line-height: 1.5; margin-top: .15rem; }

.splitpick__mini--both { background: linear-gradient(100deg, #ffb45f, #ff9933); color: var(--ink); }
.splitpick__mini--both:hover { transform: translateY(-2px); box-shadow: 0 12px 28px rgba(255,153,51,.34); }
.splitpick__mini--both .splitpick__mini__ico { background: rgba(20,18,16,.14); color: #141414; }
.splitpick__mini--both .splitpick__mini__txt > span { color: rgba(20,18,16,.78); }
.splitpick__mini--both .splitpick__go { background: var(--grad-blue-btn); color: #fff; }

/* THE EMERGENCY CARD — the wrap's deep blue, not a red-brown.
   I built this with #2a1512 because I wanted "alert" and reached for a red.
   There is no red on the truck. Pearce, 01/10/2026: "this brown colour is
   trash" — and it was, both as a colour and as a decision, since it was the
   exact thing he had just told me to stop doing.
   The deep wrap blue does the job better anyway: it separates this card from
   the orange "both" card beside it, so the two read as different KINDS of
   thing rather than two offers, and the orange call button lands on it hard. */
.splitpick__mini--emerg { align-items: flex-start; background: var(--grad-blue-deep);
  border: 1.5px solid var(--blue-bright); color: #fff; }
/* The emergency card lifts on hover like the other three.
   It is the only one of the four that is a <div> rather than an <a> — the
   whole card deliberately is not a link, because the action is the phone
   number, not a page. That is why it was the one card sitting dead still
   while the others moved. Pearce, 01/10/2026: "3/4 move when hovered over,
   flood does not, it's strange." The lift is cosmetic consistency; the
   clickable things inside it are unchanged. */
.splitpick__mini--emerg:hover { transform: translateY(-2px); box-shadow: 0 12px 28px rgba(7,110,184,.34); }
.splitpick__mini--emerg .splitpick__mini__ico { margin-top: .15rem;
  background: rgba(255,255,255,.14); color: var(--yellow); }
.splitpick__mini--emerg .splitpick__mini__txt b { color: #fff; }
.splitpick__mini--emerg .splitpick__mini__txt > span { color: rgba(255,255,255,.76); }
.splitpick__mini__acts { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  flex: 1 0 100%; margin-top: .2rem; }
.splitpick__mini--emerg .splitpick__go { background: transparent; color: rgba(255,255,255,.82);
  padding-inline: .3rem; }
.splitpick__mini--emerg .splitpick__go:hover { color: #fff; }

.splitpick__both { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  margin-top: 1rem; padding: .85rem 1.1rem; border-radius: var(--radius-lg); text-decoration: none;
  background: linear-gradient(100deg, #ffb45f, #ff9933); color: var(--ink);
  transition: transform .16s, box-shadow .16s; }
.splitpick__both:hover { transform: translateY(-2px); box-shadow: 0 12px 28px rgba(255,153,51,.34); }
.splitpick__both > span:first-child { font-size: .9rem; line-height: 1.45; }
.splitpick__both b { font-weight: 800; }
.splitpick__both .splitpick__go { background: var(--deep); color: #fff; }

@media (max-width: 760px) {
  .splitpick { grid-template-columns: 1fr; }
  .splitpick__pair { grid-template-columns: 1fr; }
  .splitpick__mini { align-items: flex-start; }
  .splitpick__side { padding: 1.4rem 1.3rem 1.2rem; }
  .splitpick__both { flex-direction: column; align-items: flex-start; }
}

/* The filler under the carpet column on the 50/50 screen — see lanePanel(). */
.bkq__panelnote { margin-top: 10px; background: var(--yellow-soft); border: 1.5px solid rgba(255,153,51,.34);
  border-radius: var(--radius); padding: 14px 15px; }
.bkq__panelnote b { display: block; font-family: var(--head); font-weight: 800; font-size: .9rem;
  color: var(--ink); line-height: 1.3; margin-bottom: 10px; }
.bkq__panelnote ol { list-style: none; margin: 0 0 10px; padding: 0; display: grid; gap: 7px; }
.bkq__panelnote li { display: flex; align-items: flex-start; gap: 9px; font-size: .84rem; color: var(--ink); line-height: 1.4; }
.bkq__panelnote li span { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 50%; background: var(--deep); color: #fff;
  font-family: var(--head); font-weight: 800; font-size: .7rem; }
.bkq__panelnote p { margin: 0; font-size: .79rem; color: var(--muted); line-height: 1.45; }

/* ============================================================
   WHAT'S INCLUDED / WHAT'S NOT — the booking flow's options step
   ============================================================
   Two lists, two headings, two colours. The exclusions are not hidden
   behind a disclosure: the whole reason this block exists is that a caveat
   nobody opened is a caveat nobody read, and the argument then happens on
   the customer's veranda with a technician who did nothing wrong. */
.bkq__copy { margin-top: 14px; }
.bkq__about { font-size: .92rem; line-height: 1.55; color: var(--body); margin: 0 0 14px; }
.bkq__inc, .bkq__exc { border-radius: var(--radius); padding: 14px 15px; margin-bottom: 10px; }
.bkq__inc { background: #f2faf3; border: 1.5px solid #cfe9d4; }
.bkq__exc { background: #fdf6f0; border: 1.5px solid #f0ddcc; }
.bkq__inc .bkq__q, .bkq__exc .bkq__q { margin: 0 0 9px; }
.bkq__inc ul, .bkq__exc ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.bkq__inc li, .bkq__exc li { display: flex; align-items: flex-start; gap: 9px;
  font-size: .86rem; line-height: 1.5; color: var(--body); }
.bkq__yes, .bkq__no { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%; font-size: .72rem; font-weight: 800; margin-top: .1em; }
.bkq__yes { background: #1f8a3d; color: #fff; }
.bkq__no { background: #b35c00; color: #fff; }
.bkq__best { font-size: .86rem; line-height: 1.5; color: var(--muted); margin: 0;
  padding: 11px 14px; background: var(--cream2); border-radius: var(--radius); }
.bkq__best b { color: var(--ink); }

/* ============================================================
   TERMS & CONDITIONS — built by build-terms.cjs
   ============================================================
   A terms page is read by someone who is already unhappy, or who is about
   to spend money and wants to know what they are agreeing to. Both deserve
   type they can actually read: a real measure, numbered headings that are
   easy to cite over the phone, and enough air between clauses that nobody
   loses their place halfway down. */
.termsbody { color: var(--body); font-size: 1rem; line-height: 1.68; counter-reset: tc; }
.termsbody h2 { font-family: var(--head); font-weight: 800; font-size: 1.16rem; line-height: 1.3;
  color: var(--ink); margin: 2.1rem 0 .55rem; padding-top: 1.4rem;
  border-top: 1px solid var(--line); text-wrap: balance; }
.termsbody h2:first-child { margin-top: .6rem; padding-top: 0; border-top: 0; }
.termsbody p { margin: 0 0 .85rem; }
.termsbody ul { margin: 0 0 1rem; padding-left: 1.15rem; }
.termsbody li { margin-bottom: .45rem; }
.termsbody b { color: var(--ink); font-weight: 700; }
.termsbody a { color: var(--orange-ink); }
@media (max-width: 600px) {
  .termsbody { font-size: .96rem; }
  .termsbody h2 { font-size: 1.08rem; margin-top: 1.7rem; padding-top: 1.1rem; }
}

/* ============================================================
   INCLUSIONS / EXCLUSIONS on the price page rows
   ============================================================
   Deliberately the same two-block, green-and-amber language as the booking
   flow (.bkq__inc / .bkq__exc), because they are the same information and a
   customer who sees it in one place and then the other should recognise it
   rather than have to re-read it. Different classes only because the price
   rows sit on cream inside a <details> rather than on the flow's white. */
.pricerow__about { font-size: .92rem; line-height: 1.55; color: var(--body); margin: 0 0 .8rem; }
.pricecopy { border-radius: var(--radius); padding: 12px 14px; margin: 0 0 .6rem; }
.pricecopy--yes { background: #f2faf3; border: 1.5px solid #cfe9d4; }
.pricecopy--no  { background: #fdf6f0; border: 1.5px solid #f0ddcc; }
.pricecopy__h { font-family: var(--head); font-weight: 800; font-size: .78rem; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink); margin: 0 0 8px; }
.pricecopy ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 7px; }
.pricecopy li { display: flex; align-items: flex-start; gap: 9px; font-size: .85rem; line-height: 1.5; color: var(--body); }
.pricecopy__m { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 17px; height: 17px; border-radius: 50%; font-size: .7rem; font-weight: 800; color: #fff; margin-top: .15em; }
.pricecopy--yes .pricecopy__m { background: #1f8a3d; }
.pricecopy--no  .pricecopy__m { background: #b35c00; }
.pricerow__best { font-size: .85rem; line-height: 1.5; color: var(--muted); margin: 0 0 .9rem;
  padding: 10px 13px; background: var(--cream2); border-radius: var(--radius); }
.pricerow__best b { color: var(--ink); }

/* ============================================================
   TRUCKMOUNT vs PORTABLE — carpet-cleaning page
   ============================================================
   An orange band, because Pearce asked for the cut-out machine to sit on
   orange and because this is the one section on the carpet page that should
   stop a skim-reader. Orange as a BAND is fine; orange as the whole page
   ground was the thing that made the site feel like glare. */
/* Same treatment as the hero, same reason. 155deg runs light at the top-left,
   where the headline and the comparison table sit, down to the deep end at the
   bottom-right behind the machine photo. */
.truckmount { background:
    linear-gradient(155deg, #FFD3A0 0%, #FFAD55 22%, #FF9933 46%, #E07C14 78%, #BE5607 100%);
  position: relative; overflow: hidden; }
/* A soft warm highlight in the top corner, so the light end reads as light
   falling on the band rather than as a flat stop. */
.truckmount::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(820px 420px at 12% -6%, rgba(255,255,255,.3), transparent 62%); }
.truckmount > * { position: relative; z-index: 1; }
.truckmount__inner { display: grid; grid-template-columns: 1.08fr .92fr; gap: 2.6rem; align-items: center; }
.truckmount__kick { display: inline-block; font-family: var(--head); font-weight: 800; font-size: .74rem;
  letter-spacing: .12em; text-transform: uppercase; color: #fff; background: var(--blue);
  padding: .32rem .8rem; border-radius: 99px; margin-bottom: .9rem; }
.truckmount h2 { font-size: clamp(1.7rem, 3.2vw, 2.5rem); line-height: 1.1; color: #141414;
  margin: 0 0 .8rem; text-wrap: balance; }
.truckmount__hl { color: #fff; }
.truckmount__lead { font-size: 1.02rem; line-height: 1.6; color: #3d2607; margin: 0 0 .9rem; max-width: 36rem; }
.truckmount__lead b { color: #141414; }

/* The comparison. Three columns on desktop; on a phone each row becomes its
   own little card, because a squeezed three-column table is unreadable and
   this is the part people actually need to get through. */
/* The cost comparison, above the table. White card on the orange band so the
   two figures read as a receipt rather than as more body copy. */
.truckmount__cost { display: grid; gap: .5rem; background: rgba(255,255,255,.55);
  border-left: 4px solid var(--blue); border-radius: 0 var(--radius) var(--radius) 0;
  padding: 1.05rem 1.2rem; margin: 1.2rem 0 0; }
.truckmount__cost__row { display: flex; align-items: baseline; gap: .7rem; flex-wrap: wrap; }
.truckmount__cost__row b { font-family: var(--head); font-weight: 800; font-size: 1.5rem; line-height: 1;
  color: var(--blue-dk); font-variant-numeric: tabular-nums; min-width: 6.2rem; }
.truckmount__cost__row > span { font-size: .88rem; color: #3d2607; font-weight: 600; }
.truckmount__cost__note { display: block; font-size: .86rem; line-height: 1.55; color: #3d2607;
  padding-top: .7rem; margin-top: .25rem; border-top: 1px solid rgba(20,18,16,.16); }
.truckmount__cost__note b { color: #141414; font-weight: 800; }

.tmtable { margin: 1.3rem 0 1.1rem; border-radius: var(--radius-lg); overflow: hidden;
  background: rgba(255,255,255,.55); border: 1.5px solid rgba(20,18,16,.16); }
.tmtable__head, .tmtable__row { display: grid; grid-template-columns: 5.5rem 1fr 1fr; gap: 0; }
.tmtable__head { background: var(--blue); }
.tmtable__head span { padding: .6rem .85rem; font-family: var(--head); font-weight: 800; font-size: .75rem;
  letter-spacing: .07em; text-transform: uppercase; }
/* White, not yellow: yellow on the brand blue is 2.5:1 at this size. The
   yellow stays where it still works — on the ticks in the rows below. */
.tmtable__head .tmtable__us { color: #fff; }
.tmtable__head .tmtable__them { color: rgba(255,255,255,.84); }
.tmtable__row { border-top: 1px solid rgba(20,18,16,.12); align-items: stretch; }
.tmtable__row:first-of-type { border-top: 0; }
.tmtable__k { padding: .75rem .85rem; font-family: var(--head); font-weight: 800; font-size: .82rem;
  color: #141414; background: rgba(255,255,255,.4); }
.tmtable__row .tmtable__us { padding: .75rem .85rem; font-size: .86rem; line-height: 1.45; color: #1d1508;
  background: #fff; display: flex; gap: .5em; align-items: flex-start; }
.tmtable__row .tmtable__us .ico { width: .95em; height: .95em; flex: 0 0 auto; margin-top: .22em; color: #1f8a3d; }
.tmtable__row .tmtable__us > span { min-width: 0; }
.tmtable__us b { color: #141414; font-weight: 800; }
/* The "us" column has had a green tick from the start; the "them" column had
   nothing. Pearce, 01/10/2026: "this has possitive ticks, but not negative X
   for portable." The cross is a darkened brand orange rather than a red — red
   is not on the vehicle, and on this peach ground a deeper orange reads as
   "not this" perfectly well. */
.tmtable__row .tmtable__them { padding: .75rem .85rem; font-size: .84rem; line-height: 1.45; color: #5a4526;
  display: flex; gap: .45rem; align-items: flex-start; }
.tmtable__row .tmtable__them > span:last-child { min-width: 0; }
.tmtable__x { flex: 0 0 auto; font-family: var(--head); font-weight: 800; font-size: 1.02em;
  line-height: 1.3; color: #A8431A; }
.tmtable__them b { color: #3d2607; font-weight: 800; }

.truckmount__note { font-size: .9rem; line-height: 1.55; color: #3d2607; margin: 0;
  background: rgba(255,255,255,.45); border-left: 4px solid #141414;
  border-radius: 0 var(--radius) var(--radius) 0; padding: .8rem 1rem; }
.truckmount__note b { color: #141414; }

.truckmount__media { text-align: center; }
.truckmount__media img { width: 100%; max-width: 480px; height: auto;
  filter: drop-shadow(0 26px 40px rgba(60,26,0,.32)); }
.truckmount__cap { font-size: .82rem; line-height: 1.5; color: #4a2f0a; margin: .9rem auto 0; max-width: 26rem; }
.truckmount__cap b { color: #141414; font-weight: 800; }

@media (max-width: 900px) {
  .truckmount__inner { grid-template-columns: 1fr; gap: 1.8rem; }
  .truckmount__media { order: -1; }
  .truckmount__media img { max-width: 340px; }
  /* Each comparison row becomes its own card rather than three squeezed columns. */
  .tmtable__head { display: none; }
  .tmtable__row { grid-template-columns: 1fr; border-top: 10px solid transparent; }
  .tmtable__k { background: var(--blue); color: #fff; border-radius: var(--radius) var(--radius) 0 0; }
  /* Both cells are flex rows (tick / cross then the text), so the stacked-view
     label needs its own line rather than becoming a third item alongside the
     mark. */
  .tmtable__row .tmtable__us, .tmtable__row .tmtable__them { flex-wrap: wrap; }
  .tmtable__row .tmtable__us::before { content: "Us"; flex: 0 0 100%; font-weight: 800; font-size: .74rem;
    letter-spacing: .1em; text-transform: uppercase; color: #3d2607; margin-bottom: .25rem; }
  .tmtable__row .tmtable__them::before { content: "A portable"; flex: 0 0 100%; font-weight: 800; font-size: .74rem;
    letter-spacing: .1em; text-transform: uppercase; color: #6b5330; margin-bottom: .25rem; }
  .tmtable__row .tmtable__them { background: rgba(255,255,255,.55); border-radius: 0 0 var(--radius) var(--radius); }
}

/* "What we don't use" — the drawn portable, beside the real machine.
   Deliberately a SCHEMATIC on a dark card, against a photograph on orange:
   one of these is a real thing BFYB owns, the other is a nameless outline,
   and the page should feel that difference before anyone reads a word. */
/* THE TAP CEILING — sits in the orange truckmount section, so it is a deep blue
   panel for contrast, same device as .tmdont on the other side of the grid. */
.tmheat { margin: 1.5rem 0 1.2rem; background: var(--grad-blue-deep); color: #fff;
  border-radius: var(--radius-lg); padding: 1.3rem 1.4rem 1.4rem; }
.tmheat__tag { display: inline-block; font-family: var(--head); font-weight: 800; font-size: .68rem;
  letter-spacing: .12em; text-transform: uppercase; color: #3d2607; background: var(--yellow);
  padding: .28rem .6rem; border-radius: 999px; }
.tmheat h3 { font-size: clamp(1.15rem, 2.1vw, 1.5rem); line-height: 1.16; margin: .75rem 0 1rem; color: #fff; }
.tmheat__hl { color: var(--yellow); }
.tmheat__scale { display: grid; gap: .1rem; }
.tmheat__step { display: grid; grid-template-columns: 5.4rem 1fr; gap: .9rem; align-items: start;
  padding: .8rem 0; border-top: 1px solid rgba(255,255,255,.14); }
.tmheat__step:first-child { border-top: 0; padding-top: .2rem; }
.tmheat__step b { font-family: var(--head); font-weight: 800; font-size: 1.6rem; line-height: 1;
  font-variant-numeric: tabular-nums; }
.tmheat__step span { font-size: .87rem; line-height: 1.55; color: rgba(255,255,255,.78); }
.tmheat__step span b { font-size: inherit; color: #fff; font-weight: 700; }
.tmheat__step--cap > b { color: #fff; }
.tmheat__step--loss > b { color: rgba(255,255,255,.45); font-size: 1.9rem; }
.tmheat__step--us > b { color: var(--yellow); }
.tmheat__why { margin: 1rem 0 0; padding-top: .9rem; border-top: 1px solid rgba(255,255,255,.16);
  font-size: .86rem; line-height: 1.55; color: rgba(255,255,255,.76); }
.tmheat__why b { color: #fff; font-weight: 700; }
@media (max-width: 560px) {
  .tmheat__step { grid-template-columns: 1fr; gap: .25rem; }
}

.tmdont { margin-top: 1.4rem; background: var(--blue-dk); border-radius: var(--radius-lg);
  padding: 1rem 1.1rem 1.1rem; text-align: left; }
.tmdont__tag { display: inline-block; font-family: var(--head); font-weight: 800; font-size: .68rem;
  letter-spacing: .12em; text-transform: uppercase; color: #141414; background: #fff;
  padding: .26rem .65rem; border-radius: 99px; margin-bottom: .75rem; }
.tmdont__row { display: flex; align-items: center; gap: .9rem; }
.tmdont__svg { flex: 0 0 auto; width: 128px; height: auto; color: rgba(255,255,255,.62); }
.tmdont__list { list-style: none; margin: 0; padding: 0; display: grid; gap: .4rem; min-width: 0; }
.tmdont__list li { font-size: .82rem; line-height: 1.4; color: rgba(255,255,255,.72);
  padding-left: 1.05rem; position: relative; }
.tmdont__list li::before { content: "\00d7"; position: absolute; left: 0; top: -.05em;
  color: var(--yellow); font-weight: 800; font-size: .95rem; }
.tmdont__list b { color: #fff; font-weight: 700; }
.tmdont__punch { margin: .85rem 0 0; padding-top: .8rem; border-top: 1px solid rgba(255,255,255,.16);
  font-size: .88rem; line-height: 1.5; color: #fff; font-weight: 600; }
@media (max-width: 480px) {
  .tmdont__row { flex-direction: column; align-items: flex-start; gap: .6rem; }
  .tmdont__svg { width: 150px; }
}

/* ============================================================
   PER-SERVICE LANDING PAGES — build-services.cjs
   ============================================================ */
.svc__hero { padding-block: 2.2rem 1.6rem; }
.svc__tag { display: inline-flex; align-items: center; gap: .45em; font-family: var(--head); font-weight: 800;
  font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--orange-ink);
  background: var(--yellow-soft); border: 1.5px solid rgba(255,153,51,.4);
  padding: .3rem .75rem; border-radius: 99px; margin-bottom: .8rem; }
.svc__tag .ico { width: 1em; height: 1em; }
.svc__hero h1 { font-size: clamp(1.9rem, 4vw, 2.9rem); line-height: 1.08; margin: 0 0 .7rem; text-wrap: balance; }
.svc__lead { font-size: 1.1rem; line-height: 1.55; color: var(--body); max-width: 42rem; margin: 0 0 1.4rem; }
.svc__cta { display: flex; gap: .8rem; flex-wrap: wrap; }
.svc__para { font-size: 1.02rem; line-height: 1.68; color: var(--body); margin: 0 0 1rem; max-width: 44rem; }
.svc__sub { font-family: var(--head); font-size: 1.05rem; margin: 1.4rem 0 .6rem; color: var(--ink); }

/* The price block — the band, then the detail behind it. */
.svc__price { background: var(--white); border: 1.5px solid var(--line); border-radius: var(--radius-lg);
  padding: 1.1rem 1.2rem; margin-bottom: 1rem; }
.svc__priceh { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  flex-wrap: wrap; padding-bottom: .7rem; border-bottom: 1px solid var(--line); margin-bottom: .7rem; }
.svc__priceh span { font-family: var(--head); font-weight: 800; font-size: 1.05rem; color: var(--ink); }
.svc__priceh b { font-family: var(--head); font-weight: 800; font-size: 1rem; color: var(--orange-ink);
  font-variant-numeric: tabular-nums; }
.svc__bands { list-style: none; margin: 0; padding: 0; display: grid; gap: .35rem; }
.svc__bands li { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  font-size: .89rem; color: var(--body); }
.svc__bands li b { font-family: var(--head); font-weight: 800; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.svc__note { font-size: .86rem; line-height: 1.5; color: var(--muted); margin: .8rem 0 0; }
.svc__warr { display: flex; gap: .5em; align-items: flex-start; font-size: .84rem; line-height: 1.45;
  color: var(--body); margin: .7rem 0 0; padding-top: .7rem; border-top: 1px solid var(--line); }
.svc__warr .ico { width: 1em; height: 1em; flex: 0 0 auto; margin-top: .2em; color: var(--orange-ink); }
.svc__ctarow { display: flex; gap: .7rem; flex-wrap: wrap; margin-top: 1.2rem; }

.svc__links { display: flex; flex-wrap: wrap; gap: .5rem; }
.svc__links a { display: inline-flex; align-items: center; font-size: .87rem; font-weight: 600;
  color: var(--ink); background: var(--white); border: 1.5px solid var(--line); border-radius: 99px;
  padding: .45rem .9rem; text-decoration: none; transition: border-color .14s, transform .14s; }
.svc__links a:hover { border-color: var(--yellow); transform: translateY(-1px); }
@media (max-width: 600px) { .svc__cta .btn, .svc__ctarow .btn { width: 100%; justify-content: center; } }

/* The base .btn--ghost is white-on-transparent, built for the dark bands it
   was first used on. On the service pages it sits on white, where it was
   invisible — white text, white border, white ground. */
.svc__cta .btn--ghost,
.svc__ctarow .btn--ghost { background: #fff; color: var(--ink); border-color: rgba(20,18,16,.32); }
.svc__cta .btn--ghost:hover,
.svc__ctarow .btn--ghost:hover { background: var(--cream2); border-color: var(--ink); }

/* ============================================================
   STILL HERE — the longevity section, home page
   ============================================================ */
/* STILL HERE — on cream, not on black.
 *
 * Pearce, 01/10/2026: "this is very black, I almost don't want to read it."
 * He was right, and it was the worst possible section to do it to: this is the
 * longest read on the page, four paragraphs of argument that only works if
 * somebody actually reads it. A full-bleed near-black ground behind 300 words
 * of body copy is asking a lot of a customer who came to price a carpet clean.
 *
 * So the ground is cream like the rest of the page, and the dark is spent
 * where it buys something — ONE panel, the cheap-quote story, which is the
 * part that should feel like it is being said quietly and directly. Contrast
 * works by being rare; when everything is dark, nothing stands out.
 */
.stillhere { background: var(--cream); color: var(--ink); position: relative; overflow: hidden; }
.stillhere__top { max-width: 46rem; margin-bottom: 1.8rem; }
.stillhere__kick { display: inline-block; font-family: var(--head); font-weight: 800; font-size: .72rem;
  letter-spacing: .12em; text-transform: uppercase; background: var(--yellow); color: #141414;
  padding: .32rem .8rem; border-radius: 99px; margin-bottom: .9rem; }
.stillhere h2 { color: var(--ink); font-size: clamp(1.7rem, 3.3vw, 2.5rem); line-height: 1.12;
  margin: 0 0 .8rem; text-wrap: balance; }
.stillhere__hl { color: var(--orange-ink); }
.stillhere__top p { color: var(--muted); font-size: 1.03rem; line-height: 1.6; margin: 0 0 .55rem; }
.stillhere__top p:last-child { margin-bottom: 0; }
.stillhere__top p b { color: var(--ink); font-weight: 800; }

/* THE ONE COLOURED BLOCK ON THE SECTION — brand orange, not black.
 *
 * It was near-black on cream, which read as a warning notice rather than the
 * owner telling you something. Pearce, 01/10/2026: "nah hate it, make the
 * black our orange." He is right and it is the better call: this passage is a
 * sales argument, not a disclaimer, and orange is the colour the rest of the
 * site already uses to mean "pay attention to this bit".
 *
 * Dark ink on the orange rather than white — #141414 on #FF9933 clears AA
 * comfortably, where white on orange does not come close.
 */
.stillnote { max-width: 46rem; margin: 0 0 2rem; padding: 1.35rem 1.6rem;
  background: var(--grad-orange); color: #141414;
  border-radius: var(--radius-lg); }
.stillnote__h { font-family: var(--head); font-weight: 800; font-size: 1.12rem; color: #141414;
  margin: 0 0 .7rem; }
.stillnote p { color: rgba(20,18,16,.86); font-size: .95rem; line-height: 1.65; margin: 0 0 .7rem; }
.stillnote p:last-child { margin-bottom: 0; }

.stillhere__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 1rem; }
.stillcard { background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius-lg); padding: 1.15rem 1.2rem; }
.stillcard__ico { display: inline-flex; align-items: center; justify-content: center; width: 38px; height: 38px;
  border-radius: 11px; background: var(--yellow); color: #141414; margin-bottom: .75rem; }
.stillcard__ico .ico { width: 19px; height: 19px; }
.stillcard h3 { font-family: var(--head); font-weight: 800; font-size: 1rem; color: var(--ink); margin: 0 0 .4rem; }
.stillcard p { font-size: .87rem; line-height: 1.55; color: var(--muted); margin: 0; }


/* ============================================================
   THE HEAT BAND — full-width, directly under the truckmount.
   Pearce, 01/10/2026: "the most important thing on the website for carpet
   cleaning... maybe it needs a huge DID YOU KNOW."
   One flat-ish dark ground, so white body text clears 6:1 everywhere — the
   earlier version ran light at the top and fell to 3.7:1.
   ============================================================ */
.heatband { background: linear-gradient(168deg, #054E85 0%, #02233C 100%); color: #fff; position: relative; overflow: hidden; }
.heatband::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(760px 340px at 88% -8%, rgba(255,153,51,.22), transparent 62%); }
.heatband__wrap { position: relative; z-index: 1; }
.heatband__head { max-width: 50rem; margin: 0 auto 2.2rem; text-align: center; }
.heatband__kick { display: inline-block; background: var(--yellow); color: #3d2607;
  font-family: var(--head); font-weight: 800; font-size: clamp(.9rem, 1.9vw, 1.15rem);
  letter-spacing: .16em; text-transform: uppercase; padding: .55rem 1.4rem; border-radius: 999px;
  box-shadow: 0 8px 22px rgba(0,0,0,.26); }
.heatband h2 { font-size: clamp(1.75rem, 4vw, 3rem); line-height: 1.08; color: #fff;
  margin: 1.1rem 0 .9rem; text-wrap: balance; }
.heatband__hl { color: var(--yellow); }
.heatband__lead { font-size: clamp(1rem, 1.6vw, 1.12rem); line-height: 1.6; color: rgba(255,255,255,.88); margin: 0; }

/* stretch, not start — Pearce, 01/10/2026: "the right bubble needs to be the
   same size as the left." The right card has less copy in it, so left to itself
   it stops short and the pair looks lopsided. */
.heatband__pair { display: grid; grid-template-columns: 1fr 1fr; gap: 1.4rem; align-items: stretch; }
.heatband__side { position: relative; overflow: hidden;
  background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.14);
  border-radius: var(--radius-lg); padding: 1.6rem 1.5rem 1.7rem; }
/* ONE BIG MARK ACROSS EACH CARD. Pearce, 01/10/2026: "one BIG red X across the
   entire left bubble, one BIG green TICK across the right bubble."
   Drawn as a background watermark rather than an element, so it sits behind the
   words and never pushes anything around, and kept low enough that the body copy
   still clears its contrast. aria-hidden by construction — it is decoration, and
   the words say the same thing. */
.heatband__side::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background-repeat: no-repeat; background-position: center;
  background-size: min(90%, 430px) auto; }
.heatband__side > * { position: relative; z-index: 1; }
.heatband__side--them::after { opacity: .26;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M18 18 L82 82 M82 18 L18 82' fill='none' stroke='%23FF5A4D' stroke-width='13' stroke-linecap='round'/%3E%3C/svg%3E"); }
.heatband__side--us::after { opacity: .28;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M14 53 L39 79 L87 21' fill='none' stroke='%2334D06A' stroke-width='13' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
@media (prefers-reduced-motion: no-preference) { .heatband__side::after { transition: opacity .3s ease; } }
.heatband__side--us { background: rgba(255,255,255,.12); border-color: rgba(255,153,51,.5); }
.heatband__side p { font-size: .92rem; line-height: 1.62; color: rgba(255,255,255,.86); margin: 0 0 .7rem; }
.heatband__side p:last-child { margin-bottom: 0; }
.heatband__side b { color: #fff; font-weight: 700; }

.heatband__tag { display: inline-block; font-family: var(--head); font-weight: 800; font-size: .7rem;
  letter-spacing: .13em; text-transform: uppercase; padding: .32rem .7rem; border-radius: 999px; }
.heatband__tag--them { background: rgba(255,255,255,.16); color: rgba(255,255,255,.92); }
.heatband__tag--us { background: var(--yellow); color: #3d2607; }

.heatband__fig { display: flex; align-items: baseline; gap: .1em; margin: .9rem 0 .1rem; font-family: var(--head); }
/* colour: inherit, or `.heatband__side b { color: #fff }` above wins and the
   90 comes out white instead of yellow. */
.heatband__fig b { color: inherit; font-weight: 800; font-size: clamp(3.4rem, 8vw, 5.4rem); line-height: .9;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.heatband__fig i { font-style: normal; font-weight: 800; font-size: clamp(1.3rem, 2.6vw, 1.9rem); }
.heatband__side--them .heatband__fig { color: rgba(255,255,255,.95); }
.heatband__side--us .heatband__fig { color: var(--yellow); }
.heatband__cap { display: block; font-size: .82rem; font-weight: 700; letter-spacing: .04em;
  color: rgba(255,255,255,.8); margin-bottom: .9rem; }

/* A bar each, to the same scale: 50 and 90 out of 100. */
.heatband__bar { height: 10px; border-radius: 999px; background: rgba(255,255,255,.16); overflow: hidden; margin-bottom: 1.1rem; }
.heatband__fill { display: block; height: 100%; border-radius: 999px; }
.heatband__fill--them { width: 50%; background: rgba(255,255,255,.55); }
.heatband__fill--us { width: 90%; background: linear-gradient(90deg, #FFC98A 0%, var(--yellow) 55%, #D96908 100%); }

.heatband__loss { color: rgba(255,255,255,.76) !important; font-size: .87rem !important;
  padding-top: .8rem; border-top: 1px solid rgba(255,255,255,.16); }

/* An explicit colour, not an alpha over the gradient — that way the contrast of
   the yellow inside it is a number we can actually check. */
.heatband__why { margin-top: 1.5rem; border-left: 4px solid var(--yellow);
  background: #022740; border-radius: 0 var(--radius-lg) var(--radius-lg) 0; padding: 1.3rem 1.5rem; }
.heatband__why h3 { font-size: 1.1rem; color: #fff; margin: 0 0 .55rem; }
.heatband__why p { font-size: .94rem; line-height: 1.62; color: rgba(255,255,255,.86); margin: 0; }
.heatband__why b { color: var(--yellow); font-weight: 700; }

@media (max-width: 820px) {
  .heatband__pair { grid-template-columns: 1fr; }
  .heatband__head { text-align: left; }
}

/* ============================================================
   THE JOB REEL — flood page. Click to play, nothing loads before.
   ============================================================ */
.reel__head { max-width: 46rem; margin: 0 auto 2rem; text-align: center; }
.reel__kick { display: inline-block; font-family: var(--head); font-weight: 800; font-size: .72rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--orange-ink-d); margin-bottom: .5rem; }
.reel h2 { font-size: clamp(1.6rem, 3vw, 2.3rem); line-height: 1.12; margin: 0 0 .8rem; text-wrap: balance; }
.reel__lead { font-size: 1rem; line-height: 1.6; color: var(--body); margin: 0; }

/* The column count comes from the markup (--reel-cols), so a page with four
   clips does not leave one sitting alone on a second row. Four drops to two
   before it drops to one — four portrait clips side by side on a tablet are
   thumbnails, not evidence. */
.reel__grid { display: grid; grid-template-columns: repeat(var(--reel-cols, 3), 1fr); gap: 1.3rem; align-items: start; }
@media (max-width: 1024px) { .reel__grid { --reel-cols: 2; } }
.reel__item { margin: 0; }
/* The poster and the player share a box, so swapping one for the other does not
   move the page under the reader's finger. */
.reel__play, .reel__video { display: block; width: 100%; aspect-ratio: 9 / 16; border-radius: var(--radius-lg);
  overflow: hidden; background: var(--blue-dk); border: 0; padding: 0; }
.reel__play { position: relative; cursor: pointer; }
.reel__play img, .reel__video { width: 100%; height: 100%; object-fit: cover; display: block; }
.reel__play::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(2,35,60,0) 45%, rgba(2,35,60,.5) 100%); }
.reel__btn { position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); z-index: 1;
  width: 64px; height: 64px; border-radius: 50%; background: var(--yellow); color: #3d2607;
  display: grid; place-items: center; box-shadow: 0 10px 26px rgba(0,0,0,.34);
  transition: transform .16s ease; }
.reel__btn svg { width: 26px; height: 26px; margin-left: 3px; }
.reel__play:hover .reel__btn, .reel__play:focus-visible .reel__btn { transform: translate(-50%,-50%) scale(1.08); }
.reel__item figcaption { font-size: .88rem; line-height: 1.55; color: var(--body); margin-top: .7rem; }
.reel__item figcaption b { display: block; font-family: var(--head); color: var(--ink); font-size: .98rem; margin-bottom: .15rem; }
.reel__note { font-size: .78rem; line-height: 1.55; color: var(--muted); margin: 1.2rem 0 0; max-width: 46rem; }
@media (prefers-reduced-motion: reduce) { .reel__btn { transition: none; } }
@media (max-width: 820px) { .reel__grid { grid-template-columns: 1fr; gap: 1.6rem; }
  .reel__play, .reel__video { aspect-ratio: 16 / 10; } .reel__head { text-align: left; } }

/* ============================================================
   THE TELESCOPIC WAND — pest page
   ============================================================
   Pearce, 01/10/2026: "this should be used under section high to reach places,
   or three storeys", "we use a telescopic wand, that MANY pesties dont use."

   The image is 772px square at source (it came through as a screenshot of his
   mail client, so that is all the resolution there is) and is capped at 560 so
   it is never upscaled.

   NO CROP. The first version framed it 4:5 anchored to the top, on the logic
   that the gable and the spray are the subject. That was wrong: cropping the
   bottom cut the TECHNICIAN out, and a photograph of a high gable with nobody
   standing under it does not say "we reach this from the ground" at all — it
   is the two of them in the same frame, the wand running between, that makes
   the point. So the frame is the file's own ratio and nothing is trimmed.
   ============================================================ */
.reach__grid { display: grid; grid-template-columns: minmax(0,.85fr) minmax(0,1.15fr);
  gap: 2.2rem; align-items: center; }
.reach__media { margin: 0; }
.reach__media picture { display: block; }
.reach__img { display: block; width: 100%; max-width: 560px; height: auto;
  border-radius: var(--radius-lg); box-shadow: 0 16px 40px rgba(2,35,60,.18); }
.reach__cap { font-size: .8rem; line-height: 1.55; color: var(--muted); margin: .7rem 0 0; max-width: 560px; }
.reach__kick { display: inline-block; font-family: var(--head); font-weight: 800; font-size: .72rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--orange-ink-d); margin-bottom: .5rem; }
.reach__body h2 { font-size: clamp(1.6rem, 3vw, 2.3rem); line-height: 1.12; margin: 0 0 .8rem; text-wrap: balance; }
.reach__lead { font-size: 1.02rem; line-height: 1.6; color: var(--body); margin: 0 0 .9rem; }
.reach__body > p { font-size: .94rem; line-height: 1.65; color: var(--body); margin: 0 0 1.1rem; }
.reach__body p b { color: var(--ink); font-weight: 700; }
.reach__pts { list-style: none; margin: 0 0 1.2rem; padding: 0; display: grid; gap: .55rem; }
.reach__pts li { display: flex; align-items: flex-start; gap: .55rem; font-size: .92rem;
  line-height: 1.5; color: var(--body); }
.reach__pts .ico { width: 1.05em; height: 1.05em; flex: 0 0 auto; margin-top: .22em; color: var(--blue); }
.reach__pts b { color: var(--ink); font-weight: 700; }
.reach__punch { font-size: .94rem; line-height: 1.6; color: #1d1508; margin: 0;
  background: rgba(255,153,51,.13); border-left: 4px solid var(--yellow);
  border-radius: 0 var(--radius) var(--radius) 0; padding: .85rem 1rem; }
@media (max-width: 880px) {
  .reach__grid { grid-template-columns: 1fr; gap: 1.5rem; }
  .reach__img, .reach__cap { max-width: none; }
}

/* ============================================================
   THE SERVICE REPORT PREVIEW — carpet page
   ============================================================
   Pearce, 01/10/2026: "a small preview what they will get from us, not the
   whole thing — competitors might take it and i dont want that."

   THE FADE IS THE FEATURE. .svcrep__doc is masked out to transparent over its
   bottom third, so the document visibly runs on past the edge of what is
   shown. That is doing two jobs at once: it says "there is more of this" to a
   customer, and it means there is nothing below the fold to copy. The mask is
   duplicated as -webkit-mask-image for Safari, and the fallback if neither
   applies is simply an un-faded box — no content is hidden BY the mask that
   matters, because the mock only ever contained its own top.

   The paper sits on a slight rotation with a shadow so it reads as a document
   rather than as another card in the layout. Everything inside it is set in
   the body face at small sizes, deliberately plainer than the page around it:
   it should look like a form, not like marketing.
   ============================================================ */
.svcrep__grid { display: grid; grid-template-columns: minmax(0,1.1fr) minmax(0,.9fr);
  gap: 2.4rem; align-items: center; }
.svcrep__kick { display: inline-block; font-family: var(--head); font-weight: 800; font-size: .72rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--orange-ink-d); margin-bottom: .5rem; }
.svcrep__body h2 { font-size: clamp(1.6rem, 3vw, 2.3rem); line-height: 1.12; margin: 0 0 .8rem; text-wrap: balance; }
.svcrep__lead { font-size: 1.02rem; line-height: 1.6; color: var(--body); margin: 0 0 1.1rem; }
.svcrep__pts { list-style: none; margin: 0 0 1.2rem; padding: 0; display: grid; gap: .55rem; }
.svcrep__pts li { display: flex; align-items: flex-start; gap: .55rem; font-size: .92rem;
  line-height: 1.5; color: var(--body); }
.svcrep__pts .ico { width: 1.05em; height: 1.05em; flex: 0 0 auto; margin-top: .22em; color: var(--blue); }
.svcrep__pts b { color: var(--ink); font-weight: 700; }
.svcrep__punch { font-size: .94rem; line-height: 1.6; color: #1d1508; margin: 0 0 1rem;
  background: rgba(255,153,51,.13); border-left: 4px solid var(--yellow);
  border-radius: 0 var(--radius) var(--radius) 0; padding: .85rem 1rem; }
.svcrep__punch b { color: var(--ink); }
.svcrep__free { font-family: var(--head); font-weight: 800; font-size: 1rem; line-height: 1.45;
  color: var(--blue-dk); margin: 0; }

.svcrep__paper { position: relative; background: #fff; border: 1px solid var(--line);
  border-radius: var(--radius-lg); box-shadow: 0 18px 44px rgba(2,35,60,.17);
  padding: 1.25rem 1.25rem 0; overflow: hidden; transform: rotate(-1.1deg);
  max-width: 440px; margin: 0 auto; }
.svcrep__doc { -webkit-mask-image: linear-gradient(180deg, #000 0, #000 62%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0, #000 62%, transparent 100%); padding-bottom: 2.6rem; }
.svcrep__head { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem;
  padding-bottom: .55rem; border-bottom: 2px solid var(--yellow); }
.svcrep__brand { font-family: var(--head); font-weight: 800; font-size: .86rem; color: var(--ink);
  letter-spacing: .01em; }
.svcrep__doctype { font-family: var(--head); font-weight: 800; font-size: .58rem; letter-spacing: .13em;
  text-transform: uppercase; color: var(--orange-ink-d); }
.svcrep__meta { display: grid; grid-template-columns: 1fr 1fr; gap: .35rem .9rem; margin: .7rem 0 .9rem; }
.svcrep__meta span, .svcrep__rows span { display: grid; gap: .05rem; min-width: 0; }
.svcrep__meta i, .svcrep__rows i { font-style: normal; font-size: .54rem; letter-spacing: .12em;
  text-transform: uppercase; font-weight: 800; color: var(--muted); }
.svcrep__meta b, .svcrep__rows b { font-size: .74rem; font-weight: 700; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.svcrep__sec { padding: .7rem 0 0; border-top: 1px solid var(--line); margin-top: .7rem; }
.svcrep__sech { display: block; font-family: var(--head); font-weight: 800; font-size: .56rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--blue-dk); margin-bottom: .45rem; }
/* The chip colours ARE the CRM's — #ECFCCB on #3F6212 is "Reasonably
   Maintained" exactly as useCarpetReports.tsx paints it. Kept literal on
   purpose: these are the report's colours, not the website's palette, and
   substituting brand orange here would misrepresent the document. */
.svcrep__chip { display: inline-block; background: #ECFCCB; color: #3F6212; font-weight: 800;
  font-size: .64rem; letter-spacing: .04em; padding: .22rem .5rem; border-radius: 999px;
  margin-bottom: .45rem; }
.svcrep__sec p { font-size: .67rem; line-height: 1.5; color: var(--body); margin: 0 0 .55rem; }
.svcrep__rows { display: grid; grid-template-columns: 1fr 1fr; gap: .35rem .9rem; }
.svcrep__shots { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; margin-top: .1rem; }
.svcrep__shots span { aspect-ratio: 4 / 3; border-radius: var(--radius); border: 1px dashed var(--line);
  background: #F4F2EE; display: grid; place-items: center; font-family: var(--head); font-weight: 800;
  font-size: .56rem; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
/* SAMPLE, on the face of it, permanently. This mock must never be mistakable
   for a record of a real job — see the note in build-pages.cjs. */
.svcrep__stamp { position: absolute; left: 1.25rem; bottom: 1.1rem; font-family: var(--head); font-weight: 800;
  font-size: .58rem; letter-spacing: .2em; text-transform: uppercase; color: #A8431A;
  border: 1.5px solid rgba(168,67,26,.5); border-radius: var(--radius); padding: .18rem .45rem;
  transform: rotate(-3deg); background: rgba(255,255,255,.88); z-index: 2; }
.svcrep__cap { font-size: .78rem; line-height: 1.55; color: var(--muted); margin: 1rem auto 0;
  max-width: 440px; text-align: center; }
@media (max-width: 880px) {
  .svcrep__grid { grid-template-columns: 1fr; gap: 1.6rem; }
  .svcrep__paper { transform: none; }
}

/* ============================================================
   THE NUMBERS BLOCK — under the heat band
   ============================================================ */
.truckfacts__head { max-width: 46rem; margin: 0 auto 2rem; text-align: center; }
.truckfacts__kick { display: inline-block; font-family: var(--head); font-weight: 800; font-size: .72rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--orange-ink-d); margin-bottom: .5rem; }
.truckfacts h2 { font-size: clamp(1.6rem, 3vw, 2.3rem); line-height: 1.12; margin: 0 0 .8rem; text-wrap: balance; }
.truckfacts__lead { font-size: 1rem; line-height: 1.6; color: var(--body); margin: 0; }

.truckfacts__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.1rem; }
.truckfact { background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 1.3rem 1.3rem 1.4rem; display: flex; flex-direction: column; }
.truckfact__lab { display: inline-flex; align-items: center; gap: .4em; font-family: var(--head); font-weight: 800;
  font-size: .7rem; letter-spacing: .13em; text-transform: uppercase; color: var(--orange-ink-d); }
.truckfact__lab .ico { width: 1em; height: 1em; }
.truckfact__fig { display: flex; align-items: baseline; gap: .55rem; flex-wrap: wrap; margin: .7rem 0 .7rem;
  padding-bottom: .7rem; border-bottom: 1px solid var(--line); }
.truckfact__fig b { font-family: var(--head); font-weight: 800; font-size: 2.2rem; line-height: 1;
  color: var(--blue); font-variant-numeric: tabular-nums; }
.truckfact__fig span { font-size: .82rem; font-weight: 700; color: var(--muted); }
.truckfact p { font-size: .9rem; line-height: 1.6; color: var(--body); margin: 0; }
.truckfact p b { color: var(--ink); font-weight: 700; }
/* THE AT-A-GLANCE STRIP at the foot of each card. Pearce, 01/10/2026: "under
   each of our Highlights, there should be a small obvious comparable to
   portable here."
   margin-top:auto is what makes it work: the card is a flex column and the six
   paragraphs are different lengths, so without it the strips would sit at six
   different heights across the grid and stop reading as a row of comparisons.
   Colours are the two already on the page — brand blue for ours, the deep
   orange-ink used for every negative mark on this site for theirs. No red and
   no green: neither is a BFYB colour. */
.truckfact__vs { margin-top: auto; padding-top: 1rem; display: grid; gap: .4rem; }
.truckfact__vs > div { display: grid; gap: .1rem; padding: .5rem .65rem; border-radius: var(--radius); }
.truckfact__vs-us { background: rgba(7,110,184,.07); border: 1px solid rgba(7,110,184,.2); }
.truckfact__vs-them { background: rgba(168,67,26,.055); border: 1px solid rgba(168,67,26,.16); }
.truckfact__vs-lab { display: inline-flex; align-items: center; gap: .35em; font-family: var(--head);
  font-weight: 800; font-size: .62rem; letter-spacing: .12em; text-transform: uppercase; }
.truckfact__vs-us .truckfact__vs-lab { color: var(--blue-dk); }
.truckfact__vs-them .truckfact__vs-lab { color: #A8431A; }
.truckfact__vs-lab .ico { width: 1em; height: 1em; }
.truckfact__vs-x { font-family: var(--head); font-weight: 800; font-size: 1.05em; line-height: 1; }
.truckfact__vs b { font-family: var(--head); font-weight: 800; font-size: .95rem; line-height: 1.25;
  font-variant-numeric: tabular-nums; }
.truckfact__vs-us b { color: var(--blue); }
.truckfact__vs-them b { color: #5a4526; }
.truckfacts__src { font-size: .78rem; line-height: 1.55; color: var(--muted); margin: 1.3rem 0 0;
  max-width: 54rem; }
@media (max-width: 980px) { .truckfacts__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .truckfacts__grid { grid-template-columns: 1fr; } .truckfacts__head { text-align: left; } }

/* ============================================================
   THE PAID PRE-VACUUM — under the pre-vacuum comparison
   ============================================================ */
.prevacbuy { display: grid; grid-template-columns: 1.45fr .55fr; gap: 1.6rem; align-items: center;
  margin-top: 1.5rem; background: var(--grad-blue-deep); color: #fff;
  border-radius: var(--radius-lg); padding: 1.7rem 1.7rem 1.8rem; box-shadow: 0 16px 36px rgba(5,78,133,.24); }
.prevacbuy__tag { display: inline-block; background: var(--yellow); color: #3d2607; font-family: var(--head);
  font-weight: 800; font-size: .68rem; letter-spacing: .13em; text-transform: uppercase;
  padding: .3rem .7rem; border-radius: 999px; }
.prevacbuy h3 { font-size: clamp(1.25rem, 2.4vw, 1.7rem); line-height: 1.14; color: #fff; margin: .8rem 0 .7rem; }
.prevacbuy__hl { color: var(--yellow); font-style: italic; }
.prevacbuy p { font-size: .94rem; line-height: 1.6; color: rgba(255,255,255,.86); margin: 0; }
.prevacbuy b { color: #fff; font-weight: 700; }
.prevacbuy__pts { list-style: none; margin: .9rem 0 0; padding: 0; display: grid; gap: .45rem; }
.prevacbuy__pts li { display: flex; gap: .55rem; align-items: flex-start; font-size: .88rem; line-height: 1.5;
  color: rgba(255,255,255,.84); }
.prevacbuy__pts .ico { flex: none; width: 1em; height: 1em; margin-top: .28em; color: var(--yellow); }
.prevacbuy__buy { text-align: center; background: rgba(255,255,255,.1); border: 1px solid rgba(255,153,51,.5);
  border-radius: var(--radius); padding: 1.2rem 1.1rem 1.3rem; }
.prevacbuy__lab { display: block; font-family: var(--head); font-weight: 800; font-size: .7rem;
  letter-spacing: .13em; text-transform: uppercase; color: rgba(255,255,255,.84); }
.prevacbuy__fig { display: flex; align-items: baseline; justify-content: center; gap: .4rem; margin: .4rem 0 .9rem; }
.prevacbuy__fig b { font-family: var(--head); font-weight: 800; font-size: 2.6rem; line-height: 1; color: var(--yellow); }
.prevacbuy__fig span { font-size: .82rem; font-weight: 700; color: rgba(255,255,255,.82); }
.prevacbuy__buy .btn { width: 100%; justify-content: center; }
.prevacbuy__fine { font-size: .76rem !important; line-height: 1.5 !important;
  color: rgba(255,255,255,.72) !important; margin-top: .8rem !important; }
@media (max-width: 820px) { .prevacbuy { grid-template-columns: 1fr; gap: 1.2rem; } }

/* ============================================================
   THE PRE-VACUUM — carpet page, under the truckmount
   Two cards side by side: ours in brand blue, the one that went over it
   first in muted cream. Same device as .tmdont, one level up.
   ============================================================ */
.prevac__head { max-width: 46rem; margin: 0 auto 2.1rem; text-align: center; }
.prevac__kick { display: inline-block; font-family: var(--head); font-weight: 800; font-size: .72rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--orange-ink-d); margin-bottom: .55rem; }
.prevac h2 { font-size: clamp(1.6rem, 3vw, 2.3rem); line-height: 1.12; margin: 0 0 1rem; text-wrap: balance; }
.prevac__lead { font-size: 1.02rem; line-height: 1.62; color: var(--body); margin: 0 0 .85rem; }
.prevac__lead b { color: var(--ink); }

/* stretch, so the two cards finish level like the heat band pair. */
.prevac__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; align-items: stretch; }
/* The italic "power" in the headline kerns hard into the next word. */
.prevac h2 i { font-style: italic; margin-right: .14em; }
.prevac__card { border-radius: var(--radius-lg); padding: 1.6rem 1.5rem 1.7rem; position: relative; }
.prevac__card h3 { font-size: 1.16rem; margin: .9rem 0 .6rem; line-height: 1.2; }
.prevac__card p { font-size: .92rem; line-height: 1.6; margin: 0 0 .7rem; }
.prevac__card--us { background: var(--grad-blue-deep); color: #fff; box-shadow: 0 16px 36px rgba(5,78,133,.26); }
.prevac__card--us h3 { color: #fff; }
.prevac__card--us p { color: rgba(255,255,255,.84); }
.prevac__card--us b { color: var(--yellow); font-weight: 700; }
.prevac__card--them { background: #fff; border: 1px solid var(--line); }
.prevac__card--them p { color: var(--body); }
.prevac__card--them b { color: var(--ink); font-weight: 700; }

/* Both tags got louder. Pearce, 01/10/2026: "GOOD but more obvious — 'What your
   bond cleaner likely used' is what the right needs." The right-hand one was a
   pale cream chip that read as a caption; it is now a filled label in the same
   deep orange as the crosses in the comparison table, white on it at 6.2:1. */
.prevac__tag { display: inline-block; font-family: var(--head); font-weight: 800; font-size: .76rem;
  letter-spacing: .1em; text-transform: uppercase; padding: .42rem .85rem; border-radius: 999px; }
.prevac__tag--us { background: var(--yellow); color: #3d2607; }
.prevac__tag--them { background: #A8431A; color: #fff; }

/* Ours is a photo, theirs is a drawing — on purpose, the same device the
   truckmount section uses. They are matched on HEIGHT rather than width so the
   two machines sit at a comparable scale beside each other.
   230px tall puts the photo at about 71px wide, a slight downscale of the 80px
   source, which keeps it sharp. Never scale it past its natural size. */
/* Centred in the card. Pearce, 01/10/2026: "icons need to be centred." */
.prevac__svg, .prevac__shot { display: block; height: 230px; width: auto; margin: 1.1rem auto 1.2rem; }
/* The 80px cap is the COLUMBUS's natural size — it must never be scaled up,
   there is no more detail in that file. Their machine is a 528px source, so it
   gets its own cap and stays sharp. */
.prevac__shot { max-width: 80px; filter: drop-shadow(0 10px 18px rgba(0,0,0,.34)); }
.prevac__shot--them { max-width: 180px; filter: drop-shadow(0 10px 20px rgba(0,0,0,.14)); }
.prevac__svg--them { color: #9A8E80; }
@media (max-width: 420px) { .prevac__svg, .prevac__shot { height: 190px; } }

.prevac__specs { list-style: none; margin: .9rem 0 0; padding: 0; display: grid; gap: .5rem; }
.prevac__specs li { display: flex; gap: .55rem; align-items: flex-start;
  font-size: .85rem; line-height: 1.45; color: rgba(255,255,255,.8); }
.prevac__specs .ico { flex: none; width: 1em; height: 1em; margin-top: .25em; color: var(--yellow); }
.prevac__specs b { color: #fff; font-weight: 700; }

/* The head-to-head strip. The surprise is that the backpack wins both numbers,
   so they are set big and plainly, with no thumb on the scale. */
.prevac__vs { background: var(--cream2); border: 1px solid var(--line); border-radius: var(--radius);
  padding: .9rem 1rem 1rem; margin: 1rem 0 0; }
.prevac__vs__head { display: block; font-family: var(--head); font-weight: 800; font-size: .66rem;
  letter-spacing: .13em; text-transform: uppercase; color: #6B6158; margin-bottom: .6rem; }
.prevac__vs__row { display: flex; align-items: baseline; gap: .45rem .6rem; flex-wrap: wrap;
  padding: .45rem 0; border-top: 1px solid var(--line); }
.prevac__vs__row:first-of-type { border-top: 0; padding-top: 0; }
.prevac__vs__row b { font-family: var(--head); font-weight: 800; font-size: 1.22rem; line-height: 1;
  color: var(--ink); font-variant-numeric: tabular-nums; }
.prevac__vs__row span { font-size: .78rem; color: #6B6158; font-weight: 600; }
.prevac__vs__row i { font-style: normal; font-family: var(--head); font-weight: 800; font-size: .72rem;
  letter-spacing: .1em; text-transform: uppercase; color: #A8431A; padding: 0 .3rem; }
.prevac__vs__row b + span { margin-right: .35rem; }

.prevac__punch { margin: .9rem 0 0 !important; padding-top: .85rem; border-top: 1px solid var(--line);
  font-size: .86rem !important; line-height: 1.55 !important; color: var(--muted) !important; }
.prevac__punch b { color: var(--ink); }

.prevac__note { margin-top: 1.5rem; background: var(--yellow-soft); border: 1px solid rgba(255,153,51,.34);
  border-left: 4px solid var(--yellow); border-radius: var(--radius-lg); padding: 1.5rem 1.6rem; }
.prevac__note h3 { font-size: 1.1rem; margin: 0 0 .7rem; }
.prevac__note p { font-size: .95rem; line-height: 1.6; color: var(--body); margin: 0 0 .75rem; max-width: 50rem; }
.prevac__note b { color: var(--ink); font-weight: 700; }
.prevac__note .btn { margin-top: .5rem; }

@media (max-width: 860px) {
  .prevac__grid { grid-template-columns: 1fr; }
  .prevac__head { text-align: left; }
}

/* ============================================================
   DRYING FAN HIRE — carpet page
   ============================================================ */
.dryfan__inner { display: grid; grid-template-columns: .8fr 1.2fr; gap: 2.4rem; align-items: center; }
.dryfan__media { text-align: center; }
.dryfan__media img { width: 100%; max-width: 300px; height: auto;
  filter: drop-shadow(0 20px 32px rgba(20,18,16,.22)); }
.dryfan__kick { display: inline-block; font-family: var(--head); font-weight: 800; font-size: .7rem;
  letter-spacing: .12em; text-transform: uppercase; color: #fff; background: var(--deep);
  padding: .28rem .75rem; border-radius: 99px; margin-bottom: .7rem; }
.dryfan h2 { font-size: clamp(1.5rem, 2.8vw, 2.1rem); line-height: 1.14; margin: 0 0 .8rem; text-wrap: balance; }
.dryfan p { font-size: 1rem; line-height: 1.6; color: var(--body); margin: 0 0 .8rem; max-width: 34rem; }
.dryfan__price { display: flex; align-items: baseline; gap: .55rem; margin: 1rem 0 .5rem !important; }
.dryfan__price b { font-family: var(--head); font-weight: 800; font-size: 2rem; color: var(--orange-ink);
  font-variant-numeric: tabular-nums; line-height: 1; }
.dryfan__price span { font-size: .88rem; color: var(--muted); }
.dryfan__note { font-size: .88rem !important; color: var(--muted) !important; }

/* Three reasons the fans are worth taking. Pearce, 01/10/2026: "our trucks
   always have 4 on board, we dont upsell them, we should." */
.dryfan__why { list-style: none; margin: 0 0 1rem; padding: 0; display: grid; gap: .6rem; max-width: 34rem; }
.dryfan__why li { display: flex; gap: .55rem; align-items: flex-start; font-size: .94rem; line-height: 1.55; color: var(--body); }
.dryfan__why .ico { flex: none; width: 1em; height: 1em; margin-top: .3em; color: var(--blue); }
.dryfan__why b { color: var(--ink); font-weight: 700; }
.dryfan__why i { font-style: italic; }
@media (max-width: 820px) {
  .dryfan__inner { grid-template-columns: 1fr; gap: 1.4rem; }
  .dryfan__media img { max-width: 210px; }
}

/* ============================================================
   CARPET ESTIMATOR — on the carpet page, near the top
   ============================================================ */
.cest__host { background: var(--white); border: 1.5px solid var(--line); border-radius: var(--radius-lg);
  padding: 1.2rem; box-shadow: 0 10px 30px rgba(20,18,16,.06); }
.cest__grid { display: grid; grid-template-columns: 1.25fr .75fr; gap: 1.4rem; align-items: start; }
.cest__q { font-family: var(--head); font-weight: 800; font-size: .82rem; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink); margin: 0 0 .6rem; }
.cest__q + .cest__seg { margin-bottom: .3rem; }
.cest__inputs .cest__q:nth-of-type(2) { margin-top: 1.1rem; }
.cest__seg { display: flex; gap: .5rem; flex-wrap: wrap; }
.cest__segb { font: inherit; font-family: var(--head); font-weight: 700; font-size: .88rem; cursor: pointer;
  background: var(--white); color: var(--ink); border: 1.5px solid var(--line); border-radius: 99px;
  padding: .5rem 1.05rem; transition: background .14s, border-color .14s, color .14s; }
.cest__segb:hover { border-color: var(--yellow); }
.cest__segb.on { background: var(--deep); border-color: var(--deep); color: #fff; }
.cest__hint { font-size: .8rem; color: var(--muted); margin: .5rem 0 0; }
.cest__rooms { display: grid; gap: .5rem; }
.cest__row { display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  border: 1.5px solid var(--line); border-radius: var(--radius); padding: .55rem .7rem; background: var(--white); }
.cest__rt { display: flex; flex-direction: column; min-width: 0; }
.cest__rt b { font-size: .92rem; color: var(--ink); font-weight: 700; }
.cest__rt span { font-size: .76rem; color: var(--muted); }
.cest__step { display: inline-flex; align-items: center; gap: .55rem; flex: 0 0 auto; }
.cest__step button { font: inherit; font-family: var(--head); font-weight: 800; font-size: 1.1rem; line-height: 1;
  cursor: pointer; width: 32px; height: 32px; border-radius: 50%; border: 1.5px solid var(--line);
  background: var(--white); color: var(--ink); transition: background .14s, border-color .14s, color .14s; }
.cest__step button:hover:not(:disabled) { background: var(--yellow); border-color: var(--yellow); }
.cest__step button:disabled { opacity: .35; cursor: default; }
.cest__step > b { min-width: 1.2rem; text-align: center; font-family: var(--head); font-weight: 800;
  font-variant-numeric: tabular-nums; }

/* Brand blue, not black. Pearce, 01/10/2026: "black back, ew."
   The faint white tints below were set against black; on the blue they are
   lifted so the label and the fine print stay readable. */
.cest__out { position: sticky; top: 92px; background: var(--grad-blue-deep); color: #fff;
  border-radius: var(--radius-lg); padding: 1.15rem 1.2rem; text-align: center; }
.cest__lab { display: block; font-size: .72rem; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: rgba(255,255,255,.76); margin-bottom: .35rem; }
.cest__num { display: block; font-family: var(--head); font-weight: 800; font-size: 2.6rem; line-height: 1;
  color: var(--yellow); font-variant-numeric: tabular-nums; }
/* "From" sits at its own size with real space after it. Pearce has pulled
   this up twice now: "From $289 is very close, needs a gap between." Set as
   an element rather than glued into the string so the gap cannot be eaten by
   HTML whitespace collapsing. */
.cest__from { display: inline-block; font-size: .95rem; font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; color: rgba(255,255,255,.8); margin-right: .5rem;
  vertical-align: .34em; }
.cest__sub { display: block; font-size: .76rem; color: rgba(255,255,255,.74); margin-top: .3rem; }
.cest__min { font-size: .76rem; line-height: 1.45; color: rgba(255,255,255,.72); margin: .8rem 0 0;
  padding-top: .7rem; border-top: 1px solid rgba(255,255,255,.16); text-align: left; }
.cest__go { display: flex; align-items: center; justify-content: center; gap: .4em; margin-top: .9rem;
  background: var(--yellow); color: #3d2607; font-family: var(--head); font-weight: 800; font-size: .92rem;
  border-radius: 10px; padding: .7rem 1rem; text-decoration: none; transition: transform .14s; }
.cest__go:hover { transform: translateY(-1px); }
.cest__go .ico { width: .85em; height: .85em; }
.cest__note { font-size: .72rem; line-height: 1.45; color: rgba(255,255,255,.74); margin: .8rem 0 0; text-align: left; }
@media (max-width: 760px) {
  .cest__grid { grid-template-columns: 1fr; }
  .cest__out { position: static; }
}

/* ============================================================
   PER-TAB PRICE LIST
   ============================================================ */
.tabprice { display: grid; gap: .5rem; }
.tabprice__bands { list-style: none; margin: 0 0 .8rem; padding: 0; display: grid; gap: .3rem; }
.tabprice__bands li { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  font-size: .88rem; color: var(--body); }
.tabprice__bands li b { font-family: var(--head); font-weight: 800; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.tabprice__warr { display: flex; gap: .5em; align-items: flex-start; font-size: .83rem; line-height: 1.45;
  color: var(--muted); margin: 0 0 .9rem; }
.tabprice__warr .ico { width: 1em; height: 1em; flex: 0 0 auto; margin-top: .2em; color: var(--orange-ink); }
.tabprice__xh { font-family: var(--head); font-weight: 800; font-size: .84rem; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); margin: 1.6rem 0 .7rem; }
.tabprice__x { list-style: none; margin: 0; padding: 0; display: grid; gap: .45rem; }
.tabprice__x li { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem;
  background: var(--white); border: 1.5px solid var(--line); border-radius: var(--radius); padding: .6rem .8rem; }
.tabprice__x li > span { display: flex; flex-direction: column; min-width: 0; }
.tabprice__x li b { font-family: var(--head); font-weight: 700; color: var(--ink); font-size: .9rem; }
.tabprice__x li > span > span { font-size: .78rem; color: var(--muted); line-height: 1.4; margin-top: .15rem; }
.tabprice__x li > b { flex: 0 0 auto; font-weight: 800; font-variant-numeric: tabular-nums; }
.tabprice__all { margin: 1.4rem 0 0; font-size: .86rem; color: var(--muted); }

/* ---------- Address autocomplete (assets/address-lookup.js) ---------- */
.al__wrap { position: relative; }
.al__list { position: absolute; left: 0; right: 0; top: 100%; z-index: 30; margin: 4px 0 0; padding: 4px;
  list-style: none; background: var(--white); border: 1.5px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 14px 34px rgba(20,18,16,.16); max-height: 260px; overflow-y: auto; }
.al__opt { display: flex; align-items: flex-start; gap: .6rem; width: 100%; text-align: left; cursor: pointer;
  font: inherit; font-size: .88rem; line-height: 1.4; color: var(--ink); background: transparent;
  border: 0; border-radius: 8px; padding: .55rem .6rem; }
.al__opt:hover, .al__opt.on { background: var(--yellow-soft); }
.al__pin { flex: 0 0 auto; color: var(--orange-ink); margin-top: .12em; }
.al__pin .ico { width: .95em; height: .95em; }
.bkq__addrok { display: flex; align-items: flex-start; gap: .55rem; margin-top: .7rem; padding: .6rem .75rem;
  background: #f2faf3; border: 1.5px solid #cfe9d4; border-radius: var(--radius);
  font-size: .85rem; line-height: 1.45; color: var(--body); }
.bkq__addrok b { color: var(--ink); }
/* "We come to Armidale" — the derived town, confirmed back to the customer.
   Brand blue rather than the green of the address tick, so the two lines read
   as two different confirmations and not one wrapped sentence. */
.bkq__addrok--town { background: rgba(7,110,184,.07); border-color: rgba(7,110,184,.24); }
.bkq__note--warn { background: #fdf3e8; border-color: #f0d5b4; }

/* THE TOWN LIST, FOLDED AWAY. It stopped being the first question on
   02/10/2026 — the address lookup derives the town now (see townFromAddr in
   booking.js). It stays reachable because geocoders miss things: new estates,
   rural properties with no street number, a blocked third party. */
.bkq__fold { margin: 12px 0 0; }
.bkq__fold > summary { cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: .4em;
  font-family: var(--head); font-weight: 700; font-size: .86rem; color: var(--blue-dk);
  text-decoration: underline; text-underline-offset: 3px; padding: 6px 2px; }
.bkq__fold > summary::-webkit-details-marker { display: none; }
.bkq__fold > summary::before { content: "+"; font-weight: 800; font-size: 1.05em; line-height: 1; }
.bkq__fold[open] > summary::before { content: "\2212"; }
.bkq__fold > summary:hover { color: var(--orange-ink-d); }
/* A card nested inside another card (the "Armidale or Hillgrove?" question
   sitting under the confirmed address) — no second border, just a tint. */
.bkq__card--inset { background: var(--cream2); border: 1.5px solid var(--line); margin-top: .7rem;
  padding: 13px 14px 11px; }

/* ---- "What are you here for?" — the question, in the hero ---- */
/* It started as a row of small pills, which Pearce could not see: "should this
   be a question that's actually larger, and over the screen somewhat, so it's
   obvious?" Larger, yes. Over the screen, no — a first-visit interstitial is
   the strongest steering available and it costs more than it buys: Google
   penalises them on mobile, someone who only wants a price has to answer
   first, and it covers the one photograph on the site doing trust work.
   So it earns attention by being a real question in a panel of its own rather
   than by blocking the page: an actual question mark, four targets big enough
   to hit with a thumb, each with its icon, and a line underneath saying what
   happens when you pick one — which is the part that makes it worth doing. */
/* OUT OF THE HERO AND INTO ITS OWN BAND, 02/10/2026 — see build-home.cjs.
   It is no longer squeezed into a card beside a headline, so it gets the full
   width of the page, four across on desktop, and the question can be the size
   a question deserves. The card chrome is gone with the move: it is the only
   thing in its band now, so a border around it framed nothing. */
.lanepick__band { padding-block: 2.2rem; background: var(--cream2); }
.lanepick { margin: 0; padding: 0; background: none; border: 0; box-shadow: none; max-width: none; }
.lanepick__q { font-family: var(--head); font-weight: 800; font-size: clamp(1.3rem, 2.2vw, 1.7rem);
  color: var(--ink); margin: 0 0 .2rem; text-align: center; }
.lanepick__row { display: grid; grid-template-columns: repeat(4, 1fr); gap: .7rem; margin-top: 1rem; }
.lanepick__hint { margin: .85rem 0 0; font-size: .88rem; color: var(--muted); text-align: center; }
@media (max-width: 760px) { .lanepick__row { grid-template-columns: 1fr 1fr; } }

.lanechip { display: flex; align-items: center; gap: .6rem; width: 100%;
  font-family: var(--head); font-weight: 700; font-size: .95rem; cursor: pointer;
  text-align: left; background: var(--cream); color: var(--blue);
  border: 1.5px solid var(--line); border-radius: 12px; padding: .7rem .85rem;
  text-decoration: none; transition: background .15s, border-color .15s, color .15s; }
.lanechip:hover { border-color: var(--blue); background: var(--white); }
.lanechip__ico { display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; flex: 0 0 30px; border-radius: 9px;
  background: var(--blue); color: #fff; }
.lanechip__ico .ico { width: 15px; height: 15px; }
.lanechip__t { min-width: 0; }
.lanechip[aria-pressed="true"] { background: var(--grad-blue); border-color: var(--blue-d); color: #fff; }
.lanechip[aria-pressed="true"] .lanechip__ico { background: rgba(255,255,255,.22); }
.lanechip--emerg { color: var(--orange-ink); border-color: rgba(203,96,31,.35); }
.lanechip--emerg .lanechip__ico { background: var(--orange-ink); }
.lanechip--emerg:hover { border-color: var(--orange-ink); }

/* z-index BELOW the nav bar (49) and the header (50): this is a status strip,
   not a layer over the site chrome. `top` is set from JS to whatever is
   actually stuck above it, because that differs between breakpoints. */
.lanebar { position: sticky; top: 0; z-index: 48; background: var(--grad-blue); color: #fff;
  font-size: .88rem; }

/* THE `hidden` ATTRIBUTE ONLY SETS display:none AT THE UA LEVEL, so ANY
   display rule in this file beats it. .splitpick__side is display:flex, so the
   pest card stayed on screen while reporting itself hidden — visible to the
   customer, invisible to the code. One rule, so it can never happen again to
   anything the lane filter touches. */
[hidden] { display: none !important; }

/* One card left means one full-width card, not a half-empty row. */
.splitpick:has(> [hidden]) { grid-template-columns: 1fr; }
.lanebar__in { display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; padding-block: .55rem; }
.lanebar b { font-weight: 800; }
.lanebar__clear { font-family: inherit; font-size: .85rem; font-weight: 700; cursor: pointer;
  background: rgba(255,255,255,.16); color: #fff; border: 0; border-radius: 99px;
  padding: .35rem .9rem; }
.lanebar__clear:hover { background: rgba(255,255,255,.28); }

@media (max-width: 540px) {
  .lanepick { padding: .9rem 1rem; }
  .lanepick__q { font-size: 1.08rem; }
  .lanepick__row { grid-template-columns: 1fr; gap: .45rem; }
}

/* ============================================================
   FLOOD & WATER DAMAGE — THE RATE CARD
   Pearce, 04/10/2026: "water restoration needs these prices too... showing the
   prices will allow them to see the charges upfront."
   Six groups in a grid. Only the inspection card is lit, because it is the only
   one you can act on — everything else is a rate the office assembles into a
   scope. The emphasis is doing the work of the page: it tells you where to
   start without a paragraph explaining it.
   ============================================================ */
.fldgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 18px; }
.fldcard { background: #fff; border: 1.5px solid var(--line); border-radius: 15px; padding: 20px 21px;
  display: flex; flex-direction: column; }
.fldcard h3 { margin: 0; font-family: var(--head); font-weight: 800; font-size: 1.1rem; color: var(--ink); }
.fldcard__note { margin: 6px 0 0; font-size: .83rem; color: var(--muted); line-height: 1.55; }
.fldlist { list-style: none; margin: 14px 0 0; padding: 0; }
.fldlist li { display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding: 10px 0; border-top: 1px solid var(--line); }
.fldlist li:first-child { border-top: 0; padding-top: 4px; }
.fldlist span { font-size: .91rem; color: var(--body); }
.fldlist b { flex: none; font-family: var(--head); font-weight: 800; font-size: 1.05rem; color: var(--ink);
  font-variant-numeric: tabular-nums; text-align: right; }
.fldlist b small { display: block; font-size: .62rem; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted); margin-top: 2px; }
/* THE ONE CARD YOU CAN PRESS. Filled rather than outlined, because on a page
   of six price cards the reader's question is "so what do I actually do?" */
.fldcard--book { background: var(--yellow-soft); border-color: var(--yellow); border-width: 2px;
  box-shadow: 0 8px 26px rgba(255,153,51,.2); }
.fldcard--book .fldlist li { border-top-color: rgba(20,18,16,.12); }
.fldcard--book .fldlist b { font-size: 1.5rem; }
.fldcard__btn { margin-top: auto; align-self: flex-start; }
.fldcard__fine { margin: 10px 0 0; font-size: .77rem; color: var(--body); line-height: 1.5; }
.fldfoot { margin: 20px 0 0; font-size: .82rem; color: var(--muted); line-height: 1.6; max-width: 62ch; }
@media (max-width: 520px) {
  .fldcard { padding: 17px 17px; }
  .fldlist b { font-size: 1rem; }
  .fldcard--book .fldlist b { font-size: 1.3rem; }
}

/* The one priced line on an otherwise "quoted" section of the price page. */
.floodline { display: flex; align-items: center; justify-content: space-between; gap: 16px;
  flex-wrap: wrap; background: var(--yellow-soft); border: 2px solid var(--yellow);
  border-radius: 14px; padding: 16px 19px; margin: 1.1rem 0 1.3rem; }
.floodline__t b { display: block; font-family: var(--head); font-weight: 800; font-size: 1.02rem; color: var(--ink); }
.floodline__t span { display: block; font-size: .83rem; color: var(--body); margin-top: 2px; }
.floodline__p { font-family: var(--head); font-weight: 800; font-size: 1.7rem; color: var(--ink);
  font-variant-numeric: tabular-nums; }


/* ============================================================
   THE PHONE PASS — 10/10/2026
   ============================================================
   Pearce, after opening the new site on his own iPhone: "i have gone
   to use the phone BFYB new website, and its bad, in many areas", and
   of the other business: "KAPOWS phone view is AMAZING! BFYB should be
   similar, but its far from."

   Measured on an iPhone 14 Pro — 393x660 CSS pixels — against Kapow's
   home page at the same size. Four differences did the damage.

     1. NOTHING COULD BE TAPPED ON SCREEN ONE. The header, the pill,
        a three-line headline and a five-line paragraph used 442 of the
        660 pixels a phone has before the first price appeared. The
        first BUTTON was 959px down and the phone number 1257px — two
        full screens of scrolling before anything could be pressed.
        Kapow puts its prices, "Book online in 60 seconds" and "Call
        the team" all inside the first screen.

     2. THE STICKY BOOK/CALL BAR WAS MISSING FROM EVERY PAGE THAT
        MATTERS. The .bookbar below has existed for weeks and works —
        but it was only ever added to the suburb and interior pages.
        The home page, the quote page, the pricing page, the eight
        service pages and the terms had none, which is to say the
        pages people actually land on. Fixed in the builders, not
        here; this block only makes the bar worth landing on.

     3. PRICES RAN DOWN THE PAGE ONE PER ROW. Kapow's are a 2x2 grid:
        the same four prices in half the height. Ours are now too.

     4. THINGS WERE TOO SMALL TO HIT OR READ. 40 tap targets under
        Apple's 44px floor — the phone links measured 27px and the room
        chips 23px — and text down to 9.9px ("FIXED PEST PRICES").

   EVERYTHING BELOW IS PHONE-ONLY, at 560px and under. Not one rule
   here reaches the desktop or tablet layout, which Pearce has signed
   off twice and which is not what he was complaining about.
   ============================================================ */
@media (max-width: 560px) {

  /* ---- 1. The header was 86px of orange before the page began. ----
     The wordmark already links home on its own, and the drawer carries
     "Home" at the top of its list, so the word under the mark was
     paying 15px of a 660px screen to repeat something said twice.
     Gone, with a tighter pad and a slightly smaller mark: 86px -> 54px.
     The burger goes UP to 44px rather than down — it is the only way
     into the menu on a phone and it was 46px, so it stays legal. */
  .header .header__inner { padding: .5rem 16px; min-height: 0; gap: .6rem; }
  .brand__home { display: none; }
  .brand__logo { height: 32px; }

  /* ---- 2. The hero says the same things in less room. ----
     Nothing is deleted. The headline, the promise, the warranty line
     and every single price are all still here — they are simply set at
     a size that leaves room underneath for something to press. The
     paragraph drops from five lines to four, the headline from 36.8px
     to 30px, and neither loses a word. */
  .hero:not(.hero--plain) .hero__copy { padding-block: .9rem; }
  /* The interior and pricing heroes — the orange ones — carried 4.5rem of
     padding above the headline and 6.5rem below it, sized for a desktop
     where that air sits beside a photo. On a phone the photo is stacked
     out of the way and the padding is just 176px of empty orange, which
     on a page titled "Every pest price, up front" pushed the first price
     off the bottom of the screen. */
  .hero--plain .hero__inner { padding: 1.5rem 18px 2.2rem; min-height: 0; }
  .hero--plain h1 { font-size: 1.9rem; line-height: 1.08; }
  .herochips { margin-top: .9rem; gap: .45rem; }
  .herochip { font-size: .84rem; padding: .5rem .8rem; min-height: 40px; }
  /* The eight service pages open with 35px of white, a breadcrumb row and
     a category pill before the headline. On a 660px screen that is a
     tenth of the page spent saying where you are. */
  .svc__hero { padding-block: 1.1rem 1.2rem; }
  /* Section rhythm. 48px above and below every band is a desktop measure; on
     a 660px screen it is a seventh of the viewport, thirteen times down the
     home page. 35px still separates them and gives back about 340px. */
  .section { padding-block: 2.2rem; }
  /* The orange heroes with no chip row — quote, terms — were leaving 130px of
     empty orange under the last line. */
  .hero--plain .hero__inner { padding-bottom: 1.4rem; }
  /* The breadcrumb row carried 17.6px above it and, once its links were
     given a 44px target, 58px in all — on the page where every pixel above
     the fold is spoken for. It keeps the target and loses the air. */
  .crumbs { margin-bottom: .3rem; padding-top: 0; }
  .hero--plain .hero__cta { gap: .62rem; }

  /* ---- 7. The booking page gets to the question faster. ----
     "Book pest control & carpet cleaning in Armidale" set at 36.8px is
     three lines and 170px of a 660px screen, and it sits directly above
     a heading that asks the actual question ("What are you after?").
     One of the three service cards was visible; the other two, including
     carpet, were below the fold on the page whose entire job is to let
     someone choose. The H1 stays — it is the page's title and Google
     reads it — at a size that leaves room for the choice underneath. */
  .bkq__h1 { font-size: 1.32rem; line-height: 1.2; margin: 0 0 .9rem; }

  /* ---- 8. The controls further down the page. ----
     The sweep found three that a thumb has to hit and could not hit
     reliably:
       - the carpet estimator's room counters, the - and + buttons, at
         32px. Ten of them, on the one tool on this site that lets a
         customer build their own carpet price. Getting one wrong adds
         a room they did not want.
       - "Get this price" on every price accordion, at 38px. That is the
         button that starts a booking, nine times on the pest page.
       - the single/double storey toggle, at 41px. */
  .cest__step button { min-width: 44px; min-height: 44px; }
  .pricerow__body .btn--sm { min-height: 44px; }
  .cest__segb { min-height: 44px; }

  /* ---- 9. The kickers. ----
     The small uppercase eyebrow above a heading — "The bit nobody tells
     you", "What we don't use", "Since 2011" — is a house pattern used
     about thirty times across the site, and it was setting between
     10.2px and 11.8px. At arm's length on a phone that is a grey smear
     above the thing it is introducing. They are letter-spaced, which
     costs another notch of legibility, so 12.5px is the floor here.
     Matched on the class suffix rather than listed one by one, so the
     next section written with a __kick or a __tag is covered too. */
  [class*="__kick"], [class*="__tag"], [class*="__lab"] { font-size: .78rem; }
  /* Units and fine print. "/seating position" was 10.2px and "FROM" 9px —
     the two bits of text that say what a number actually means. */
  .pricerow__price small { font-size: .76rem; }
  .heroprice__p small { font-size: .68rem; }
  .cest__rt span, .cest__sub, .cest__min, .cest__note,
  .prevacbuy__fine, .prevac__vs__head { font-size: .79rem; }
  .heropill { font-size: .82rem; padding-block: .34rem; margin-bottom: .4rem; }
  .hero h1 { font-size: 1.88rem; line-height: 1.06; margin-bottom: .35rem; }
  .hero__lead { font-size: .95rem; line-height: 1.45; margin-top: .3rem; margin-bottom: .55rem; }

  /* ---- 3. Prices in a grid, the way Kapow does it. ----
     Three pest prices and the "all 8" door fill two rows of two
     instead of four rows of one; the two carpet prices share a row.
     240px becomes 100px on the pest side and 282px becomes ~150px on
     the carpet side, and not one price is hidden to do it.

     The "All 8 pest prices" link is deliberately left as the fourth
     TILE rather than a full-width button under them — it is the same
     move as Kapow's "+16 more services & prices", and it makes the
     block read as one 2x2 object instead of a list with a lid. */
  .heropair--c { gap: .55rem; margin: .2rem 0 .55rem; }
  .heropair--c .heropair__col {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto;
    gap: .45rem; }
  .herobuild { display: grid; grid-template-columns: 1fr 1fr; gap: .45rem;
    padding: .6rem; align-content: start; }
  .herobuild > .herobuild__rooms,
  .herobuild > .herobuild__btn { grid-column: 1 / -1; }
  .herobuild .heroprice { align-items: center; text-align: center; }
  /* The sentence under the carpet prices — "Yours is neither of those,
     tick the rooms and the price builds as you go" — is what the room
     chips and the button underneath it already show. On a desktop it
     is a helpful aside; on a phone it is 35px of repetition standing
     between a price and a button. */
  .herobuild__p { display: none; }

  /* ---- 4. Nothing a thumb has to hit is under 44px. ----
     Apple's own floor, and it is not a style preference: a 23px chip
     on a 2.9mm-wide finger is a mis-tap, and a mis-tap on a price is
     a customer who thinks the site is broken. Measured before this
     block: room chips 23px, both phone links 27px, the two hero
     buttons 37px. */
  .heroprice { min-height: 46px; justify-content: center; padding: .42rem .5rem; }
  .heropair--c .heropair__btn,
  .herobuild__btn { min-height: 46px; }
  .herobuild__rooms i { padding: .32rem .5rem; }
  /* The burger menu is the only way to the phone numbers on a phone, and
     both of them measured 27px. The close button was 42px, the logo 40px.
     These are the controls a one-handed customer standing in a kitchen
     full of ants actually uses. */
  .m-drawer__cta .mn-phone { min-height: 44px; }
  .m-drawer__close { width: 44px; height: 44px; }
  .m-drawer__logo { display: flex; align-items: center; min-height: 44px; }
  .brand { min-height: 44px; justify-content: center; }
  /* The footer is 18 links at 23px — the whole site map, on the page
     everybody scrolls to the bottom of when they cannot find something. */
  .footer__col a { display: flex; align-items: center; min-height: 44px; }
  .footer__base > .wrap > a { display: inline-flex; align-items: center; min-height: 44px; }
  .arealist__group li a { display: inline-flex; align-items: center; min-height: 44px; }
  .crumbs a, .crumbs span { display: inline-flex; align-items: center; min-height: 40px; }
  .feat h3 a, .pricepanel__all, .splitpick__go,
  .svc__links a { display: inline-flex; align-items: center; min-height: 44px; }
  /* NOT .qform__know a. Those two links sit mid-sentence; giving them a 44px
     box pushed the lines of the sentence apart and the paragraph came out
     double-spaced. An inline link gets padding, not a box. */
  .qform__know a { display: inline-block; padding-block: .25rem; }
  .hero__alt a { padding-block: .5rem; }
  .linkcloud a, .localfacts li { padding-block: .62rem; }

  /* ---- 5. The type floor is 12px. ----
     "FIXED PEST PRICES" was setting at 9.9px and the service names at
     11.2px. Both are brand-critical — the first says the prices are
     fixed, which is the whole proposition, and the second says what
     you are buying. Neither should need squinting at. */
  .heropair__h, .herobuild__h { font-size: .78rem; letter-spacing: .08em; }
  .heroprice__n { font-size: .8rem; }
  .heroprice__p { font-size: 1rem; }
  .herobuild__rooms i { font-size: .72rem; }
  .heroboth__txt { font-size: .8rem; }
  .heroboth__txt > span { font-size: .76rem; }

  /* ---- 6. The bar at the bottom of the screen. ----
     It was deep blue on an orange-and-black site. Pearce, 28/09/2026,
     on blue: "Make the top bar this blue, that's fine, the rest no" —
     and the top bar is orange now anyway, so the blue bar at the foot
     of the page was the last piece of a scheme that no longer exists.
     Near-black ground, orange button, orange hairline: the brand order
     as he set it (orange first, black a surface).

     The call button carries the word "Call" now rather than a bare
     handset glyph. An icon on its own is a guess, and the one thing on
     this bar that must never be a guess is the way to reach a person.
     It keeps a fixed width so the Book button always reads as the
     primary one. */
  .bookbar { padding: .55rem .7rem calc(.55rem + env(safe-area-inset-bottom)); gap: .5rem; }
  .bookbar .btn { min-height: 46px; padding: .6rem .8rem; }
  /* The bar is 72px of fixed furniture. Without this the last thing on
     every page sits underneath it, which on the terms page is the
     cancellation clause and on a service page is the book button. */
  body { padding-bottom: calc(82px + env(safe-area-inset-bottom)); }
}

/* The line under the hero buttons. The booking flow is the primary door
   now, so this is where the quote door is named — for the jobs that
   genuinely need one, rather than as the default for everybody. */
.hero__alt { margin: .6rem 0 0; font-size: .92rem; line-height: 1.45; color: var(--muted); max-width: 32rem; }
.hero__alt a { color: var(--orange-ink); font-weight: 700; text-decoration: underline;
  text-underline-offset: 2px; }
.hero__alt a:hover { color: var(--ink); }
@media (max-width: 560px) {
  /* A sentence, not a control. The link inside it gets what room an inline
     link can take without pushing the words apart — a 44px box here would
     break the line it sits in, so this one stops at about 38px and the
     booking button above it carries the weight. */
  .hero__alt { font-size: .85rem; margin-top: .5rem; line-height: 1.6; }
  .hero__alt a { display: inline-block; padding-block: .55rem; }
}

/* "Skip to the prices" — the one-tap shortcut under the interior hero CTAs.
   Shown only where the page is long: at 860px and under the layout is
   stacked and carpet-cleaning runs to 36 phone screens, 21 of them the
   equipment story that Pearce put in front of the price on purpose. The
   story stays where it is; this is the door for somebody who has already
   decided. Styled as a link with a target, not a third button — two
   buttons and a third would read as indecision about what to press. */
.heroskip { display: none; }
@media (max-width: 860px) {
  .heroskip { display: inline-flex; align-items: center; justify-content: center;
    gap: .45em; min-height: 44px; margin-top: .7rem; padding: .5rem 1.1rem;
    border: 2px solid rgba(20,18,16,.32); border-radius: 999px;
    background: rgba(255,255,255,.35);
    font-family: var(--head); font-weight: 700; font-size: .92rem;
    color: #141414; text-decoration: none; }
  .heroskip .ico { width: .9em; height: .9em; }
  .heroskip:active { background: rgba(255,255,255,.6); }
}
/* The anchors it lands on sit under a sticky header, so without this the
   heading it jumps to is hidden behind the orange bar. */
#price, #prices, #rates { scroll-margin-top: 72px; }

/* ============================================================
   THE HOME HERO, ON A PHONE: THE PHOTO IS THE HERO.
   ============================================================
   Pearce, 10/10/2026, sending a photo of Kapow on his own phone: "This is
   Kapow. It looks amazing, can see the image behind the buttons... BFYB
   honestly the phone view is crap."

   He is pointing at one thing. On Kapow the team and the truck fill the
   screen and the prices and buttons float on top of them. On BFYB the same
   photograph is there — hero-team-ai.jpg, already loaded, already scrimmed —
   and then a 90% white card is laid over it, which on a 393px screen covers
   everything but a 30px strip down each edge. We were paying to load a
   photograph and then hiding it.

   The frosted card is right on a desktop, where it sits in the left half of
   a wide frame and the photo fills the other half. It has nothing to sit
   beside on a phone.

   So on phones the card goes and the copy sits on the picture, which is what
   the scrim was always for. Everything below is the re-colouring that makes
   that readable: light type, tiles in smoked glass with orange prices, and
   the primary button in brand orange rather than blue — a blue button on a
   blue-dark photograph is the one thing on this screen that would disappear.

   Contrast, measured over the darkest and lightest parts of the crop:
     white on the scrim          12.1:1 to 6.8:1
     --orange-bright on the scrim 7.4:1 to 4.2:1
     #141414 on the orange button 8.9:1
   ============================================================ */
@media (max-width: 560px) {
  /* A heavier scrim, because the type is on the photo now rather than on a
     card over it. Still lightest at the bottom, where the two of them and
     the ute are — that is the part worth seeing. */
  /* SCOPED TO THE PHOTO HERO. `.hero` on its own would also repaint every
     .hero--plain — the pricing page, the quote page and the five interior
     pages — which are orange by design and would have ended up with the team
     photograph behind black-on-light type. */
  .hero:not(.hero--plain) { background:
    linear-gradient(180deg,
      rgba(10,22,34,.90) 0%, rgba(10,22,34,.86) 38%, rgba(10,22,34,.76) 62%,
      rgba(10,22,34,.58) 84%, rgba(10,22,34,.42) 100%),
    url("img/hero-team-ai.jpg");
    background-size: cover, cover;
    background-position: center, 68% center; }

  .hero:not(.hero--plain) .hero__copy {
    background: none; backdrop-filter: none; -webkit-backdrop-filter: none;
    border-radius: 0; box-shadow: none; padding: .9rem 18px 1.3rem; }

  .hero:not(.hero--plain) h1 { color: #fff; }
  /* --orange-bright is the wrap's LIGHT orange, and the token's own note says
     it is for dark grounds only. This is the dark ground it was meant for. */
  .hero:not(.hero--plain) h1 .hl { color: var(--orange-bright); text-shadow: none; }
  .hero:not(.hero--plain) .hero__lead { color: rgba(255,255,255,.9); }
  .heropair__h, .herobuild__h { color: var(--orange-bright); }

  /* The price tiles: smoked glass with an orange edge, the way Kapow's sit on
     its photo. Not a flat dark fill — the point is that the picture still
     shows through them. */
  .heropair--c .heroprice,
  .herobuild .heroprice {
    background: rgba(10,22,34,.52);
    border-color: rgba(255,153,51,.75);
    -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
    box-shadow: none; }
  .heroprice__n { color: #fff; }
  .heroprice__p { color: var(--orange-bright); }
  .heroprice__p small { color: rgba(255,255,255,.72); }

  /* The carpet column's card loses its white fill for the same reason. */
  .herobuild { background: rgba(10,22,34,.42); border-color: rgba(255,153,51,.6);
    -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); box-shadow: none; }
  .herobuild__rooms i { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.26);
    color: rgba(255,255,255,.9); }
  .herobuild__more { background: rgba(255,153,51,.22) !important;
    border-color: rgba(255,153,51,.6) !important; color: var(--orange-bright) !important; }

  /* "All 8 pest prices" stays solid white — it is the fourth tile in the 2x2
     and the one that opens the rest, so it should be the brightest thing in
     the block. */
  .heropair--c .heropair__btn { background: #fff; color: var(--ink);
    border-color: #fff; }

  /* ORANGE, NOT BLUE. `.hero .btn--accent` is a blue gradient, which was right
     when it sat on a white card. On a near-navy photograph it is camouflage.
     Brand orange with a near-black label — the same pairing as the sticky bar
     at the foot of the screen, so the two read as the same control. */
  .hero .hero__cta .btn--accent { background: var(--grad-orange); color: var(--ink);
    border-color: #000; box-shadow: 0 3px 0 #000, 0 10px 24px rgba(0,0,0,.45); }
  .hero .hero__cta .btn--ghost { background: #fff; color: var(--ink);
    border-color: #000; box-shadow: 0 3px 0 #000; }
  .hero__alt { color: rgba(255,255,255,.82); }
  .hero__alt a { color: var(--orange-bright); }

  /* The halftone dots were drawn for a light card edge; over the photo at
     .6 they read as dirt on the lens. */
  .hero:not(.hero--plain)::after { opacity: .3; }
}

/* ============================================================
   THE HERO SPLIT — pest left, carpet right.
   ============================================================
   10/10/2026. Replaces the heropair/herobuild/heroboth block, which was
   four different card shapes in one box. One shape now, twice, plus a
   strip. See heroPrices() in build-home.cjs for why.

   THE PALETTE IS THE BRAND CREAM AND THE GRADIENT, AND NOTHING ELSE.
   Pearce, 10/10/2026, of a near-black version: "this blackness is a no";
   and of the gradient on the Book button: "this button colour not being
   ONE exact orange is exactly what I love and want for the website."
   That is --grad-orange, light #FFC98A into #FF9933 into deep #D96908 —
   already the token behind every accent button, the top bar and the
   sticky bar. So the cards are --yellow-soft, their rules are the wrap's
   deep orange rather than --ink, their shadows are a warm brown rather
   than a black one, and the buttons and the time ribbon are the gradient.
   The only #141414 left in here is text on a light card, which is
   reading, not a black surface.
   ============================================================ */
.herosplit { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; margin: 1rem 0 0; }
/* The card itself is the <a>; the button inside it is a <span>. Everything
   from the ribbon to the price to the button is one target. */
.herohalf { position: relative; display: flex; flex-direction: column; align-items: center;
  gap: .2rem; padding: 1.5rem .7rem .8rem; overflow: hidden; border-radius: 15px;
  background: var(--yellow-soft); border: 2.5px solid var(--orange-ink-d);
  box-shadow: 0 4px 0 rgba(122,58,17,.55);
  text-decoration: none; color: inherit; cursor: pointer;
  transition: transform .14s ease, box-shadow .14s ease; }
.herohalf:hover { transform: translateY(-2px); box-shadow: 0 6px 0 rgba(122,58,17,.55); }
.herohalf:active { transform: translateY(3px); box-shadow: 0 0 0 rgba(122,58,17,.55); }
/* the inner button keeps its own hover so it still looks pressable, but it is
   decoration now — the whole card carries the click */
.herohalf:hover .herohalf__btn { background: var(--yellow-d); }
.herohalf__h { display: block; font-family: var(--head); font-weight: 800; font-size: .76rem;
  letter-spacing: .1em; text-transform: uppercase; color: var(--orange-ink-d); }
.herohalf__p { display: inline-flex; align-items: baseline; gap: .3em; line-height: 1.05;
  font-family: var(--head); font-weight: 800; font-size: 1.7rem; color: var(--ink); }
.herohalf__p small { font-weight: 700; font-size: .46rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--orange-ink); }
.herohalf__sub { margin-bottom: .45rem; font-size: .76rem; line-height: 1.3;
  color: var(--body); text-align: center; }
.herohalf__btn { display: flex; align-items: center; justify-content: center; gap: .4em;
  width: 100%; margin-top: auto; min-height: 44px; padding: .6rem .5rem; border-radius: 10px;
  background: var(--grad-orange); color: var(--ink); border: 2px solid var(--orange-ink-d);
  text-decoration: none; font-family: var(--head); font-weight: 800; font-size: .84rem;
  text-align: center; line-height: 1.2; }
.herohalf__btn .ico { width: .85em; height: .85em; flex: none; }

/* HOW LONG IT TAKES, where he asked for it.
   Pearce, 10/10/2026: "people need to know HOW LONG it will take to fill
   out the details to get the actual build-yourself carpet quote", and of
   Kapow's "Book online in 60 seconds": "KAPOW has this, its excellent."
   Pinned into the top-right corner on a desktop, where the card is wide
   enough; a ribbon across the top of the card on a phone, where a corner
   badge would land on the heading. */
/* A RIBBON AT EVERY WIDTH, NOT A PINNED CORNER PILL.
   First cut pinned it top-right on desktop, where Pearce asked for it. It
   does not fit: these cards are about 210px wide even on a 2380px screen,
   because they live inside the hero's copy column, so the pill landed on
   top of "PEST CONTROL" and half-hid it. A ribbon across the head of the
   card cannot collide with anything, reads at a glance, and is the same
   shape on a phone — one rule instead of two that can disagree. */
.herohalf__time { display: flex; align-items: center; justify-content: center; gap: .35em;
  align-self: stretch; margin: -1.5rem -.7rem .55rem; padding: .32rem .5rem;
  border-radius: 12px 12px 0 0;
  background: var(--grad-orange); border-bottom: 2px solid rgba(168,67,26,.45);
  font-family: var(--head); font-weight: 800; font-size: .72rem; letter-spacing: .02em;
  color: var(--ink); white-space: nowrap; line-height: 1.2; }
.herohalf__time .ico { width: .95em; height: .95em; color: var(--ink); flex: none; }

/* The third door. One line, brand blue — the only thing in the block that
   is not orange, which is what stops it competing with the pair above. */
.heroboth2 { display: flex; align-items: center; gap: .55rem; margin-top: .55rem;
  padding: .6rem .8rem; border-radius: 12px; text-decoration: none;
  background: var(--blue); color: #fff; }
.heroboth2__txt { flex: 1 1 auto; min-width: 0; font-size: .84rem; line-height: 1.3; }
.heroboth2__txt b { color: #fff; font-weight: 800; }
.heroboth2__ic, .heroboth2__go { flex: none; width: 1.05em; height: 1.05em; color: var(--yellow); }
.heroboth2:hover { background: var(--blue-d); }

@media (max-width: 560px) {
  .herosplit { gap: .5rem; margin-top: .5rem; }
  .herohalf { padding: .72rem .6rem .7rem; }
  /* 12px is the floor set in the phone pass; .72rem landed at 11.5px. */
  .herohalf__sub { font-size: .76rem; margin-bottom: .05rem; line-height: 1.25; }
  .herohalf__time { margin: -.72rem -.6rem .55rem; font-size: .68rem; }
  /* THE TWO PRICES MUST SIT ON THE SAME LINE. Pearce, 11/10/2026: "see how
     the prices are not aligned on the phone? The website is good though."

     He is right, and it is width-dependent, which is why the desktop looked
     fine. Measured across phone widths: at 320px both headings wrap to two
     lines and the prices align; at 393px and above neither wraps and they
     align; at 360px — which is what his phone renders at — "CARPET CLEANING"
     wraps and "PEST CONTROL" does not, so $289 sits 19px lower than $189.
     One card looks taller than the other and the pair stops reading as a
     pair. It is the same fault he called out on the old two-column block on
     03/10: "something that's doing my head in is they're not inline."

     Fixing the wrap itself would mean shrinking the type below the 12px
     floor or cutting the letter-spacing, and would only move the breakpoint
     at which it happens. Reserving two lines of height for BOTH headings
     removes the dependency altogether: wrapped or not, the box is the same
     height on both sides, so the prices cannot drift apart at any width.
     The tighter line-height keeps the cost of that to about 11px. */
  .herohalf__h { display: flex; align-items: center; justify-content: center;
    line-height: 1.25; min-height: 2.5em; text-align: center; }
  .heroboth2 { margin-top: .5rem; }
  /* THE HERO'S OWN BOOK/CALL ROW GOES ON A PHONE. Pearce, 10/10/2026:
     "Book online and number is doubled up when you scroll?"
     He is right — on a phone the sticky bar at the foot of the screen is
     already "BOOK ONLINE" and "Call", and the hero repeated both a few
     hundred pixels above it. Two identical primary buttons on one screen is
     not emphasis, it is a reader wondering whether they do different things.
     The sticky bar never scrolls away, so it is the one that stays; the hero
     keeps its four real choices (pest, carpet, both, and the quote link
     underneath) and gives back 126px.
     DESKTOP KEEPS IT, because there is no sticky bar above 560px and the
     hero row is the only Book online on the page. */
  .hero:not(.hero--plain) .hero__cta { display: none; }
  .hero:not(.hero--plain) .hero__alt { margin-top: .75rem; }
  .heroboth2__txt { font-size: .8rem; }
}

/* ============================================================
   THE HERO WASH — one tone of orange, dark into light. DESKTOP ONLY.
   ============================================================
   Pearce, 10/10/2026: "Kapows is dark, to lighter, BFYB needs to be the
   same" ... "this section MUST stay on brand for BFYB so a faded orange"
   ... "light is what i want."

   Measured off his screenshot, Kapow's wash is a single flat deep purple
   (#2B004F, lightness 15) holding across the left half and opening to
   #3E2368 (lightness 27) at the right edge before the photograph takes
   over. One hue, one ramp.

   What was here was rgba(10,22,34) — a cold near-navy belonging to no
   part of this brand, which over a warm evening photograph read as dirty
   grey. This is the same ramp in the brand's own orange. A dark rust
   version was tried first and went brown: purple stays purple when you
   darken it, orange does not. It does not need to be dark — the headline
   sits on the white card, not on the wash — so the dark end is short and
   the band is mostly light orange, which is what he asked for.

   PHONE IS DELIBERATELY NOT INCLUDED. The phone hero puts the copy
   straight onto the darkened photograph with white type, and Pearce on
   that: "the new phone view is very good." A light orange wash there
   would make white text unreadable and undo it. */
@media (min-width: 561px) {
  /* THE WASH STOPS DEAD AT THE EDGE OF THE CARD. Pearce, 10/10/2026, of the
     team and the ute: "the second pic should have NO BLUR/orange."
     The first cut ran the gradient to 94% at low opacity, so a thin orange
     veil sat over the photograph — enough to take the blue out of the shirts
     and the white off the ute. The card's right edge measures 48.4% at
     1280px and 49.2% at 2560px, so 49% clears the colour everywhere without
     leaving a visible seam: the last of the fade happens BEHIND the card,
     which is 86% white, and the photo starts at full strength. */
  .hero:not(.hero--plain) { background:
    linear-gradient(95deg,
      rgba(179,82,0,.96) 0%, rgba(255,153,51,.92) 18%, rgba(255,201,138,.76) 32%,
      rgba(255,226,198,.40) 42%, rgba(255,226,198,0) 49%),
    url("img/hero-team-ai.jpg");
    background-size: cover, cover;
    background-position: center, center;
    background-color: #B35200; }
  /* the halftone dots were drawn for a cold dark ground; on orange at .6
     they read as grain */
  .hero:not(.hero--plain)::after { opacity: .26; }
  /* AND THE GLOW OVER THE PHOTO GOES. .hero::before carries two warm radials;
     the first is centred at 86% across — directly over the two of them and
     the ute — and was laying another 10% of orange on the one part of this
     hero that is meant to be a photograph. The second sits at 30%, behind
     the card, and stays. */
  .hero:not(.hero--plain)::before { background:
    radial-gradient(620px 420px at 30% 106%, rgba(255,153,51,.08), transparent 62%); }
}

/* The lane picker's sub-lines were setting at 11.8px on every phone width —
   "9 treatments, fixed prices" and "Your exact figure in about a minute" are
   the two sentences that tell somebody which door to go through, on the first
   screen of the booking flow. 12px is the floor set in the phone pass. */
@media (max-width: 560px) {
  .bkq__lane em { font-size: .76rem; }
}

/* ============================================================
   THE HEADER MARK — full colour, on a white plate, with HOME.
   ============================================================
   Pearce, 11/10/2026: "I want the BFYB without the 'Bang For Ya Buck'
   and instead of that under BFYB it says HOME. The current one on the
   website is also too small."

   WHY IT LOOKED SMALL, which was not a sizing mistake. The old file,
   bfyb-logo-white-full.png, is a 500x500 canvas with the artwork sitting
   in the middle of it: the wordmark occupies rows 127-315, about 38% of
   the height, and the rest is transparent padding. So a rule saying
   height:46px produced a wordmark about 17px tall. Scaling the old file
   up would only have scaled the empty space with it.

   bfyb-logo-mark.png is the same artwork cropped to its own edges, with
   the "BANG FOR YA BUCK" strap (rows 290-315) removed — the word HOME
   takes its place, set in the page so it stays crisp and can be a real
   link rather than baked into a picture. 40px of logo is now 40px of
   logo.

   WHY THE PLATE. The coloured mark has its F, Y and B in #FF9933, which
   is the same orange as the header bar — on the bar they disappear and
   only the black B survives. The mark is drawn for a light ground, so it
   gets one. Pearce picked this option from three.

   The drawer and the footer keep bfyb-logo-white-full.png: both sit on
   dark grounds where the flat white version is the right one.
   ============================================================ */
/* TAKEN DOWN 20% ON 11/10/2026, at Pearce's word, after a fortnight of
   looking at it on a real screen. Every number below is the old one times
   0.8 — the mark, the padding, the radius, the word and the gap — because
   shrinking only the logo inside a plate that stays put does not make the
   plate smaller, it makes the plate look empty. */
.header .brand { flex-direction: column; align-items: center; gap: .11rem;
  background: #fff; border-radius: 11px; padding: .4rem .76rem .36rem;
  box-shadow: 0 3px 0 rgba(122,58,17,.32); transition: transform .15s ease, box-shadow .15s ease; }
.header .brand:hover { transform: translateY(-1px) rotate(0deg); box-shadow: 0 5px 0 rgba(122,58,17,.32); }
.header .brand__logo { height: 32px; width: auto; display: block; }
.header .brand__home { display: block; font-family: var(--head); font-weight: 800;
  font-size: .61rem; letter-spacing: .2em; text-transform: uppercase; color: var(--ink);
  opacity: 1; padding-left: 0; line-height: 1; }
.header .brand:hover .brand__home { color: var(--orange-ink); }

@media (max-width: 560px) {
  /* The plate shrinks but the mark stays legible — and HOME comes back,
     because it is now part of the mark rather than a label stuck under it.
     Costs about 6px of header height against what was there before. */
  .header .brand { padding: .29rem .56rem .26rem; border-radius: 9px; gap: .08rem; }
  .header .brand__logo { height: 24px; }
  /* display:block is doing real work here. The phone pass hid .brand__home
     back when it was a stray label under a flat wordmark; now it is part of
     the mark Pearce asked for, so that rule has to be undone explicitly or
     the word simply does not appear on a phone. It did not, first time. */
  .header .brand__home { display: block; font-size: .56rem; letter-spacing: .16em; }
}

/* ============================================================
   THE LAST-MINUTE OFFER, IN THE STICKY BAR
   ============================================================
   assets/offer-bar.js replaces the contents of the orange Book
   button when there is a discount on, so this styles what goes
   INSIDE a button that already exists rather than adding a
   second bar. The phone button never moves: most people on these
   pages have a flood or termites and want a person, and taking
   the number away to win one discounted job loses them.

   IT APPEARS ON A COMPUTER TOO, WHICH THE ORDINARY BAR DOES NOT.
   The plain bar is a phone convenience — on a desktop the hero's
   own Book button is right there and a fixed bar would just be
   the same offer twice. A live discount is not that: it is news,
   it expires, and there is nowhere else on the page saying so.
   So the bar exists at every width ONLY while an offer is up,
   and on a wide screen it floats as a centred pill rather than
   spanning the window like furniture.

   THE SHINE IS TURNED OFF while an offer is showing. A sweeping
   highlight behind a ticking countdown is two things moving for
   no reason, and the countdown is the one that matters.
   ============================================================ */
.bookbar--offer { display: flex; }
@media (min-width: 561px) {
  .bookbar--offer {
    position: fixed; left: 50%; right: auto; bottom: 18px; transform: translateX(-50%);
    width: min(760px, calc(100% - 32px)); z-index: 60;
    gap: .7rem; padding: .7rem .8rem;
    background: #141414; border: 2.5px solid #000; border-top: 3px solid var(--yellow);
    border-radius: 16px; box-shadow: 0 14px 34px rgba(0,0,0,.4);
  }
  .bookbar--offer .btn { flex: 1; padding: .8rem 1rem; }
  .bookbar--offer .bookbar__call { flex: none; }
}
.bookbar--offer .btn--accent::after { display: none; }

/* Two columns: what is on offer, and how long it lasts. */
.bookbar--offer .btn--accent {
  justify-content: space-between; gap: .6rem; padding: .6rem .8rem;
  text-align: left; line-height: 1.1;
}
.ob__l, .ob__r { display: flex; flex-direction: column; min-width: 0; }
.ob__r { align-items: flex-end; text-align: right; flex: none; }

/* The day on its own is a banner. The TIME is the offer — "TOMORROW 12PM"
   is something somebody can picture. */
.ob__day { font-size: .72rem; font-weight: 800; letter-spacing: .07em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; opacity: .9; }
.ob__off { font-size: 1.12rem; font-weight: 900; letter-spacing: .01em; white-space: nowrap; }
.ob__why { font-size: .62rem; font-weight: 800; letter-spacing: .06em; opacity: .78;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 11ch; }
/* There is room for the whole reason on a computer; the 11ch cap exists to
   stop it eating the saving on a 390px phone. */
@media (min-width: 561px) { .ob__why { max-width: 24ch; } }

/* The countdown sits in its own pill so it reads as a deadline rather than
   as more of the sentence. */
/* No cut-off set means no countdown, and an empty pill is a grey blob with
   nothing in it. */
.ob__cd:empty { display: none; }
.ob__cd { margin-top: .18rem; font-size: .68rem; font-weight: 800; letter-spacing: .02em;
  white-space: nowrap; padding: .14rem .42rem; border-radius: 999px;
  background: rgba(20, 20, 20, .16); color: var(--ink);
  font-variant-numeric: tabular-nums; }

/* URGENT IS THE WHOLE OF TODAY, not the last hour. Four hours to go is still
   today, and today is what makes somebody move. Deep brand orange and cream
   rather than a warning red — it reads hotter without leaving the palette. */
.bookbar--offer.is-urgent .ob__cd { background: #141414; color: var(--yellow-soft); animation: obpulse 1.8s ease-in-out infinite; }
.bookbar--offer.is-urgent .btn--accent { background: linear-gradient(100deg, #FFB45E 0%, #F08A1E 45%, #B5540C 100%); }
@keyframes obpulse { 0%, 100% { opacity: 1; } 50% { opacity: .62; } }
@media (prefers-reduced-motion: reduce) { .bookbar--offer.is-urgent .ob__cd { animation: none; } }

/* On a narrow phone the right-hand column is the first thing to go: the
   saving and the time are the offer, the reason is a nicety. */
@media (max-width: 380px) {
  .ob__why { display: none; }
  .ob__off { font-size: 1.02rem; }
}

/* ============================================================
   THE LAST-MINUTE SLOT, INSIDE THE BOOKING FLOW
   ============================================================
   The discount is marked ON THE WINDOW it belongs to rather
   than announced at the top of the page. "20% off today" above
   a list of six times, one of which is actually discounted, is
   a page that has to be read twice.

   The tag sits under the time rather than beside it: the times
   are the thing being scanned, and a chip that grows sideways
   breaks the rhythm of the row it is in.
   ============================================================ */
.bkq__chip--offer { border-color: var(--yellow); background: var(--yellow-soft);
  color: var(--ink); display: inline-flex; flex-direction: column; align-items: center;
  gap: 1px; line-height: 1.15; }
.bkq__chip--offer.sel { box-shadow: 0 0 0 2px rgba(255,153,51,.45); }
.bkq__chipoff { font-style: normal; font-size: .7rem; font-weight: 800;
  letter-spacing: .02em; color: var(--orange-ink); text-transform: uppercase; }

/* Said once, above the days. Orange ground so it reads as the same thing the
   sticky bar is advertising, not as another warning. */
.bkq__note--offer { background: var(--yellow-soft); border-color: rgba(255,153,51,.55); }
.bkq__note--offer b:first-child { color: var(--orange-ink); }

/* The saving gets its own small card directly above the total, so nobody has
   to work out why the number moved. Two lines: what it was, and what came
   off. */
.bkq__card--offer { border-color: rgba(255,153,51,.55); background: var(--yellow-soft); }
.bkq__card--offer .bkq__lines--plain li b { font-weight: 800; }

/* ============================================================
   THE JOB CLIPS ON THE HOME PAGE
   ============================================================
   Two tiles, carpet then pest, sitting directly on top of the
   two "pick yours" cards they belong to. The position is the
   one Kapow uses — the first content block after the stats
   band, not the hero. Pearce, 11/10/2026: "NO VIDEOS OVER OUR
   headdeer main photo. they are to be futher down, so MATCH
   KAPOW."

   16:9 rather than the portrait the clips were shot in. The
   source is 540x960 and object-fit crops to the middle of it,
   which is where the work is in both of these — the wand on the
   carpet and the hinge line in the cupboard. A portrait tile
   here would be most of a screenful before anybody reached a
   price.
   ============================================================ */
.svid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1rem; }
.svid__one { margin: 0; position: relative; border-radius: var(--radius-lg); overflow: hidden;
  background: #141414; box-shadow: 0 10px 28px rgba(20,18,16,.18); }
.svid__tap { display: block; position: relative; width: 100%; aspect-ratio: 16 / 9;
  padding: 0; border: 0; background: #141414; cursor: pointer; overflow: hidden; }
.svid__poster, .svid__el { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.svid__scrim { position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(0,0,0,0) 45%, rgba(0,0,0,.5) 100%); }
.svid__play { position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%);
  width: 62px; height: 62px; border-radius: 50%; background: var(--yellow); color: var(--ink);
  display: grid; place-items: center; border: 2.5px solid #000;
  box-shadow: 0 3px 0 #000, 0 10px 22px rgba(0,0,0,.4); transition: transform .15s ease; }
.svid__play svg { width: 28px; height: 28px; margin-left: 3px; }
.svid__one:hover .svid__play { transform: translate(-50%,-50%) scale(1.07); }

/* The name is a LINK and the picture is a BUTTON, deliberately two things:
   one plays, one goes to the page with the rest of the footage on it.

   Pearce, 11/10/2026: "its over the options to stop, pause, make bigger etc?"
   It was. The bar used to be laid over the bottom of the picture, which is
   exactly where a browser draws its own video controls, so play, the scrubber
   and full-screen were all underneath it. It now sits BELOW the picture, in
   normal flow, where it covers nothing. */
.svid__more { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .08rem;
  padding: .55rem .5rem .6rem; text-decoration: none; line-height: 1.15;
  font-family: var(--head); color: var(--ink); background: var(--yellow); }
.svid__one--pest .svid__more { background: var(--blue); color: #fff; }
.svid__more b { font-weight: 800; font-size: .95rem; }
.svid__more span { display: inline-flex; align-items: center; gap: .3em; font-weight: 700; font-size: .73rem; opacity: .85; }
.svid__more .ico { width: .95em; height: .95em; }
.svid__more:hover { filter: brightness(1.06); }
/* Once it is really playing, the poster furniture gets out of the way: the
   dark gradient was only there to carry the play badge, and both of them over
   a running clip is just dirt on the picture. */
.svid__one.is-playing .svid__scrim,
.svid__one.is-playing .svid__play { display: none; }
.svid__el { z-index: 1; }

/* The cards stack on a phone, so the clips stack with them and each one
   stays directly above the card it belongs to. */
@media (max-width: 760px) {
  .svid { grid-template-columns: 1fr; gap: .7rem; margin-bottom: .7rem; }
  .svid__tap { aspect-ratio: 16 / 10; }
  .svid__play { width: 50px; height: 50px; } .svid__play svg { width: 23px; height: 23px; }
}

/* ============================================================
   THE VANS, AT REAL HOUSES
   ============================================================
   Pearce, 11/10/2026: "nothing thats the focal, as its not. its
   just showing the general public, we actually exist."

   So: no headings, no captions, nothing clickable. A slow drift
   of small photographs between the areas list and the FAQ. The
   track is printed twice and translated by exactly half, which
   is what makes the loop seamless rather than snapping back.

   It pauses on hover, and stops dead for anyone who has asked
   their machine to reduce motion -- a strip that will not stop
   moving is the one way a decoration can become a problem.
   ============================================================ */
.fleet{padding-top:2.2rem;padding-bottom:2.4rem;overflow:hidden}
/* Pearce, 11/10/2026: "now this shows a lot all at once, can you take it down
   to 8 ... i personally dont like how long this looks."

   Then, bigger again: "actually make it 6 photos, i want them bigger then you
   have made live please, and have each 6 rotate like you have now."

   The strip used to run the full width of the window, so a wide monitor got
   thirteen photographs in a row and the thing read as a banner. The WINDOW is
   now exactly six tiles wide (6 x 210px + 5 x 14px gaps) and centred; the
   track behind it is unchanged and still carries every photo, drifting
   through. On anything narrower than that the window is simply the width of
   the screen. */
.fleet__win{max-width:1330px;margin:0 auto;overflow:hidden;
  /* Fades at both edges so photographs arrive and leave rather than being
     chopped off at the window. */
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent)}
.fleet__rail{display:flex;width:max-content;
  /* The two tracks sit side by side and the pair slides left by half its
     own width, so copy two lands exactly where copy one started. */
  animation:fleetdrift 150s linear infinite}
.fleet__win:hover .fleet__rail{animation-play-state:paused}
.fleet__track{display:flex;gap:14px;padding-right:14px}
.fleet__track img{display:block;width:210px;height:158px;object-fit:cover;border-radius:12px;background:#efe3d6}
@keyframes fleetdrift{from{transform:translate3d(0,0,0)}to{transform:translate3d(-50%,0,0)}}
@media (max-width:720px){
  .fleet__track img{width:150px;height:113px}
  .fleet__rail{animation-duration:110s}
}
@media (prefers-reduced-motion:reduce){
  .fleet__win{mask-image:none;-webkit-mask-image:none;overflow-x:auto;scroll-snap-type:x mandatory}
  .fleet__rail{animation:none}
  .fleet__track[aria-hidden="true"]{display:none}
  .fleet__track img{scroll-snap-align:start}
}

/* The "only done with the other one" line on a picker row. Deliberately quiet
   and orange rather than grey: it is not a disclaimer, it is the answer to the
   question the reader is about to ask. */
.bkq__rowpair { display: block; margin-top: .18rem; font-size: .76rem; font-weight: 700;
  color: #B35C00; line-height: 1.3; }

/* "Most booked" on a price row. Brand yellow on ink so it reads as a label
   rather than a sale sticker — the claim is doing the work, not the colour. */
.pricerow__pop { display: inline-block; margin-left: .5rem; vertical-align: 2px;
  font-family: var(--head); font-size: .62rem; font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; background: var(--yellow); color: #141414;
  padding: .18rem .45rem; border-radius: 99px; white-space: nowrap; }


/* ============================================================
   WHAT ARMIDALE SAYS — the Google reviews band
   ============================================================
   Pearce, 11/10/2026: "why cant i have 10 or more actual reviews there? link
   the google profile even?"

   Ten of them, in a row that scrolls sideways. Stacked they would add most of
   a screen to a page that is already long; this way they cost one band and the
   rest are a flick away. The cards are a fixed width rather than a fraction of
   the container, because a review is read, not scanned — a column too narrow
   turns four lines into eight.

   Scroll-snap so a flick lands on a card rather than halfway between two, and
   the whole row is keyboard-reachable (tabindex on the container) so it is not
   a mouse-only feature.
   ============================================================ */
.reviews .section__lead { max-width: 42rem; margin-left: auto; margin-right: auto; }

/* The 4.9 badge. A link, because the number is a claim and the claim should be
   one tap from the page it came from. */
.gbadge { display: inline-flex; align-items: center; gap: .55rem; background: #fff;
  border: 1px solid var(--line, #eee3d6); border-radius: 999px; padding: .55rem 1.15rem;
  font-family: var(--head); color: var(--ink); text-decoration: none;
  box-shadow: 0 6px 18px rgba(20,18,16,.07); transition: transform .16s ease, box-shadow .16s ease; }
.gbadge:hover { transform: translateY(-1px); box-shadow: 0 10px 24px rgba(20,18,16,.12); }
.gbadge .ico { width: 20px; height: 20px; }
.gbadge b { font-size: 1.05rem; font-weight: 800; }
.gbadge__n { font-size: .85rem; font-weight: 700; color: var(--muted); }
.review__stars { color: #FF9933; letter-spacing: .04em; font-size: .95rem; line-height: 1; }

/* Each card is as tall as its own quote. Stretching them all to match the
   longest one left big voids under the short reviews — see Emma S. next to
   Scott J., twenty words against sixty. Ragged bottoms read as a row of
   separate notes, which is what they are. */
.reviewrow { display: flex; align-items: flex-start; gap: 1rem; overflow-x: auto; padding: .4rem .2rem 1rem;
  scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
  /* A thin scrollbar rather than none: an invisible one is a row most people
     never discover is a row. */
  scrollbar-width: thin; scrollbar-color: #e2d6c6 transparent; }
.reviewrow::-webkit-scrollbar { height: 8px; }
.reviewrow::-webkit-scrollbar-thumb { background: #e2d6c6; border-radius: 99px; }
.reviewrow::-webkit-scrollbar-track { background: transparent; }
.review { flex: 0 0 320px; scroll-snap-align: start; margin: 0; background: #fff;
  border: 1px solid var(--line, #eee3d6); border-radius: var(--radius-lg);
  padding: 1.3rem 1.4rem; box-shadow: 0 8px 22px rgba(20,18,16,.06);
  display: flex; flex-direction: column; gap: .6rem; }
.review blockquote { margin: 0; font-size: .92rem; line-height: 1.6; color: var(--body); }
.review figcaption { margin-top: .2rem; font-family: var(--head); font-weight: 800;
  font-size: .88rem; color: var(--ink); }
.review figcaption span { display: block; font-family: inherit; font-weight: 600;
  font-size: .74rem; color: var(--muted); margin-top: .1rem; }
.reviewrow__hint { text-align: center; font-size: .76rem; color: var(--muted); margin: 0; }
@media (min-width: 1100px) { .reviewrow__hint { display: none; } }
@media (max-width: 560px) { .review { flex-basis: 84%; } }
@media (prefers-reduced-motion: reduce) { .gbadge { transition: none; } }
