@charset "UTF-8";
/* =============================================================================
   Aus Cut Sawing & Drilling
   Design system per the July 2026 style guide, rebased onto the brand mark:
   red #CC0000 on charcoal, concrete-grey ground, square edges throughout.
   Site design by Dingoblue Services — https://dingoblue.com.au
   ============================================================================= */

/* --- Tokens ---------------------------------------------------------------- */
:root {
  --red:        #CC0000;   /* brand red, sampled from the logo */
  --red-hover:  #A30000;
  --red-ink:    #FFFFFF;
  --red-text:   #A80000;   /* darkened for small text, AA on --ground */
  --red-invert: #FF5347;   /* red for a surface that inverts, ie charcoal here */

  --ink:        #1A1B1A;   /* charcoal, INVERTS with the theme */
  /* Secondary text: eyebrows, hints, card copy, FAQ answers. Was #5C5F5C,
     which is 4.84:1 on --panel, a pass at AA and a miss at AAA. It carries
     most of the small text on the site, so it is the one that matters if your
     contrast sensitivity is reduced. #434543 is 7.24:1 on --panel and 8.03:1
     on --ground. Darkening it moved 50-odd elements to AAA in one line. */
  --muted:      #434543;

  /* Charcoal that never inverts, for surfaces that are dark by design and
     carry hardcoded white type: the hero, .band-dark, the footer. Those used
     var(--ink), which flips to near-white in dark mode and left white text on
     a white slab. Do not swap these back to --ink. */
  --slab:       #1A1B1A;
  --slab-ink:   #EAEAE8;
  --ground:     #EAEAE8;   /* cured concrete */
  --panel:      #DFDFDC;
  --line:       #D0D0CC;

  --ok:         #2F6B3A;
  --err:        #A03A2C;

  --display: "Helvetica Neue", Helvetica, Arial, "Liberation Sans", sans-serif;
  --body:    ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
             "Helvetica Neue", Arial, sans-serif;
  --mono:    ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
             "Liberation Mono", monospace;

  --measure: 66ch;
  --gutter:  clamp(1.15rem, 4vw, 3rem);
  --shell:   76rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --red: #FF5347; --red-hover: #FF7A70; --red-ink: #141414; --red-text: #FF6E63;
    --red-invert: #CC0000;
    --ink: #E9EAE7; --muted: #ADB1AD; --ground: #151615; --panel: #1F211F; --line: #2E312E;
    --ok: #7FB187; --err: #E08A7C;
  }
}
:root[data-theme="dark"] {
  --red: #FF5347; --red-hover: #FF7A70; --red-ink: #141414; --red-text: #FF6E63;
  --red-invert: #CC0000;
  --ink: #E9EAE7; --muted: #ADB1AD; --ground: #151615; --panel: #1F211F; --line: #2E312E;
  --ok: #7FB187; --err: #E08A7C;
}
:root[data-theme="light"] {
  --red: #CC0000; --red-hover: #A30000; --red-ink: #FFFFFF; --red-text: #A80000;
  --red-invert: #FF5347;
  --ink: #1A1B1A; --muted: #434543; --ground: #EAEAE8; --panel: #DFDFDC; --line: #D0D0CC;
  --ok: #2F6B3A; --err: #A03A2C;
}

/* --- Base ------------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--body);
  font-size: 1rem;
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1.08;
  text-wrap: balance;
  margin: 0 0 .75rem;
}
h1 { font-size: clamp(2.1rem, 6vw, 3.6rem); text-transform: uppercase; letter-spacing: -.035em; }
h2 { font-size: clamp(1.5rem, 3.8vw, 2.1rem); text-transform: uppercase; }
h3 { font-size: 1.12rem; text-transform: uppercase; }

p { margin: 0 0 1rem; }
p:last-child { margin-bottom: 0; }

a { color: var(--red-text); text-underline-offset: 2px; }
a:hover { color: var(--red-hover); }

:focus-visible { outline: 3px solid var(--red); outline-offset: 3px; }

.shell { max-width: var(--shell); margin-inline: auto; padding-inline: var(--gutter); }
.prose { max-width: var(--measure); }

.eyebrow {
  display: block;
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: .5rem;
}

.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--ink); color: var(--ground);
  padding: .75rem 1.15rem; z-index: 200;
}
.skip:focus { left: 0; }

/* --- Header ---------------------------------------------------------------- */
/* The .topbar was removed on 29 July 2026. It carried the tagline plus both
   phone numbers above the masthead; the numbers still appear in the hero CTA,
   the contact page and the footer. Its rules are gone with it, so don't be
   surprised by the missing selector. */

.masthead { border-bottom: 3px solid var(--ink); background: var(--ground); }
.masthead .shell {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.25rem; padding-block: .9rem;
}
.brand { display: inline-flex; align-items: center; flex-shrink: 0; }
.brand img { width: clamp(150px, 22vw, 210px); }

