/* ============================================================
   K2KONNECT ELECTRICAL
   Visual system: the site as an AS/NZS 3000 electrical drawing.
   Cool paper, blueprint linework, one hue: the logo blue. Red is emergency only.
   Golden Marketing, Aug 2026. See DESIGN.md at repo root.
   ============================================================ */

/* ONE HUE. The logo is two inks, so the site is two inks.
   Everything below sits on hue 240, the logo's own blue, including the paper and the
   text. The only exception is --isolate, which is confined to the emergency page.

   This replaced a seven-hue palette (warm paper 85, neutral ink 286, blue 240, gold 78
   and 66, green 152, red 27) that had accumulated around a two-colour logo. Gold and
   green are gone. Do not reintroduce a second accent: if something needs emphasis, use
   lightness and weight, not a new hue. */
:root{
  /* SURFACES. Three steps, and the order matters:
     --surface is the page ground, --paper-2 is a quiet mid step, --paper is the
     lightest and is reserved for panels that should sit ON the ground.

     Changed 10 Aug 2026 on Kishan's feedback — he did not like the white background.
     The ground dropped from 0.977 to 0.949 so the page reads as grey, and --paper
     went the other way, to 0.985, so the schedule, the callouts, the contact plate
     and the form now read as sheets of paper laid on a grey desk rather than as
     white-on-white. Do not collapse these back into one value: the whole layering
     of the design now depends on the gap between --surface and --paper.

     Changed AGAIN 12 Aug 2026 — 0.949 still read as "off-white" to Kishan and he
     asked for full grey. The ground went to 0.902 (#DBDEE1), which is unambiguously
     a grey desk rather than a warm white.

     Changed A THIRD TIME 12 Aug 2026, same day, after Kishan saw it: "needs to be
     more darker, no white at all, besides the header. maybe a darker grey then a
     lighter grey." The first two rounds only moved the GROUND — every panel was
     still --paper at 0.985, i.e. functionally white, so the page still read as
     white sheets on a grey desk. This round moves BOTH:
       --surface  0.902 -> 0.855  (#CCD0D3, a mid grey desk)
       --paper    0.985 -> 0.950  (#ECEFF1, a light grey sheet, not white)
     paper-2 and paper-3 came down with them to keep the same spacing. The gap
     between ground and sheet is 0.095, marginally WIDER than it was, so the
     layering did not flatten — the whole stack just moved down.

     The ONLY white left on the site is the masthead (--header-white, 0.985),
     which Kishan explicitly asked to keep. See the .mast note below.

     THIS IS NOT A ONE-LINE CHANGE AND IT CANNOT BE. Moving the surfaces pulls the
     rest of the palette with it, because it was all tuned against the old values:
       --ink-2, --ink-3    4.78:1 and 4.68:1 now. Both darkened; ink-3 was 4.38:1
                           on the new ground, i.e. under AA.
       --brand-2           was 4.32:1 on the new ground. Darkened to 0.44.
       --blue              linework, would have been 3.02:1 — a rounding error off
                           the 3:1 floor. Darkened to 0.53.
       --blue-1, --blue-2  hairline rules. blue-1 at 0.815 sits only 0.04 above a
                           0.855 ground, so every hairline on the hero, the FAQ and
                           the form would have all but vanished. Darkened hard.
     Run `node contrast-check.js` after any further move. It is the gate.
     --brand cannot move: it is the logo hex. It is at 3.01:1 on --paper, which is
     the tightest pair in the palette — if --paper is ever lowered again, that pair
     fails and brand stops being usable as a boundary on a panel. */
  --surface:oklch(0.855 0.006 245);
  --paper:oklch(0.950 0.004 245);
  --paper-2:oklch(0.920 0.005 245);
  --paper-3:oklch(0.890 0.008 245);

  /* The masthead, and ONLY the masthead. Not a general-purpose light token —
     if you find yourself reaching for it anywhere else, you are putting white
     back on the page and Kishan has now asked three times for it to go. */
  --header-white:oklch(0.985 0.004 245);

  /* brand — sampled from the final logo Kishan supplied 8 Aug 2026.
     #2491D0 is the exact ink in K2Konnect_Logo_Colour.pdf. Do not drift it. */
  --brand:#2491D0;
  --brand-2:oklch(0.440 0.130 240.4);  /* the working blue: CTA fills and accent text */

  /* linework + text */
  --ink:oklch(0.22 0.010 240);
  --ink-2:oklch(0.45 0.010 240);
  --ink-3:oklch(0.455 0.008 240);

  /* drawing furniture — same hue, chroma held low so linework stays quiet and the
     logo and the CTAs are still the strongest blue on the page */
  /* Darkened 0.63 -> 0.62 on 10 Aug: against the then-new grey ground it landed at
     2.98:1, just under the 3:1 non-text minimum.
     Darkened again 12 Aug (0.62 -> 0.555) when the ground went to full grey.
     Darkened a third time (0.555 -> 0.530) when the ground went to 0.855.
     blue-1 and blue-2 moved with it each time — blue-1 at 0.90 was LIGHTER than
     the 0.902 ground, and at 0.815 it was only 0.04 above the 0.855 one, so every
     hairline rule sitting directly on the page would have disappeared. They are
     hairlines: if they stop being visible the drawing language goes with them. */
  --blue:oklch(0.530 0.080 240.4);
  --blue-1:oklch(0.775 0.035 240.4);
  --blue-2:oklch(0.715 0.050 240.4);

  /* the one exception, and it earns it: 000 and the emergency page only */
  --isolate:oklch(0.52 0.205 27);

  --rule:1px;
  --ease:cubic-bezier(0.22,1,0.36,1);
  --gut:clamp(18px,4vw,44px);
}

