/* =====================================================================
   HG Electrical landing pages
   Language: docs/v2/language/hg-electrical/spec.md (ratified by Ethan
   2026-09-03: blue action, sign-written hero, Roboto on the review cards).
   Every value here has a line in the spec saying where it came from.
   Hand-written CSS, no Tailwind. Section 3 is the R17 device registry:
   a device that is not there does not exist on these pages.
   ===================================================================== */

/* ---------- faces: self-hosted latin woff2 ---------- */
@font-face{font-family:Barlow;src:url(/assets/fonts/barlow-400.woff2?v=1)format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:Barlow;src:url(/assets/fonts/barlow-500.woff2?v=1)format('woff2');font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:Barlow;src:url(/assets/fonts/barlow-600.woff2?v=1)format('woff2');font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:Barlow;src:url(/assets/fonts/barlow-700.woff2?v=1)format('woff2');font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:'Barlow Condensed';src:url(/assets/fonts/barlow-condensed-700.woff2?v=1)format('woff2');font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:Caveat;src:url(/assets/fonts/caveat-600.woff2?v=1)format('woff2');font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:Roboto;src:url(/assets/fonts/roboto-400.woff2?v=1)format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:Roboto;src:url(/assets/fonts/roboto-500.woff2?v=1)format('woff2');font-weight:500;font-style:normal;font-display:swap}

/* =====================================================================
   1. THEME (spec section 1)
   ===================================================================== */
:root{
  /* palette: measured off the client's own material */
  --ink:          #2C2D33;   /* the logo file's ground */
  --ink-deep:     #181E2D;   /* the bolt's core in the roundel; HG's black leans blue */
  --blue:         #1B74B9;   /* the HG letters in the roundel */
  --blue-lift:    #4FA3E6;   /* the mark's blue lifted until it reads on the flank, 5.0:1 */
  --blue-ink:     #15629E;   /* the mark's blue darkened until it reads on paper at 17px */
  --silver:       #CCCDCE;   /* the roundel's ring and its ELECTRICAL letters */
  --amber:        #FBBC04;   /* Google's own star, and only ever a star */
  --paper:        #ECEEEC;   /* the van's body highlight opened to a reading ground */
  --plate:        #FFFFFF;

  /* ink roles */
  --read:         #3A3C43;   /* reading matter on paper            9.5:1 */
  --quiet-paper:  #5E616A;   /* second-rank lines on paper         5.3:1 */
  --quiet:        var(--quiet-paper);   /* the GROUND re-points this; see below */
  --flank-read:   #D5D7DC;   /* reading matter on the flank        9.5:1 */
  --flank-quiet:  #9BA0AA;   /* second-rank lines on the flank     4.8:1 */
  --error:        #B3261E;   /* form errors, on the white plate only, 5.9:1 */

  /* the two line weights the mark carries */
  --stroke:       2px;                        /* the roundel's ring, reduced */
  --hair-dark:    rgba(213,215,220,.34);      /* the trace, on the flank */
  --hair-light:   rgba(44,45,51,.28);         /* the trace, on paper */

  /* the action: the mark's own blue, ruled by Ethan 2026-09-03 (spec Q1) */
  --act-fill:     var(--blue);
  --act-ink:      #FFFFFF;
  --act-edge:     #2E8AD6;

  /* type: two anchors, both the mark's own ratios.
     ELECTRICAL cap height 100u : HG cap height 329u = 3.29 (label to heading)
     HG lockup width 484u : ring diameter 788u       = 1.63 (heading to display)
     label 13 x 3.29 = 43 (h2 max) x 1.63 = 70 (h1 max) */
  --f-display: Barlow, system-ui, sans-serif;
  --f-read:    Barlow, system-ui, sans-serif;
  --f-label:   'Barlow Condensed', 'Barlow Semi Condensed', system-ui, sans-serif;
  --f-review:  Roboto, system-ui, sans-serif;
  --f-hand:    Caveat, 'Bradley Hand', 'Segoe Print', cursive;   /* the notes: handwriting, the first build's device, ruled back 2026-09-04 */

  --t-h1:    clamp(2.25rem,  1.643rem + 3.036vw, 4.375rem);  /* 36 -> 70 */
  --t-h2:    clamp(1.625rem, 1.321rem + 1.518vw, 2.6875rem); /* 26 -> 43 */
  --t-h3:    clamp(1.125rem, 1.054rem + 0.357vw, 1.375rem);  /* 18 -> 22 */
  --t-lede:  clamp(1.125rem, 1.018rem + 0.536vw, 1.5rem);    /* 18 -> 24 */
  --t-phone: clamp(1.375rem, 1.161rem + 1.071vw, 2.125rem);  /* 22 -> 34 */
  --t-body:  1.0625rem;                                       /* 17, fixed */
  --t-small: 0.9375rem;                                       /* 15, fixed */
  --t-label: 0.8125rem;                                       /* 13, fixed: the mark's ELECTRICAL */

  /* rhythm: proposed, the material carries no spacing system */
  --s-1: .25rem; --s-2: .5rem;  --s-3: .75rem; --s-4: 1rem;
  --s-5: 1.5rem; --s-6: 2rem;   --s-7: 3rem;   --s-8: 4.5rem;
  --band:      clamp(3.25rem, 2.464rem + 3.929vw, 6rem);   /* 52 -> 96 */
  --band-hero: clamp(2.25rem, 1.964rem + 1.429vw, 3.5rem); /* 36 -> 56 */
  --gutter:    clamp(1.25rem, .893rem + 1.786vw, 2.5rem);  /* 20 -> 40 */

  /* width tracks (R35, R36) */
  --w-hold:  1400px;   /* was 1200; Ethan 2026-09-03 on the render: "width issue". Content breathes wide (R35). */
  --w-prose: 68ch;

  --header-h: 68px;
  color-scheme: light;
}

/* =====================================================================
   2. RESET AND BASE
   ===================================================================== */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;
     background:linear-gradient(var(--ink) 50%,var(--ink-deep) 50%) center / 100% 300vh no-repeat fixed;
     background-color:var(--ink)}   /* overscroll: the header's ground at the top, the footer's at the foot */
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{
  margin:0;background:var(--paper);color:var(--read);
  font:400 var(--t-body)/1.6 var(--f-read);
  overflow-x:clip;min-height:100svh;display:flex;flex-direction:column;
}

main{flex:1 0 auto}
img{max-width:100%;display:block}
ul,ol{margin:0;padding:0;list-style:none}
h1,h2,h3,p,figure{margin:0}
a{color:inherit}
:focus-visible{outline:3px solid var(--blue-lift);outline-offset:3px}
.hold{width:100%;max-width:var(--w-hold);margin-inline:auto;padding-inline:var(--gutter)}
.prose{max-width:var(--w-prose)}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.skip{position:absolute;left:var(--gutter);top:-100px;z-index:20;background:var(--plate);color:var(--ink);display:inline-flex;align-items:center;min-height:44px;
      padding:.75rem 1rem;font:700 var(--t-small)/1 var(--f-read)}
.skip:focus{top:var(--s-3)}
/* the in-page jumps land under the header, not behind it */
#enquire,#enquire-again{scroll-margin-top:calc(var(--header-h) + var(--s-5))}

/* =====================================================================
   3. THE DEVICE VOCABULARY (spec section 2)
   ===================================================================== */

/* No.1 The Trace Rule: 48px of the ring's stroke in blue, the van's fine
   trace running out, a 45 degree jog, a junction dot. The page's one rule
   device; a tick, not a fence (R4), because only 48px of it is loud. */
.rule{display:flex;align-items:flex-end;width:100%;line-height:0}
.rule__bar{width:48px;height:var(--stroke);background:var(--blue);flex:none}
.rule__line{flex:1;height:1px;background:var(--hair-light);transform-origin:left center}
/* The terminal's own lead-in has to sit on the SAME ink centre as the line, or
   the trace steps down 1px where they meet and the rule reads as broken (Ethan
   2026-09-04, on a crop: "there is this broken shift"). It did, on all eight
   rules including the header's. The arithmetic, so nobody re-nudges it: the line
   is 1px tall and flex-end aligned, so its ink centre is 0.5px above the rule's
   bottom; the terminal's path starts at y=11.5 of a 12-unit viewBox drawn 1:1,
   which is 0.5px above ITS box's bottom. The two agree exactly when the boxes
   share a bottom edge, and the -1px margin that used to be here pushed the
   terminal down by precisely the 1px that was showing. */