.nav-toggle, .nav-toggle-label { display: none; }

.nav ul {
  list-style: none; margin: 0; padding: 0;
  display: flex; align-items: center; gap: clamp(.75rem, 2vw, 1.6rem);
}
.nav a {
  font-family: var(--display);
  font-weight: 700;
  font-size: .84rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--ink);
  text-decoration: none;
  padding-block: .4rem;
  border-bottom: 3px solid transparent;
  white-space: nowrap;
}
.nav a:hover { border-bottom-color: var(--red); color: var(--ink); }
.nav a[aria-current="page"] { border-bottom-color: var(--red); }

/* --- Buttons --------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  font-family: var(--display); font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; font-size: .87rem; line-height: 1;
  padding: .85rem 1.4rem; border: 2px solid transparent; border-radius: 0;
  text-decoration: none; cursor: pointer; transition: background .15s, color .15s;
}
.btn-primary  { background: var(--red); color: var(--red-ink); border-color: var(--red); }
.btn-primary:hover { background: transparent; color: var(--red-text); }
.btn-outline  { background: transparent; color: var(--ink); border-color: var(--ink); }
.btn-outline:hover { background: var(--ink); color: var(--ground); }
.btn-phone    { background: var(--ink); color: var(--ground); border-color: var(--ink); font-variant-numeric: tabular-nums; }
.btn-phone:hover { background: var(--red); border-color: var(--red); color: var(--red-ink); }
.btn-ghost    { background: transparent; color: #fff; border-color: rgba(255,255,255,.6); }
.btn-ghost:hover { background: #fff; color: var(--ink); border-color: #fff; }

/* --- Hero ------------------------------------------------------------------ */
.hero { position: relative; background: var(--slab); color: #fff; overflow: hidden; }
/* Contact leads with its form, so that hero is a band rather than a full
   screen. Two classes deep on purpose: it has to beat the min-height the
   62rem query sets on every .hero, whatever the source order. */
.hero.hero-short { min-height: 0; }
/* Overlay is weighted to the left, where the copy sits, and clears away to the
   right so the truck reads properly. Kept just heavy enough behind the text to
   hold white type against the bright sky in the photo. */
.hero::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg, rgba(12,12,12,.76) 0%, rgba(12,12,12,.50) 42%, rgba(12,12,12,.12) 100%);
}
/* Slides stack; only .is-active is visible. Without JS the first slide keeps
   is-active from the markup, so the hero still has a background.
   The slide is oversized by 30% with 15% bleed above and below, which is the
   headroom the parallax travel moves through. .hero clips the overflow. */
.hero img.hero-bg {
  position: absolute;
  top: -15%; left: 0; right: 0;
  width: 100%; height: 130%;
  object-fit: cover;
  opacity: 0;
  transition: opacity .9s ease-in-out;
  will-change: transform;
}
.hero img.hero-bg.is-active { opacity: .9; }

@media (prefers-reduced-motion: reduce) {
  .hero img.hero-bg {
    transition: none;
    transform: none !important;
    top: 0; height: 100%;
  }
}
.hero .shell { position: relative; z-index: 2; padding-block: clamp(3.5rem, 11vw, 7rem); }

/* Pull the hero copy out of the centred column and toward the left edge, where
   the overlay is heaviest. The max() clamps the shift so the text can never be
   pushed past the page gutter on narrower desktops: it simply shifts less. */
:root { --hero-shift: 50px; }
@media (min-width: 62rem) {
  .hero .shell {
    max-width: none;
    margin-inline: 0;
    padding-left: max(var(--gutter), calc((100vw - var(--shell)) / 2 + var(--gutter) - var(--hero-shift)));
    padding-right: var(--gutter);
  }
}