*{margin:0;padding:0;box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;}
body{
  font-family:'Chivo',ui-sans-serif,system-ui,sans-serif;
  color:var(--ink);
  background:var(--surface);
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
  /* drafting-film grid. Alpha raised .055 -> .07 on 12 Aug, then .07 -> .085 when
     the ground dropped again to 0.855: the same wash over a darker ground is a
     smaller step every time, so the grid has to be re-tuned with the surface or
     it quietly disappears. Colour tracks --blue. */
  background-image:
    repeating-linear-gradient(90deg,oklch(0.530 0.080 240.4 / .085) 0 1px,transparent 1px 64px),
    repeating-linear-gradient(0deg,oklch(0.530 0.080 240.4 / .085) 0 1px,transparent 1px 64px);
}
img{max-width:100%;display:block;}
a{color:inherit;text-decoration:none;}
:focus-visible{outline:3px solid var(--brand-2);outline-offset:3px;}

h1,h2,h3{
  font-family:'Saira Condensed','Chivo',sans-serif;
  font-weight:800;
  line-height:1.02;
  letter-spacing:-0.005em;
  text-transform:uppercase;
}

/* annotation type: sheet numbers, circuit refs, labels */
.anno{
  font-family:'Martian Mono','Chivo',ui-monospace,monospace;
  font-size:clamp(9.5px,1.1vw,11px);
  letter-spacing:0.14em;
  text-transform:uppercase;
  color:var(--ink-2);
  font-weight:500;
}
/* drawing references: sheet no, circuit ref, revision, suburb. Not energised — blue. */
.anno-ref{color:var(--brand-2);}

/* ---------- sheet ---------- */
.sheet{
  max-width:1240px;
  margin:0 auto;
  padding:0 var(--gut);
  position:relative;
}
/* The fixed sheet-edge frame was removed 9 Aug 2026. It was position:fixed at z-index 60,
   above the sticky masthead, so its top border drew a line straight through the logo and
   its bottom border cut across live text at whatever point the viewport happened to end.
   It read as a rendering artifact rather than a drawing sheet edge. Do not reinstate it:
   the sheet metaphor is already carried by the drafting grid, the sheet numbers, the title
   block, none of which sit on top of content. (The riser diagram carried it too until
   12 Aug 2026 — see the removal note further down.) */

/* ---------- masthead ----------
   The header stays WHITE while the page ground is grey. Kishan's call, 12 Aug 2026:
   "header where logo stays as white". The logo is a blue-and-charcoal lockup whose
   eagle is negative space, so it takes its eagle colour from whatever sits behind
   it — on the grey ground that eagle turns grey and the mark muddies. A white bar
   keeps the lockup reading exactly as the designer drew it, and it gives the sticky
   header a hard edge against the desk below it.
   Reaffirmed 12 Aug when the whole palette went darker: "no white at all, besides
   the header". This bar is the exception the rest of the page is measured against.
   Do not "tidy" this back to var(--surface) or to var(--paper). It is deliberate. */
.mast{
  position:sticky;top:0;z-index:50;
  /* Literal, not oklch(from var(--header-white) ...). Relative colour syntax would
     read better but a browser that does not support it drops the declaration and
     the sticky header goes transparent over scrolling content — too expensive a
     failure for a syntax win. Keep this value in sync with --header-white. */
  background:oklch(0.985 0.004 245 / .96);
  backdrop-filter:blur(8px);
  border-bottom:var(--rule) solid var(--ink);
}
.mast-in{
  max-width:1240px;margin:0 auto;padding:10px var(--gut);
  display:flex;align-items:center;gap:20px;
}
.mast-logo img{height:52px;width:auto;transition:height .3s var(--ease);}
.mast.stuck .mast-logo img{height:40px;}
@media(max-width:420px){.mast-logo img{height:42px;}}
.mast-nav{display:none;gap:26px;margin-left:auto;align-items:center;}
.mast-nav a{
  font-size:13.5px;font-weight:500;color:var(--ink-2);
  padding:6px 0;border-bottom:2px solid transparent;transition:color .2s,border-color .2s;
}
@media(hover:hover){.mast-nav a:hover{color:var(--ink);border-bottom-color:var(--brand);}}
.mast-nav a[aria-current]{color:var(--ink);border-bottom-color:var(--brand);}
.mast-right{margin-left:auto;display:flex;align-items:center;gap:12px;}
@media(min-width:1000px){.mast-nav{display:flex;}.mast-right{margin-left:0;}}

/* terminal-block button */
.tb{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  font-family:'Saira Condensed',sans-serif;
  font-weight:700;font-size:16px;letter-spacing:0.045em;text-transform:uppercase;
  padding:13px 22px;min-height:46px;
  border:2px solid var(--ink);
  background:var(--brand);color:var(--ink);
  border-radius:0;
  transition:transform .14s var(--ease),box-shadow .2s var(--ease);
  box-shadow:3px 3px 0 var(--ink);
  white-space:nowrap;
}
.tb svg{width:17px;height:17px;flex:none;}
@media(hover:hover){.tb:hover{transform:translate(-1px,-1px);box-shadow:5px 5px 0 var(--ink);}}
.tb:active{transform:translate(2px,2px);box-shadow:1px 1px 0 var(--ink);}
/* Shadow is --brand-2, not --brand. The ghost button's usual home is the hero and
   the service-page head, both of which sit on the grey ground, and the logo blue
   only reaches 2.60:1 there — see the note in contrast-check.js. --brand-2 is
   5.02:1 on the ground and 6.44:1 on paper, so it holds up in both places. */
.tb-ghost{background:transparent;color:var(--ink);box-shadow:3px 3px 0 var(--brand-2);}
@media(hover:hover){.tb-ghost:hover{background:var(--paper-2);box-shadow:5px 5px 0 var(--brand-2);}}
.tb-sm{font-size:14px;padding:9px 16px;min-height:42px;box-shadow:2px 2px 0 var(--ink);}
.tb-danger{background:var(--isolate);color:var(--paper);border-color:var(--isolate);box-shadow:3px 3px 0 var(--ink);}

