/* ============================================================ LANDING PAGE
   Paid-traffic page only, loaded on top of site.css.

   LIGHT, like the rest of the site and like Pristine (Zaak, 2026-10-23: "i
   like the light colours too like the light blue as opposed to the dark you
   did ... and light blue high shine buttons"). The first build was dark
   navy, which looked moody and read heavy over eighteen screens.

   THE COLOUR RULE THAT MATTERS: site.css carries a note that --accent
   (#24c0f0) FAILS CONTRAST as text on a light ground, which is exactly why
   --accent-deep exists. So the bright cyan is only ever a BACKGROUND here
   (buttons, chips, the avatar discs), and accent-coloured TEXT always uses
   --accent-deep. Getting that backwards is how a page ends up looking bright
   and being unreadable in sunlight, which is where half of these clicks
   actually happen.

   Structure follows Zaak's wireframe. The no-nav rule is the one thing
   deliberately not taken from Pristine, because this page takes paid clicks
   and a menu is a list of ways to leave before converting.
   ========================================================================= */

body.lp {
  background: var(--surface);
  color: var(--body);
  padding-bottom: 4.6rem;   /* room for the sticky bar */
}

/* ---- header: logo left, the offer in the bar, phone right ---- */
/* Anything a Google Ads sitelink can land on gets a bit of air above it,
   so the heading is not welded to the top edge of the phone. Also turns the
   jump into a glide, which reads as "the page moved me" rather than "the
   page changed". */
.lp [id] { scroll-margin-top: 1.1rem; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

.lp-bar { background: var(--white); border-bottom: 1px solid var(--line); position: relative; z-index: 5; }
.lp-bar__in { display: flex; align-items: center; justify-content: space-between; padding: .6rem 0; gap: 1rem; }
.lp-bar__logo { height: 42px; width: auto; flex: 0 0 auto; }
.lp-bar__offer {
  margin: 0; display: inline-flex; align-items: center; gap: .45rem;
  color: var(--accent-deep); font-weight: 800; font-size: .78rem;
  letter-spacing: .07em; text-transform: uppercase; text-align: center;
}

.lp-call {
  display: inline-flex; align-items: center; gap: .45rem;
  color: var(--accent-deep); font-weight: 700; text-decoration: none;
  border: 2px solid var(--accent); border-radius: 999px;
  padding: .45rem .95rem; font-size: .95rem; white-space: nowrap;
  background: var(--white);
}
.lp-call:hover { background: var(--wash); }
.lp-call--big { margin-top: 1.1rem; font-size: 1.02rem; padding: .62rem 1.25rem; }
.lp-call--hero { padding: .9rem 1.5rem; font-size: 1.04rem; }

/* ---- PATTERNS. Zaak asked for them and they earn their place: a flat panel
   three screens tall reads as dead space. Pure CSS gradients, so no requests
   and no bytes. Kept faint on purpose; anything you actually notice is
   competing with the photography. ---- */
.lp-dots { position: relative; }
.lp-dots::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: radial-gradient(rgba(11,127,168,.16) 1px, transparent 1px);
  background-size: 22px 22px;
  -webkit-mask-image: radial-gradient(ellipse at 50% 0%, #000 8%, transparent 70%);
  mask-image: radial-gradient(ellipse at 50% 0%, #000 8%, transparent 70%);
}
.lp-rule { position: relative; }
.lp-rule::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: repeating-linear-gradient(
    -45deg, rgba(11,127,168,.05) 0 1px, transparent 1px 11px);
}
.lp-dots > *, .lp-rule > * { position: relative; z-index: 1; }

/* ---- HERO: text left, fanned photos right on desktop. One column on a
   phone, where the DOM order takes over. ---- */
.lp-hero {
  padding: 2.4rem 0 0; overflow: hidden;
  background:
    radial-gradient(ellipse 80% 70% at 15% 0%, rgba(36,192,240,.20), transparent 68%),
    linear-gradient(180deg, var(--white) 0%, var(--surface) 100%);
}
.lp-hero__in {
  display: grid; gap: 2rem 3rem; align-items: center;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); text-align: left;
}
.lp-hero__copy { min-width: 0; max-width: 100%; container-type: inline-size; }
/* One line per span, never wrapped. Paired with type sized in cqi (the
   width of .lp-hero__copy), so a line is always exactly as wide as the
   column allows and the count of lines is fixed by the markup. */
.lp-line { display: block; white-space: nowrap; }
.lp-hero__media { display: flex; flex-direction: column; align-items: center; gap: .9rem; }

.lp-eyebrow {
  color: var(--accent-deep); font-weight: 800; font-size: .76rem;
  letter-spacing: .14em; text-transform: uppercase; margin: 0;
}
/* CAPS, as Zaak wrote it (2026-10-24), but in DM Sans bold rather than the
   Bebas display face: this hero deliberately uses the body font at weight
   700, the way every page that beat ours in the teardown does, and a
   condensed display face at caps would lose the weight that makes it hit.
   Uppercased in CSS so the markup stays readable to a screen reader and
   copies out of the page as normal text.

   The line is seven words now instead of four and caps are wider again, so
   the clamp comes down or it eats the fold on a small phone. */
.lp-hero h1 {
  color: var(--ink); margin: .5rem 0 .9rem; line-height: .92;
  /* TWO LINES, as big as two lines can be (Zaak, 2026-10-24, after "much
     larger" ran it to three). "YOU FELL IN LOVE WITH" is the longer line at
     about 10.8em, so 9cqi fills the column with ~3% to spare: ~31px on a
     375 phone, ~35px on a 414, ~54px in the desktop column. The vw line is
     the fallback for a browser without container units. */
  font-size: clamp(1.6rem, 8.2vw, 3.4rem);
  font-size: clamp(1.6rem, 9cqi, 4.2rem);
  text-transform: uppercase; letter-spacing: -.025em;
}
.lp-topstars {
  margin: 0 0 .3rem; color: var(--star); line-height: 1;
  font-size: .95rem; letter-spacing: .12em;
}
.lp-hero h1 .hl { color: var(--accent-deep); }
/* A page whose longer headline line runs past the home page's ~10.8em
   ("(without the price tag)" is 23 characters) gets the type a step
   smaller so it still fits two lines on a 375 phone. */
.lp--tight .lp-hero h1 { font-size: clamp(1.45rem, 7.6cqi, 3.6rem); }
/* The eyebrow, now the first block of the h1 (SEO, 2026-10-24): the h1's
   display size and .92 line height must not reach it. Margin recreates the
   gap the old paragraph left above the headline. */
.lp-hero h1 .lp-eyebrow {
  display: block; font-size: .76rem; line-height: 1.4;
  letter-spacing: .14em; margin: 0 0 .55rem; color: var(--accent-deep);
}
.lp-promise { color: var(--body); font-size: 1.06rem; line-height: 1.55; margin: 0 0 1.2rem; max-width: 46ch; }
/* TWO LINES: "Professional detailing services in Brisbane / delivered to
   your doorstep" (Zaak, 2026-10-24). Naming Brisbane took the longer line
   from 13.9em to 19.3em, and because the old 6.9cqi was capped at 1.3rem
   the type did not shrink to suit, it just ran 401px of text through a
   349px column and the hero clipped it. 5.0cqi is what fits the longer
   line with about 3% to spare at every phone width. */
.lp-hero .lp-promise {
  max-width: none; line-height: 1.4;
  font-size: clamp(.95rem, 4.6vw, 1.3rem);
  font-size: min(1.3rem, 5.0cqi);
}
.lp-promise b { color: var(--ink); }

/* ---- the Google badge ---- */
.lp-gbadge {
  display: inline-flex; align-items: center; gap: .7rem; margin: 0 0 1.4rem;
  background: var(--white); border: 1px solid var(--line);
  border-radius: 999px; padding: .5rem 1.1rem .5rem .6rem;
  box-shadow: var(--shadow);
}
.lp-gbadge__g {
  display: grid; place-items: center; width: 2rem; height: 2rem; flex: 0 0 auto;
  border-radius: 50%; background: var(--wash); color: #4285f4;
  font-weight: 800; font-size: 1.15rem; font-family: Arial, sans-serif;
}
.lp-gbadge__in { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.15; }
.lp-gbadge__stars { color: var(--star); font-size: .82rem; letter-spacing: .1em; }
.lp-gbadge__txt { color: var(--muted); font-size: .82rem; }
.lp-gbadge__txt b { color: var(--ink); }