.hero h1 {
  color: #fff; max-width: 16ch;
  text-shadow: 0 2px 14px rgba(0,0,0,.55);
}
.hero .lede {
  max-width: 48ch; font-size: clamp(1rem, 2.2vw, 1.18rem);
  color: rgba(255,255,255,.92); margin-top: 1.1rem;
  text-shadow: 0 1px 10px rgba(0,0,0,.55);
}
.hero .eyebrow { color: var(--red); }
:root[data-theme="light"] .hero .eyebrow { color: #FF6E63; }
@media (prefers-color-scheme: light) { .hero .eyebrow { color: #FF6E63; } }
:root[data-theme="dark"] .hero .eyebrow { color: var(--red); }
.hero .actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1.9rem; }

/* --- Sections -------------------------------------------------------------- */
.band { padding-block: clamp(2.75rem, 7vw, 4.5rem); }
.band + .band { border-top: 1px dashed var(--line); }
.band-panel { background: var(--panel); border-block: 1px solid var(--line); }
.band-dark { background: var(--slab); color: var(--slab-ink); border: 0; }
.band-dark h2, .band-dark h3 { color: #fff; }
.band-dark .eyebrow { color: rgba(255,255,255,.55); }

.band-head { margin-bottom: 2rem; max-width: var(--measure); }
.band-head p { color: var(--muted); }
.band-dark .band-head p { color: rgba(255,255,255,.75); }

/* --- Closing call to action -------------------------------------------------
   "Tell us about the job" closes every page except contact, where the form is
   the CTA. It was a plain .band-dark, which made it read as one more dark
   section rather than the thing we want clicked, so it now carries a red rule,
   the dark concrete tile, larger type and buttons a size up.

   Selector is .band.band-cta, not .band-cta, because `.band + .band` sets a
   dashed top rule at the same 0,2,0 specificity. A single class would lose to
   it no matter where it sat in the file.

   The tile is hardcoded rather than var(--tex-panel) for the --slab reason at
   the top of this file: the token swaps to the LIGHT tile in dark mode, and
   this surface is dark by design and never inverts. */
.band.band-cta {
  border-top: 6px solid #FF5347;
  padding-block: clamp(3.25rem, 8vw, 5.5rem);
  background-image: url("../img/concrete-dark-panel.webp");
  background-repeat: repeat;
  background-size: 512px 512px;
  text-align: center;
}
/* .band-head is capped at --measure, so it needs the auto margins to sit in
   the middle rather than just centring its own text against a left edge. */
.band-cta .band-head { margin-inline: auto; margin-bottom: 2.25rem; }
.band-cta h2 { font-size: clamp(1.85rem, 4.4vw, 2.9rem); }
.band-cta .eyebrow { color: rgba(255,255,255,.86); font-size: .76rem; }
.band-cta .band-head p {
  color: rgba(255,255,255,.94);
  font-size: clamp(1.05rem, 1.5vw, 1.19rem);
  line-height: 1.62;
}

/* Two numbers here are doing accessibility work, not just sizing.

   1.2rem is 19.2px. White on brand red is 5.89:1, which passes AA but misses
   the 7:1 AAA bar for normal text. Above 18.66px and bold, WCAG counts it as
   large text and the bar drops to 4.5:1, so the same red now clears AAA. The
   brand red cannot move, so the type had to.

   3.5rem is 56px, well clear of the 44px minimum target size in WCAG 2.5.5.
   The default .btn lands at about 45px, a pass with nothing spare. */
.cta-actions { display: flex; flex-wrap: wrap; gap: 1rem; justify-content: center; }
.cta-actions .btn { font-size: 1.2rem; padding: 1rem 1.75rem; min-height: 3.5rem; }
.band-cta .btn-ghost { border-color: #fff; }

/* Focus rings on charcoal. The global ring is var(--red); #CC0000 on the slab
   is 3.0:1, the bare WCAG 1.4.11 minimum and close to invisible if your
   contrast sensitivity is reduced. Light ring on dark slabs instead, 14.6:1.
   .call-fab already did this on its own; this generalises it. */
.hero :focus-visible,
.band-dark :focus-visible,
.site-foot :focus-visible { outline-color: var(--slab-ink); }

/* .btn-primary:hover goes transparent with var(--red-text), which in the light
   theme is #A80000. On the charcoal slab that is 2.2:1, so the main CTA became
   unreadable the moment you pointed at it. Dark slabs get a light red instead.
   In dark mode --red-text is already #FF6E63, so this changes nothing there. */
.hero .btn-primary:hover,
.band-dark .btn-primary:hover { color: #FF6E63; border-color: #FF6E63; }

/* --- Grids ----------------------------------------------------------------- */
.grid { display: grid; gap: 1.35rem; }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }

/* auto-fit puts three 20rem tracks across a 76rem shell, so a block of exactly
   four items breaks 3 + 1 orphan on desktop. Add .grid-quad alongside .grid-2
   where the four are deliberate and it holds a 2x2. Below 62rem .grid-2 is
   already giving two columns, so this only bites on desktop. */
@media (min-width: 62rem) {
  .grid-quad { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Contact puts the form beside the "ring us instead" column. At the default
   1.35rem the two read as one block on a wide screen, so widen the gutter
   once there is room for it. Stacked below that, where gap is vertical. */
@media (min-width: 62rem) {
  .grid-contact { column-gap: clamp(2.5rem, 5vw, 4.5rem); }
}

/* --- Service card ---------------------------------------------------------- */
.svc {
  background: var(--panel);
  border: 1px solid var(--line);
  border-top: 4px solid var(--red);
  display: flex; flex-direction: column;
  text-decoration: none; color: inherit;
}
.svc img { aspect-ratio: 3 / 2; object-fit: cover; width: 100%; }
.svc .body { padding: 1.15rem 1.15rem 1.35rem; display: flex; flex-direction: column; gap: .5rem; flex: 1; }
.svc h3 { margin: 0; }
.svc p { font-size: .9rem; color: var(--muted); margin: 0; }
.svc .more {
  font-family: var(--mono); font-size: .72rem; text-transform: uppercase;
  letter-spacing: .1em; color: var(--red-text); margin-top: auto; padding-top: .6rem;
}
a.svc:hover { border-color: var(--red); }
a.svc:hover .more { text-decoration: underline; }

/* --- Feature row (image + copy) -------------------------------------------- */
.feature { display: grid; gap: clamp(1.5rem, 4vw, 3rem); align-items: center; }
@media (min-width: 52rem) {
  .feature { grid-template-columns: 1fr 1fr; }
  .feature.flip .feature-media { order: 2; }
}
.feature-media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border: 1px solid var(--line); }

/* --- Credentials ----------------------------------------------------------- */
.creds { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); }
.creds > div { background: var(--panel); padding: 1.15rem 1rem; }
.band-dark .creds { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.14); }
.band-dark .creds > div { background: var(--slab); }
.creds .fig {
  font-family: var(--display); font-weight: 700; font-size: 1.95rem;
  color: var(--red); line-height: 1; font-variant-numeric: tabular-nums; display: block;
}
.creds .cap {
  font-family: var(--mono); font-size: .68rem; text-transform: uppercase;
  letter-spacing: .09em; color: var(--muted); margin-top: .45rem; display: block; line-height: 1.45;
}
.band-dark .creds .cap { color: rgba(255,255,255,.65); }

/* --- Lists ----------------------------------------------------------------- */
.ticks { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }
.ticks li { position: relative; padding-left: 1.65rem; }
.ticks li::before {
  content: "▚"; position: absolute; left: 0; top: .05em;
  color: var(--red); font-size: .85em;
}

/* --- People ---------------------------------------------------------------- */
.person { border-left: 4px solid var(--red); padding-left: 1.1rem; }
.person .role {
  font-family: var(--mono); font-size: .7rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); display: block; margin-bottom: .2rem;
}
.person h3 { margin-bottom: .5rem; }

/* --- FAQ accordion ----------------------------------------------------------
   <details> on a plain .band, so the panel-filled cards contrast with the body
   concrete behind them. Do not move this onto a .band-panel: same fill, and
   the cards disappear into the section. The plus and minus are two real
   icons toggled by [open], which avoids guessing the icon font's family
   name in a ::after. */
/* Desktop pairs the accordion with a portrait photo so the block balances.
   The photo is hidden below 62rem: on a phone it would push six questions off
   the screen for no gain. */
.faq-layout { display: grid; gap: 2rem; align-items: start; }
.faq-media { display: none; }
@media (min-width: 62rem) {
  .faq-layout { grid-template-columns: minmax(0, 22rem) minmax(0, 1fr); gap: clamp(2rem, 4vw, 3.5rem); }
  .faq-media { display: block; position: sticky; top: 2rem; }
  .faq-media img {
    width: 100%; height: auto; display: block;
    border-radius: var(--radius-img);
    box-shadow: var(--lift);
  }
}

.faq { display: grid; gap: .6rem; max-width: var(--measure); }
.faq details {
  background: var(--panel);
  background-image: var(--tex-panel);
  background-repeat: repeat; background-size: 512px 512px;
  border: 1px solid var(--line);
  border-left: 4px solid var(--red);
}
.faq summary {
  display: flex; align-items: baseline; gap: .9rem;
  padding: .95rem 1.15rem;
  cursor: pointer; list-style: none;
  font-family: var(--display); font-weight: 700;
  font-size: 1rem; line-height: 1.35;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary span { flex: 1; }
.faq summary .fa-solid { color: var(--red); font-size: .8rem; flex: none; }
.faq summary .fa-minus { display: none; }
.faq details[open] summary .fa-plus { display: none; }
.faq details[open] summary .fa-minus { display: inline-block; }
.faq summary:hover { color: var(--red-text); }
.faq summary:focus-visible { outline: 3px solid var(--red); outline-offset: -3px; }
.faq details p {
  margin: 0; padding: 0 1.15rem 1.15rem;
  color: var(--muted); font-size: .95rem;
}

/* Separator between a footer label and its number. Dimmed so it reads as
   punctuation rather than content. */
.sep { opacity: .45; margin-inline: .15em; }

/* Monospace, like every other measured number on the site. */
.abn { font-family: var(--mono); font-variant-numeric: tabular-nums; letter-spacing: .04em; margin: 0; }

/* --- Callout --------------------------------------------------------------- */
.callout { border-left: 4px solid var(--red); background: var(--panel); padding: 1.1rem 1.25rem; }
.callout h3 { margin-top: 0; }

/* --- Out-of-lane strip ------------------------------------------------------
   Full-bleed one-liner naming the work we do not take, on the service pages
   and About. min-height rather than height on purpose: the line wraps below
   about 60rem and a fixed box would clip it, the way the trust bar clips its
   row. Set --lane-h to change the height, nothing else measures it.

   It inverts against the page, the same trick .band-dark uses: --ink and
   --ground swap by theme, so the strip is charcoal on a light page and light
   on a dark one, and can never be mistaken for the section above or below.
   It had the --panel fill and the --panel tile before, which is exactly what
   .band-panel carries, so the two merged into one slab and the strip vanished.
   Flat colour, no tile: the tile is what made it disappear.

   No margin. Every other section on this page stacks flush against its
   neighbours, so this one does too: it starts exactly where the section above
   finishes. The contrast is what separates it now, not a gap.              */
:root { --lane-h: 45px; }

.lane {
  background: var(--ink);
  color: var(--ground);
}
.lane .shell {
  min-height: var(--lane-h);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: .55rem;
  padding-block: .45rem;
  font-size: .95rem;
  line-height: 1.4;
  color: inherit;
}
.lane p { margin: 0; }
.lane i { color: var(--red-invert); flex: none; }

/* --- Forms ----------------------------------------------------------------- */
.form-grid { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); }
.field { display: flex; flex-direction: column; gap: .35rem; }
.field.full { grid-column: 1 / -1; }
.field label { font-family: var(--display); font-weight: 700; font-size: .82rem; text-transform: uppercase; letter-spacing: .05em; }
.field .hint { font-size: .78rem; color: var(--muted); }
.field input, .field select, .field textarea {
  font-family: var(--body); font-size: 1rem; color: var(--ink);
  background: var(--ground); border: 2px solid var(--line); border-radius: 0;
  padding: .7rem .8rem; width: 100%;
}
.field textarea { min-height: 9rem; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--red); outline: none; }
.field .err { color: var(--err); font-size: .82rem; font-weight: 600; }
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"] { border-color: var(--err); }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.notice { border-left: 4px solid var(--err); background: var(--panel); padding: 1rem 1.15rem; margin-bottom: 1.75rem; }
.notice.ok { border-left-color: var(--ok); }
.notice h3 { margin-top: 0; }

/* --- Footer ---------------------------------------------------------------- */
.site-foot { background: var(--slab); color: rgba(255,255,255,.78); padding-block: clamp(2.5rem, 6vw, 3.75rem) 0; margin-top: 0; }
.site-foot h3 { color: #fff; font-size: .84rem; letter-spacing: .08em; margin-bottom: .9rem; }
.site-foot a { color: rgba(255,255,255,.78); text-decoration: none; }
.site-foot a:hover { color: #fff; text-decoration: underline; }
.foot-grid { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); }
.site-foot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .45rem; font-size: .9rem; }
.site-foot .foot-brand img { width: 170px; margin-bottom: 1rem; }
.site-foot address { font-style: normal; font-size: .9rem; line-height: 1.7; }
.site-foot .tel { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.colophon {
  border-top: 1px solid rgba(255,255,255,.16);
  margin-top: 2.5rem; padding-block: 1.25rem 1.5rem;
  display: flex; flex-wrap: wrap; gap: .5rem 1.5rem; justify-content: space-between;
  font-size: .78rem; color: rgba(255,255,255,.55);
}

/* --- Mobile nav ------------------------------------------------------------ */
@media (max-width: 60rem) {
  .nav-toggle-label {
    display: inline-flex; align-items: center; gap: .5rem; cursor: pointer;
    font-family: var(--display); font-weight: 700; font-size: .82rem;
    text-transform: uppercase; letter-spacing: .05em;
    border: 2px solid var(--ink); padding: .6rem .9rem;
  }
  .nav-toggle-label::before { content: "☰"; font-size: 1rem; line-height: 1; }
  .nav { flex-basis: 100%; order: 3; }
  .nav ul { display: none; flex-direction: column; align-items: stretch; gap: 0; padding-bottom: .75rem; }
  .nav a { display: block; padding: .8rem .25rem; border-bottom: 1px solid var(--line); }
  .nav a:hover, .nav a[aria-current="page"] { border-bottom-color: var(--red); }
  .nav-toggle:checked ~ .nav ul { display: flex; }
  .masthead .shell { flex-wrap: wrap; }
  .masthead .btn-quote { display: none; }
}
@media (min-width: 60.0625rem) {
  .nav-toggle-label { display: none; }
}

/* =============================================================================
   Concrete ground, image treatment, icons and utilities
   Square corners stay the rule for buttons and panels. Photographs get a hair
   of softening so the crops stop reading as clipped.
   ============================================================================= */

:root {
  --radius-img: 3px;
  --tex:       url("../img/concrete-light.webp");
  --tex-panel: url("../img/concrete-panel.webp");
  --lift:      0 1px 2px rgba(0,0,0,.05), 0 10px 26px -14px rgba(0,0,0,.30);
  --lift-hi:   0 2px 4px rgba(0,0,0,.07), 0 16px 34px -16px rgba(0,0,0,.38);
}
@media (prefers-color-scheme: dark) {
  :root {
    --tex:       url("../img/concrete-dark.webp");
    --tex-panel: url("../img/concrete-dark-panel.webp");
    --lift:      0 1px 2px rgba(0,0,0,.4), 0 10px 26px -14px rgba(0,0,0,.7);
    --lift-hi:   0 2px 6px rgba(0,0,0,.5), 0 16px 34px -16px rgba(0,0,0,.8);
  }
}
:root[data-theme="dark"] {
  --tex:       url("../img/concrete-dark.webp");
  --tex-panel: url("../img/concrete-dark-panel.webp");
  --lift:      0 1px 2px rgba(0,0,0,.4), 0 10px 26px -14px rgba(0,0,0,.7);
  --lift-hi:   0 2px 6px rgba(0,0,0,.5), 0 16px 34px -16px rgba(0,0,0,.8);
}
:root[data-theme="light"] {
  --tex:       url("../img/concrete-light.webp");
  --tex-panel: url("../img/concrete-panel.webp");
  --lift:      0 1px 2px rgba(0,0,0,.05), 0 10px 26px -14px rgba(0,0,0,.30);
  --lift-hi:   0 2px 4px rgba(0,0,0,.07), 0 16px 34px -16px rgba(0,0,0,.38);
}

/* Seamless 512px tile, generated to match the slab in the soff-cut photo.
   The flat colour stays underneath as the fallback and as the true token. */
body        { background-image: var(--tex); background-repeat: repeat; background-size: 512px 512px; }
.band-panel { background-image: var(--tex-panel); background-repeat: repeat; background-size: 512px 512px; }
.panel,
.svc,
.callout    { background-image: var(--tex-panel); background-repeat: repeat; background-size: 512px 512px; }
.svc img    { background: none; }

/* --- Service cards ---------------------------------------------------------- */
.svc {
  overflow: hidden;
  border-radius: var(--radius-img);
  box-shadow: var(--lift);
  transition: box-shadow .25s ease, transform .25s ease, border-color .25s ease;
}
.svc img {
  transition: transform .5s cubic-bezier(.22,.61,.36,1), filter .35s ease;
  will-change: transform;
}
a.svc:hover, a.svc:focus-visible { box-shadow: var(--lift-hi); transform: translateY(-2px); }
a.svc:hover img, a.svc:focus-visible img { transform: scale(1.045); filter: brightness(1.04); }

/* --- Feature images --------------------------------------------------------- */
.feature-media {
  overflow: hidden;
  border-radius: var(--radius-img);
  box-shadow: var(--lift);
  transition: box-shadow .25s ease;
}
.feature-media img {
  border: 0;
  transition: transform .6s cubic-bezier(.22,.61,.36,1);
  will-change: transform;
}
.feature-media:hover { box-shadow: var(--lift-hi); }
.feature-media:hover img { transform: scale(1.03); }

/* --- Hero: ease the hard bottom edge into the page -------------------------- */
.hero { border-bottom: 3px solid var(--red); }
.hero::before {
  content: ""; position: absolute; inset: auto 0 0 0; height: 5rem; z-index: 1;
  background: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,.22));
  pointer-events: none;
}