.burger{
  display:flex;flex-direction:column;gap:5px;background:none;
  border:2px solid var(--ink);padding:9px;cursor:pointer;min-height:44px;min-width:44px;
  align-items:center;justify-content:center;
}
.burger span{width:20px;height:2px;background:var(--ink);display:block;}
@media(min-width:1000px){.burger{display:none;}}
.drawer{display:none;border-bottom:var(--rule) solid var(--ink);background:var(--paper);}
.drawer.open{display:block;}
.drawer a{
  display:flex;justify-content:space-between;align-items:center;gap:14px;
  padding:15px var(--gut);border-top:var(--rule) solid var(--blue-1);
  font-weight:500;font-size:16px;min-height:52px;
}
.drawer a .anno{color:var(--ink-3);}
.drawer .drawer-cta{padding:18px var(--gut);border-top:var(--rule) solid var(--ink);}
.drawer .drawer-cta .tb{width:100%;}

/* ---------- hero ---------- */
.hero{padding:clamp(34px,5vw,60px) 0 clamp(40px,6vw,72px);}
.hero-head{
  display:flex;justify-content:space-between;align-items:baseline;gap:20px;
  padding-bottom:12px;border-bottom:2px solid var(--ink);flex-wrap:wrap;
}
/* Two-column hero restored 11 Sep 2026. The riser diagram was removed 12 Aug
   at Kishan's request; he now wants more photos on the page, so a real job
   photo replaces the invented schematic in the right-hand track. */
.hero-grid{
  display:grid;grid-template-columns:1fr;gap:clamp(30px,4vw,54px);
  padding-top:clamp(26px,3.5vw,44px);align-items:center;
}
@media(min-width:940px){
  .hero-grid{grid-template-columns:1.06fr 0.94fr;}
}

/* 13ch while the riser occupied the right-hand track. On a single-column hero that
   same measure ran the headline to five lines down the left edge with half the sheet
   empty beside it, so it opens out to 17ch and lands in three. */
.hero h1{
  font-size:clamp(40px,7.6vw,84px);
  max-width:17ch;
}
@media(min-width:940px){.hero h1{max-width:13ch;}}
.hero h1 .live{
  color:var(--brand-2);
  position:relative;
  display:inline-block;
}
/* live conductor underline: the word is an energised circuit */
.hero h1 .live::after{
  content:'';position:absolute;left:0;right:0;bottom:0.06em;height:0.075em;
  background:var(--brand);
  transform-origin:left;
  animation:energise 1s var(--ease) .35s both;
}
@keyframes energise{from{transform:scaleX(0);}to{transform:scaleX(1);}}

.hero-sub{
  font-size:clamp(16px,1.75vw,18.5px);
  color:var(--ink-2);max-width:52ch;margin:22px 0 0;
}
.hero-acts{display:flex;flex-wrap:wrap;gap:14px;margin-top:30px;}

/* spec strip: replaces the banned tick-list / proof-item pattern */
.spec{
  margin-top:clamp(28px,3.5vw,40px);
  border-top:var(--rule) solid var(--ink);
  display:grid;grid-template-columns:1fr;
}
@media(min-width:560px){.spec{grid-template-columns:repeat(3,1fr);}}
.spec div{
  padding:14px 0 14px 0;
  border-bottom:var(--rule) solid var(--blue-1);
}
@media(min-width:560px){
  .spec div{padding:14px 16px;border-bottom:0;border-left:var(--rule) solid var(--blue-1);}
  .spec div:first-child{padding-left:0;border-left:0;}
}
.spec b{display:block;font-family:'Saira Condensed',sans-serif;font-weight:700;
  font-size:19px;text-transform:uppercase;letter-spacing:0.01em;margin-top:5px;}

/* ---------- riser diagram — REMOVED 12 Aug 2026, photo REPLACED 11 Sep 2026 ----------
   The hero carried an inline SVG riser schematic as its imagery, drawn on scroll.
   Kishan asked for it gone 12 Aug. He now wants more photos on the page, so a real
   job photo sits in the right-hand track where the schematic was. The .riser / .dwg-*
   rules and keyframes were deleted with the diagram and are not restored.
   ------------------------------------------------------------------------- */

/* ---------- hero photo ---------- */
.hero-shot{
  border:var(--rule) solid var(--ink);
  background:var(--paper);
  display:flex;flex-direction:column;
}
.hero-shot img{width:100%;height:auto;max-height:560px;object-fit:cover;display:block;background:var(--paper-2);}
.hero-shot figcaption{
  display:flex;justify-content:space-between;align-items:center;gap:10px;
  padding:9px 12px;border-top:var(--rule) solid var(--ink);
}

/* ---------- section scaffolding ---------- */
.sec{padding:clamp(52px,7vw,92px) 0;position:relative;}
/* Sunk sections are now the LIGHTEST surface, not the darkest. With a grey page
   ground the alternating rhythm reads as sheets of paper laid on the desk, which
   is the whole metaphor. Before 10 Aug this was --paper-2 against a near-white
   ground, i.e. a barely-visible step in the other direction. */
.sec-sunk{background:var(--paper);border-top:var(--rule) solid var(--blue-1);border-bottom:var(--rule) solid var(--blue-1);}
.sec-head{
  display:flex;align-items:baseline;gap:16px;flex-wrap:wrap;
  padding-bottom:14px;border-bottom:2px solid var(--ink);margin-bottom:clamp(28px,3.5vw,44px);
}
.sec-no{
  font-family:'Martian Mono',monospace;font-size:clamp(11px,1.3vw,13px);
  font-weight:600;color:var(--brand-2);letter-spacing:0.1em;flex:none;
}
.sec-head h2{font-size:clamp(27px,4.2vw,46px);flex:1;min-width:min(100%,16ch);}
.sec-note{color:var(--ink-2);font-size:15px;max-width:38ch;margin-left:auto;}

/* ---------- switchboard schedule (services) ----------
   Each row is a BORDERED PLATE, not a line in a table. Changed 12 Aug 2026:
   Kishan read the old version — rows separated only by hairlines, sharing one
   continuous block — as compacted. It was doing the right thing typographically
   (a switchboard schedule IS a table) and the wrong thing for a customer, who
   saw one dense slab rather than six services.

   Full ink border plus a real gap between rows. The rows sit on --paper inside a
   sunk section that is also --paper, so the border is the entire separation —
   do not remove it and expect the gap alone to carry it. */