.rule__end{flex:none;width:30px;height:12px;color:var(--ink)}
.flank .rule__line{background:var(--hair-dark)}
.flank .rule__end{color:var(--flank-read)}
.rule--short{max-width:300px}

/* No.3 The Rail: the van's service list. Tracked condensed caps with hairline
   separators. The one label register on the page (R7). */
.rail{
  font:700 var(--t-label)/1.2 var(--f-label);
  letter-spacing:.15em;text-transform:uppercase;
  display:flex;flex-wrap:wrap;align-items:center;gap:0;color:var(--quiet);
}
.rail>li{display:flex;align-items:center}
.rail>li+li::before{content:"";width:1px;height:.95em;flex:none;background:currentColor;opacity:.45;margin-inline:.85em}
.rail .i{width:15px;height:15px;margin-right:.45em}
.label{font:700 var(--t-label)/1.2 var(--f-label);letter-spacing:.15em;text-transform:uppercase;color:var(--quiet)}
.flank .label{color:var(--flank-quiet)}

/* No.4 The Cut: the bolt's notch through the letterforms. One corner, 45
   degrees. Two adjacent cuts face each other across a gutter (R58). */
.cut-br{clip-path:polygon(0 0,100% 0,100% calc(100% - 22px),calc(100% - 22px) 100%,0 100%)}
.cut-tr{clip-path:polygon(0 0,calc(100% - 22px) 0,100% 22px,100% 100%,0 100%)}
.cut-bl{clip-path:polygon(0 0,100% 0,100% 100%,22px 100%,0 calc(100% - 22px))}

/* No.5 The Action Plate: the flyer's phone plate. Carries the cut on its
   trailing corner and a 1px edge of its own fill darkened, so it reads as
   an object on the flank where blue is 2.8:1 against the ground. */