/* --- The logo keeps its own edges ------------------------------------------- */
.brand img, .foot-brand img { border-radius: 0; box-shadow: none; background: none; }

/* --- Icons ------------------------------------------------------------------ */
.eyebrow .fa-solid, .eyebrow .fa-regular { margin-right: .4em; color: var(--red); }
h3 .fa-solid { margin-right: .45em; color: var(--red); font-size: .9em; }
.btn .fa-solid { font-size: .95em; }
.svc .more .fa-solid { margin-left: .35em; transition: transform .25s ease; }
a.svc:hover .more .fa-solid { transform: translateX(3px); }
.site-foot ul li .fa-solid { width: 1.1em; margin-right: .5em; opacity: .6; font-size: .8em; }

/* --- Back to top ------------------------------------------------------------ */
.to-top {
  position: fixed; right: clamp(1rem, 3vw, 2rem); bottom: clamp(1rem, 3vw, 2rem);
  z-index: 90; width: 3rem; height: 3rem;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--red); color: var(--red-ink);
  border: 2px solid var(--red); border-radius: 2px;
  box-shadow: var(--lift);
  text-decoration: none; font-size: 1rem; line-height: 1;
  opacity: 0; visibility: hidden; transform: translateY(.65rem);
  transition: opacity .25s ease, transform .25s ease, visibility .25s,
              background .2s ease, color .2s ease;
}
.to-top.is-visible, .to-top:focus { opacity: 1; visibility: visible; transform: translateY(0); }
.to-top:hover { background: var(--ink); border-color: var(--ink); color: #fff; }
.to-top:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; }