.sched{display:grid;gap:12px;}
.sched-row{
  display:grid;grid-template-columns:auto 1fr auto;
  gap:14px 18px;align-items:start;
  padding:18px 20px;
  border:var(--rule) solid var(--ink);
  background:var(--paper);
  position:relative;transition:background .2s var(--ease),box-shadow .2s var(--ease);
}
@media(min-width:760px){.sched-row{grid-template-columns:74px 1fr 190px auto;align-items:center;padding:20px 24px;}}
@media(hover:hover){.sched-row:hover{background:oklch(0.63 0.13 240 / .06);box-shadow:3px 3px 0 var(--brand);}}
.sched-ref{
  font-family:'Martian Mono',monospace;font-size:12px;font-weight:600;
  color:var(--ink-2);letter-spacing:0.06em;display:flex;align-items:center;gap:8px;
}
/* Drawn as an open terminal, filled solid on hover: the same drawn-then-live
   logic the rest of the page runs on, now carried by weight rather than a second hue. */
.sched-ref::before{
  content:'';width:9px;height:9px;border:2px solid var(--brand-2);border-radius:50%;flex:none;
  transition:background .2s var(--ease);
}
.sched-row:hover .sched-ref::before{background:var(--brand);}
.sched-t h3{font-size:clamp(19px,2.2vw,25px);margin-bottom:3px;}
.sched-t p{color:var(--ink-2);font-size:14.5px;line-height:1.55;max-width:46ch;}
.sched-rate{grid-column:1/-1;}
@media(min-width:760px){.sched-rate{grid-column:auto;}}
.sched-go{
  font-family:'Saira Condensed',sans-serif;font-weight:700;text-transform:uppercase;
  font-size:14px;letter-spacing:0.05em;color:var(--brand-2);
  display:flex;align-items:center;gap:7px;white-space:nowrap;
}
.sched-go svg{width:16px;height:16px;transition:transform .25s var(--ease);}
@media(hover:hover){.sched-row:hover .sched-go svg{transform:translateX(5px);}}

/* ---------- method: circuit run down the page ----------
   Same fix as the schedule above, same reason, same day: Kishan found the three
   steps compacted. They were bare text hanging off a vertical conductor with no
   container of their own, so on a phone the three ran together as one paragraph.

   Each step is now a bordered plate on the conductor. The circuit run and the
   terminal dots stay — they are the drawing metaphor and the boxes hang off
   them, which is exactly what a circuit run should look like. */
.run{position:relative;padding-left:34px;display:grid;gap:14px;}
/* Gradient runs --blue to --blue-2, not --brand to --blue-2. This conductor is drawn
   directly on the grey ground, where the logo blue is only 2.60:1. --blue is 3.51:1
   and clears the 3:1 non-text minimum. */
.run::before{
  content:'';position:absolute;left:8px;top:6px;bottom:6px;width:2px;
  background:linear-gradient(180deg,var(--blue) 0%,var(--blue-2) 100%);
}
.run-step{
  position:relative;
  border:var(--rule) solid var(--ink);
  background:var(--paper);
  padding:18px 20px;
}
@media(min-width:760px){.run-step{padding:20px 24px;}}
/* Aligned to the "Step 01" label inside the box, not to the box's top edge —
   the dot is the terminal that step connects to, so it has to sit level with
   the label rather than with the border. */
.run-step::before{
  content:'';position:absolute;left:-30px;top:23px;width:12px;height:12px;
  border:2px solid var(--ink);background:var(--paper);border-radius:50%;
}
.run-step.on::before{background:var(--brand);}
.run-step h3{font-size:clamp(19px,2.2vw,24px);margin:6px 0 7px;}
.run-step p{color:var(--ink-2);font-size:15.5px;max-width:54ch;}

/* ---------- feature blocks (photo + text, Clear Logic pattern) ----------
   Added 11 Sep 2026 at Kishan's request. He likes how clearlogicelectrical.com.au
   uses big editorial photo+text blocks for key services. Same idea here: a large
   job photo beside a short heading and paragraph, breaking up the text-heavy
   services schedule and method sections. Photos are Kishan's own work. */
.feature{
  display:grid;grid-template-columns:1fr;gap:0;
  border:var(--rule) solid var(--ink);
  background:var(--paper);
}
@media(min-width:760px){
  .feature{grid-template-columns:1fr 1fr;}
  .feature.flip{grid-template-columns:1fr 1fr;}
  .feature.flip .feature-img{order:2;}
  .feature.flip .feature-text{order:1;}
}
.feature-img{
  position:relative;overflow:hidden;min-height:280px;
  border-bottom:var(--rule) solid var(--ink);
}
@media(min-width:760px){.feature-img{border-bottom:0;border-right:var(--rule) solid var(--ink);max-height:520px;}}
.feature.flip .feature-img{border-right:0;border-left:var(--rule) solid var(--ink);}
.feature-img img{width:100%;height:100%;object-fit:cover;object-position:center 30%;display:block;background:var(--paper-2);}
.feature-text{padding:clamp(24px,3.5vw,44px);display:flex;flex-direction:column;justify-content:center;}
.feature-text h3{font-size:clamp(22px,3vw,34px);margin-bottom:12px;}
.feature-text p{color:var(--ink-2);font-size:16px;line-height:1.6;max-width:42ch;margin-bottom:18px;}
.feature-text .feature-link{
  font-family:'Saira Condensed',sans-serif;font-weight:700;text-transform:uppercase;
  font-size:15px;letter-spacing:0.05em;color:var(--brand-2);
  display:flex;align-items:center;gap:7px;
}
.feature-text .feature-link svg{width:16px;height:16px;transition:transform .25s var(--ease);}
@media(hover:hover){.feature-text .feature-link:hover svg{transform:translateX(5px);}}