.lp-hero__ctas { display: flex; gap: .8rem; justify-content: flex-start; flex-wrap: wrap; }
.lp-hero .lp-cta { padding: .92rem 2rem; font-size: 1.06rem; }
.lp-under { color: var(--muted); font-size: .84rem; margin: .8rem 0 0; }
/* ONE LINE on a phone (Zaak, 2026-10-24). The three guarantees wrapping
   "service" onto a line of its own read like a mistake. Sized off the
   viewport so it just fits at 360px and grows back to normal on anything
   wider, and nowrap so it can never break mid-promise. */
@media (max-width: 560px) {
  .lp-under { font-size: min(.84rem, 2.9vw); white-space: nowrap; letter-spacing: -.01em; }
}

/* ---- THE AFTER SCROLLER. One big photo with the next peeking in, snapped,
   so a flick lands on a frame rather than between two. The peek is the only
   affordance it needs: a tile cut off at the edge says "there is more" more
   plainly than an arrow does. ---- */
/* It DRIFTS now, at the same rate as the reviews (Zaak, 2026-10-24), so it
   is a plain scroll container like the review strip: no scroll snapping,
   because a snap container re-snaps after every programmatic scrollLeft
   write and the drift would stutter from tile to tile. */
/* The height of a photo tile on a phone. The hero's background layer stops
   this far above the bottom of the hero, so the video never runs behind the
   gallery. One value, both rules. */
.lp { --lp-shot-h: min(48vh, 380px); --lp-bg-lift: 1.5rem; }
/* The thank you hero carries a caption under its strip, so its background
   layer has to stop that much higher to clear the gallery. Measured: with
   the landing page's 1.5rem it overlapped the first photo by 16px. */
.lp-ty { --lp-bg-lift: 3.7rem; }
.lp-shots {
  width: 100%; overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none; overscroll-behavior-x: contain;
  cursor: grab; padding: 0 0 .3rem;
}
.lp-shots.is-grabbing { cursor: grabbing; }
.lp-shots::-webkit-scrollbar { display: none; }
.lp-shots img { -webkit-user-drag: none; user-select: none; pointer-events: none; }
.lp-shots__track { display: flex; gap: .7rem; list-style: none; margin: 0; padding: 0; width: max-content; }
.lp-shots__item {
  flex: 0 0 auto; position: relative;
  /* 3:4 is the shape the phone took the photo in, so nothing is cut off. */
  width: 270px; aspect-ratio: 3/4; border-radius: 16px; overflow: hidden;
  background: var(--wash); border: 3px solid var(--white);
  box-shadow: var(--shadow-lg);
}
.lp-shots__v, .lp-shots__v img, .lp-shots__v video {
  width: 100%; height: 100%; display: block; object-fit: cover;
}
/* The label sits ON the photo, at the TOP (Zaak, 2026-10-24: "have the
   overlay text on top"), over a gradient rather than a flat bar, so the sky
   or a white roof at the top of the frame still reads. The headlight tile
   draws its own BEFORE and AFTER pills at the bottom of each half so they
   stay clear of this. */
.lp-shots__tag {
  position: absolute; inset: 0 0 auto 0; display: block;
  padding: .7rem .75rem 2.2rem; color: #fff; text-align: left;
  font-size: .76rem; line-height: 1.3;
  background: linear-gradient(180deg, rgba(2,14,24,.84) 0%, rgba(2,14,24,.5) 58%, transparent 100%);
  pointer-events: none;
}
.lp-shots__tag b {
  display: block; font-family: "Bebas Neue", Impact, sans-serif;
  font-size: .72rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent); margin-bottom: .1rem;
}
.lp-stack__cta {
  display: inline-flex; align-items: center; gap: .4rem;
  color: var(--accent-deep); font-weight: 700; font-size: .92rem;
  text-decoration: none; border: 2px solid var(--accent);
  border-radius: 999px; padding: .5rem 1.15rem; background: var(--white);
}
.lp-stack__cta:hover { background: var(--wash); }

/* ---- the sliding review strip, skinny ---- */
/* NATIVELY SCROLLABLE, not a CSS marquee (Zaak: "have it so you can like
   click/tap to hold it on a spot or spin it faster"). A transform animation
   cannot be grabbed; a real scroll container can. So the drift is a rAF loop
   nudging scrollLeft, and everything else comes free from the browser:
   touch drag, flick momentum, trackpad, keyboard, and a scrollbar we hide.
   The JS pauses the drift on pointer down and on hover. */
.lp-hstrip {
  position: relative; margin: 2.2rem 0 0; padding-bottom: 2.2rem;
  min-width: 0; max-width: 100%;
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none;
  /* No `-webkit-overflow-scrolling: touch` here on purpose. It hands the
     element its own iOS scrolling layer, where a scrollLeft written every
     frame is unreliable, and iOS has scrolled overflow smoothly without it
     since 13. The reel below still carries it: that one is only ever
     scrolled by a thumb. */
  cursor: grab; overscroll-behavior-x: contain;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}
.lp-hstrip::-webkit-scrollbar { display: none; }
.lp-hstrip.is-grabbing { cursor: grabbing; }
.lp-hstrip__track { display: flex; gap: .7rem; width: max-content; }
/* Dragging a card should move the strip, not start a browser image drag. */
.lp-hstrip img, .lp-hstrip video { -webkit-user-drag: none; user-select: none; pointer-events: none; }