/* --- Form utilities --------------------------------------------------------- */
.field label .req {
  font-family: var(--mono); font-size: .6rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--red-text);
  margin-left: .45em; font-weight: 400; vertical-align: .1em;
}
.field input, .field select, .field textarea { background-color: var(--ground); }
.tel-lg { font-family: var(--mono); font-size: 1.15rem; font-variant-numeric: tabular-nums; }

/* --- Motion preferences ----------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .svc, .svc img, .feature-media, .feature-media img, .to-top, .svc .more .fa-solid {
    transition: none !important;
  }
  a.svc:hover, a.svc:focus-visible { transform: none; }
  a.svc:hover img, .feature-media:hover img { transform: none; }
}

/* =============================================================================
   Header, hero sizing and in-hero trust badges
   ============================================================================= */

:root {
  /* Red that still reads against the dark hero and footer. */
  --red-on-dark: #FF6E63;
  /* Approximate stacked height of topbar + masthead, used to size the hero. */
  /* Masthead only since the topbar went. Measured: 171px at 1440, 152px at
     375. site.js overwrites this at runtime; these are the pre-script values. */
  --header-h: 9.5rem;
}

/* --- Header sits on the same concrete as the page --------------------------- */
.masthead {
  background-color: var(--ground);
  background-image: var(--tex);
  background-repeat: repeat;
  background-size: 512px 512px;
}