/* ---------- annotation callout (replaces banned side-stripe) ---------- */
.callout{
  border:var(--rule) solid var(--ink);
  background:var(--paper);
  padding:20px 22px;margin:28px 0;position:relative;
}
.callout::before{
  content:'';position:absolute;left:-1px;top:-1px;width:26px;height:26px;
  border-top:3px solid var(--brand);border-left:3px solid var(--brand);
}
.callout b{
  display:block;font-family:'Saira Condensed',sans-serif;font-weight:700;
  text-transform:uppercase;font-size:18px;letter-spacing:0.02em;margin-bottom:7px;
}
.callout p{color:var(--ink-2);font-size:15.5px;margin:0;max-width:60ch;}
/* The red wash is layered OVER --paper, not used instead of it. As a bare
   translucent fill it let the page ground through, so on the darker grey the one
   callout that most needs to read as a sheet was the only one that did not.
   Tint raised .045 -> .06 to stay visible against a darker paper. */
.callout-danger{
  border-color:var(--isolate);
  background-color:var(--paper);
  background-image:linear-gradient(oklch(0.52 0.205 27 / .06),oklch(0.52 0.205 27 / .06));
}
.callout-danger::before{border-color:var(--isolate);}
.callout-danger b{color:var(--isolate);}

/* ---------- contact plate ---------- */
.plate{
  border:2px solid var(--ink);background:var(--paper);
  display:grid;grid-template-columns:1fr;
}
@media(min-width:860px){.plate{grid-template-columns:1.1fr 0.9fr;}}
.plate-l{padding:clamp(26px,3.4vw,42px);}
.plate-r{
  padding:clamp(26px,3.4vw,42px);
  border-top:2px solid var(--ink);background:var(--ink);color:var(--paper);
}
@media(min-width:860px){.plate-r{border-top:0;border-left:2px solid var(--ink);}}
.plate-r h3{color:var(--paper);font-size:clamp(24px,3vw,32px);margin-bottom:12px;}
.plate-r p{color:oklch(0.950 0.004 245 / .74);font-size:16px;margin-bottom:22px;max-width:36ch;}
.plate-r .anno{color:oklch(0.950 0.004 245 / .6);}
.plate-r .tb{width:100%;}
.plate-r .tb-ghost{color:var(--paper);border-color:var(--paper);box-shadow:3px 3px 0 oklch(0.950 0.004 245 / .3);margin-top:12px;}
@media(hover:hover){.plate-r .tb-ghost:hover{background:oklch(0.950 0.004 245 / .1);}}
.dl{display:grid;gap:0;border-top:var(--rule) solid var(--blue-1);margin-top:20px;}
.dl > div{
  display:grid;grid-template-columns:1fr;gap:2px;
  padding:14px 0;border-bottom:var(--rule) solid var(--blue-1);
}
@media(min-width:520px){.dl > div{grid-template-columns:140px 1fr;gap:16px;align-items:baseline;}}
.dl b{font-size:17px;font-weight:700;word-break:break-word;}
.dl small{color:var(--ink-2);font-size:13.5px;display:block;}

/* ---------- enquiry form ----------
   Added 10 Aug 2026 at Kishan's request. The site shipped without one on
   purpose (same call as BMH: a tradie starting out wants the phone ringing),
   so the phone stays the primary CTA above and this sits underneath it as the
   after-hours option, not as a replacement.

   Styled as a drawing schedule, not as a generic form: square corners, ink
   rules, mono labels. Inputs get a 2px ink border and a real focus ring, and
   nothing here is placeholder-only — every field has a visible <label>, which
   is the single most common accessibility failure in a contact form. */
/* SIZE. Kishan, 12 Aug 2026: the form takes up a lot of space on desktop. It did —
   at two columns it ran four full-width rows plus a 132px textarea, so on a 1440px
   screen it was a tall stack of half-empty rows under an already-tall contact plate.

   Fixed by reflowing rather than by shrinking type or tap targets, both of which
   are load-bearing (16px inputs or iOS Safari zooms on focus; 48px minimum height
   for a thumb). At 900px it goes to THREE columns:

     row 1   name · phone · suburb
     row 2   email · what do you need (2 cols)
     row 3   what is happening (full)

   Six fields in three rows instead of four, and the textarea drops to 104px on
   desktop, where the extra height was buying nothing. */
.form-plate{
  border:2px solid var(--ink);background:var(--paper);
  margin-top:26px;
}
.form-head{
  display:flex;justify-content:space-between;align-items:baseline;gap:14px;flex-wrap:wrap;
  padding:14px clamp(20px,2.6vw,28px);border-bottom:2px solid var(--ink);
}
.form-head h3{font-size:clamp(20px,2.4vw,26px);}
.form-body{padding:clamp(18px,2.4vw,26px);}
.form-grid{display:grid;grid-template-columns:1fr;gap:16px;}
/* span 2 TRACKS, not 1/-1. At two columns those are the same thing; at three they
   are not, and the select wants two of three rather than the whole row. Anything
   that genuinely needs the full width uses .span-full. */
@media(min-width:620px){
  .form-grid{grid-template-columns:1fr 1fr;}
  .form-grid .span-2{grid-column:span 2;}
}
@media(min-width:900px){
  .form-grid{grid-template-columns:repeat(3,1fr);gap:14px 16px;}
}
.form-grid .span-full{grid-column:1/-1;}
.field{display:flex;flex-direction:column;gap:6px;}
.field label{
  font-family:'Martian Mono','Chivo',ui-monospace,monospace;
  font-size:10.5px;letter-spacing:0.14em;text-transform:uppercase;
  color:var(--ink-2);font-weight:500;
}
.field label .opt{color:var(--ink-3);letter-spacing:0.08em;}
.field input,.field select,.field textarea{
  font-family:'Chivo',ui-sans-serif,system-ui,sans-serif;
  font-size:16px;   /* 16px minimum, or iOS Safari zooms the page on focus */
  color:var(--ink);
  background:var(--paper);
  border:2px solid var(--ink);
  border-radius:0;
  padding:12px 13px;
  min-height:48px;
  width:100%;
  transition:box-shadow .15s var(--ease);
}
.field textarea{min-height:120px;resize:vertical;line-height:1.6;}
/* Shorter on desktop, where the box was tall enough to hold an essay nobody
   writes. It is still resizable, so anyone with more to say can drag it. */