.lp-hcard {
  flex: 0 0 auto; width: 236px; margin: 0; display: flex; gap: .45rem;
  align-items: center;
  background: var(--white); border: 1px solid var(--line);
  border-radius: 12px; padding: .45rem .6rem; text-align: left;
  box-shadow: var(--shadow);
}
.lp-hcard__av {
  flex: 0 0 auto; width: 1.65rem; height: 1.65rem; border-radius: 50%;
  display: grid; place-items: center; background: var(--accent);
  color: var(--accent-ink); font-weight: 800; font-size: .66rem;
}
.lp-hcard__body { min-width: 0; }
.lp-hcard__stars { color: var(--star); font-size: .66rem; letter-spacing: .07em; display: block; }
.lp-hcard q { display: block; color: var(--body); font-size: .76rem; line-height: 1.32; margin: .06rem 0 .12rem; quotes: none; }
.lp-hcard__who {
  display: block; color: var(--muted); font-size: .67rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lp-hcard__who b { color: var(--accent-deep); }

/* ---- THE QUOTE FORM, ours. One white card: a gift header, four big
   fields, optional chips, one button. Inputs are 52px tall with a 16px
   font on purpose: under 16px iOS zooms the page on focus, and a short
   input is the first thing a thumb misses. ---- */
/* Straight from the photo strip into the form (Zaak, 2026-10-24: "remove the
   instant quote under the sliding gallery and go straight into the form"),
   so the form's top padding is trimmed on a phone. */
.lp-formsec { padding-top: clamp(1.6rem, 4vw, 3.5rem); }
.lp-formsec {
  background: linear-gradient(180deg, var(--wash) 0%, var(--surface) 100%);
  border-block: 1px solid var(--line);
}
.lp-formsec__in { max-width: 560px; margin-inline: auto; }
.lp-form {
  background: var(--white); border-radius: 22px; overflow: hidden;
  border: 1px solid var(--line); box-shadow: var(--shadow-lg);
}
.lp-form__head {
  /* A size container, so the heading below can be sized off the width of
     the card rather than the viewport. */
  container-type: inline-size;
  text-align: center; padding: 1.7rem 1.2rem 1.25rem;
  background: linear-gradient(180deg, #e9f7fd, var(--white));
  border-bottom: 1px solid var(--line);
}
.lp-form__gift {
  /* grid, not inline-grid: it has to start its own line so it sits UNDER
     the live badge rather than beside it. */
  display: grid; margin-inline: auto; place-items: center; width: 3.3rem; height: 3.3rem;
  border-radius: 50%; background: var(--white); color: var(--accent-deep);
  border: 2px solid var(--accent); box-shadow: var(--shadow); margin-bottom: .7rem;
}
/* THE LIVE BADGE. A pill with a dot that breathes rather than blinks: a
   hard blink reads as an error light, a slow pulse reads as a heartbeat. */
.lp-form__live {
  display: inline-flex; align-items: center; gap: .45rem;
  margin: 0 0 .7rem; padding: .32rem .8rem .32rem .62rem;
  border-radius: 999px; background: var(--white);
  border: 1px solid var(--line); box-shadow: var(--shadow);
  color: var(--ink); font-size: .74rem; font-weight: 700;
  letter-spacing: .04em;
}
.lp-form__dot {
  width: .55rem; height: .55rem; border-radius: 50%;
  background: #1db954; flex: 0 0 auto;
  box-shadow: 0 0 0 0 rgba(29,185,84,.7);
  animation: lp-beat 1.4s cubic-bezier(.4,0,.2,1) infinite;
}
/* Outside hours it is amber and still, because a pulsing light that means
   "nobody is here" is just a lie with movement. */
.lp-form__live.is-off .lp-form__dot { background: #e0a526; animation: none; box-shadow: none; }
@keyframes lp-beat {
  0%   { box-shadow: 0 0 0 0 rgba(29,185,84,.75); transform: scale(1); }
  55%  { box-shadow: 0 0 0 .72rem rgba(29,185,84,0); transform: scale(1.32); }
  100% { box-shadow: 0 0 0 0 rgba(29,185,84,0); transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) { .lp-form__dot { animation: none; } }
/* TWO LINES, EACH UNBREAKABLE. "Claim your free Air Vent Flush" is the
   longer at about 15.4em, so 6.2cqi fills the card with a little room and
   it can never wrap to a third line at any width. The vw line is the
   fallback for a browser without container units. */
.lp-form__h {
  color: var(--ink); font-weight: 800; line-height: 1.14;
  font-size: clamp(1.3rem, 5.4vw, 2rem);
  font-size: min(2rem, 6.2cqi);
  margin: 0 auto .55rem; max-width: none;
}
.lp-form__h .hl { color: var(--accent-deep); }
/* Three unbreakable lines, sized off the card like the heading. The
   longest is "Tell us the car and we'll give you your quote." at about
   22.5em, so 4.3cqi fills the card with a little room. */
.lp-form__sub {
  color: var(--body); line-height: 1.5; margin: 0 auto; max-width: none;
  font-size: clamp(.78rem, 3.6vw, .95rem);
  font-size: min(.95rem, 4.3cqi);
}
.lp-form__sub .hl { color: var(--accent-deep); font-weight: 700; }
.lp-form form { padding: 1.15rem 1.05rem 1.25rem; display: grid; gap: .85rem; }
.lp-field label { display: block; color: var(--ink); font-weight: 700; font-size: .82rem; margin: 0 0 .3rem; }
.lp-field input {
  width: 100%; height: 3.25rem; border-radius: 12px; padding: 0 .95rem;
  border: 1.5px solid var(--line); background: var(--white);
  font: inherit; font-size: 1rem; color: var(--ink); -webkit-appearance: none;
  transition: border-color .15s, box-shadow .15s;
}
.lp-field input::placeholder { color: #9fb1bf; }
.lp-field input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 4px rgba(36,192,240,.18); }
.lp-field.is-bad input { border-color: #d64545; }
.lp-field__err { display: block; color: #b33a3a; font-size: .76rem; line-height: 1.3; margin-top: .3rem; }
.lp-field__err:empty { display: none; }
.lp-chips { border: 0; margin: 0; padding: 0; min-width: 0; }
.lp-chips legend { color: var(--ink); font-weight: 700; font-size: .82rem; padding: 0; margin-bottom: .5rem; }
.lp-chips legend span { color: var(--muted); font-weight: 500; }
.lp-chips__row { display: flex; flex-wrap: wrap; gap: .45rem; }
.lp-chip { position: relative; }
.lp-chip input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.lp-chip span {
  display: inline-block; padding: .55rem .9rem; border-radius: 999px;
  border: 1.5px solid var(--line); background: var(--white); color: var(--ink);
  font-weight: 600; font-size: .86rem; line-height: 1; transition: .15s;
}
.lp-chip input:checked + span {
  background: var(--accent); border-color: var(--accent); color: var(--accent-ink);
  box-shadow: 0 6px 16px rgba(36,192,240,.35);
}
.lp-chip input:focus-visible + span { outline: 3px solid var(--accent-deep); outline-offset: 2px; }
.lp-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.lp-form__btn { width: 100%; padding: 1rem 1.1rem; font-size: 1.04rem; line-height: 1.2; margin-top: .15rem; }
.lp-form__btn.is-busy { opacity: .75; }
.lp-form__fine {
  display: flex; gap: .45rem; align-items: flex-start; justify-content: center;
  color: var(--muted); font-size: .78rem; line-height: 1.4; margin: 0; text-align: left;
}
.lp-form__fine svg { flex: 0 0 auto; color: var(--accent-deep); margin-top: .1rem; }
/* The badges under the button. Three short facts, every one of them also
   stated at length further down the page, because this is the moment the
   visitor is deciding and nobody scrolls back up to check. */
.lp-form__trust {
  grid-column: 1 / -1; list-style: none; margin: .2rem 0 0; padding: .7rem 0 0;
  border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; justify-content: center; gap: .4rem 1rem;
}
.lp-form__trust li {
  display: inline-flex; align-items: center; gap: .3rem;
  color: var(--muted); font-size: .76rem; font-weight: 600; white-space: nowrap;
}
.lp-form__trust svg { color: var(--accent-deep); flex: 0 0 auto; }
.lp-form__done { text-align: center; padding: 2.2rem 1.3rem 2rem; }
.lp-form__tick {
  display: inline-grid; place-items: center; width: 3.6rem; height: 3.6rem;
  border-radius: 50%; background: var(--accent); color: var(--accent-ink);
  margin-bottom: .9rem; box-shadow: 0 8px 22px rgba(36,192,240,.4);
}
.lp-form__done h3 { color: var(--ink); font-size: 1.5rem; margin: 0 0 .5rem; }
.lp-form__done p { color: var(--body); line-height: 1.55; margin: 0 auto 1.1rem; max-width: 36ch; }
.lp-form__err { margin: 0; padding: .9rem 1.1rem 1.2rem; text-align: center; color: #b33a3a; font-size: .9rem; line-height: 1.5; }
.lp-form__err a { color: var(--accent-deep); font-weight: 700; }
@media (min-width: 560px) {
  .lp-form form { grid-template-columns: 1fr 1fr; }
  .lp-chips, .lp-hp, .lp-form__btn, .lp-form__fine { grid-column: 1 / -1; }
}

/* ---- THE SERVICE CARDS. A before and after side by side, the sizzle under
   them, and the whole card is the link. ---- */
.lp-svc__grid { display: grid; gap: 1.1rem; grid-template-columns: 1fr; margin-top: 1.8rem; }
.lp-svc__card {
  display: block; text-decoration: none; color: inherit; overflow: hidden;
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow); transition: transform .25s, box-shadow .25s, border-color .25s;
}
.lp-svc__pair { display: grid; grid-template-columns: 1fr 1fr; gap: 3px; background: var(--white); }
.lp-svc__t { margin: 0; position: relative; background: var(--wash); }
.lp-svc__t img { width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block; }
.lp-svc__tag {
  position: absolute; left: .5rem; bottom: .5rem; padding: .22rem .6rem;
  border-radius: 999px; font-size: .64rem; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase;
}
.lp-svc__tag--b { background: rgba(4,24,38,.82); color: #fff; }
.lp-svc__tag--a { background: var(--accent); color: var(--accent-ink); }
.lp-svc__body { padding: 1rem 1.1rem 1.1rem; }
.lp-svc__body h3 { color: var(--ink); font-size: 1.25rem; line-height: 1.2; margin: 0 0 .35rem; }
.lp-svc__body p { color: var(--body); font-size: .93rem; line-height: 1.55; margin: 0 0 .5rem; }
.lp-svc__note { display: block; color: var(--muted); font-size: .78rem; margin-bottom: .7rem; }
.lp-svc__go { display: inline-flex; align-items: center; gap: .35rem; color: var(--accent-deep); font-weight: 800; font-size: .88rem; }
@media (hover: hover) {
  .lp-svc__card:hover { transform: translateY(-3px); border-color: var(--accent); box-shadow: var(--shadow-lg); }
}
@media (min-width: 720px) { .lp-svc__grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1080px) { .lp-svc__grid { grid-template-columns: 1fr 1fr 1fr; } }

/* ---- trust badges ---- */
.lp-badges { background: var(--white); border-block: 1px solid var(--line); padding: 1.5rem 0; }
.lp-badges__row { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.1rem; grid-template-columns: repeat(6, 1fr); }
.lp-badges__row li { display: flex; flex-direction: column; align-items: center; text-align: center; gap: .3rem; padding: 0 .4rem; }
.lp-badges__row svg { color: var(--accent-deep); margin-bottom: .2rem; }
.lp-badges__row b { color: var(--ink); font-size: .86rem; line-height: 1.25; }
.lp-badges__row span { color: var(--muted); font-size: .76rem; line-height: 1.35; }

/* ---- sections ---- */
.lp-sec { background: var(--surface); }
.lp-sec--alt { background: var(--white); }
.lp-centre { text-align: center; margin-inline: auto; }
.lp-sec h2, .lp-final h2, .lp-guarantee h2 { color: var(--ink); }
.lp-sec .lede { max-width: 60ch; color: var(--body); }

.lp-ctas { display: flex; flex-wrap: wrap; gap: .9rem; justify-content: center; align-items: center; margin-top: 2.2rem; }
.lp-cta { font-size: 1.04rem; padding: .9rem 1.8rem; }

/* ---- steps ---- */
.lp-steps { list-style: none; margin: 2rem 0 0; padding: 0; display: grid; gap: 1.2rem; grid-template-columns: repeat(3,1fr); }
.lp-step { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.5rem 1.3rem; box-shadow: var(--shadow); }
.lp-step__n { display: grid; place-items: center; width: 2.4rem; height: 2.4rem; border-radius: 50%; background: var(--accent); color: var(--accent-ink); font-weight: 800; margin-bottom: .8rem; }
.lp-step h3 { color: var(--ink); font-size: 1.08rem; margin: 0 0 .4rem; }
.lp-step p { color: var(--body); font-size: .93rem; line-height: 1.55; margin: 0; }

/* ---- concerns ---- */
.lp-concerns { list-style: none; margin: 2rem 0 0; padding: 0; display: grid; gap: 1.1rem; grid-template-columns: repeat(2,1fr); }
.lp-concern { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.4rem; box-shadow: var(--shadow); }
.lp-concern__ico { display: inline-grid; place-items: center; width: 2.5rem; height: 2.5rem; border-radius: 12px; background: var(--wash); color: var(--accent-deep); margin-bottom: .7rem; }
.lp-concern h3 { color: var(--ink); font-size: 1.08rem; line-height: 1.3; margin: 0 0 .5rem; }
.lp-concern__bad { color: var(--muted); font-size: .9rem; line-height: 1.5; margin: 0 0 .7rem; font-style: italic; }
.lp-concern__fix { color: var(--body); font-size: .95rem; line-height: 1.6; margin: 0; padding-top: .7rem; border-top: 1px solid var(--line); }

/* ---- guarantees. Green rather than blue: a guarantee is a different kind
   of promise from a service, and the colour shift is what makes the block
   read as reassurance instead of more marketing. ---- */
.lp-gtees { list-style: none; margin: 2rem 0 0; padding: 0; display: grid; gap: 1.1rem; grid-template-columns: repeat(2,1fr); }
.lp-gtee { border: 1px solid #b9e3cd; background: #f0faf5; border-radius: var(--radius); padding: 1.3rem 1.4rem; }
.lp-gtee__ico { display: inline-grid; place-items: center; color: #1a8f5d; margin-bottom: .5rem; }
.lp-gtee h3 { color: var(--ink); font-size: 1.06rem; margin: 0 0 .45rem; }
.lp-gtee p { color: #39584a; font-size: .94rem; line-height: 1.6; margin: 0; }

/* ---- value stack ---- */
.lp-value { list-style: none; margin: 2rem 0 0; padding: 0; display: grid; gap: .7rem 1.6rem; grid-template-columns: repeat(2,1fr); }
.lp-value li { display: flex; gap: .6rem; align-items: flex-start; color: var(--body); font-size: .97rem; line-height: 1.5; }
.lp-value li svg { flex: 0 0 auto; margin-top: .22rem; color: var(--accent-deep); }

/* ---- reel ---- */
.lp-reel { display: flex; gap: .85rem; overflow-x: auto; margin-top: 2rem; padding-bottom: .6rem; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; }
.lp-reel__item { flex: 0 0 auto; width: 184px; scroll-snap-align: start; border-radius: var(--radius); overflow: hidden; aspect-ratio: 9/16; background: var(--wash); border: 3px solid var(--white); box-shadow: var(--shadow); }
.lp-reel__item img, .lp-reel__item video { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---- why ---- */
.lp-why { list-style: none; margin: 2rem 0 0; padding: 0; display: grid; gap: 1.1rem; grid-template-columns: repeat(4,1fr); }
.lp-why__item { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.4rem 1.25rem; box-shadow: var(--shadow); }
.lp-why__ico { display: inline-grid; place-items: center; width: 2.5rem; height: 2.5rem; border-radius: 12px; background: var(--wash); color: var(--accent-deep); margin-bottom: .7rem; }
.lp-why__item h3 { color: var(--ink); font-size: 1.04rem; margin: 0 0 .4rem; }
.lp-why__item p { color: var(--body); font-size: .91rem; line-height: 1.55; margin: 0; }

/* ---- crew ---- */
/* FOUR of them since Jack joined, so the row is four across on a desktop
   and two across from tablet down, rather than three and a lonely one. */
.lp-crew { display: grid; gap: 1.2rem; grid-template-columns: repeat(4,1fr); margin-top: 2rem; }
.lp-crew__card { margin: 0; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow); }
.lp-crew__card img { width: 100%; aspect-ratio: 1/1; object-fit: cover; display: block; }
.lp-crew__card figcaption { padding: 1.1rem 1.2rem 1.3rem; }
.lp-crew__card b { display: block; color: var(--ink); font-size: 1.1rem; margin-bottom: .3rem; }
.lp-crew__card span { color: var(--body); font-size: .92rem; line-height: 1.55; }

/* ---- the big review scroller ---- */
.lp-revsec { overflow: hidden; }
.lp-revs { overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; margin-top: 2rem; padding-bottom: .5rem; }
.lp-revs::-webkit-scrollbar { display: none; }
.lp-revs__track { display: flex; gap: 1rem; width: max-content; padding-inline: max(1.2rem, calc((100vw - 1200px) / 2)); }
.lp-rev { flex: 0 0 auto; width: 320px; margin: 0; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.3rem 1.4rem; display: flex; flex-direction: column; box-shadow: var(--shadow); }
.lp-rev__stars { color: var(--star); font-size: 1rem; letter-spacing: .12em; margin-bottom: .7rem; }
.lp-rev blockquote { margin: 0 0 1rem; color: var(--body); font-size: .95rem; line-height: 1.6; flex: 1; }
.lp-rev figcaption b { display: block; color: var(--ink); font-size: .96rem; }
.lp-rev figcaption span { color: var(--accent-deep); font-size: .82rem; font-weight: 600; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .lp-revs__track { animation: lp-marquee 70s linear infinite; }
  .lp-revs:hover .lp-revs__track, .lp-revs:focus-within .lp-revs__track { animation-play-state: paused; }
}
@keyframes lp-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ---- objections ---- */
.lp-qs { margin-top: 2rem; display: grid; gap: .6rem; }
.lp-q { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); padding: 1rem 1.2rem; }
.lp-q summary { cursor: pointer; color: var(--ink); font-weight: 700; font-size: 1.01rem; list-style: none; display: flex; justify-content: space-between; gap: 1rem; }
.lp-q summary::-webkit-details-marker { display: none; }
.lp-q summary::after { content: "+"; color: var(--accent-deep); font-size: 1.4rem; line-height: 1; }
.lp-q[open] summary::after { content: "\2212"; }
.lp-q p { color: var(--body); line-height: 1.6; margin: .8rem 0 0; font-size: .95rem; }

/* ---- closing guarantee ---- */
.lp-guarantee { text-align: center; background: linear-gradient(180deg, var(--wash) 0%, var(--surface) 100%); }
.lp-guarantee__ico { display: inline-grid; place-items: center; color: var(--accent-deep); margin-bottom: .8rem; }
.lp-guarantee p { color: var(--body); line-height: 1.65; font-size: 1.04rem; }

/* ---- final ---- */
.lp-final { background: var(--white); }
.lp-final__in { display: grid; gap: 2.2rem; grid-template-columns: 1fr 1fr; align-items: start; }
/* The second GHL iframe is gone from this block, so it is one centred column
   rather than copy beside a form. */
.lp-final__in--solo { grid-template-columns: 1fr; max-width: 720px; margin-inline: auto; text-align: center; }
.lp-final__in--solo .lp-proof--stack { display: inline-flex; flex-direction: column; text-align: left; }
.lp-final__ctas { justify-content: center; margin-top: 1.4rem; }
.lp-proof { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .5rem 1.3rem; justify-content: center; }
.lp-proof li { display: flex; gap: .45rem; align-items: center; color: var(--body); font-size: .92rem; }
.lp-proof li svg { flex: 0 0 auto; color: var(--accent-deep); }
.lp-proof b { color: var(--ink); }
.lp-proof--stack { justify-content: flex-start; flex-direction: column; align-items: flex-start; margin-top: 1.2rem; }
.lp-proof--row { flex-direction: row; justify-content: center; margin-top: 1.8rem; }

.lp-foot { background: var(--navy-900); padding: 1.6rem 0; text-align: center; }
.lp-foot p { color: #7e94a6; font-size: .85rem; margin: 0; }

/* ---- sticky CTA. Hidden by JS whenever a form is on screen, because a bar
   covering the form it points at is how this pattern usually goes wrong. ---- */
.lp-sticky {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  display: flex; gap: .6rem; padding: .6rem .8rem;
  padding-bottom: calc(.6rem + env(safe-area-inset-bottom, 0px));
  background: rgba(255,255,255,.96); backdrop-filter: blur(10px);
  border-top: 1px solid var(--line); box-shadow: 0 -6px 24px rgba(4,24,38,.12);
}
.lp-sticky[hidden] { display: none; }
/* It arrives rather than appearing (Zaak, 2026-10-24: "hidden until they
   scroll down to here and then it fades in"). The `hidden` attribute still
   does the real hiding, so with JS off there is simply no bar. */
.lp-sticky.is-in { animation: lp-rise .28s ease-out both; }
@keyframes lp-rise { from { opacity: 0; transform: translateY(100%); } }
@media (prefers-reduced-motion: reduce) { .lp-sticky.is-in { animation: none; } }
.lp-sticky__call, .lp-sticky__quote {
  display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
  border-radius: 999px; font-weight: 800; text-decoration: none;
  padding: .8rem 1rem; font-size: .96rem; line-height: 1;
}
.lp-sticky__call { flex: 0 0 auto; color: var(--accent-deep); border: 2px solid var(--accent); }
.lp-sticky__quote { flex: 1; background: var(--accent); color: var(--accent-ink); }

/* ---- fade up on scroll. Armed by JS only, never by CSS alone: the default
   state is visible, so with JS off or reduced motion on, nothing is left
   hidden waiting for an event that will never arrive. ---- */
.lp-reveal.is-armed { opacity: 0; transform: translateY(26px); }
.lp-reveal.is-armed.is-in {
  opacity: 1; transform: none;
  transition: opacity .6s cubic-bezier(.4,0,.2,1), transform .6s cubic-bezier(.4,0,.2,1);
}

/* ---- responsive ---- */
@media (max-width: 980px) {
  .lp-concerns, .lp-gtees, .lp-why, .lp-crew, .lp-steps,
  .lp-value, .lp-final__in { grid-template-columns: repeat(2,1fr); }
  .lp-badges__row { grid-template-columns: repeat(3,1fr); }
  .lp-hero__in { grid-template-columns: minmax(0, 1fr); text-align: center; }
  /* `width: 100%` is load bearing. The copy is a size container now, and a
     grid item with auto margins is sized to its content, which containment
     counts as nothing: without it the column measured 0px wide on a phone. */
  .lp-hero__copy { width: 100%; max-width: min(620px, 100%); margin-inline: auto; }
  .lp-promise { margin-inline: auto; }
  .lp-gbadge { display: inline-flex; }
  .lp-hero__ctas { justify-content: center; }
}
@media (max-width: 720px) {
  .lp-concerns, .lp-gtees, .lp-why, .lp-crew, .lp-steps,
  .lp-value, .lp-final__in { grid-template-columns: 1fr; }
  .lp-bar__logo { height: 34px; }
  .lp-rev { width: 280px; }
  .lp-reel__item { width: 150px; }
  .lp-ctas { flex-direction: column; align-items: stretch; }
  .lp-cta { text-align: center; }
  .lp-call { justify-content: center; }
  .lp-revs__track { animation: none !important; }
}
@media (max-width: 560px) {
  .lp-badges__row { grid-template-columns: repeat(2,1fr); gap: 1rem .6rem; }
  .lp-badges__row b { font-size: .8rem; }
  .lp-hcard { width: 250px; }
  /* ONE ROW on a phone (Zaak, 2026-10-24): logo, the offer, and the phone
     as a plain icon in the corner. Dropping the digits is what buys the
     offer the width to sit between them instead of wrapping onto a second
     row of its own. The tel: link and its tap target are unchanged, and the
     number is still read out by a screen reader through aria-label. */
  /* The gutter is tight on a phone, so the bar gets a little of its own:
     the logo and the phone icon were both sitting hard against the edge. */
  .lp-bar__in { flex-wrap: nowrap; gap: .5rem; padding-inline: .4rem; }
  .lp-call--bar .lp-call__num { display: none; }
  .lp-call--bar { padding: .45rem; width: 2.3rem; height: 2.3rem; justify-content: center; gap: 0; }
  .lp-bar__offer {
    flex: 1 1 auto; justify-content: center; min-width: 0;
    font-size: .64rem; letter-spacing: .04em; gap: .3rem;
  }
  .lp-bar__offer span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* ---- HERO BACKGROUND LAYER. Mobile only, sits UNDER the text at low
   opacity, never over it. A background that competes with the headline is
   exactly the mistake MobileWash NYC makes, where a genuinely good-looking
   cinematic hero has unreadable copy on top of it. On desktop the fanned
   photos already carry the visual weight, so this is off entirely. ---- */
.lp-hero { position: relative; }
.lp-hero__bg { display: none; }
.lp-hero__bgv { width: 100%; height: 100%; object-fit: cover; display: block; }
/* iOS LOW POWER MODE (Zaak's screenshot, 2026-10-24, yellow battery): Safari
   blocks autoplay outright and paints its own play glyph over the first
   frame. Nothing starts the clip before the first touch in that mode, but
   the glyph is a control on a decorative background and it goes. The
   inline script restarts the clip on the first touchstart, which iOS fires
   the moment a thumb lands to scroll. */
.lp-hero__bgv::-webkit-media-controls-start-playback-button,
.lp-ty__clipv::-webkit-media-controls-start-playback-button,
.lp-hero__bgv::-webkit-media-controls-overlay-play-button,
.lp-ty__clipv::-webkit-media-controls-overlay-play-button {
  display: none !important; -webkit-appearance: none; opacity: 0; pointer-events: none;
}
.lp-hero__bgv::-webkit-media-controls, .lp-ty__clipv::-webkit-media-controls,
.lp-hero__bgv::-webkit-media-controls-panel, .lp-ty__clipv::-webkit-media-controls-panel {
  display: none !important; -webkit-appearance: none;
}

@media (max-width: 980px) {
  .lp-hero__bg {
    display: block; position: absolute; z-index: 0;
    top: 0; left: 0; right: 0;
    /* IT STOPS ABOVE THE PHOTO STRIP (Zaak, 2026-10-24: "have it stop just
       before the scrolling photo gallery"). The strip's height is the same
       --lp-shot-h both rules read, so the two cannot drift apart; the extra
       is the flex gap above it. */
    bottom: calc(var(--lp-shot-h) + var(--lp-bg-lift));
    overflow: hidden; pointer-events: none;
    opacity: .34;
    /* FULL STRENGTH ALL THE WAY DOWN to where the layer stops, which is
       just above the photo strip (Zaak, 2026-10-24, bracketing the hero
       from under the bar to the top of the gallery: "have it go down to
       here"). Only the top is feathered, so there is no hard edge against
       the white bar. */
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 8%, #000 100%);
    mask-image: linear-gradient(180deg, transparent 0%, #000 8%, #000 100%);
  }
  .lp-hero__in { position: relative; z-index: 1; }

  /* THE COPY GETS A HALO, NOT THE VIDEO A VEIL. At 34% the clip shows real
     detail, and the grey guarantee line under the buttons was the first
     thing to stop reading over it. A white glow behind each line keeps
     every word legible without dimming the footage Zaak asked to see more
     of, and it costs nothing on a page that is already painted. */
  .lp-hero__copy .lp-topstars,
  .lp-hero__copy .lp-eyebrow,
  .lp-hero__copy h1,
  .lp-hero__copy .lp-promise,
  .lp-hero__copy .lp-under {
    text-shadow: 0 1px 3px rgba(255,255,255,.95), 0 0 14px rgba(255,255,255,.85);
  }
  /* ...and that line goes from the muted grey to body colour, because it is
     a promise, not a footnote, and it now has competition behind it. */
  .lp-hero .lp-under { color: var(--body); }

  /* The strip replaces the badge as the proof element on a phone. */
  .lp-gbadge { display: none; }
  .lp-hstrip { margin: .2rem 0 1.4rem; padding-bottom: 0; }
  .lp-shots__item { height: var(--lp-shot-h); width: auto; }
}

/* ---- SKINNY on a phone. These are a texture of proof drifting past, not
   something anyone stops to read in full, so the quote is clamped to two
   lines and the card loses a third of its height. ---- */
@media (max-width: 720px) {
  .lp-hcard { width: 208px; padding: .4rem .55rem; gap: .4rem; border-radius: 10px; }
  .lp-hcard__av { width: 1.45rem; height: 1.45rem; font-size: .6rem; }
  .lp-hcard q {
    font-size: .72rem; line-height: 1.28; margin: .05rem 0 .1rem;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .lp-hcard__stars { font-size: .6rem; }
  .lp-hcard__who { font-size: .63rem; }
  .lp-hstrip__track { gap: .5rem; }
}


@media (max-width: 760px) { .lp-gal__grid { grid-template-columns: 1fr; gap: 1.5rem; } }

/* ---- HOVER AND PRESS STATES (Zaak). Every button now lifts on hover and
   settles on press, so a cursor landing on one gets an answer. `:active`
   matters more than the hover here: on a phone there is no hover at all, and
   the press state is the only feedback a thumb ever gets that the tap
   registered. Transitions stay short, because a CTA that takes 300ms to
   acknowledge you feels broken rather than smooth. ---- */
.lp-cta, .lp-call, .lp-stack__cta,
.lp-sticky__call, .lp-sticky__quote {
  transition: transform .14s ease, box-shadow .18s ease,
              background-color .18s ease, border-color .18s ease;
}

/* Primary: the accent fill. Brightens and lifts. */
.lp-cta:hover, .lp-sticky__quote:hover {
  background: var(--accent-bright);
  transform: translateY(-2px);
  box-shadow: 0 10px 22px -6px rgba(11,127,168,.55);
}
.lp-cta:active, .lp-sticky__quote:active {
  transform: translateY(0); box-shadow: 0 3px 8px -3px rgba(11,127,168,.5);
}

/* Secondary: the outlined call buttons. Fill on hover rather than just
   tinting, so the pair reads as equally clickable. */
.lp-call:hover, .lp-stack__cta:hover, .lp-sticky__call:hover {
  background: var(--accent); color: var(--accent-ink);
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: 0 10px 22px -6px rgba(11,127,168,.45);
}
.lp-call:hover svg, .lp-stack__cta:hover svg, .lp-sticky__call:hover svg { color: var(--accent-ink); }
.lp-call:active, .lp-stack__cta:active, .lp-sticky__call:active {
  transform: translateY(0); box-shadow: none;
}

/* Keyboard users get the same affordance as a mouse, which they otherwise
   would not: the outline alone says "focused", not "pressable". */
.lp-cta:focus-visible, .lp-call:focus-visible, .lp-stack__cta:focus-visible,
.lp-sticky__call:focus-visible, .lp-sticky__quote:focus-visible {
  outline: 3px solid var(--accent-deep); outline-offset: 3px;
}

/* A device with no hover should never get stuck in a hover state after a
   tap, which is what happens when these rules apply on touch. */
@media (hover: none) {
  .lp-cta:hover, .lp-sticky__quote:hover,
  .lp-call:hover, .lp-stack__cta:hover, .lp-sticky__call:hover {
    transform: none; box-shadow: none;
  }
  .lp-call:hover, .lp-stack__cta:hover, .lp-sticky__call:hover {
    background: var(--white); color: var(--accent-deep);
  }
  .lp-call:hover svg, .lp-stack__cta:hover svg, .lp-sticky__call:hover svg { color: var(--accent-deep); }
  .lp-cta:hover, .lp-sticky__quote:hover { background: var(--accent); }
}

/* ==================================================== THE THANK YOU PAGE.
   Same bones, same colours. Only what differs is here. ---- */
.lp-bar__home { display: inline-flex; line-height: 0; border-radius: 8px; }
.lp-bar__home:focus-visible { outline: 3px solid var(--accent-deep); outline-offset: 3px; }
.lp-ty__tick {
  display: inline-grid; place-items: center; width: 3.4rem; height: 3.4rem;
  border-radius: 50%; background: var(--accent); color: var(--accent-ink);
  box-shadow: 0 10px 26px rgba(36,192,240,.4); margin-bottom: .8rem;
}
.lp-ty__cap { color: var(--muted); font-size: .8rem; text-align: center; margin: 0; }
/* The three steps carry an icon in the number spot and read as a list. */
.lp-steps--next { counter-reset: none; }
.lp-step--next .lp-step__n { width: 2.7rem; height: 2.7rem; }
.lp-step--next h3 { font-size: 1.15rem; }
/* The badge over the wall. Its own class, because the hero's badge is
   hidden on a phone and this one must not be. */
.lp-ty__badge {
  display: inline-flex; align-items: center; gap: .7rem; margin: 0 0 1rem;
  text-decoration: none;
  background: var(--white); border: 1px solid var(--line);
  border-radius: 999px; padding: .5rem 1.1rem .5rem .6rem; box-shadow: var(--shadow);
}
.lp-sec .lp-ty__badge { position: relative; left: 50%; transform: translateX(-50%); }
/* THE WALL: columns, so cards of different heights pack without holes. The
   first batch shows, the rest wait behind the button. */
.lp-wall { columns: 1; column-gap: 1rem; margin-top: 1.8rem; }
.lp-wall__card {
  width: auto; display: flex; flex-direction: column;
  break-inside: avoid; page-break-inside: avoid; margin: 0 0 1rem;
  text-decoration: none; color: inherit;
  transition: transform .2s, border-color .2s, box-shadow .2s;
}
.lp-wall__card .lp-rev__by { display: block; }
.lp-wall__card .lp-rev__by b { display: block; color: var(--ink); font-size: .96rem; }
.lp-wall__card .lp-rev__by > span { color: var(--accent-deep); font-size: .82rem; font-weight: 600; }
@media (hover: hover) {
  .lp-wall__card:hover { transform: translateY(-2px); border-color: var(--accent); box-shadow: var(--shadow-lg); }
}
.lp-wall__card:focus-visible { outline: 3px solid var(--accent-deep); outline-offset: 3px; }
.lp-wall__card.is-more { display: none; }
.lp-wall.is-open .lp-wall__card.is-more { display: flex; }
.lp-wall__card blockquote { font-size: .93rem; }
.lp-rev__date { display: block; color: var(--muted) !important; font-weight: 500 !important; font-size: .76rem !important; margin-top: .1rem; }
.lp-wall__more { margin-top: .6rem; font: inherit; font-weight: 700; font-size: .95rem; cursor: pointer; }
.lp-svc__card--static { cursor: default; }
@media (hover: hover) { .lp-svc__card--static:hover { transform: none; border-color: var(--line); box-shadow: var(--shadow); } }
@media (min-width: 720px) { .lp-wall { columns: 2; } }
@media (min-width: 1080px) { .lp-wall { columns: 3; } }

/* The thank you promise is three short lines, not two long ones, so it is
   sized a touch under the landing page's: the longest line is ~20em, which
   at 4.7cqi fills a 353px phone column with room to spare. Measured at
   20.8px it ran 48px past the edge. */
.lp-ty .lp-hero .lp-promise { font-size: min(1.12rem, 4.7cqi); }

/* Somebody who has asked for less motion gets the first frame and no more:
   the clip is still laid out (preload="metadata" paints frame one) and the
   inline script never calls play() under this media query. It used to be
   display:none here, which was "nothing", not "the first frame". */

/* ---- THE SHORT FORM at the foot of the page. The same card, narrower and
   without the gift header: by this point the offer has been made four
   times and the only thing left to ask is who to ring. ---- */
.lp-form--mini { max-width: 420px; margin: 1.6rem auto 0; text-align: left; }
.lp-form--mini form { padding: 1.15rem 1.05rem 1.25rem; display: grid; gap: .85rem; }
.lp-form--mini .lp-form__fine { grid-column: 1 / -1; }
.lp-final__call { margin-top: 1.2rem; }
@media (min-width: 560px) {
  .lp-form--mini form { grid-template-columns: 1fr 1fr; }
  .lp-form--mini .lp-form__btn, .lp-form--mini .lp-form__fine { grid-column: 1 / -1; }
}

/* ---- THE FOOTER. Address, coverage, phone, email and the hours, because
   a landing page with no way to check we are a real business is the first
   thing a careful buyer backs out of. ---- */
.lp-foot__name { color: var(--ink); font-weight: 800; margin: 0 0 .6rem; }
.lp-foot__list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem 1.4rem;
}
.lp-foot__list li { display: inline-flex; align-items: center; gap: .4rem; }
.lp-foot__list svg { color: var(--accent-deep); flex: 0 0 auto; }
.lp-foot__list a { color: var(--accent-deep); text-decoration: none; font-weight: 600; }
.lp-foot__list a:hover { text-decoration: underline; }
@media (max-width: 560px) {
  .lp-foot__list { flex-direction: column; align-items: center; gap: .45rem; }
}

/* The crew stay TWO across on a phone rather than dropping to one with the
   rest of the grids: four square portraits in a single column is most of a
   screen each and nobody scrolls to the fourth. */
@media (max-width: 760px) {
  .lp-crew { grid-template-columns: repeat(2, 1fr); gap: .8rem; }
  .lp-crew__card figcaption { padding: .8rem .85rem 1rem; }
  .lp-crew__card b { font-size: 1rem; }
  .lp-crew__card span { font-size: .84rem; line-height: 1.5; }
}

/* ---- THE THANK YOU CLIP. Small, under the promise, no controls. It is
   proof that a real person does this, shown at the one moment the visitor
   has nothing to do but wait. ---- */
.lp-ty__clip {
  margin: 1.1rem auto 1.4rem; width: min(190px, 46vw);
  aspect-ratio: 9 / 16; border-radius: 16px; overflow: hidden;
  border: 3px solid var(--white); box-shadow: var(--shadow-lg);
  background: var(--wash);
}
.lp-ty__clipv { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Reduce Motion: frame one, no playback (the script never calls play()). */

/* ================================================= DESKTOP HERO, REBUILT.
   Zaak, 2026-10-24: "on desktop have the scrolling gallery thing as a
   transparent feature over the hero section without the text overlays,
   slightly transparent and move the form to top right."

   So on a wide screen the photo strip stops being a column and becomes a
   drifting band ACROSS the whole hero at low opacity, and the form takes
   the space it used to hold. The form in the first screen is the single
   biggest difference between the pages that beat ours in the teardown and
   ours; on a phone it cannot fit above the fold, on a desktop it can.

   MOBILE IS UNTOUCHED. Everything here is behind min-width 981px, which is
   where the one-column layout ends. landing.js does the DOM move and puts
   it back if the window is resized across the line. ---- */
@media (min-width: 981px) {
  /* Room above and below the form card so the photo band shows past it
     top and bottom (Zaak, 2026-10-24: "a little bit of a buffer on the top
     and bottom of the form so u can see the background a bit behind it").
     The card is the tallest thing in the hero, so the breathing room has to
     come from the hero's own padding. */
  /* The buffer that lets the band show above and below the form card. One
     variable, because the band has to cancel it out exactly. */
  .lp-hero { overflow: hidden; --lp-hero-pad: 4.4rem; padding: var(--lp-hero-pad) 0; }

  /* The strip, full bleed, STRETCHED to the height of the hero (Zaak,
     2026-10-24: "needs to stretch to fit background"). */
  .lp-hero__media {
    /* FULL BLEED. It is a child of .lp-hero__in, which is .wrap (max-width
       plus gutters) and is positioned, so `inset: 0` only ever reached the
       edges of the CONTENT column and the band stopped a few hundred pixels
       short on a wide screen. 100vw off the centre line breaks it out
       without moving it in the DOM; .lp-hero is overflow:hidden so the extra
       width can never make the page scroll sideways. */
    /* NEGATIVE TOP AND BOTTOM, not 0. The band's containing block is
       .lp-hero__in, which is positioned and sits INSIDE the hero's padding,
       so `top: 0` stopped level with the form card and there was no gap to
       see the photos through. Backing it out by exactly the hero's padding
       puts the band's edges on the hero's edges. */
    position: absolute; top: calc(-1 * var(--lp-hero-pad));
    bottom: calc(-1 * var(--lp-hero-pad)); left: 50%;
    width: 100vw; transform: translateX(-50%); z-index: 0;
    display: flex; align-items: stretch; justify-content: flex-start;
    pointer-events: none; opacity: .2;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  }
  .lp-hero__media .lp-shots { padding: 0; height: 100%; }
  .lp-hero__media .lp-shots__track { gap: 0; height: 100%; align-items: stretch; }
  /* EDGE TO EDGE: no gap, no border, no rounding, so the photos touch and
     read as one wall rather than a row of cards (Zaak). */
  .lp-hero__media .lp-shots__item {
    height: 100%; width: auto; min-width: 0;
    border: 0; box-shadow: none; border-radius: 0;
  }
  /* No captions on the background band: it is texture, and text over text
     is the fastest way to make a hero unreadable. */
  .lp-hero__media .lp-shots__tag { display: none; }

  .lp-hero__in { position: relative; z-index: 1; align-items: center; }

  /* BOTH COLUMNS HAVE TO BE POSITIONED. The band is an absolute child of
     this same grid, so with the columns left static it painted straight
     over them: a positioned element at z-index 0 beats a static sibling
     whatever its order. That is why the form card and the headline looked
     see-through. */
  .lp-hero__copy, .lp-hero__form { position: relative; z-index: 1; }

  /* The form card, top right, in the column the photos used to have. */
  .lp-hero__form { width: 100%; }
  .lp-hero__form .lp-form { max-width: 460px; margin-left: auto; }
  .lp-hero__form .lp-form__head { padding: 1.3rem 1.2rem 1rem; }
  .lp-hero__form .lp-form__gift { width: 2.8rem; height: 2.8rem; margin-bottom: .55rem; }
  .lp-hero__form .lp-form__sub { font-size: min(.9rem, 4.1cqi); }

  /* The section the form came out of has nothing left to show. */
  .lp-formsec.is-empty { display: none; }

  /* MORE ROOM, AND FURTHER LEFT (Zaak, 2026-10-24: "make this section a
     bit bigger like the text, can go a bit to the left increase width if
     needed"). The hero's wrap is widened past the site's 1200px and the
     copy takes the larger share of it. The headline and the promise are
     sized in cqi off this column, so giving it width is all it takes to
     make the type bigger: no font sizes change hands. */
  .lp-hero__in { max-width: min(1420px, 95vw); grid-template-columns: minmax(0, 1.3fr) minmax(0, .8fr); gap: 2.6rem; }
  .lp-hero__copy { max-width: none; }

  /* The same white halo the phone layout uses. The copy now sits over real
     photographs instead of a flat gradient, and the eyebrow and the
     guarantee line were the first things to stop reading. */
  .lp-hero__copy .lp-topstars,
  .lp-hero__copy .lp-eyebrow,
  .lp-hero__copy h1,
  .lp-hero__copy .lp-promise,
  .lp-hero__copy .lp-under {
    text-shadow: 0 1px 3px rgba(255,255,255,.95), 0 0 16px rgba(255,255,255,.9);
  }
  .lp-hero .lp-under { color: var(--body); }
  /* A soft wash behind the left column only, so the band stays visible at
     the edges and the words stay solid where they matter. */
  .lp-hero__copy::before {
    content: ""; position: absolute; z-index: -1;
    inset: -2rem -3rem -2rem -50vw;
    background: radial-gradient(ellipse 70% 80% at 30% 50%, rgba(255,255,255,.82), rgba(255,255,255,0) 72%);
    pointer-events: none;
  }
  .lp-hero__copy { position: relative; }
}

/* ---- DESKTOP CHROME: a compact sticky CTA and a back-to-top button. ---- */
@media (min-width: 981px) {
  /* The bar spanned the whole window, which on a 1440px screen is a slab
     with two buttons marooned at either end (Zaak: "smaller and in the
     middle"). Now it is a pill that is only as wide as its contents. */
  .lp-sticky {
    left: 50%; right: auto; transform: translateX(-50%);
    bottom: 1.1rem; width: auto; max-width: min(520px, 92vw);
    border-radius: 999px; border: 1px solid var(--line);
    padding: .5rem .55rem; gap: .5rem;
    box-shadow: 0 10px 30px rgba(4,24,38,.18);
  }
  .lp-sticky.is-in { animation: lp-rise-mid .28s ease-out both; }
  @keyframes lp-rise-mid {
    from { opacity: 0; transform: translateX(-50%) translateY(120%); }
    to   { opacity: 1; transform: translateX(-50%) translateY(0); }
  }
  .lp-sticky__call, .lp-sticky__quote { padding: .66rem 1.15rem; font-size: .92rem; }
  .lp-sticky__quote { flex: 0 0 auto; }
}

/* Back to top. Zaak: "a little button on the side of the page that goes back
   to top kind of arrow". It only exists once there is something to go back
   up from, and it sits clear of the sticky CTA. */
.lp-top {
  position: fixed; right: 1rem; bottom: 5.2rem; z-index: 59;
  width: 2.9rem; height: 2.9rem; display: grid; place-items: center;
  border-radius: 50%; border: 1px solid var(--line); background: var(--white);
  color: var(--accent-deep); cursor: pointer; padding: 0;
  box-shadow: 0 8px 22px rgba(4,24,38,.16);
  transition: transform .2s, box-shadow .2s, opacity .25s;
}
.lp-top[hidden] { display: none; }
.lp-top svg { transform: rotate(-90deg); }
.lp-top:focus-visible { outline: 3px solid var(--accent-deep); outline-offset: 3px; }
@media (hover: hover) {
  .lp-top:hover { transform: translateY(-2px); box-shadow: 0 12px 28px rgba(4,24,38,.22); }
}
@media (min-width: 981px) {
  /* Clear of the centred pill, so it can live on the edge of the page. */
  .lp-top { right: 1.6rem; bottom: 1.6rem; width: 3.1rem; height: 3.1rem; }
}

/* ===================================== THE THANK YOU HERO ON A DESKTOP.
   Zaak, 2026-10-24: bigger text, the vertical video moved right and made
   "huge, huge", the reviews scrolling under the copy, the call button and
   a row of trust badges under that. Mobile keeps the stacked order through
   `order`, so none of this touches a phone. ---- */
.lp-ty__trust { justify-content: flex-start; border-top: 0; padding-top: .9rem; margin-top: .9rem; }
@media (max-width: 980px) {
  /* On a phone the source order is already right: headline and promise,
     the clip, then the proof and the photo strip. No `order` needed, which
     is why the hero was split into three blocks rather than two. */
  .lp-ty__trust { justify-content: center; }
}
@media (min-width: 981px) {
  /* Copy left and wide, the clip right and big. The photo strip drops
     behind the lot as the same faint band the landing page uses. */
  /* GRID AREAS, so the copy and the proof stack down the left while the
     clip runs the full height of the right. Source order stays correct for
     a phone. */
  .lp-ty .lp-hero__in {
    max-width: min(1420px, 95vw);
    grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
    grid-template-areas: "copy clip" "after clip";
    gap: .4rem 3rem; align-items: center;
  }
  .lp-ty .lp-hero__copy { grid-area: copy; align-self: end; }
  .lp-ty__after { grid-area: after; align-self: start; position: relative; z-index: 1; }
  .lp-ty .lp-hero__copy { max-width: none; position: relative; z-index: 1; }
  .lp-ty__clip {
    grid-area: clip; position: relative; z-index: 1;
    width: 100%; max-width: 420px; margin: 0 0 0 auto;
    border-width: 5px; border-radius: 26px;
  }
  /* The headline and promise are sized off the copy column, so the wider
     column is what makes the text bigger. The promise gets a nudge of its
     own because three short lines were sized for a phone. */
  .lp-ty .lp-hero .lp-promise { font-size: min(1.45rem, 4.4cqi); }
  .lp-ty .lp-hstrip { margin-top: 1.6rem; }
}


/* The footer link block (2026-10-24, when this page became the home page).
   Small and grey on purpose: it is for Google and for the one visitor in a
   hundred who scrolls past the last form, not part of the pitch. */
.lp-foot__links {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.2rem 2rem;
  margin-top: 1.6rem; padding-top: 1.2rem; border-top: 1px solid var(--line);
  text-align: left;
}
.lp-foot__links h4 {
  margin: 0 0 .4rem; font-size: .7rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted); font-weight: 800;
}
.lp-foot__links ul { list-style: none; margin: 0; padding: 0; }
.lp-foot__links li { margin: 0 0 .25rem; }
.lp-foot__links a { color: var(--muted); font-size: .8rem; text-decoration: none; }
.lp-foot__links a:hover { color: var(--ink); text-decoration: underline; }
@media (max-width: 640px) {
  .lp-foot__links { grid-template-columns: 1fr 1fr; }
  .lp-foot__links > div:last-child { grid-column: 1 / -1; }
}