/* Logo stays at its full presence in the nav bar, sized by width as originally set. */
.brand img { width: clamp(150px, 22vw, 210px); height: auto; }

/* --- Hero fills the viewport ------------------------------------------------
   Hero plus header equals exactly one screen, at every width now, so the photo
   runs to the fold on a phone the same way it does on a desktop. svh, not vh,
   so a mobile browser's collapsing address bar does not overshoot.
   --header-h is measured at runtime by site.js; the :root value is only the
   pre-script fallback. .hero.hero-short opts the contact page out. */
.hero { display: flex; flex-direction: column; min-height: calc(100svh - var(--header-h)); }
.hero .shell {
  flex: 1 1 auto;
  display: flex; flex-direction: column; justify-content: center;
}
@media (min-width: 62rem) {
  :root { --header-h: 10.75rem; }
}

/* --- Charcoal trust bar, pinned to the fold ---------------------------------
   NOTE: the inner wrapper is deliberately NOT .shell. `.hero .shell` above
   carries padding-block up to 7rem, which a descendant .shell would inherit
   and burst straight out of this 25px box. .bar-shell provides the same
   gutters without colliding with that rule.                                  */
:root { --bar-h: 35px; }

.hero-creds {
  position: relative; z-index: 3;
  margin-top: auto;
  height: var(--bar-h);
  background: #383A38;
  border-top: 1px solid rgba(255,255,255,.14);
  overflow: hidden;
}
.hero-creds .bar-shell {
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
  height: var(--bar-h);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.hero-creds .bar-shell::-webkit-scrollbar { display: none; }

.hero-facts {
  list-style: none; margin: 0 auto; padding: 0;
  height: var(--bar-h);
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  /* `safe` keeps the left end reachable if the row ever overflows and has to
     scroll; plain `center` would clip it out of reach. */
  justify-content: center;
  justify-content: safe center;
  gap: 0;
  white-space: nowrap;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: rgba(255,255,255,.84);
}
.hero-facts li {
  display: flex;
  align-items: center;
  gap: .5em;
  padding-inline: 1.1rem;
  height: var(--bar-h);
  line-height: 1;
}
.hero-facts li + li { border-left: 1px solid rgba(255,255,255,.22); }
.hero-facts strong { color: #fff; font-weight: 700; }
.hero-facts .fa-solid {
  color: var(--red-on-dark);
  font-size: 12px;
  line-height: 1;
}
@media (max-width: 44rem) {
  .hero-facts { font-size: 11px; }
  .hero-facts li { padding-inline: .7rem; }
}

/* Between the mobile cut-off (48rem, where the bar is hidden outright) and
   roughly 1050px, four facts do not fit on one line. The row is a scroller
   with scrollbars suppressed, so it did not break visibly, it just clipped
   both ends and put them behind a horizontal scroll gesture no mouse user
   would find. Wrap to two rows instead: nothing hidden, nothing to scroll to.
   The separators come off because a wrapped row starts with a stray rule. */
@media (min-width: 48.0625rem) and (max-width: 65.625rem) {
  .hero-creds, .hero-creds .bar-shell, .hero-facts, .hero-facts li { height: auto; }
  .hero-creds .bar-shell { overflow-x: visible; }
  .hero-facts {
    flex-wrap: wrap;
    justify-content: center;
    row-gap: .35rem;
    padding-block: .45rem;
    font-size: 11px;
  }
  .hero-facts li { padding-inline: .85rem; }
  .hero-facts li + li { border-left: 0; }
}

/* --- Mobile --------------------------------------------------------------- */
/* The .topbar used to be hidden here. It is gone from every width now.
   The trust badges go too: at this width the row had to scroll sideways to
   fit, which is a poor way to read four short facts, and it was eating the
   fold ahead of the hero CTAs. */
/* Hidden by default and switched on inside the mobile query below. This
   declaration must stay above that query: same specificity, so source order
   decides, and a later display:none would win and kill the pill. */
.call-fab { display: none; }

/* Drops in a beat after the page settles, so it reads as an offer rather than
   as part of the furniture. fill-mode both is what holds it invisible during
   the delay; without it the pill would sit there and then jump. Every frame
   repeats translateX(-50%) because the same property carries the centring. */
@keyframes fab-drop {
  from { opacity: 0; transform: translateX(-50%) translateY(-70px); }
  70%  { opacity: 1; transform: translateX(-50%) translateY(6px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* The gradient is two identical periods across a 200% wide image, and the
   sweep travels exactly one period, so the loop has no visible seam. A single
   period would jump back to a different colour at the wrap. */
@keyframes fab-sweep {
  from { background-position: 0% 0; }
  to   { background-position: 100% 0; }
}

@media (max-width: 48rem) {
  :root { --header-h: 9.5rem; }
  .hero-creds { display: none; }

  /* The site number floats instead, so the hero does not need to carry it.
     Only the tel button goes; "Request a quote" stays. */
  .hero .actions .btn-ghost { display: none; }

  /* Centred on the viewport, not tucked in a corner: it is the primary action
     on a phone. translateX keeps it centred whatever the pill is wide.
     .to-top stays bottom right and clears it. */
  /* The 4px of padding IS the border: the gradient lives on the anchor and
     .call-fab-face lays the yellow over the middle of it. A real border cannot
     carry an animated gradient, and border-image cannot be transitioned.
     Hi-vis yellow with near-black on it is 12.9:1, comfortably AAA, and it is
     the one colour pairing that survives every form of colour blindness. */
  .call-fab {
    display: block;
    position: fixed; z-index: 90;
    left: 50%; transform: translateX(-50%);
    bottom: max(clamp(1rem, 3vw, 2rem), env(safe-area-inset-bottom));
    padding: 4px;
    border-radius: 2px;
    background-image: linear-gradient(90deg,
      #CC0000, #FF8A00, #FFD400, #FFFFFF, #FFD400, #FF8A00,
      #CC0000, #FF8A00, #FFD400, #FFFFFF, #FFD400, #FF8A00, #CC0000);
    background-size: 200% 100%;
    box-shadow: var(--lift);
    text-decoration: none;
    animation:
      fab-drop  .7s cubic-bezier(.22,.9,.3,1.25) 2.6s both,
      fab-sweep 3.2s linear 3.3s infinite;
  }
  .call-fab-face {
    display: flex; align-items: center; gap: .5rem;
    padding: .7rem .95rem;
    background: #FFD400; color: #141414;
    font-family: var(--mono); font-size: .85rem; font-weight: 700;
    font-variant-numeric: tabular-nums; letter-spacing: .02em; line-height: 1;
  }
  /* Black ring, not --slab-ink: a light ring disappears against the yellow. */
  .call-fab:focus-visible { outline: 3px solid #141414; outline-offset: 3px; }

  /* Runway under the colophon so the floating pill has somewhere to sit and
     never covers the Dingoblue credit. The pill is about 44px tall and sits
     16px off the bottom, so that is 60px of it, plus the 25px gap asked for. */
  .site-foot .colophon { padding-bottom: calc(60px + 25px); }
}

/* The global reduced-motion rule only shortens durations. This pill starts at
   opacity 0 behind a 2.6s delay, and the delay is not shortened, so on its own
   that rule would leave the number invisible for two and a half seconds and
   then snap it in. Kill both animations outright instead; the static
   transform on .call-fab still centres it. */
@media (prefers-reduced-motion: reduce) {
  .call-fab { animation: none; opacity: 1; }
}