@media(min-width:900px){.field textarea{min-height:104px;}}
.field select{
  /* The native arrow is inconsistent across platforms and none of them match
     the drawing language, so it is replaced with a drawn chevron. */
  appearance:none;-webkit-appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23171b1f' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 12px center;
  background-size:17px;
  padding-right:40px;
}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:3px solid var(--brand-2);outline-offset:2px;
}
.form-acts{
  display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  margin-top:20px;padding-top:18px;border-top:var(--rule) solid var(--blue-1);
}
.form-acts .tb{flex:none;}
.form-note{font-size:13px;color:var(--ink-2);max-width:44ch;line-height:1.6;}

/* Honeypots — display:none on BOTH the wrapper and the inputs.
   NOT the usual position:absolute;left:-9999px trick. That is the common
   advice and it is wrong: **Chrome autofills offscreen fields**, it only skips
   display:none. Sentient Space shipped with the offscreen version on 31 Jul
   2026 and the very first live test submission was binned as spam because
   Chrome had filled the honeypot. Every genuine enquiry would have gone the
   same way. Fixed there 2 Aug; do not reintroduce it here or anywhere else.
   The `display:none` on .hp input is redundant while the wrapper is hidden,
   and deliberately kept — it survives anyone unhiding the wrapper. */
.hp{display:none!important;}
.hp input{display:none!important;}

/* ---------- thanks page ---------- */
.thanks{padding:clamp(60px,10vw,120px) 0;text-align:left;}
.thanks h1{font-size:clamp(32px,5.5vw,58px);margin:14px 0 16px;}
/* .live is scoped per page type, not global — see .hero h1 .live and
   .sp-head h1 .live. Without this line the highlight silently does nothing. */
.thanks h1 .live{color:var(--brand-2);}
.thanks p{color:var(--ink-2);font-size:17px;max-width:52ch;margin-bottom:12px;}
.thanks .sp-acts{margin-top:28px;}

/* ---------- coverage ---------- */
.cov{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(168px,1fr));
  border-top:var(--rule) solid var(--ink);border-left:var(--rule) solid var(--blue-1);
}
.cov span{
  padding:11px 14px;font-size:14.5px;min-height:46px;
  border-bottom:var(--rule) solid var(--blue-1);border-right:var(--rule) solid var(--blue-1);
  display:flex;align-items:center;gap:9px;white-space:nowrap;
}
.cov span::before{content:'';width:5px;height:5px;background:var(--brand);flex:none;}
.cov span.core{font-weight:700;}
.cov span.core::before{background:var(--brand);width:7px;height:7px;}
.map{
  margin-top:26px;border:var(--rule) solid var(--ink);
  aspect-ratio:16/7;position:relative;overflow:hidden;
}
@media(max-width:640px){.map{aspect-ratio:4/3;}}
.map iframe{position:absolute;inset:0;width:100%;height:100%;border:0;filter:grayscale(.35) contrast(1.05);}

/* ---------- title block (footer) ---------- */
.title-block{
  border-top:2px solid var(--ink);background:var(--paper-2);
  padding:clamp(30px,4vw,48px) 0 22px;
}
.tb-grid{display:grid;grid-template-columns:1fr;gap:28px;}
@media(min-width:760px){.tb-grid{grid-template-columns:1.5fr 1fr 1fr;gap:34px;}}
.tb-grid img{height:56px;width:auto;}
.tb-grid p{font-size:14px;color:var(--ink-2);margin-top:14px;max-width:34ch;}
.tb-col h4{
  font-family:'Martian Mono',monospace;font-size:10.5px;font-weight:600;
  letter-spacing:0.14em;text-transform:uppercase;color:var(--ink-2);
  padding-bottom:8px;border-bottom:var(--rule) solid var(--ink);margin-bottom:6px;
}
.tb-col a{display:block;padding:8px 0;font-size:14.5px;border-bottom:var(--rule) solid var(--blue-1);}
@media(hover:hover){.tb-col a:hover{color:var(--brand-2);}}
/* the actual drawing title block: business, licence, revision */
.stamp{
  margin-top:clamp(28px,3.5vw,42px);
  border:var(--rule) solid var(--ink);
  display:grid;grid-template-columns:1fr;
}
@media(min-width:640px){.stamp{grid-template-columns:2fr 1fr 1fr 1fr;}}
.stamp div{
  padding:11px 14px;border-bottom:var(--rule) solid var(--blue-1);
}
@media(min-width:640px){
  .stamp div{border-bottom:0;border-right:var(--rule) solid var(--blue-1);}
  .stamp div:last-child{border-right:0;}
}
.stamp b{display:block;font-size:14px;font-weight:700;margin-top:3px;}
.by{text-align:center;font-size:12px;color:var(--ink-3);margin-top:18px;}
.by a{color:var(--ink-2);}

/* ---------- service page ---------- */
.sp-head{padding:clamp(30px,4vw,50px) 0 clamp(30px,4vw,46px);border-bottom:2px solid var(--ink);}
.crumb{display:flex;gap:8px;align-items:center;margin-bottom:18px;}
.crumb a{color:var(--ink-2);}
@media(hover:hover){.crumb a:hover{color:var(--brand-2);}}
.sp-head h1{font-size:clamp(34px,6.2vw,66px);max-width:15ch;}
.sp-head h1 .live{color:var(--brand-2);}
.sp-lead{font-size:clamp(16px,1.7vw,18px);color:var(--ink-2);max-width:56ch;margin:20px 0 0;}
.sp-acts{display:flex;flex-wrap:wrap;gap:14px;margin-top:28px;}