.act{
  display:inline-flex;align-items:center;justify-content:center;gap:.6em;
  background:var(--act-fill);color:var(--act-ink);border:1px solid var(--act-edge);
  padding:.95rem 1.5rem;min-height:52px;
  font:700 var(--t-label)/1 var(--f-label);letter-spacing:.13em;text-transform:uppercase;
  text-decoration:none;cursor:pointer;
  clip-path:polygon(0 0,100% 0,100% calc(100% - 16px),calc(100% - 16px) 100%,0 100%);
  transition:filter .18s ease;
}
.act:hover{background:var(--blue-ink);border-color:var(--blue-lift)}   /* the action DARKENS and its edge lifts, ruled by Ethan 2026-09-04 ("nav items hover needs to be better"): brightness(1.1) both read as nothing and took white on the fill from 4.96:1 to 3.67:1, under the floor for a 13px label. Darkening takes it to 6.5:1, so the state is louder AND more legible. */
.act:active{background:#12578B;border-color:#12578B}
/* the cut clips an outline, so the focus ring is inset where the clip cannot eat it */
.act:focus-visible{outline:none;box-shadow:inset 0 0 0 3px var(--act-ink),inset 0 0 0 5px var(--blue-lift)}
.act:disabled{cursor:progress;filter:saturate(.6)}
/* the block action flows its marker inline with the label, so when the locked
   copy wraps at 320 the mark stays after the last word instead of floating
   beside two centred lines */
.act--block{display:block;width:100%;min-height:58px;font-size:.8125rem;letter-spacing:.1em;line-height:1.3;text-align:center;padding-block:1.05rem}
.act--block .i{display:none;vertical-align:-4px;margin-left:.4em}   /* at 320 the locked label already wraps; the mark waits for phone-large */
.act .i{width:18px;height:18px}

/* No.6 The Phone Display: the van paints the number to be read from the far
   kerb, so it is display type wherever it appears, never a small link. */
.phone{
  display:inline-flex;align-items:center;gap:.55em;text-decoration:none;min-height:44px;
  font:700 var(--t-phone)/1 var(--f-display);letter-spacing:-.01em;color:var(--flank-read);
  transition:color .15s ease;position:relative;
}
.phone .i{width:1em;height:1em;color:var(--blue-lift);transition:color .15s ease}
/* the number answers a pointer with the Trace Rule's own bar drawn under it,
   ruled by Ethan 2026-09-04 ("nav items hover needs to be better"): D5D7DC to
   white alone was a step too small to see on display type. */
.phone::after{content:"";position:absolute;left:0;right:0;bottom:-2px;height:var(--stroke);background:var(--blue-lift);transform:scaleX(0);transform-origin:left center;transition:transform .18s cubic-bezier(.2,.7,.3,1)}
.phone:hover{color:#fff}
.phone:hover .i{color:#fff}
.phone:hover::after,.phone:focus-visible::after{transform:scaleX(1)}

/* No.7 The Marker: a bare Lucide glyph at 20px, inline before a fact. The
   sprite's symbols carry the 1.75 stroke themselves. 18px until 2026-09-04,
   raised on James Roberts's review ("these are really quite small... people's
   eyesight is never particularly good, particularly when it gets to my age"),
   which is the ICP's age on a homeowner page. */
.i{width:20px;height:20px;flex:none;color:inherit}

/* No.8 The Medallion Row: the recruitment poster's own device. The glyph in a
   disc, a short connector, the label. For rows a reader scans.

   FILLED AND ENLARGED 2026-09-04 on James's review, two findings in one device.
   It was a 46px hairline ring holding a 21px glyph in blue, which FILLED with
   the mark's blue on row hover. He read the fill as an affordance: "when they
   light up like that, people think they're clickable", and none of these rows
   is a link. Rather than lose the fill, the hover state became the RESTING
   state: a solid disc that never changes cannot promise a click, and it answers
   his other note ("I would double the size of them... I would use a more
   visible colour") in the same move. 62px disc, 28px glyph, no transition. */
.med{width:62px;height:62px;flex:none;border-radius:50%;
     background:var(--blue-ink);border:1px solid var(--blue-ink);
     display:grid;place-items:center;color:#fff}
.med .i{width:28px;height:28px}
.flank .med{background:var(--blue);border-color:var(--blue);color:#fff}
.row{display:flex;align-items:center}
.row__link{width:16px;height:1px;background:var(--hair-light);flex:none}
.flank .row__link{background:var(--hair-dark)}
.row__text{padding-left:.9rem;min-width:0}

/* THE GROUND OWNS THE QUIET INK, and a light plate standing on a dark ground
   puts it back. Fixed 2026-09-04 after the axe gate found the FOOTER's service
   rail at #5E616A on #181E2D, 2.7:1 and effectively unreadable, because the
   override had been written as `.flank .rail` and the footer is `.foot`, not
   `.flank`. That is the named-selector-list trap: the list looks complete in
   the source and only the render knows what it missed. Re-pointing the TOKEN on
   each dark ground means every device on it follows, including devices nobody
   has written yet. */
.flank,.foot,.chrome{--quiet:var(--flank-quiet)}
.plate{--quiet:var(--quiet-paper)}   /* the forms stand on white inside the hero flank */

/* No.9 The Flank and The Body: the van's two surfaces. */
.flank{background:var(--ink);color:var(--flank-read);position:relative;isolation:isolate}
.flank::after{
  content:"";position:absolute;inset:auto 0 14px 0;height:110px;pointer-events:none;z-index:-1;
  background:url(/assets/trace-band.svg?v=3) repeat-x left bottom;background-size:auto 110px;
  -webkit-mask-image:linear-gradient(transparent,#000 45%);mask-image:linear-gradient(transparent,#000 45%);
}
.flank h1,.flank h2,.flank h3{color:#fff}
.band{padding-block:var(--band)}
.band--paper{background:var(--paper)}
.band--plate{background:var(--plate)}

/* No.10 The Band Head: an h2 and one short Trace Rule. No eyebrow (R33). */
.head{display:grid;gap:var(--s-3);margin-bottom:var(--s-7)}
/* Centred, ruled by Ethan 2026-09-04 on the steps band ("How It Works - 3 Simple
   Steps center this both pages where relavant"), which is the mockups' own setting
   for that head. The Trace Rule keeps its whole construction and centres as a
   GROUP rather than collapsing to a bare bar: the device is the site's, used at
   eight seats, and a one-off variant of it would read as inconsistency (R17). */
.head--centre{justify-items:center;text-align:center}
.head--centre .rule{margin-inline:auto}
.head h2{font:700 var(--t-h2)/1.05 var(--f-display);letter-spacing:-.015em;color:var(--ink);text-wrap:balance}
.head .rule{margin-top:var(--s-2)}

/* No.11 The Ledger: like facts as marked, ruled rows. Ink, not boxes. */
.ledger{display:grid;grid-template-columns:1fr}
.ledger>li{display:flex;align-items:flex-start;padding-block:var(--s-5)}
.ledger>li+li{border-top:1px solid var(--hair-light)}
.ledger .med{margin-top:2px}
.ledger .row__link{margin-top:33px}   /* the connector meets the medallion's centre line: 2px offset + half of 62 */
.ledger h3{font:700 var(--t-h3)/1.25 var(--f-display);color:var(--ink);margin-bottom:.2rem}
.ledger p{color:var(--quiet);font-size:var(--t-small);text-wrap:pretty}

/* No.19 The Card, RULED BY ETHAN 2026-09-03 on the third render ("think this
   should be styled like cards"): the reasons a homeowner chooses HG as plates
   on the band, a hairline edge, the medallion on top, a heading and one line.
   The plate takes the band's other ground (paper on white, white on paper) so
   the edge is not doing all the work. Two across from 320, three from tablet,
   the five-set all across from desktop-large. */
.cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s-3)}   /* two across from 320 (R30): a set reads as a set; minmax(0) so a long word cannot widen one column */
.cards--5 .card:last-child{grid-column:1 / -1}   /* the odd fifth spans the row below tablet */
.card{background:var(--plate);border:1px solid var(--hair-light);padding:var(--s-4);display:grid;gap:var(--s-3);align-content:start;grid-template-rows:auto auto 1fr}
/* no hover edge: a card that answers a pointer promises a click it does not
   have (James Roberts, 2026-09-04, on the medallions; same defect on the card) */
.band--plate .card{background:var(--paper)}
.card h3{font:700 var(--t-h3)/1.25 var(--f-display);color:var(--ink)}
.card p{color:var(--quiet);font-size:var(--t-small);text-wrap:pretty}

/* No.12 The Form Plate: white, square, a blue bar across its top, the cut on
   its top-right. The one boxed thing besides a photograph. */
.plate{background:var(--plate);border:1px solid rgba(44,45,51,.10)}
.form{padding:var(--s-5);position:relative}
.form__top{display:block;height:var(--stroke);background:var(--blue);margin:calc(var(--s-5) * -1) calc(var(--s-5) * -1) var(--s-5)}
.form__title{font:700 var(--t-h3)/1.2 var(--f-display);color:var(--ink)}
.form__sub{font-size:var(--t-small);color:var(--quiet);margin-bottom:var(--s-4)}
.field{display:grid;gap:.25rem;margin-bottom:.625rem}
.field label{font:700 var(--t-label)/1 var(--f-label);letter-spacing:.13em;text-transform:uppercase;color:var(--quiet)}
.field input{
  font:400 1rem/1.4 var(--f-read);color:var(--ink);background:#F7F8F7;
  border:1px solid rgba(44,45,51,.16);padding:.7rem .8rem;min-height:48px;width:100%;
}
.field input{transition:border-color .15s ease,background-color .15s ease}
.field input:hover{border-color:rgba(44,45,51,.36)}
.field input:focus{background:#fff;border-color:var(--blue);outline:none}
.field input:focus-visible{outline:3px solid var(--blue-lift);outline-offset:2px}
.field.is-invalid input{border-color:var(--error)}
.field__error{font-size:var(--t-small);line-height:1.3;color:var(--error)}
.field__error:empty{display:none}
.form__note{display:flex;align-items:center;gap:.45em;font-size:var(--t-small);color:var(--quiet);margin-top:var(--s-3)}
.form__note .i{width:14px;height:14px}
.form__status{font-size:var(--t-small);color:var(--read);margin-top:var(--s-3)}
.form__status:empty{display:none}
.form__status.is-error{color:var(--error)}
.hp{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden}

/* No.14 The Frame: a photograph is cut, never rounded and never shadowed.
   The mark never sits on a photograph. */
.frame{position:relative;overflow:hidden;background:var(--ink-deep)}
.frame img{width:100%;height:100%;object-fit:cover}


/* No.13 The Quiet Quote: a plain plate whose ground is what separates it,
   Google's own amber for the stars, Roboto because it is the face the
   visitor saw the words in. */
.quote{background:var(--plate);padding:var(--s-5);display:grid;gap:var(--s-3);align-content:start;grid-template-rows:auto 1fr auto}
.band--plate .quote{background:var(--paper)}
.quote__foot{display:flex;align-items:center;justify-content:space-between;gap:var(--s-3)}   /* the reviewer's name, and Google's mark at the card's foot (Ethan 2026-09-04) */
/* Google's G in Google's four colours, ruled 2026-09-04 on James's review
   ("either make that G colour like the Google G"). It was monochrome at .7.
   The four paths are the mark's own four segments, so this is the real mark
   rather than a tint of it. */
.quote__src{width:20px;height:20px;flex:none}
.quote__src .g-blue{fill:#4285F4}
.quote__src .g-green{fill:#34A853}
.quote__src .g-amber{fill:#FBBC05}
.quote__src .g-red{fill:#EA4335}
/* The reviewer, ruled 2026-09-04 on James's review: he wanted the letter and
   picture avatars Google shows beside a review, "if Tracy's got a T and it's
   blue, put the T there in blue... then they subliminally realise" it is real.
   The LETTER is taken (it is the reviewer's own initial, already published
   beside their words); their PHOTOGRAPH is not, because republishing a private
   person's face on an advertisement is a different act from quoting them. */
.quote__who{display:flex;align-items:center;gap:.6rem;min-width:0}
.avatar{width:36px;height:36px;flex:none;border-radius:50%;display:grid;place-items:center;
        font:500 1.0625rem/1 var(--f-review);color:#fff;letter-spacing:0}
.avatar--red{background:#C5372C}
.avatar--blue{background:#1967D2}
.avatar--green{background:#0B7C43}
.avatar--amber{background:#A85A00}
.avatar--purple{background:#7B32BE}
.avatar--teal{background:#00707D}
.stars{display:flex;gap:2px;color:var(--amber)}
.stars .i{width:20px;height:20px}
.quote p{font:400 var(--t-small)/1.55 var(--f-review);color:var(--read)}
/* MY CALL, 2026-09-04, not ruled: the reviewer's name moves out of the site's
   tracked-caps label register into Roboto sentence case, which is how Google
   sets it. The band's whole job is to read as the surface the visitor saw these
   words on (James: "I usually use the font that Google uses for reviews, as
   this makes them more real"), and a Barlow Condensed caps name beside a Roboto
   avatar letter and a Roboto quote was the one thing left breaking that. Inside
   the ratified "Roboto on the review cards" rule rather than a departure from
   it, but it IS a register change on a device and reverses in one line. */
.quote cite{font:500 var(--t-small)/1.2 var(--f-review);font-style:normal;color:var(--ink);min-width:0}

/* No.20 The Listing Panel, ADDED 2026-09-04 on James Roberts's review: "I would
   put on the Google My Business... the H and G and the address and that, copy
   that to give it that flavour that it is the real deal, which obviously it
   is." It sits at the head of the reviews band and says where the words under
   it came from, which is the job the outbound "read more on Google" link used
   to do before he asked for it to go (a link off a landing page is a lost
   lead). Set in Roboto for the same reason the quote cards are: it is the face
   the visitor read these words in on Google.

   NO STREET ADDRESS, deliberately. HG is a service-area business and Google
   itself shows no address for one, so an address here would be a detail Google
   does not carry and nobody could check. The service area is what Google shows
   and what a homeowner is actually asking. */
.gbp{background:var(--plate);border:1px solid var(--hair-light);padding:var(--s-4) var(--s-5);
     display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:var(--s-4);
     margin-bottom:var(--s-6)}
.band--plate .gbp{background:var(--paper)}
/* the roundel is a silver ring and blue letters on TRANSPARENT (no ground of
   its own, which is why the header sets it on the dark chrome), so on a white
   panel it needs the ink disc under it or the ring disappears. contain, not
   cover: the mark is round and cover would shave it. */
.gbp__mark{width:56px;height:56px;flex:none;background:var(--ink);border-radius:50%;overflow:hidden}
.gbp__mark img{width:100%;height:100%;object-fit:contain;display:block}
.gbp__body{min-width:0}
.gbp__name{font:700 1.25rem/1.2 var(--f-display);color:var(--ink)}
.gbp__meta{font:400 var(--t-small)/1.4 var(--f-review);color:var(--quiet);margin-top:.1rem}
.gbp__rate{display:flex;align-items:center;flex-wrap:wrap;gap:.5rem;margin-top:.35rem}
.gbp__score{font:500 1.0625rem/1 var(--f-review);color:var(--ink)}
.gbp__count{font:400 var(--t-small)/1 var(--f-review);color:var(--quiet)}
.gbp__src{width:26px;height:26px;flex:none;align-self:start}
.gbp__src .g-blue{fill:#4285F4}
.gbp__src .g-green{fill:#34A853}
.gbp__src .g-amber{fill:#FBBC05}
.gbp__src .g-red{fill:#EA4335}
@media (max-width:559px){
  .gbp{grid-template-columns:auto 1fr;gap:var(--s-3) var(--s-4);padding:var(--s-4)}
  .gbp__src{grid-row:1;grid-column:2;justify-self:end}
  .gbp__body{grid-column:1 / -1}
}

/* No.21 The Rating Card, ADDED 2026-09-05. James Roberts, on the recorded
   round, read the space under the hero's claims as the place to prove the
   reviews; Ethan agreed and asked for a card there. It is No.20 compressed to
   the one thing a homeowner reads while deciding, in the same Roboto and with
   the same Google mark, for the same reason: it is the face they read these
   numbers in on Google.

   NOT A WHITE PLATE, deliberately. No.12 rules the form "the one boxed thing
   besides a photograph" on the flank, and a second white box beside it would
   fight the form for the eye at the exact moment the form is meant to win. So
   the card takes the flank's own ground with a hairline, and lets Google's
   mark and the amber do the saying.

   NO LINK, for James's own reason on the reviews band: a link off a landing
   page is a lost lead.

   The two numbers are Google's, read 2026-09-03. They appear here AND on the
   trust rail, so RE-READ BOTH at go-live; each carries a comment saying so. */
.rating{display:grid;grid-template-columns:auto minmax(0,1fr);
        grid-template-rows:auto auto;align-items:center;
        gap:var(--s-2) var(--s-4);border:1px solid var(--hair-dark);
        padding:var(--s-4) var(--s-5)}
/* `grid-row: 1 / -1` is a trap in an implicit grid: -1 names the last line of
   the EXPLICIT grid, and with no grid-template-rows that is line 1, so the
   span collapses and the count falls under the mark instead of beside it.
   Two explicit rows, and both body lines pinned to column 2. */
.rating__src{width:30px;height:30px;flex:none;grid-row:1 / span 2;align-self:center}
.rating__top,.rating__count{grid-column:2}
.rating__src .g-blue{fill:#4285F4}
.rating__src .g-green{fill:#34A853}
.rating__src .g-amber{fill:#FBBC05}
.rating__src .g-red{fill:#EA4335}
.rating__top{display:flex;align-items:center;flex-wrap:wrap;gap:.6rem}
.rating__score{font:500 1.75rem/1 var(--f-review);color:var(--flank-read)}
.rating__count{font:400 var(--t-small)/1.3 var(--f-review);color:var(--flank-quiet)}
/* the plate grounds re-point the ink, so the card can sit on paper unchanged
   if it is ever wanted below the fold */
.band .rating,.band--plate .rating{border-color:var(--hair-light)}
.band .rating__score,.band--plate .rating__score{color:var(--ink)}
.band .rating__count,.band--plate .rating__count{color:var(--quiet)}

/* No.15 The Brand Lockup */
.brand{display:flex;align-items:center;gap:.8rem;text-decoration:none;color:inherit;min-height:44px}
.brand__roundel{width:48px;height:auto;display:block;transition:filter .15s ease}   /* the roundel, the mark his own site wears (Ethan 2026-09-04) */
.brand:hover .brand__roundel{filter:brightness(1.15)}
.brand__rail{transition:color .15s ease}
.brand:hover .brand__rail{color:var(--flank-read)}   /* the lockup answers as a whole: the roundel lifts and the van's own service rail comes up out of the quiet grey */
.brand__name{font:700 1.0625rem/1 var(--f-display);letter-spacing:.03em;text-transform:uppercase;color:#fff;display:block}
.brand__rail{flex-wrap:nowrap;margin-top:.35rem}
.brand__words{display:none}

/* =====================================================================
   4. THE PAGE
   ===================================================================== */

/* ---- chrome ---- */
.chrome{background:var(--ink);color:var(--flank-read);position:sticky;top:0;z-index:5}   /* the number stays reachable the whole way down */
.chrome__in{display:flex;align-items:center;justify-content:space-between;gap:var(--s-4);min-height:var(--header-h);padding-block:.6rem;max-width:none}   /* the nav runs EDGE TO EDGE, ruled by Ethan 2026-09-04 ("nav full width"): it composes .hold for the gutter but drops the 1400px hold, which left 260px of dead ink each side of the bar at 1920 while the brand and the number sat in from the glass. Below 1480 nothing moves, the hold was never binding there. */
.chrome__acts{display:flex;align-items:center;gap:var(--s-4)}
.chrome__acts .act{display:none}
/* the header's bottom edge is the Trace Rule's blue segment, starting where
   every other mark on the page starts: the container's left edge. */
.chrome__edge{position:absolute;inset:auto 0 11px 0}   /* 11px UP, ruled by Ethan 2026-09-04 ("still cant see the wire in the nav bottom"). Pinned to the bar's bottom edge it was a 1px hairline sitting in the last row of dark ink, directly against the white content the sticky bar rides over, so the eye read the dark-to-white boundary and never the wire. Lifted, it has dark under it and reads as a trace inside the bar. Same diagnosis as No.9's band. */
.chrome__edge .rule{padding-inline:var(--gutter)}   /* the header's own rule tracks the bar it closes, so it runs full width with it */
/* the header is a flank too: the rule takes the flank's colours (the critic
   measured the first version painted in the paper colours on the dark ground,
   436 of 270,400 device pixels changing by one unit) */
.chrome .rule__line{background:var(--hair-dark)}
.chrome .rule__end{color:var(--flank-read)}
/* at rest the edge is the blue segment alone; once the page is scrolled the
   trace draws across the track and lands on its dot, the same one motion */
.chrome__edge .rule__line{transform:scaleX(0)}
.chrome__edge .rule__end{opacity:0}
.chrome.is-stuck .chrome__edge .rule__line{transform:scaleX(1)}
.chrome.is-stuck .chrome__edge .rule__end{opacity:1}

/* ---- hero ---- */
.hero{padding-top:var(--band-hero);padding-bottom:0;overflow-x:clip}   /* Cam stands on the flank's floor; the copy carries its own room below */

/* No.22 The Place Backdrop, ADDED 2026-09-05 on Ethan's ask for "a sort of
   image ish style hero like the mockups". The town Cam works in, standing
   behind him, dissolving into the flank before it reaches the copy.

   IT IS A REAL PHOTOGRAPH OF WHANGANUI, replaced 2026-09-05 (Ethan, on being
   shown three heroes side by side: "B cost in the footer is worth it"). The
   generated stand-in it replaces was 1584x672, which covered a desktop panel
   at well under 1x and only survived because a backdrop is veiled. This is the
   view over the town from Durie Hill, 4272x2848 at source:

       Whanganui River to Dublin Street Bridge
       Ang Wickham, 2009, via Wikimedia Commons
       CC BY 2.0, https://creativecommons.org/licenses/by/2.0
       ATTRIBUTION IS REQUIRED and it is the line in the footer. Do not
       remove that line while this photograph is on the page.

   Checked against the fleet's third-party identifier rule before shipping: at
   full magnification on the closest vehicles no plate is legible at any scale,
   and there is no identifiable person in the frame.

   TWO SIZES, because the two shapes need very different amounts of picture:
   the phone band is a fraction of the desktop panel, so it takes the 1000px
   file (88 KB) and the desktop rule below takes the 2400px one (261 KB).

   The veil is part of the device, not a fix applied to it: the copy column
   must never sit on a photograph, so the gradient is opaque ink where the
   words are and only opens up under Cam. */
.hero::before{
  content:"";position:absolute;z-index:-2;pointer-events:none;
  background-repeat:no-repeat;background-position:center;background-size:cover;
  background-image:
    linear-gradient(to bottom, var(--ink) 0%, rgba(44,45,51,.92) 26%, rgba(44,45,51,.62) 100%),
    image-set(url(/assets/img/hero-scene-whanganui-sm.webp?v=1) type("image/webp"),
              url(/assets/img/hero-scene-whanganui-sm.jpg?v=1) type("image/jpeg"));
  /* PHONE AND TABLET: the copy runs the full width, so there is no side for a
     panel. The place sits UNDER the copy and behind Cam, who stands at the
     bottom of the hero, and fades upward before it reaches the words. A strip
     down one edge is what this device looked like before the vertical form
     existed, and it read as a leak rather than a decision. */
  inset:auto 0 0 0;height:62%;
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 42%);
          mask-image:linear-gradient(to bottom,transparent 0,#000 42%);
}
.hero__head{display:grid;gap:var(--s-3);margin-bottom:var(--s-4)}
.hero h1{font:700 var(--t-h1)/1.02 var(--f-display);letter-spacing:-.022em;color:#fff;text-wrap:balance}   /* uncapped below desktop: the track is the measure (R28) */
.hero__lede{font:400 var(--t-lede)/1.4 var(--f-read);color:var(--flank-read);max-width:46ch;margin-bottom:var(--s-4);text-wrap:pretty}
.hero__grid{display:grid;gap:var(--s-6)}
/* R30, mobile is grammar: on a phone the form comes before the claims, so the
   action is on the first screen; from tablet the reading order is the
   composed one: what you get, then the ask. */
.hero__copy{display:flex;flex-direction:column;position:relative}
.hero__aside{display:flex;flex-direction:column;gap:var(--s-4)}
.hero__copy .hero__lede{order:1}
.hero__copy .form{order:2}
.hero__copy .hero__aside{order:3;margin-top:var(--s-5)}
.claims{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-4)}
.claims li{display:flex;gap:.6rem;align-items:flex-start;font-size:var(--t-small);color:var(--flank-read);line-height:1.35}
.claims .i{color:var(--blue-lift);margin-top:1px}
/* No.17 The Cutout and No.18 The Pointer, RULED BACK IN BY ETHAN 2026-09-03
   on the second render: "i liked the arrow things from the mock and the fact
   cam was sort of transparent". Cam stands on the flank's floor with no frame,
   a labelled pointer above his shoulder, and a drawn pointer leads the eye
   from the claims to the form (hero) and from the phone line to the form
   (close). The pointers take the lifted blue, the action's own colour, so an
   arrow and the thing it points at read as one idea. */
.hero__figure{display:flex;flex-direction:column;align-items:center;margin-top:var(--s-5)}   /* 5.9rem until 2026-09-04, all of it room for a label that hung ABOVE his head. The label is now drawn ON him (below), so the figure takes the ordinary gap. Desktop resets this to 0. */
.hero__stand{position:relative;width:min(82%, 26rem);margin-top:auto;container-type:inline-size}   /* Cam and his label ride one stand, so the label is anchored to him, not to the column. The stand is a CONTAINER: the label is a device drawn on the photograph, so its type and its hook scale with the photograph (cqw) instead of drifting against it as the column changes width. */
.hero__cutout{width:100%;height:auto;display:block;filter:drop-shadow(0 18px 24px rgba(0,0,0,.35))}
.hand{font:600 1.5rem/1.15 var(--f-hand);color:var(--blue-lift);white-space:nowrap;display:block;transform:rotate(-5deg);transform-origin:left bottom}   /* a note in handwriting, the first build's device. line-height carries the two-line closing note */
/* THE LABEL SITS BESIDE HIM, NOT ABOVE HIM, ruled by Ethan 2026-09-04 on a crop
   ("the text and arrow is in the wrong place and not pointing at the photo").
   Traced off the residential mockup rather than recalled: its words sit to the
   RIGHT of Cam's head at face height, and the hook falls from under their right
   end, curling down-LEFT onto his shoulder. Every previous pass had the words
   above his crown and to his LEFT, so a hook drawn with the mockup's own
   down-left handedness could only point away from him, into empty ground.
   Measured against the cutout's alpha, not its box (silhouette sampled per
   column): the head spans x 11-45% of the stand, so the words start at 55% and
   clear it by a tenth of his width; the hook's head lands at 60% of the width,
   on his shoulder, standing 13 to 25px clear of it at every stand width from
   230 to 544px. The words end between 82% and 99% of the stand, so they never
   leave it. Geometry in cqw and em so all of that holds by construction.
   The gap was 48% and 3% of his width until Ethan read it on a crop the same
   day ("too close to him"), which is the mockup's own gap and too tight once
   the words are set beside a face rather than a turned head. */
/* The label is drawn ON him, so its offsets are tuned to the CUTOUT and not
   to the column. MOVED 55% -> 64% on 2026-09-05 when the cutout was
   replaced: the old figure sat further left in its own frame, so 55%
   cleared his face; on the new one it landed on his cheek. Measured, not
   eyeballed (head ends at 61% of the stand, the words now start at 64%).
   RE-MEASURE THIS WHENEVER THE CUTOUT CHANGES. */
/* THE LABEL SITS TO HIS LEFT NOW, and the hook turns with it. Ethan's
   2026-09-04 ruling put the words to his upper-RIGHT with the hook falling
   down-left onto him, and that was correct for the OLD cutout, which sat left
   in its own frame with room beside it. The 2026-09-05 cutout is centred and
   the stand is cropped at the viewport edge on purpose, so there is no room on
   that side: measured across 1024, 1280, 1440 and 1920, the words landed on his
   cheek and shoulder every time and ran past the right edge at 1280.
   The same measurement says the LEFT side works at every one of those widths:
   the gap between the form's right edge and his head is 177 to 229px and the
   label is 109 to 148 wide. So the box is pinned to the left of his head (his
   head starts at 33% of the stand; the label ends at 31%) and the hook is
   mirrored so it still falls ONTO him rather than away.
   RE-MEASURE ALL OF THIS WHENEVER THE CUTOUT CHANGES. */
.hero__label{position:absolute;top:29.3cqw;left:auto;right:69%;display:grid;gap:.06em;justify-items:end;text-align:right;pointer-events:none;font-size:clamp(1.4rem, 6cqw, 2.05rem)}
.hero__label .hand{font-size:inherit}   /* the label's own size, so the hook (em) and the words cannot drift apart */
.hero__label .arrow{width:1.35em;height:1.35em;margin-right:.6em;transform:scaleX(-1)}   /* #arrow-label is drawn pointing down-LEFT, which was the handedness Ethan ruled on 2026-09-04 when the words sat to his right. The words are on his left now (above), so the hook is mirrored to fall down-RIGHT onto him. Same rule, mirrored situation, not a reversal of it. */
@container (max-width: 372px){
  /* below this the type stops shrinking with him (the clamp's floor holds it
     readable), so the device is relatively larger and has to start higher or
     its head lands in his shoulder. 13 to 16px clear at 230 to 372px. */
  .hero__label{top:calc(52.1cqw - 5.18rem)}
}
.arrow{display:block;color:var(--blue-lift)}
.draw path{stroke-dasharray:180;stroke-dashoffset:0}
/* the claims-to-form pointer is a zero-height row between the two: it draws
   over the claims' right edge and lands its head on the form's cut corner */
/* a pointer comes from a few words and lands on the thing (Ethan 2026-09-04:
   "make sure the arrows point at something meaningful with text"), in the
   handwriting of the first build. Heads stop a finger's width short. */
/* THE SHAPE IS THE MOCKUPS' (Ethan 2026-09-04: "can we have the arrows sort of
   poiting in the shape of the original mockups"). Traced off the Kingfisher PNGs
   rather than recalled: both of their form pointers leave going DOWN, flatten,
   and enter the plate travelling HORIZONTALLY RIGHT under an open chevron. One
   shape, used twice. Measured on the residential mockup: the hero pointer is
   43x40 of an 809px render (about 76x70 of ours), the head stopping 13 mockup px
   (about 23 of ours) short of the plate. The head entering square-on is the part
   that reads; the previous build's heads came in diagonally.
   viewBox 100x96 at 0.8: the tip sits at (73.6, 17.6) of an 80x76.8 box when the
   hook rises, and at (73.6, 59.2) when it falls. */
.note{display:none;pointer-events:none}
.note--hero{position:relative;z-index:1;align-self:flex-end;justify-content:flex-end;align-items:flex-start;gap:.5rem;margin:0 2rem 0 0}
.note--hero .arrow{width:5rem;height:4.8rem;transform:rotate(40deg) scaleY(-1);margin-top:-.6rem}   /* below desktop-large the note sits ABOVE the form, so the mockups' falling hook is turned to come down onto the plate's top edge */
.close__copy{position:relative}
/* Pinned to the copy column's BOTTOM, not centred on it. Centred put the words
   straight through the h2's second line at every desktop width on the repair page
   and from 1024 to 1344 on the residential one (Ethan 2026-09-04, "overlapping?").
   The bottom is the only edge that holds: the h2 growing a line pushes the whole
   column down and the clearance is preserved, where a percentage moves the words
   INTO the heading. The words take two lines so they fit the free ground to the
   right of the contact rows, which is what made the one-line version too wide.
   The head then lands about 80% down the form, on the action, which is where the
   mockup's own closing pointer lands. */
.note--close{position:absolute;right:-1.55rem;bottom:0;flex-direction:column;align-items:flex-end;gap:.15rem}   /* measured: the head stops 14px short of the form's left edge, the same finger's width the hero hook keeps; landing inside it is painted over by the plate */
.note--close .arrow{width:5rem;height:4.8rem;transform:none;margin-right:-2.475rem}   /* the mockups' falling hook, unturned: the words sit above it and it enters the plate square-on, which is exactly the mockup's own closing pointer */

/* ---- trust rail: the van's service list on the first light band. The two
   third-party badges carry their own grounds and were drawn for white. ---- */
/* ENLARGED 2026-09-04 on James Roberts's review. The rail was already the
   second thing on the page and he still missed it: "I didn't see that hazard
   one until I got right to the bottom and I thought, oh, that should be at the
   top and then I went back up to the top and I found that. So I'd double the
   size of that and just open it up a bit more." So the fault was never the
   POSITION, it was that a 40px mark under a 13px label reads as a footer
   ornament. Every mark and both glyph sets are roughly doubled and the band
   carries more air. */
.trust{background:var(--plate);padding-block:var(--s-7)}
.trust ul{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-7) 0}
/* space-between, not a plain stack: the rating item carries a THIRD line (the
   score) that the other three do not, so a top-packed column would drop its
   label 44px below its peers': four things that claim to be alike, unevenly
   set (R11). Marks pin to the top, labels to the bottom, and the score floats
   in the rating item's own slack. */
/* min-width:0 because a grid track's automatic minimum is min-content, and
   the Google mark's min-content (the G, the score and five stars in a row)
   is wider than a 1fr track at 375, which pushed the whole grid 29px past
   the viewport. The mark wraps instead, so the stars drop under the score
   on a small phone rather than the page scrolling sideways. */
.trust li{display:flex;flex-direction:column;justify-content:space-between;align-items:center;text-align:center;gap:1rem;padding-inline:var(--s-4);position:relative;min-width:0}
.trust li+li::before{content:"";position:absolute;left:0;top:4px;bottom:4px;width:1px;background:var(--hair-light)}
.trust li:nth-child(3)::before{display:none}
/* THE MARKS READ EVENLY (R11), which is a SIZE question and not a height one.
   Measured at 1440 before this: the four marks carried 265, 118, 138 and 44
   pixels of ink inside cells all about 290 wide, so a wordmark strip ran away
   with the row while a lone glyph disappeared. Ethan 2026-09-05: "whangnui
   buiness is too small relative to space", "licenses and insurfed logo needs
   to take up its space".
   So the mark is one fixed box every mark fills to its own shape: 88 tall,
   capped in width so the wide strip cannot dominate. */
.trust .mark{height:88px;width:100%;max-width:15rem;min-width:0;display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:.4rem .7rem}
.trust img{max-height:88px;width:auto;max-width:100%;object-fit:contain}
.trust .mark--ink{background:var(--ink);padding:0 1.35rem;max-width:17rem}   /* the HazardCo mark is white on transparent, drawn for a dark ground */
.trust .mark--ink img{max-height:38px}
/* a glyph is a drawing, not a lockup, so it carries its optical weight at a
   smaller box than a wordmark needs: 68 reads level with an 88-tall mark. */
.trust .mark--glyph>.i{width:68px;height:68px;color:var(--blue-ink)}
/* Google's own summary, the same construction as the hero's Rating Card
   (No.21), because Ethan asked for this one to be "the one like hero". The
   COUNT is deliberately not repeated here: it is on the card above the fold
   and on the Listing Panel at the head of the reviews band, and a third
   printing in a rail whose peers are one mark plus one label would break the
   even set this block was just fixed for. */
.trust__g{width:42px;height:42px;flex:none}
.trust__g .g-blue{fill:#4285F4}
.trust__g .g-green{fill:#34A853}
.trust__g .g-amber{fill:#FBBC05}
.trust__g .g-red{fill:#EA4335}
.trust__score{font:500 2rem/1 var(--f-review);color:var(--ink)}
.trust span:not(.mark):not(.stars):not(.trust__score){font:700 1rem/1.35 var(--f-label);letter-spacing:.11em;text-transform:uppercase;color:var(--read)}
.trust .stars{gap:1px}
.trust .stars .i{width:24px;height:24px}
/* the rating mark carries the NUMBER, not just five stars: James asked for the
   accumulated count at the top ("you can get like a button where it gives an
   accumulation of the reviews"). 5.0 and the count are Google's own figures. */

/* ---- meet Cam: a cut frame and the copy beside it ---- */
.meet{display:grid;gap:var(--s-6);align-items:center}
/* Meet Cam takes the CUTOUT on the band's own ground, no Frame (Ethan
   2026-09-05: "just the cutout on the bg done it such a way there are no hard
   cuts"). Two things follow from having no box. The paper is his ground, so
   nothing is cut and nothing is shadowed, which is what No.14 was protecting
   in the first place. And the file's bottom edge WOULD be a hard cut, since
   the photograph stops just under his hands, so the last stretch is masked
   out and he fades into the band instead of being sliced by it. */
.meet__figure{display:flex;justify-content:center}
.meet__cutout{width:100%;max-width:26rem;height:auto;display:block;
  -webkit-mask-image:linear-gradient(to bottom,#000 82%,rgba(0,0,0,.5) 93%,transparent 100%);
          mask-image:linear-gradient(to bottom,#000 82%,rgba(0,0,0,.5) 93%,transparent 100%)}
.meet .head{margin-bottom:var(--s-5)}
.meet p{text-wrap:pretty}
.meet p+p{margin-top:var(--s-4)}
.meet .rail{margin-top:var(--s-5);color:var(--blue-ink)}

/* ---- how it works: three Medallion Rows joined by the trace. On the
   narrowest phones a column with the trace running down; from phone-large
   3-across with the trace running between, which is R30's across-feel. ---- */
.steps{display:grid;gap:var(--s-6)}
.step{position:relative;display:flex;gap:0;align-items:flex-start}
.step .row__link{margin-top:23px}
.step .rail{margin-bottom:.35rem}
.step h3{font:700 var(--t-h3)/1.25 var(--f-display);color:var(--ink);margin-bottom:.2rem}
.step p{color:var(--quiet);font-size:var(--t-small);text-wrap:pretty}
.step:not(:last-child)::after{content:"";position:absolute;left:23px;top:54px;bottom:calc(var(--s-6) * -1 + 8px);width:1px;background:var(--hair-light)}

/* ---- FAQ: ruled rows, two independent stacks from tablet ---- */
.faq{display:grid;gap:0 var(--s-7)}
.faq__col{display:grid;align-content:start}
.faq details{border-top:1px solid var(--hair-light)}
.faq__col details:last-child{border-bottom:1px solid var(--hair-light)}
.faq summary{
  display:flex;align-items:center;justify-content:space-between;gap:var(--s-4);
  padding-block:var(--s-4);min-height:44px;cursor:pointer;list-style:none;
  font:600 1.125rem/1.35 var(--f-display);color:var(--ink);
}
.faq summary::-webkit-details-marker{display:none}
.faq summary .i{color:var(--blue-ink);transition:transform .2s ease}
.faq details[open] summary .i{transform:rotate(180deg)}
.faq summary{transition:color .15s ease}
.faq summary:hover{color:var(--blue-ink)}
.faq summary:hover .i{transform:translateY(2px)}
.faq details[open] summary:hover .i{transform:rotate(180deg) translateY(2px)}
.faq__body{padding-bottom:var(--s-5);color:var(--read);max-width:var(--w-prose);text-wrap:pretty}
.faq details.is-animating .faq__body{overflow:hidden}
.faq__body a{color:var(--blue-ink);font-weight:600;padding-block:.75rem;margin-block:-.75rem;text-underline-offset:4px;transition:text-decoration-thickness .15s ease}
.faq__body a:hover{text-decoration-thickness:2px}  /* an inline link's padding is its hit area and moves no line */

/* ---- close ---- */
.close{padding-block:var(--band)}
.close__grid{display:grid;gap:var(--s-7)}
.close h2{font:700 var(--t-h2)/1.05 var(--f-display);letter-spacing:-.015em;text-wrap:balance;margin-block:var(--s-3)}
.close__lines{display:grid;gap:var(--s-4);margin-top:var(--s-6)}
.close__lines strong{display:block;font:700 var(--t-label)/1 var(--f-label);letter-spacing:.13em;text-transform:uppercase;color:var(--flank-quiet);margin-bottom:.35rem}
.close__lines .big{font:700 var(--t-phone)/1 var(--f-display);color:#fff;text-decoration:none;display:inline-flex;align-items:center;min-height:44px;transition:color .15s ease}
.close__lines .big:hover{color:var(--blue-lift)}
.close__lines .small{font-size:var(--t-small);color:var(--flank-read)}

/* ---- reviews ---- */
.quotes{display:grid;gap:var(--s-4);grid-template-columns:1fr}
/* The outbound "read more reviews on Google" link and its .more device are GONE,
   2026-09-04, on James Roberts's review: "I would take this link away because we
   don't want them checking out the reviews, that takes them off the page and we
   don't want to do that." Nothing else on either page used the device, so the
   rules go with it rather than sitting here unreachable. The listing panel
   (No.20) now carries the provenance the link was carrying. */

/* ---- footer: the deep flank, three bands (R30: convert, orient, reassure) ---- */
.foot{background:var(--ink-deep);color:var(--flank-read)}
.foot__top{padding-block:var(--s-7);display:grid;gap:var(--s-6);text-align:center;justify-items:center}
.foot__top .brand{flex-direction:column;gap:.6rem}
.foot__top .brand__roundel{width:64px}
.foot__top .brand__words{display:block}
.foot__top .brand__rail{justify-content:center}
.foot__top .phone{color:#fff}
.foot__mid{border-top:1px solid var(--hair-dark);padding-block:var(--s-6);display:grid;grid-template-columns:1fr 1fr;gap:var(--s-6) var(--s-5)}
.foot__col h3{font:700 var(--t-label)/1 var(--f-label);letter-spacing:.15em;text-transform:uppercase;color:#fff}
.foot__col ul{display:grid;gap:.15rem;margin-top:var(--s-3)}
.foot__col li{display:flex;align-items:center;gap:.55rem;font-size:var(--t-small);color:var(--flank-quiet);min-height:44px}
.foot__col li a{display:inline-flex;align-items:center;min-height:44px}
.foot__col .i{color:var(--blue-lift)}
.foot__col:last-child{grid-column:1 / -1}   /* the odd third column spans the phone's two, its links side by side */
.foot__col:last-child ul{grid-template-columns:auto auto;justify-content:start;gap:.15rem var(--s-6)}
.foot a{text-decoration:none;transition:color .15s ease;text-underline-offset:5px;text-decoration-thickness:1px}
.foot a:hover{color:#fff;text-decoration:underline}
.foot__badges{display:flex;gap:var(--s-5);align-items:center;justify-content:center;flex-wrap:wrap}
.foot__badges img{height:20px;width:auto}
.foot__badges .foot__badge--tall{height:48px;background:#fff;padding:2px}
.foot__bottom{border-top:1px solid var(--hair-dark);padding-block:var(--s-5);display:grid;gap:var(--s-4);justify-items:center;text-align:center}
.foot__legal{font-size:var(--t-small);color:var(--flank-quiet);display:flex;flex-wrap:wrap;gap:.35rem var(--s-4);align-items:center;justify-content:center}
.foot__legal a{display:inline-flex;align-items:center;min-height:44px}
/* The photograph credit. It is a LICENCE OBLIGATION, not a courtesy: the hero
   backdrop is CC BY 2.0 and attribution is a condition of using it, so this
   line stays as long as that photograph is on the page (No.22 names it). Set a
   step quieter than the rest of the legal line, because it is owed to a
   stranger rather than said to the reader, and its links inherit the line's
   own 44px target so it does not become a tap hazard on a phone. */
.foot__credit{color:var(--flank-quiet);opacity:.8}
/* the links KEEP the legal line's 44px target. The first cut set min-height:0
   to make the credit sit tighter and the responsive gate failed every one of
   the twelve viewports on the tap-target floor, which is exactly what that
   floor is for. Tidy is not a reason to shrink a target. */
.foot__credit a{text-decoration:underline;text-underline-offset:2px}
.foot--thin .foot__bottom{border-top:0}

/* ---- the thank-you page ---- */
.thanks{padding-block:var(--band)}
.thanks__in{display:grid;gap:var(--s-4);justify-items:start}
.thanks .rail{color:var(--blue-lift)}
.thanks h1{font:700 var(--t-h1)/1.02 var(--f-display);letter-spacing:-.022em;color:#fff;text-wrap:balance}
.thanks p{font:400 var(--t-lede)/1.4 var(--f-read);color:var(--flank-read);text-wrap:pretty;max-width:44rem}
.thanks p a{color:#fff;font-weight:700;white-space:nowrap;padding-block:.75rem;margin-block:-.75rem;text-underline-offset:5px;transition:color .15s ease}
.thanks p a:hover{color:var(--blue-lift)}
.thanks .act{margin-top:var(--s-4)}

/* =====================================================================
   5. TIERS: phone 320 base, phone-large 400, tablet 768, desktop 1024,
      desktop-large 1280. Collapse grammar per R30.
   ===================================================================== */
@media (min-width:25rem){                    /* phone-large */
  .act--block{font-size:.875rem;letter-spacing:.13em}
  .act--block .i{display:inline-block}
  .cards{gap:var(--s-4)}
  .card{padding:var(--s-5)}
  .steps{grid-template-columns:repeat(3,1fr);gap:var(--s-5);--steps-gap:var(--s-5)}
  .step{flex-direction:column;align-items:center;text-align:center;gap:var(--s-3)}   /* centred in its cell (Ethan 2026-09-04) */
  .step .row__link{display:none}
  .step .row__text{padding-left:0}
  .step .rail{justify-content:center}
  /* the trace runs centre to centre, stopping 8px short of each medallion */
  .step:not(:last-child)::after{left:calc(50% + 31px);top:23px;bottom:auto;height:1px;width:auto;right:calc(-50% - var(--steps-gap) + 31px)}
}
@media (min-width:48rem){                    /* tablet */
  .foot__top{grid-template-columns:auto auto;justify-content:space-between;text-align:left;justify-items:start;align-items:center}
  .foot__top .brand{flex-direction:row}
  .foot__top .brand__rail{justify-content:flex-start}
  .foot__mid{grid-template-columns:repeat(3,auto);justify-content:space-between;gap:var(--s-6) var(--s-7)}
  .foot__col:last-child{grid-column:auto}
  .foot__col:last-child ul{grid-template-columns:none}
  .foot__bottom{grid-template-columns:auto auto;justify-content:space-between;text-align:left;justify-items:start}
  .chrome__acts .act{display:inline-flex}
  .brand__words{display:block}
  .trust ul{display:flex;justify-content:space-between;gap:var(--s-7)}
  .trust li{flex:0 1 auto;padding-inline:0}
  .trust li:nth-child(3)::before{display:block}
  .trust li+li::before{left:calc(var(--s-7) / -2)}   /* the tick sits in the ink gutter, not on a box edge (R2) */
  .ledger{grid-template-columns:1fr 1fr;column-gap:var(--s-7)}
  .ledger>li:nth-child(2){border-top:0}
  .quotes{grid-template-columns:1fr 1fr}
  .claims{gap:var(--s-4) var(--s-6)}
  .hero__copy .hero__aside{order:1;margin:0 0 var(--s-5)}
  .hero__copy .form{order:2}
  .hand{font-size:1.75rem}
  .meet{grid-template-columns:5fr 7fr;gap:var(--s-8)}
  .meet__figure .frame{max-width:none;aspect-ratio:4/5}   /* portrait, Ethan 2026-09-04: "image should be taller" */
  .meet{grid-template-columns:4fr 8fr}
  .steps{gap:var(--s-7);--steps-gap:var(--s-7)}
  .faq{grid-template-columns:1fr 1fr}
  .cards{grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s-5)}
  .close__grid{grid-template-columns:1fr 1fr;align-items:center;gap:var(--s-8)}
}
@media (min-width:64rem){                    /* desktop */
  /* DESKTOP: the copy and the form take the left, Cam takes the right, so the
     place becomes a panel behind him and dissolves before the reading column.
     Opaque ink where the words are is the point: the copy column never sits on
     a photograph. */
  /* WIDER, AND THE HANDOVER SITS ACROSS THE FORM (Ethan 2026-09-05: "just
     want more image ... the transition to it more like maybe middle of the
     form"). Measured at 1440: the copy column ends at x=560 and the form runs
     615 to 1145, so a panel starting at x=374 paints nothing until about
     x=650 and is open by about x=1000. The copy still never sits on a
     photograph, which is the line that does not move. */
  .hero::before{inset:0 0 0 auto;width:min(74%,74rem);height:auto;
    background-image:
      linear-gradient(to right, var(--ink) 0%, rgba(44,45,51,.92) 18%, rgba(44,45,51,.55) 44%, rgba(44,45,51,.38) 100%),
      image-set(url(/assets/img/hero-scene-whanganui.webp?v=2) type("image/webp"),
                url(/assets/img/hero-scene-whanganui.jpg?v=2) type("image/jpeg"));
    -webkit-mask-image:linear-gradient(to right,transparent 0,#000 26%);
            mask-image:linear-gradient(to right,transparent 0,#000 26%)}
  :root{--header-h:88px}
  .hero__grid{grid-template-columns:minmax(0,15fr) minmax(0,9fr);align-items:stretch;gap:var(--s-8)}
  .hero__head{margin-bottom:var(--s-6)}
  .hero h1{max-width:24ch}   /* two lines at 70px, composed rather than wrapped (R34) */
  .close h2{max-width:24ch}
  .hero__copy{padding-bottom:var(--band)}
  .hero__figure{margin-top:0;align-items:flex-end}
  .hero__stand{width:min(120%, 34rem);margin-right:-2.5rem}   /* a little wider than the column, cropped at the edge as the mockups crop him */
  .note{display:flex}
  .hand{font-size:2rem}
  .quotes{grid-template-columns:repeat(3,1fr)}
  .chrome__in{min-height:var(--header-h)}
  .brand__roundel{width:56px}
}
@media (min-width:80rem){                    /* desktop-large */
  .hero__grid{gap:calc(var(--s-8) * 1.3)}
  .meet{gap:calc(var(--s-8) * 1.3)}
  /* the mockups' composition: the claims beside the form, the note hanging off the
     claims' bottom-right with its arrow crossing the gutter onto the form's edge */
  .hero__copy{display:grid;grid-template-columns:minmax(0,1fr) 24rem;grid-template-areas:'lede lede' 'aside form';column-gap:2.5rem;align-items:start}
  .hero__copy .hero__lede{grid-area:lede;max-width:none}
  .hero__copy .hero__aside{grid-area:aside;align-self:start;margin:0;gap:var(--s-5);position:relative}   /* the claims stay attached to the lede; the slack below is Cam standing taller than the copy, which is the mockups' own look. Position: the hook below is pinned to this box's TOP edge, which is the form's top edge (align-items:start), so the hook's target does not move when the claims change length. */
  .hero__copy .claims{grid-template-columns:1fr;gap:1.4rem;margin:0}
  .hero__copy .claims li{font-size:var(--t-body)}
  .hero__copy .form{grid-area:form}
  /* "Start here" has to land on the START of the form, and it was landing on the
     EMAIL field: the hook rode the note's flow position under the claims, which
     is 233px down the form (Ethan 2026-09-04, "issue with overlapping / position
     of arrows"). So the WORDS stay in flow under the claims and the HOOK is
     pinned to the aside's top instead, where the first field is: measured, the
     Name input's centre is a constant 134px below the form's top at every
     desktop width, and the gutter is 40px. My call, not ruled: the head stops
     14px short of the plate, the finger's width the close note already keeps. */
  .note--hero{position:static;height:auto;margin:0 4rem 0 0;flex-direction:column;align-items:flex-end;gap:.1rem}
  .note--hero .arrow{position:absolute;top:7.28rem;right:-2.03rem;width:5rem;height:4.8rem;margin:0;transform:none}   /* the mockups' hook mirrored to rise: the tip sits at (73.6, 17.6) of the box, so these two offsets land it 14px left of the plate on the Name input's centre line, entering horizontally as the mockup's does */
  .cards--5{grid-template-columns:repeat(5,minmax(0,1fr))}
  .cards--5 .card:last-child{grid-column:auto}
}

/* =====================================================================
   6. MOTION. One moment: the trace draws itself (spec No.16). The start
      state is applied per rule by app.js, only to a rule below the fold
      when the page arms; a rule already on screen is never hidden.
   ===================================================================== */
@media (prefers-reduced-motion:no-preference){
  .chrome__edge .rule__line{transition:transform .46s cubic-bezier(.2,.7,.3,1)}
  .chrome__edge .rule__end{transition:opacity .2s ease}
  .chrome.is-stuck .chrome__edge .rule__end{transition-delay:.4s}
  .draw.is-pending path{stroke-dashoffset:180}
  .draw.is-in path{stroke-dashoffset:0;transition:stroke-dashoffset .6s ease-out}
  .draw.is-in path+path{transition-delay:.42s}
  .rule.is-pending .rule__line{transform:scaleX(0)}
  .rule.is-pending .rule__end{opacity:0}
  .rule.is-in .rule__line{transform:scaleX(1);transition:transform .46s cubic-bezier(.2,.7,.3,1)}
  .rule.is-in .rule__end{opacity:1;transition:opacity .2s ease .42s}
}