.sp-body{display:grid;grid-template-columns:1fr;gap:clamp(34px,4vw,56px);align-items:start;}
@media(min-width:960px){.sp-body{grid-template-columns:1fr 316px;}}
.prose h2{font-size:clamp(24px,3.2vw,36px);margin:0 0 14px;padding-bottom:10px;border-bottom:2px solid var(--ink);}
.prose h2:not(:first-child){margin-top:clamp(40px,4.5vw,58px);}
.prose h3{font-size:19px;margin:26px 0 7px;}
.prose p{color:var(--ink-2);font-size:16.5px;line-height:1.72;margin-bottom:15px;max-width:66ch;}
.prose a{color:var(--brand-2);border-bottom:1px solid var(--brand);}
/* numbered schedule list, not a bullet list */
.prose ol{list-style:none;counter-reset:sch;margin:22px 0 26px;border-top:var(--rule) solid var(--blue-1);}
.prose ol li{
  counter-increment:sch;position:relative;
  padding:15px 0 15px 52px;border-bottom:var(--rule) solid var(--blue-1);
  font-size:16px;color:var(--ink-2);line-height:1.6;
}
.prose ol li::before{
  content:counter(sch,decimal-leading-zero);
  position:absolute;left:0;top:15px;
  font-family:'Martian Mono',monospace;font-size:11.5px;font-weight:600;
  color:var(--brand-2);letter-spacing:0.06em;
}
.prose ol li strong{color:var(--ink);font-weight:700;}

.aside{position:sticky;top:88px;display:grid;gap:18px;}
@media(max-width:959px){.aside{position:static;}}
.aside-card{border:2px solid var(--ink);background:var(--ink);color:var(--paper);padding:24px;}
.aside-card h3{color:var(--paper);font-size:21px;margin-bottom:9px;}
.aside-card p{color:oklch(0.950 0.004 245 / .74);font-size:14.5px;margin-bottom:18px;}
.aside-card .tb{width:100%;}
.aside-card .tb-ghost{color:var(--paper);border-color:var(--paper);box-shadow:3px 3px 0 oklch(0.950 0.004 245 / .3);margin-top:10px;}
.aside-card .anno{color:oklch(0.950 0.004 245 / .55);display:block;text-align:center;margin-top:14px;}
.aside-links{border:var(--rule) solid var(--ink);background:var(--paper);padding:20px;}
.aside-links h4{
  font-family:'Martian Mono',monospace;font-size:10.5px;font-weight:600;letter-spacing:0.14em;
  text-transform:uppercase;color:var(--ink-2);padding-bottom:8px;
  border-bottom:var(--rule) solid var(--ink);margin-bottom:4px;
}
.aside-links a{
  display:flex;justify-content:space-between;align-items:center;gap:10px;
  padding:11px 0;border-bottom:var(--rule) solid var(--blue-1);font-size:14.5px;font-weight:500;
}
.aside-links a:last-child{border-bottom:0;}
.aside-links a::after{content:'→';color:var(--brand-2);}
@media(hover:hover){.aside-links a:hover{color:var(--brand-2);}}

/* FAQ */
/* ---------- work plates (real job photos) ----------
   Added 10 Aug 2026, when Kishan sent the first batch of his own job photos.

   The site had no photography until now on purpose: the riser diagram was the
   imagery, because stock photos of models in hard hats would have been a lie
   for a business six weeks old. His own photos are not a lie, so they go in —
   but they enter the drawing rather than sitting on top of it. Each one is a
   plate: ink border, mono caption bar, figure number.

   These ran Fig. 2-9 while the riser was Fig. 1. The riser was removed 12 Aug
   2026, so they are now Fig. 1-8.

   NEVER add stock photography here. The whole point is that these are his.

   ONE RAIL AT EVERY WIDTH — not a grid that becomes a rail.
   This started as a 3-column grid. Measured on desktop it came to 1,987px,
   **23% of the entire page**, with each row taller than the viewport under the
   masthead — so you saw one row at a time and the section dominated a page
   where it is supporting evidence, not the main event. As a single rail it is
   ~700px at every width, with no photos dropped and no extra cropping.

   Do not reintroduce the grid. If it ever needs to show more at once, widen
   the plates rather than stacking rows. */
.work{
  display:flex;
  overflow-x:auto;
  scroll-snap-type:x mandatory;
  /* Cancel the section gutter, then re-apply it as padding, so the first plate
     lines up with the heading above but the rail runs to the screen edges while
     scrolling. scroll-padding keeps snapped plates off the very edge. */
  margin-inline:calc(var(--gut) * -1);
  padding-inline:var(--gut);
  padding-bottom:4px;
  scroll-padding-inline:var(--gut);
  gap:14px;
  overscroll-behavior-x:contain;
  -webkit-overflow-scrolling:touch;
  scrollbar-width:none;
}
.work::-webkit-scrollbar{display:none;}

/* Plate width by viewport. Each step leaves a partial plate visible at the
   right edge. THAT PEEK IS THE AFFORDANCE — a rail whose plates divide evenly
   into the container reads as a finished row and never gets scrolled. */
.work .plate-fig{
  flex:0 0 82%;
  scroll-snap-align:start;
}
@media(min-width:520px){.work .plate-fig{flex-basis:46%;}}
@media(min-width:900px){.work .plate-fig{flex-basis:29%;}}

/* The rail is focusable so it can be driven from a keyboard. Make that visible
   rather than letting the ring sit invisibly behind a plate. */
.work:focus-visible{outline:3px solid var(--brand-2);outline-offset:4px;}

.plate-fig{
  border:var(--rule) solid var(--ink);
  background:var(--paper);
  display:flex;flex-direction:column;
  overflow:hidden;
}
/* height:auto is LOAD-BEARING. Every <img> carries width and height attributes
   (correctly — they reserve space and stop layout shift), and a specified
   height makes the browser ignore aspect-ratio entirely. Without this line the
   photos render at their full 1240px intrinsic height and the rail becomes a
   row of 1.4m-tall slivers. Same applies to .fig-inline below. */
.plate-fig img{
  width:100%;height:auto;aspect-ratio:3/4;object-fit:cover;
  background:var(--paper-2);
}

/* The one landscape photo in the set gets a double-width plate so it is not
   cropped to a portrait keyhole. height:100% + aspect-ratio:auto rather than a
   fixed ratio: every plate in the rail is the height of the tallest, and a
   fixed ratio on the wide one floats its caption bar ~190px below its photo.
   If a second landscape photo ever arrives, give it .wide too. */
.work .plate-fig.wide{flex-basis:82%;}
@media(min-width:520px){.work .plate-fig.wide{flex-basis:78%;}}
@media(min-width:900px){.work .plate-fig.wide{flex-basis:52%;}}
.work .plate-fig.wide img{height:100%;aspect-ratio:auto;}

.plate-fig figcaption{
  display:flex;justify-content:space-between;align-items:center;gap:10px;
  padding:9px 12px;border-top:var(--rule) solid var(--ink);
  margin-top:auto;
}
.plate-fig figcaption .anno{line-height:1.5;}
.plate-fig figcaption .anno-ref{flex:none;}

/* ---------- rail controls ----------
   Hidden until main.js confirms the rail actually overflows, so it can never
   show a dead "01 / 08" or arrows that do nothing. Everything below is
   progressive enhancement: the rail scrolls by swipe, trackpad and keyboard
   with none of this present. */
.work-rail{
  display:none;
  justify-content:space-between;align-items:center;gap:14px;
  margin-top:14px;padding-top:12px;
  border-top:var(--rule) solid var(--blue-1);
}
.js .work-rail.on{display:flex;}
.work-rail .hint{color:var(--ink-3);}
/* The swipe hint is for touch only. On a pointer device the arrows say it. */
@media(min-width:520px){.work-rail .hint{display:none;}}
.work-rail-left{display:flex;align-items:center;gap:10px;}
.work-rail b{
  font-family:'Martian Mono','Chivo',ui-monospace,monospace;
  font-size:11px;letter-spacing:0.12em;font-weight:600;
  color:var(--brand-2);flex:none;
}
.rail-btn{
  width:44px;height:44px;flex:none;
  display:inline-flex;align-items:center;justify-content:center;
  border:2px solid var(--ink);background:transparent;color:var(--ink);
  cursor:pointer;border-radius:0;
  box-shadow:2px 2px 0 var(--brand);
  transition:transform .14s var(--ease),box-shadow .2s var(--ease),opacity .2s;
}
.rail-btn svg{width:19px;height:19px;}
@media(hover:hover){.rail-btn:hover{transform:translate(-1px,-1px);box-shadow:4px 4px 0 var(--brand);}}
.rail-btn:active{transform:translate(1px,1px);box-shadow:1px 1px 0 var(--brand);}
.rail-btn[disabled]{opacity:.3;cursor:default;box-shadow:2px 2px 0 var(--blue-2);}
@media(hover:hover){.rail-btn[disabled]:hover{transform:none;box-shadow:2px 2px 0 var(--blue-2);}}

/* A single photo dropped into the body copy of a service page. Same plate,
   just not in a grid. */
.fig-inline{
  border:var(--rule) solid var(--ink);
  background:var(--paper);
  margin:26px 0;
  overflow:hidden;
}
.fig-inline img{width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;background:var(--paper-2);}
.fig-inline figcaption{
  display:flex;justify-content:space-between;align-items:center;gap:10px;
  padding:10px 13px;border-top:var(--rule) solid var(--ink);
}

.faq{border-top:2px solid var(--ink);margin-top:22px;}
.faq details{border-bottom:var(--rule) solid var(--blue-1);}
.faq summary{
  cursor:pointer;padding:17px 40px 17px 0;position:relative;list-style:none;
  font-family:'Saira Condensed',sans-serif;font-weight:700;text-transform:uppercase;
  font-size:17px;letter-spacing:0.01em;min-height:52px;display:flex;align-items:center;
}
.faq summary::-webkit-details-marker{display:none;}
.faq summary::after{
  content:'';position:absolute;right:6px;top:50%;width:13px;height:13px;margin-top:-6px;
  border-right:2px solid var(--brand-2);border-bottom:2px solid var(--brand-2);
  transform:rotate(45deg);transition:transform .25s var(--ease);
}
.faq details[open] summary::after{transform:rotate(225deg);}
.faq details p{padding:0 0 18px;color:var(--ink-2);font-size:15.5px;line-height:1.7;max-width:62ch;margin:0;}

/* bottom CTA band */
.band{background:var(--ink);color:var(--paper);border-top:2px solid var(--ink);}
.band .sheet{padding-top:clamp(44px,5.5vw,68px);padding-bottom:clamp(44px,5.5vw,68px);}
.band h2{color:var(--paper);font-size:clamp(26px,4vw,44px);max-width:18ch;}
.band p{color:oklch(0.950 0.004 245 / .72);font-size:16.5px;max-width:52ch;margin:14px 0 26px;}
.band .anno{color:oklch(0.950 0.004 245 / .58);}
.band .tb-ghost{color:var(--paper);border-color:var(--paper);box-shadow:3px 3px 0 oklch(0.950 0.004 245 / .3);}
@media(hover:hover){.band .tb-ghost:hover{background:oklch(0.950 0.004 245 / .1);}}

/* mobile call bar: the phone number is the interface */
.callbar{
  position:fixed;left:0;right:0;bottom:0;z-index:70;
  border-top:2px solid var(--ink);background:var(--brand);
  padding:10px 14px calc(10px + env(safe-area-inset-bottom));
  display:flex;gap:12px;align-items:center;
}
.callbar a{
  flex:1;display:flex;align-items:center;justify-content:center;gap:9px;
  font-family:'Saira Condensed',sans-serif;font-weight:800;text-transform:uppercase;
  font-size:17px;letter-spacing:0.04em;min-height:46px;color:var(--ink);
}
.callbar svg{width:18px;height:18px;}
@media(min-width:760px){.callbar{display:none;}}
@media(max-width:759px){body{padding-bottom:74px;}}

/* reveal */
.rv{opacity:0;transform:translateY(14px);transition:opacity .6s var(--ease),transform .6s var(--ease);transition-delay:calc(var(--i,0)*60ms);}
.rv.in{opacity:1;transform:none;}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important;}
  html{scroll-behavior:auto;}
  .rv{opacity:1;transform:none;}
  .hero h1 .live::after{transform:scaleX(1);}
}

@media print{
  .mast,.callbar,.band{display:none;}
  body{background:#fff;}
}
