/*
 * Carpet Clinic - Cleaner Carpets, Healthier Spaces.
 * © 2026 Carpet Clinic - Cleaner Carpets, Healthier Spaces.
 *
 * Brand identity, creative direction, UX/UI and website design
 * by Defined Media — Sydney, Australia
 */
/* ==========================================================================
   Carpet Clinic - Cleaner Carpets, Healthier Spaces.
   Stylesheet built from the Visual Brand & Web Style Guide.
   Do not invent extra blues. Cyan is an accent, navy carries authority,
   white remains the dominant canvas.
   ========================================================================== */

/* --- Fonts -----------------------------------------------------------------
   Creato Display by Anugrah Pasau, licensed under the SIL Open Font License
   1.1 (see assets/fonts/OFL.txt). Web embedding is permitted; the licence
   file must ship with the font files.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "Creato Display";
  src: url("../fonts/CreatoDisplay-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Creato Display";
  src: url("../fonts/CreatoDisplay-Medium.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Creato Display";
  src: url("../fonts/CreatoDisplay-Bold.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}

:root {
  --cc-cyan: #00ADEF;
  --cc-navy: #0C3C88;
  --cc-white: #FFFFFF;
  --cc-off-white: #F7F9FB;
  --cc-ink: #172033;
  --cc-muted: #657080;
  --cc-border: #E4E9EF;
  --cc-font: "Creato Display", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --cc-radius: 10px;
  /* Alert state. Muted and desaturated on purpose: a wrong phone number is a
     typo, not a failure, so it gets a quiet signal rather than a red alarm. */
  --cc-alert: #A2555C;
  --cc-content: 1280px;
  --cc-reading: 780px;

  --pad-section: 72px;
  --pad-section-sm: 62px;
}

/* --- Reset ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--cc-font);
  font-size: 18px;
  font-weight: 400;
  line-height: 1.62;
  color: var(--cc-ink);
  background: var(--cc-white);
  -webkit-font-smoothing: antialiased;
}
img, svg { max-width: 100%; display: block; }
a { color: var(--cc-navy); text-decoration-thickness: 1px; text-underline-offset: 3px; }
h1, h2, h3, h4 { color: var(--cc-navy); line-height: 1.12; margin: 0 0 .5em; font-weight: 700; letter-spacing: -0.015em; }
h1 { font-size: clamp(38px, 5.4vw, 68px); }
h2 { font-size: clamp(30px, 3.6vw, 46px); }
h3 { font-size: clamp(22px, 2vw, 28px); font-weight: 500; }
p { margin: 0 0 1.15em; }
ul { margin: 0; padding: 0; list-style: none; }

:focus-visible {
  outline: 3px solid var(--cc-cyan);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-link {
  /* Clipped rather than pushed off-screen. A large negative offset - whether
     `left` or `inset-inline-start` - lands outside the viewport in one writing
     direction or the other and creates real horizontal overflow. Clipping takes
     the link out of view without occupying any space in either direction. */
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
  top: 0; inset-inline-start: 0; z-index: 200;
  background: var(--cc-navy); color: #fff; padding: 12px 20px;
  border-radius: 0 0 var(--cc-radius) 0;
}
.skip-link:focus { width: auto; height: auto; clip-path: none; }

/* --- Layout --------------------------------------------------------------- */
/* padding-inline, not the padding shorthand: several elements carry .wrap
   alongside a layout class that sets its own padding-block (.footer-brand,
   .footer-top, .hero-grid, .strip-grid). A shorthand here would reset their
   vertical padding to zero wherever it wins on source order. */
.wrap { width: 100%; max-width: var(--cc-content); margin: 0 auto; padding-inline: 28px; }
.reading { max-width: var(--cc-reading); }
.section { padding: var(--pad-section) 0; }
.section--tight { padding: var(--pad-section-sm) 0; }
/* When two same-type sections stack directly, treat it as one shared gap instead of two */
.section + .section { padding-top: 36px; }
.section--tight + .section--tight { padding-top: 36px; }
.section--offwhite { background: var(--cc-off-white); }
.section--navy { background: var(--cc-navy); color: #fff; }
.section--navy h2, .section--navy h3 { color: #fff; }
.centred { text-align: center; }
.centred .lede { margin-left: auto; margin-right: auto; }

/* --- Heading-to-content spacing scale ------------------------------------- */
/* Two steps only: .block-gap for a section's main content, .block-gap--sm for
   sub-blocks (FAQs, nearby links) that sit closer to their heading. */
.block-gap { margin-top: 34px; }
.block-gap--sm { margin-top: 22px; }

.lede { font-size: 19px; color: var(--cc-muted); max-width: 62ch; }
.section--navy .lede { color: rgba(255,255,255,.78); }

.eyebrow {
  font-size: 14px; font-weight: 500; letter-spacing: .09em;
  text-transform: uppercase; color: var(--cc-cyan); margin: 0 0 14px;
}
.rule { width: 56px; height: 3px; background: var(--cc-cyan); border: 0; margin: 0 0 4px; }
.centred .rule { margin-left: auto; margin-right: auto; }

/* --- Numbered commitments on /the-standard/ -------------------------------- */
/* Icon replaces the "1." numbering and sits just after the heading text, so it
   stays tied to the title however the heading wraps. */
/* Sized and offset in em so the icon tracks the heading. These headings are
   26px inside .prose but use the global clamp(30px, 3.6vw, 46px) elsewhere,
   so a fixed pixel box drifts out of alignment as the viewport changes.
   vertical-align = .35em (centre of the cap height) minus half the icon box,
   which sits the icon's centre on the centre of the capitals. */
.step-h-icon {
  width: 1.02em; height: 1.02em; color: var(--cc-cyan);
  display: inline-block; vertical-align: -.16em; margin-left: .42em;
}
.step-h .acc { stroke: var(--cc-navy); }
/* Trophy reads a little smaller than the others at the same box size, so give
   it 10% more room to sit level with them. */
.step-h-icon--trophy { width: 1.12em; height: 1.12em; vertical-align: -.21em; }

/* --- On this page navigation ---------------------------------------------- */
/* Lighter than .terms-toc, which suits a legal page but sits too heavy under a
   service or article heading. */
.page-toc { margin: 28px 0 0; }
.page-toc-label {
  font-size: 13px; font-weight: 500; letter-spacing: .09em;
  text-transform: uppercase; color: var(--cc-muted); margin: 0 0 12px;
}
.page-toc-links { display: flex; flex-wrap: wrap; gap: 8px 9px; }
.page-toc a {
  font-size: 14px; color: var(--cc-navy); text-decoration: none;
  padding: 6px 13px; border: 1px solid var(--cc-border); border-radius: 40px;
  background: #fff; transition: border-color .2s ease, color .2s ease;
}
.page-toc a:hover, .page-toc a:focus-visible { color: var(--cc-cyan); border-color: var(--cc-cyan); }
/* Clear the sticky header when jumping to a section. */
.prose h2 { scroll-margin-top: 96px; }

/* --- Stain type headings on the spills article ----------------------------- */
/* Leading icon, aligned in a column, because this section is a reference list
   people scan rather than read straight through. */
.stain-h {
  display: grid; grid-template-columns: 1.55em 1fr; align-items: center;
  column-gap: .72em;
}
.stain-h-icon { width: 1.35em; height: 1.35em; color: var(--cc-navy); justify-self: center; }
.stain-h .acc { stroke: var(--cc-cyan); }

/* --- Header --------------------------------------------------------------- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(255,255,255,.96);
  backdrop-filter: saturate(180%) blur(8px);
  border-bottom: 1px solid var(--cc-border);
}
.header-inner { display: flex; align-items: center; gap: 28px; min-height: 84px; }
.logo { flex: 0 0 auto; }
.logo img { width: var(--logo-w); height: auto; max-width: 100%; }
/* Leave room for the language selector so the quote button stays inside .wrap. */
.nav { margin-left: auto; display: flex; align-items: center; gap: 20px; }
.nav a {
  font-size: 16px; white-space: nowrap; font-weight: 500; color: var(--cc-navy);
  text-decoration: none; padding: 6px 0; border-bottom: 2px solid transparent;
}
.nav a:hover, .nav a[aria-current="page"] { border-bottom-color: var(--cc-cyan); }
.nav a.btn { padding: 13px 22px; border-bottom: 1.5px solid transparent; color: #fff; }
.nav a.btn:hover { border-bottom-color: transparent; }
.nav .tel { display: inline-flex; align-items: center; gap: 8px; }
.nav-toggle {
  display: none; margin-left: auto; background: none; border: 1px solid var(--cc-border);
  border-radius: var(--cc-radius); padding: 10px 14px; font: inherit; font-size: 15px;
  font-weight: 500; color: var(--cc-navy); cursor: pointer;
}

/* --- Buttons -------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 15px 26px; border-radius: var(--cc-radius);
  font-size: 16px; font-weight: 500; text-decoration: none;
  border: 1.5px solid transparent; transition: background .18s ease, color .18s ease, border-color .18s ease;
}
.btn--primary { background: var(--cc-cyan); color: #fff; }
.btn--primary:hover { background: #0098d1; }
.btn--ghost { border-color: var(--cc-border); color: var(--cc-navy); background: #fff; }
.btn--ghost:hover { border-color: var(--cc-cyan); }
.btn--onnavy { background: var(--cc-cyan); color: #fff; }
.btn--onnavy:hover { background: #22bcf5; }
.btn--outline-light { border-color: rgba(255,255,255,.4); color: #fff; }
.btn--outline-light:hover { border-color: #fff; }
.btn-row { display: flex; flex-wrap: wrap; gap: 14px; margin: 30px 0 0; }

/* --- Hero ----------------------------------------------------------------- */
.hero { border-bottom: 1px solid var(--cc-border); }
.hero-grid {
  display: grid; grid-template-columns: 1.02fr .98fr; gap: 56px; align-items: center;
  padding-block: 52px 60px;
}
.hero h1 { margin-bottom: .34em; }
.hero h1 .alt { color: var(--cc-cyan); display: block; }
.hero-media {
  border-radius: var(--cc-radius); overflow: hidden; background: var(--cc-off-white);
  aspect-ratio: 4 / 3; border: 1px solid var(--cc-border);
}
.hero-media img { width: 100%; height: 100%; object-fit: cover; }

.assurances { display: flex; flex-wrap: wrap; gap: 12px 30px; margin: 34px 0 0; }
.assurances li { display: flex; align-items: center; gap: 9px; font-size: 15px; color: var(--cc-muted); }
.tick { flex: 0 0 auto; width: 18px; height: 18px; color: var(--cc-cyan); }

/* --- Trust strip ---------------------------------------------------------- */
.strip { background: var(--cc-off-white); border-bottom: 1px solid var(--cc-border); }
.strip-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; padding-block: 40px;
}
.strip-item { padding: 0 30px; border-left: 1px solid var(--cc-border); }
.strip-item:first-child { border-left: 0; padding-left: 0; }
.strip-item h3, .strip-item .strip-heading { font-size: 18px; font-weight: 700; margin-bottom: .45em; }
.strip-item p { font-size: 15px; color: var(--cc-muted); margin: 0; }
.strip-icon { width: 30px; height: 30px; color: var(--cc-cyan); margin-bottom: 16px; }

/* --- The Standard (signature navy section) -------------------------------- */
.section--navy { padding-block: var(--pad-section); }
/* Both columns span the same band: the icon grid stretches to the height of
   the text column and distributes its three rows across it, so the tops and
   bottoms of the two columns line up. */
.standard-grid { display: grid; grid-template-columns: 340px 1fr; gap: 64px; align-items: stretch; }
.standard-grid > :last-child { display: grid; }
.standard-steps {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 34px 26px;
  height: 100%; grid-auto-rows: 1fr; align-content: stretch;
}
/* Each cell is the same height and its icon sits at the cell top, so the three
   icon rows line up even when one label runs to two lines. */
.standard-step {
  text-align: center; display: flex; flex-direction: column;
  align-items: center; justify-content: flex-start;
}
.standard-step .icon { width: 36px; height: 36px; margin: 0 auto 14px; color: #fff; flex: 0 0 auto; }
.standard-step p {
  font-size: 14.5px; line-height: 1.45; color: rgba(255,255,255,.88); margin: 0;
  /* Two lines are reserved for every label so a wrapping one does not sit
     lower than its neighbours. */
  min-height: calc(2 * 1.45em);
}

/* The text column runs full height with the button pinned to the bottom, so
   it finishes level with the last row of icons instead of hanging below it. */
.standard-grid > :first-child { display: flex; flex-direction: column; }
.standard-grid > :first-child .btn-row { margin-top: auto; margin-bottom: 0; }

/* --- Cards ---------------------------------------------------------------- */
.cards { display: grid; gap: 26px; }
.cards--5 { grid-template-columns: repeat(5, 1fr); }
.cards--4 { grid-template-columns: repeat(4, 1fr); }
.cards--3 { grid-template-columns: repeat(3, 1fr); }
.card {
  background: #fff; border: 1px solid var(--cc-border); border-radius: var(--cc-radius);
  padding: 30px 26px; display: flex; flex-direction: column;
  transition: border-color .18s ease, transform .18s ease;
}
.card:hover { border-color: var(--cc-cyan); }
.card .icon { width: 40px; height: 40px; color: var(--cc-cyan); margin-bottom: 20px; }
.card h3 { font-size: 20px; font-weight: 700; margin-bottom: .5em; }
.card p { font-size: 15.5px; color: var(--cc-muted); margin-bottom: 1.2em; }
.card .more { margin-top: auto; font-size: 15px; font-weight: 500; color: var(--cc-cyan); text-decoration: none; }
.card .more:hover { text-decoration: underline; }

/* --- Owner / local -------------------------------------------------------- */
.split { display: grid; grid-template-columns: 1fr 1.05fr; gap: 60px; align-items: center; }
.split-media { border-radius: var(--cc-radius); overflow: hidden; border: 1px solid var(--cc-border); aspect-ratio: 3 / 2; background: var(--cc-off-white); }
.split-media img { width: 100%; height: 100%; object-fit: cover; }

/* --- Areas ---------------------------------------------------------------- */
.area-cols { display: grid; grid-template-columns: repeat(4, 1fr); gap: 34px; }
.area-col h3 { font-size: 17px; font-weight: 700; margin-bottom: .8em; }
.area-col li { margin-bottom: 7px; }
.area-col a { font-size: 15.5px; color: var(--cc-muted); text-decoration: none; }
.area-col a:hover { color: var(--cc-navy); text-decoration: underline; }

.suburb-index { columns: 4; column-gap: 34px; }
.suburb-index li { break-inside: avoid; margin-bottom: 9px; }
.suburb-index a { font-size: 16px; text-decoration: none; color: var(--cc-ink); }
.suburb-index a:hover { color: var(--cc-cyan); }

/* --- Article / suburb body ------------------------------------------------ */
.crumbs { font-size: 14.5px; color: var(--cc-muted); padding-block: 26px 0; }
.crumbs a { color: var(--cc-muted); text-decoration: none; }
.crumbs a:hover { color: var(--cc-navy); text-decoration: underline; }
.crumbs span { margin: 0 8px; opacity: .5; }

.page-head { padding: 0 0 8px; }
/* Kicker H2 directly under the H1: real heading, sized below the H1 but given
   presence with weight and the cyan rule motif used elsewhere on the site.
   Cyan text was ruled out here: #00ADEF on white is 2.55:1, under the 3:1
   minimum for large text. */
.page-kicker {
  font-size: clamp(20px, 2vw, 26px); font-weight: 700;
  color: var(--cc-navy); margin: .45em 0 30px; line-height: 1.3;
}
h2.page-kicker { font-size: clamp(22px, 2.2vw, 30px); }
.page-kicker::after {
  content: ""; display: block; width: 72px; height: 4px;
  background: var(--cc-cyan); border-radius: 2px; margin-top: 18px;
}
.prose { max-width: var(--cc-reading); }

/* --- Numbered commitment panels (The Standard) ----------------------------
   Ten sections of continuous prose read as one long undifferentiated column,
   so each commitment sits in a panel using the same border, radius and
   off-white as the cards elsewhere. Stacked rather than gridded on purpose:
   the sections vary from 40 to 180 words, and in a grid a short panel leaves
   a hole beside a tall one on every row. Panels run to 980px rather than the
   780px reading measure, which uses some of the empty column without
   stretching the line length. */
.commit-list { max-width: 980px; }
.commit {
  background: #fff; border: 1px solid var(--cc-border);
  border-radius: var(--cc-radius); padding: 32px 36px; margin: 0 0 16px;
}
.commit:nth-child(even) { background: var(--cc-off-white); border-color: transparent; }
.commit > .commit-head { display: flex; align-items: center; margin-bottom: 12px; }
/* Unnumbered panels (About) have no counter, so the heading sits flush. */
.commit-head > .step-h:first-child { margin-left: 0; }
.commit-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: 0 0 auto; margin-right: 14px;
  border-radius: 50%; background: var(--cc-cyan); color: #fff;
  font-size: 15px; font-weight: 700; line-height: 1;
}
.commit .step-h { font-size: 23px; margin: 0; }
.commit p { max-width: 68ch; }
.commit p:last-child { margin-bottom: 0; }
@media (max-width: 760px) {
  .commit { padding: 26px 22px; }
  .commit-num { width: 30px; height: 30px; font-size: 14px; margin-right: 12px; }
  .commit .step-h { font-size: 20px; }
}

.faq { max-width: var(--cc-reading); }
.faq-item { border-top: 1px solid var(--cc-border); padding: 26px 0; }
.faq-item:last-child { border-bottom: 1px solid var(--cc-border); }
.faq-item h3 { font-size: 19px; font-weight: 700; margin-bottom: .4em; }
.faq-item p { font-size: 16.5px; color: var(--cc-muted); margin: 0; }

.nearby { display: flex; flex-wrap: wrap; gap: 10px; }
.nearby a {
  font-size: 15px; text-decoration: none; color: var(--cc-navy);
  border: 1px solid var(--cc-border); border-radius: 100px; padding: 8px 16px; background: #fff;
}
.nearby a:hover { border-color: var(--cc-cyan); }

/* --- A-Z suburb index (Service Areas hub) ---------------------------------- */
.az-filter { margin: 26px 0 0; max-width: 460px; position: relative; }
/* On the homepage the finder sits directly above the region chips, so it is
   sized and shaped to read as part of that group rather than a separate form. */
.section--offwhite .az-filter { max-width: 520px; }
.az-filter + .nearby { margin-top: 20px; }
.az-field { position: relative; display: block; }
.az-icon {
  position: absolute; left: 17px; top: 50%; transform: translateY(-50%);
  width: 19px; height: 19px; color: var(--cc-muted); pointer-events: none;
}
.az-input {
  width: 100%; font: inherit; font-size: 16px; color: var(--cc-ink);
  padding: 13px 18px 13px 46px; background: #fff;
  border: 1px solid var(--cc-border); border-radius: 100px;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.az-input::placeholder { color: var(--cc-muted); }
.az-input:focus {
  outline: none; border-color: var(--cc-cyan);
  box-shadow: 0 0 0 3px rgba(0,173,239,.22);
}
.az-field:focus-within .az-icon { color: var(--cc-cyan); }
.az-status { font-size: 14px; color: var(--cc-muted); margin: 9px 0 0; min-height: 1.1em; }
.az-results {
  margin-top: 8px; background: #fff;
  border: 1px solid var(--cc-border); border-radius: var(--cc-radius);
  padding: 8px; box-shadow: 0 6px 22px rgba(12,60,136,.09);
}
.az-hits { list-style: none; margin: 0; padding: 0; }
.az-hits li { margin: 0; }
.az-hits a {
  display: block; padding: 9px 12px; border-radius: 7px;
  color: var(--cc-ink); text-decoration: none; font-size: 15.5px;
}
.az-hits a:hover, .az-hits a:focus {
  background: var(--cc-off-white); color: var(--cc-navy); outline: none;
}
.az-hits a:focus-visible { box-shadow: inset 0 0 0 2px var(--cc-cyan); }
.az-more, .az-none { font-size: 14.5px; color: var(--cc-muted); margin: 6px 0 4px; padding: 0 12px; }
.az-none a { color: var(--cc-navy); }
[hidden] { display: none !important; }

/* --- CTA band ------------------------------------------------------------- */
.cta-band { background: var(--cc-navy); color: #fff; text-align: center; }
.cta-band h2 { color: #fff; margin-bottom: .3em; }
.cta-band .lede { color: rgba(255,255,255,.78); margin-left: auto; margin-right: auto; }
.cta-band .btn-row { justify-content: center; }

/* --- Footer --------------------------------------------------------------- */
.site-footer { background: var(--cc-navy); color: rgba(255,255,255,.72); font-size: 15px; }
.footer-brand {
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; flex-wrap: wrap;
  padding-block: 40px 28px;
  border-bottom: 1px solid rgba(255,255,255,.16);
}
.footer-top {
  display: grid; grid-template-columns: 1.35fr 1fr 1fr .85fr;
  gap: 38px 40px; padding-block: 38px 42px; align-items: start;
}
.site-footer h4, .site-footer .footer-heading { color: #fff; font-size: 15px; font-weight: 700; margin: 0 0 16px; letter-spacing: .02em; }
.site-footer a { color: rgba(255,255,255,.72); text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
.site-footer li { margin-bottom: 8px; }
.footer-logo { display: inline-block; }
.footer-logo img { width: var(--logo-w); height: auto; max-width: 100%; display: block; }
.footer-contact li { display: block; }
.footer-subheading {
  color: #fff; font-size: 13px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  margin: 14px 0 8px; opacity: .85;
}
.footer-hours { margin: 0; }
.footer-hours li { display: flex; justify-content: space-between; gap: 14px; max-width: 240px; margin-bottom: 5px; }
.footer-hours .day { color: rgba(255,255,255,.72); }
.footer-hours .time { color: rgba(255,255,255,.9); white-space: nowrap; }
.footer-legal {
  border-top: 1px solid rgba(255,255,255,.16); padding-block: 22px 30px;
  display: flex; flex-wrap: wrap; gap: 12px 32px; align-items: baseline;
  justify-content: space-between;
  font-size: 13.5px; color: rgba(255,255,255,.6);
}
/* four items spread evenly across the bar: copyright, ABN, legal links, credit */
.footer-legal > * { flex: 0 1 auto; }
.footer-legal > *:last-child { text-align: right; }
/* Between these widths the four items no longer fit on one line, so pair them
   into a 2x2 block rather than letting the last one orphan onto its own row. */
@media (min-width: 761px) and (max-width: 1080px) {
  .footer-legal > * { flex: 0 1 calc(50% - 16px); }
  /* .made-by is a flex container, so it needs justify-content rather than
     text-align to sit flush against the right edge. */
  .footer-legal > *:nth-child(even) { text-align: right; justify-content: flex-end; }
  .footer-legal > *:nth-child(odd) { text-align: left; justify-content: flex-start; }
}
@media (max-width: 760px) {
  .footer-legal { justify-content: flex-start; gap: 8px 0; }
  .footer-legal > * { flex: 1 1 100%; text-align: left; }
  .footer-legal > *:last-child { text-align: left; }
  .footer-legal > .footer-business-identity { flex: 1 1 100%; }
}

/* --- Responsive ----------------------------------------------------------- */
@media (max-width: 1080px) {
  .cards--5 { grid-template-columns: repeat(3, 1fr); }
  .standard-grid { grid-template-columns: 1fr; gap: 40px; }
  .suburb-index { columns: 3; }
  .footer-top { grid-template-columns: 1fr 1fr; gap: 36px 32px; }
}
@media (max-width: 860px) {
  :root { --pad-section: 60px; --pad-section-sm: 44px; }
  body { font-size: 17px; }
  .header-inner { min-height: 72px; }
  .hero-grid { grid-template-columns: 1fr; gap: 36px; padding-block: 36px 44px; }
  .hero-media { aspect-ratio: 16 / 10; }
  .strip-grid { grid-template-columns: 1fr 1fr; gap: 34px 0; padding-block: 44px; }
  .strip-item { padding: 0 20px; }
  .strip-item:nth-child(odd) { border-left: 0; padding-left: 0; }
  .cards--5, .cards--4, .cards--3 { grid-template-columns: 1fr; }
  .split { grid-template-columns: 1fr; gap: 34px; }
  .area-cols { grid-template-columns: 1fr 1fr; }
  .suburb-index { columns: 2; }
  .footer-top { grid-template-columns: 1fr; gap: 30px; padding-block: 34px 40px; }
  .footer-brand { padding-block: 40px 24px; }
}
/* Mobile call button.
   Below 1110px the whole nav collapses behind the Menu button, and the phone
   number lives inside that nav. For a trade where most enquiries arrive by
   phone, that put a tap between the visitor and the call on every page. This
   sits beside Menu in the sticky header so the number is always one tap away.
   Hidden on desktop, where the number is already visible in the nav. */
.header-call { display: none; }
@media (max-width: 1110px) {
  .header-call {
    display: inline-flex; align-items: center; gap: 8px;
    margin-left: auto; flex: 0 0 auto;
    padding: 10px 14px; border-radius: var(--cc-radius);
    background: var(--cc-navy); color: #fff;
    font-size: 15px; font-weight: 500; text-decoration: none;
    transition: background .2s ease;
  }
  .header-call:hover, .header-call:focus-visible { background: var(--cc-cyan); color: #fff; }
  .header-call-icon { width: 18px; height: 18px; flex: 0 0 auto; }
  /* The nav toggle had margin-left:auto to push itself right. The call button
     now owns that job, or the two would fight for the same free space. */
  .nav-toggle { margin-left: 0; }
  .header-inner { gap: 10px; }
}
/* Narrow handsets: drop the word and keep the icon, so the logo, call button
   and Menu still fit on one line without the page scrolling sideways. */
@media (max-width: 480px) {
  .header-call span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .header-call { padding: 11px 12px; }
}

/* Service-areas hub: 164 suburb blurbs across eight regions. Two columns on
   desktop is a browsable directory; one column on a phone is several thousand
   pixels of scrolling before the next region heading. Each region already ends
   with an "All N suburbs" link, so the tail is hidden on narrow screens and
   that link carries the rest. Hidden rather than omitted, so every suburb link
   stays in the markup for crawlers. */
@media (max-width: 860px) {
  .suburb-blurbs > div:nth-child(n+7) { display: none; }
}

/* Homepage "Latest Advice": all nine articles are in the HTML, which suits
   desktop's three-column grid. Once the grid collapses to one column the
   full list becomes a long scroll before the button below it, so the tail is
   hidden on narrow screens and the "View All Articles" button carries the
   rest. Hidden rather than omitted, so the links stay in the markup. */
@media (max-width: 860px) {
  .advice-teasers > .card:nth-child(n+4) { display: none; }
}

@media (max-width: 520px) {
  .standard-steps { grid-template-columns: repeat(2, 1fr); }
  .area-cols, .suburb-index { grid-template-columns: 1fr; columns: 1; }
  .wrap { padding-inline: 20px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- Content pages (services / advice / areas hub) ------------------------ */
.prose h2 { font-size: 26px; margin: 1.7em 0 .55em; }
.prose h3 { font-size: 19px; margin: 1.5em 0 .45em; }
.prose ul, .prose ol { padding-left: 24px; margin: 0 0 1.1em; }
.prose li { margin-bottom: .35em; font-size: 17px; }
.prose .inline-more { display: inline-block; font-weight: 500; color: var(--cc-cyan); text-decoration: none; }
.prose .inline-more:hover { text-decoration: underline; }
.suburb-blurbs { display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px 44px; margin-top: 36px; max-width: 1040px; }
.suburb-blurbs .sname { font-weight: 700; font-size: 17px; color: var(--cc-navy); text-decoration: none; }
.suburb-blurbs .sname:hover { color: var(--cc-cyan); }
.suburb-blurbs p { margin: .3em 0 0; font-size: 15px; color: var(--cc-muted); }
@media (max-width: 760px) {
  .suburb-blurbs { grid-template-columns: 1fr; }
}

/* --- Service-areas hub: suburb blurbs -------------------------------------- */
.suburb-blurbs { display: grid; grid-template-columns: repeat(2, 1fr); gap: 26px 44px; margin-top: 38px; }
.suburb-blurbs a.sname { font-size: 17px; font-weight: 700; color: var(--cc-navy); text-decoration: none; }
.suburb-blurbs a.sname:hover { color: var(--cc-cyan); }
.suburb-blurbs p { margin: .3em 0 0; font-size: 15px; line-height: 1.5; color: var(--cc-muted); }

/* --- Inline article links --------------------------------------------------- */
.prose .inline-more { display: inline-block; font-weight: 500; color: var(--cc-cyan); text-decoration: none; }
.prose .inline-more:hover { text-decoration: underline; }
.prose h2 { margin-top: 1.9em; }
.prose h3 { margin-top: 1.4em; font-size: 20px; }

/* --- Homepage reviews (renders only when real reviews exist) ---------------- */
.review-card .review-quote { font-size: 16.5px; color: var(--cc-ink); }
.review-card .review-name { margin: 0; font-size: 15px; font-weight: 500; color: var(--cc-muted); }

/* --- Nine-step Standard band ------------------------------------------------ */
@media (max-width: 900px) { .suburb-blurbs { grid-template-columns: 1fr; } }

/* --- Quiet motion (gated on html.anim, which is never set when the visitor
       prefers reduced motion) ------------------------------------------------ */
@keyframes cc-rise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
html.anim .hero h1 { animation: cc-rise .6s ease both; }
html.anim .hero .lede { animation: cc-rise .6s .12s ease both; }
html.anim .hero .btn-row { animation: cc-rise .6s .22s ease both; }
html.anim .hero .assurances { animation: cc-rise .6s .32s ease both; }
html.anim .hero-media { animation: cc-rise .7s .15s ease both; }
html.anim .rv { opacity: 0; transform: translateY(14px); transition: opacity .5s ease, transform .5s ease; }
html.anim .rv.in { opacity: 1; transform: none; }

.site-header { transition: box-shadow .25s ease; }
.site-header.is-scrolled { box-shadow: 0 4px 18px rgba(12, 60, 136, .08); }

.card { transition: border-color .25s ease, box-shadow .25s ease, transform .25s ease; }
.card:hover { transform: translateY(-3px); box-shadow: 0 12px 28px rgba(12, 60, 136, .10); }
.btn { transition: background .2s ease, border-color .2s ease, transform .15s ease; }
.btn:hover { transform: translateY(-1px); }
.nearby a { transition: border-color .2s ease, transform .15s ease; }
.nearby a:hover { transform: translateY(-1px); }
.standard-step .icon { transition: transform .25s ease, color .25s ease; }
.standard-step:hover .icon { transform: translateY(-2px); color: var(--cc-cyan); }
.suburb-blurbs a.sname { transition: color .2s ease; }

/* Arrow leads the link on hover. The glyph moves, not the whole label, so the
   text stays put and nothing reflows. */
.arw { display: inline-block; transition: transform .18s ease; }
a:hover > .arw, a:focus-visible > .arw { transform: translateX(4px); }

/* Cross-document view transitions. This is a 419-page static site, so every
   click is a full document load and a white flash between pages. A short
   cross-fade removes that without touching the markup or adding any script.
   Browsers without support ignore the whole block and navigate as before. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  ::view-transition-old(root),
  ::view-transition-new(root) { animation-duration: .22s; }
  /* The header is identical on every page, so name it and it persists through
     the transition instead of fading out and back in with the body. */
  .site-header { view-transition-name: cc-header; }
}

@media (prefers-reduced-motion: reduce) {
  html.anim .rv, html.anim .hero h1, html.anim .hero .lede, html.anim .hero .btn-row,
  html.anim .hero .assurances, html.anim .hero-media { animation: none; transition: none; opacity: 1; transform: none; }
  .card:hover, .btn:hover, .nearby a:hover, .standard-step:hover .icon { transform: none; }
  a:hover > .arw, a:focus-visible > .arw { transform: none; }
}

/* --- Service-area region figures -------------------------------------------- */
.area-head { display: grid; grid-template-columns: 1fr 400px; gap: 44px; align-items: start; }
.area-figure { margin: 22px 0 0; }
.area-figure img { width: 100%; height: auto; border-radius: var(--cc-radius); border: 1px solid var(--cc-border); display: block; }
@media (max-width: 940px) { .area-head { grid-template-columns: 1fr; gap: 10px; } .area-figure { max-width: 460px; } }

/* --- Footer social icons ----------------------------------------------------- */
.social-row { display: flex; gap: 14px; }
.social-row a {
  color: #9DB4D6; transition: color .2s ease, transform .15s ease, background .2s ease;
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: 100px;
  background: rgba(255,255,255,.06);
}
.social-row a:hover, .social-row a:focus-visible {
  color: var(--cc-cyan); transform: translateY(-1px); background: rgba(255,255,255,.12);
}

/* --- Optical logo alignment --------------------------------------------------
   The logo SVGs are trimmed exactly to their artwork, so geometrically the
   header logo, page text and footer logo already share one left edge. This
   variable nudges both logos for OPTICAL alignment (round C vs type side
   bearing). Positive moves the logos right. Tune by eye in DevTools; expect
   to revisit once the Creato Display webfonts are installed. */
:root { --logo-w: 263px;
  --logo-align: 0px; }
.logo img, .footer-logo img { margin-left: var(--logo-align); }

/* --- Bespoke icon accents ----------------------------------------------------- */
.icon .acc, .tick .acc { stroke: var(--cc-cyan); }
.standard-step .icon .acc { stroke: var(--cc-cyan); }

/* --- Quote CTA: a contained card, clearly separate from the footer ------------ */
.cta-section { padding: 28px 0 56px; }
.section + .cta-section { padding-top: 48px; }
.section:has(+ .cta-section) { padding-bottom: 44px; }
.cta-card {
  background: var(--cc-navy); border-radius: 16px; padding: 44px 48px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 40px; flex-wrap: wrap; box-shadow: 0 18px 44px rgba(12, 60, 136, .16);
}
.cta-card h2 { color: #fff; margin-bottom: .25em; font-size: clamp(24px, 2.6vw, 32px); }
.cta-card .lede { color: rgba(255,255,255,.78); font-size: 17px; margin: 0; max-width: 560px; }
.cta-card .btn-row { margin: 0; flex: 0 0 auto; }
@media (max-width: 820px) { .cta-card { flex-direction: column; align-items: flex-start; padding: 34px 30px; } }

/* --- Footer credit ------------------------------------------------------------ */
.made-by { display: inline-flex; align-items: center; gap: 5px; }
.made-by svg { color: var(--cc-cyan); flex: 0 0 auto; }
.made-by a { color: rgba(255,255,255,.78); text-decoration: none; border-bottom: 1px solid transparent; transition: color .2s ease, border-color .2s ease; }
.made-by a:hover, .made-by a:focus-visible { color: #fff; border-bottom-color: var(--cc-cyan); }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --- Terms page --------------------------------------------------------------- */
.terms-meta { font-size: 14.5px; color: var(--cc-muted); margin: 0 0 26px; }
.terms-toc { display: flex; flex-wrap: wrap; gap: 8px 10px; margin: 0 0 44px; padding: 24px; background: var(--cc-off-white); border-radius: var(--cc-radius); }
.terms-toc a { font-size: 14px; color: var(--cc-navy); text-decoration: none; padding: 5px 11px; border: 1px solid var(--cc-border); border-radius: 40px; background: #fff; transition: border-color .2s ease, color .2s ease; }
.terms-toc a:hover { color: var(--cc-cyan); border-color: var(--cc-cyan); }
.terms-body { max-width: var(--cc-reading); }
.terms-body h2 { font-size: 21px; scroll-margin-top: 96px; }
.terms-body li { font-size: 16px; margin-bottom: 4px; }
.footer-legal a { color: rgba(255,255,255,.78); text-decoration: none; border-bottom: 1px solid transparent; transition: color .2s ease, border-color .2s ease; }
.footer-legal a:hover { color: #fff; border-bottom-color: var(--cc-cyan); }

/* --- Body copy lists ---------------------------------------------------------
   The global `ul { list-style: none }` reset above is right for nav, footer and
   pill lists, but body copy needs markers, so they are restored here. */
.prose ul, .terms-body ul { list-style: disc; padding-left: 22px; }
.prose ul ul { list-style: circle; }
.prose ol, .terms-body ol { list-style: decimal; padding-left: 22px; }
.prose li::marker, .terms-body li::marker { color: var(--cc-muted); }

/* --------------------------------------------------------------------------
   Quote form
   -------------------------------------------------------------------------- */
.quote-grid {
  display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: 48px; align-items: start; margin-top: 40px;
}
.quote-form { max-width: 640px; }
.field { margin: 0 0 24px; border: 0; padding: 0; min-width: 0; }
.field > label, .field > legend {
  display: block; font-weight: 600; font-size: 15.5px;
  color: var(--cc-navy); margin: 0 0 8px; padding: 0;
}
.req {
  font-weight: 500; font-size: 12.5px; color: var(--cc-muted);
  text-transform: uppercase; letter-spacing: .06em; margin-left: 6px;
}
.field input[type="text"], .field input[type="tel"], .field input[type="email"],
.field select, .field textarea {
  width: 100%; font: inherit; font-size: 16px; color: inherit;
  padding: 12px 14px; background: #fff;
  border: 1px solid var(--cc-border); border-radius: var(--cc-radius);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.field textarea { resize: vertical; min-height: 96px; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--cc-cyan);
  box-shadow: 0 0 0 3px rgba(0, 173, 239, .18);
}
.field input[type="file"] { font-size: 16px; width: 100%; padding: 10px 0; }
.field input[type="file"]:focus-visible { outline: 3px solid var(--cc-cyan); outline-offset: 2px; }
.hint { margin: 7px 0 0; font-size: 14px; color: var(--cc-muted); line-height: 1.5; }

/* Inline validation. The browser's own bubble cannot be styled, so the script
   turns off native reporting and writes these messages instead. They only
   appear once a field has been left or the form submitted, never while the
   person is still part-way through typing. */
/* Deliberately quiet. No icon, no panel, no red text: the message reads in
   navy like the rest of the form, and the only colour is a soft muted tone on
   the input border. A mistyped number is a typo, not an error state worth
   shouting about. */
.field-error {
  margin: 8px 0 0; font-size: 14px; line-height: 1.5;
  color: var(--cc-navy); font-weight: 500;
}
.field input.is-invalid, .field textarea.is-invalid, .field select.is-invalid {
  border-color: var(--cc-alert);
}
.field input.is-invalid:focus, .field textarea.is-invalid:focus,
.field select.is-invalid:focus {
  border-color: var(--cc-alert);
  box-shadow: 0 0 0 3px rgba(162, 85, 92, .14);
}
}
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 20px; }

.check-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 20px; }
.check {
  display: flex; align-items: flex-start; gap: 10px;
  font-size: 15.5px; font-weight: 400; color: var(--cc-ink, inherit);
  padding: 6px 0; cursor: pointer; line-height: 1.4;
}
/* Drawn rather than left to accent-color: Chrome picks the tick colour itself
   and chooses a dark one against a light accent, which gave a black tick on
   the cyan fill. */
.check input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 24px; height: 24px; margin: 0; flex: 0 0 auto;
  border: 1px solid var(--cc-border); border-radius: 6px; background: #fff;
  cursor: pointer; transition: background-color .12s ease, border-color .12s ease;
  display: inline-block; position: relative;
}
.check input[type="checkbox"]:hover { border-color: var(--cc-cyan); }
.check input[type="checkbox"]:checked {
  background-color: var(--cc-cyan); border-color: var(--cc-cyan);
}
/* White tick, drawn as two borders on a rotated box so it scales cleanly and
   needs no image request. */
.check input[type="checkbox"]:checked::after {
  content: ""; position: absolute;
  left: 8px; top: 4px; width: 6px; height: 11px;
  border: solid #fff; border-width: 0 2.5px 2.5px 0;
  transform: rotate(43deg);
}
.check input[type="checkbox"]:focus-visible {
  outline: 3px solid var(--cc-navy); outline-offset: 2px;
}

/* Honeypot: hidden from people, still reachable by bots that fill everything. */
/* Honeypot. Clipped for the same reason as the skip link: a negative left
   offset became real overflow on every right-to-left form page. */
.hp-field { position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; }

.quote-form .btn { margin-top: 8px; }
/* Phone links stay comfortably tappable even mid-sentence, since on a phone
   this is one of the likeliest things a visitor taps. */
.prose a[href^="tel:"] { display: inline-block; padding-block: 4px; }

.quote-aside {
  background: var(--cc-offwhite, #F7F9FB); border: 1px solid var(--cc-border);
  border-radius: 14px; padding: 28px 30px;
}
.quote-aside h2 { font-size: 20px; margin: 0 0 16px; }
.quote-expect { margin: 0; }
.quote-expect dt {
  font-weight: 700; font-size: 15.5px; color: var(--cc-navy); margin: 0;
}
.quote-expect dd {
  margin: 5px 0 18px; font-size: 15.5px; line-height: 1.6; color: var(--cc-muted);
}
.quote-expect dd:last-of-type { margin-bottom: 0; }
.quote-aside-note {
  margin: 20px 0 0; padding-top: 18px; border-top: 1px solid var(--cc-border);
  font-size: 14.5px; color: var(--cc-muted); line-height: 1.55;
}

@media (max-width: 900px) {
  .quote-grid { grid-template-columns: 1fr; gap: 34px; }
  .quote-aside { order: -1; }   /* context before the form on small screens */
}
@media (max-width: 560px) {
  .field-row, .check-grid { grid-template-columns: 1fr; }
  .field-row { gap: 0; }
}

/* Small phones: the logo is a fixed-ratio SVG, so below ~420px it has to be
   allowed to scale down or it pushes the menu button past the viewport edge
   and the whole page scrolls sideways. */
/* Three items share the header bar on mobile now (logo, call, Menu), so the
   logo has to give up more width than it did with two. Sized so the row still
   fits a 320px viewport without the page scrolling sideways. */
@media (max-width: 480px) {
  .header-inner { gap: 10px; }
  .logo { flex: 0 1 auto; min-width: 0; }
  :root { --logo-w: 168px; }
  .nav-toggle { padding: 10px 12px; flex: 0 0 auto; }
}
@media (max-width: 360px) {
  :root { --logo-w: 140px; }
  .nav-toggle { padding: 10px 10px; font-size: 14.5px; }
}

/* Grid children default to min-width:auto, so a long word inside one can force
   the whole track wider than the screen. This caps them at the track width. */
.standard-grid > *, .standard-steps > *, .quote-grid > * { min-width: 0; }
.standard-step p, .standard-step h3 { overflow-wrap: break-word; }
@media (max-width: 360px) {
  .standard-steps { grid-template-columns: 1fr; gap: 26px; }
}

/* --------------------------------------------------------------------------
   Touch targets
   Link text sits at 17-19px tall by default, which is under the WCAG 2.2
   minimum of 24x24. Padding is added on touch-sized screens only, so the
   desktop layout keeps its tighter rhythm. Links inside a sentence are exempt
   under WCAG and are left alone.
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
  .site-footer li > a,
  .site-footer .footer-contact a { display: inline-block; padding-block: 5px; }
  .site-footer li { margin-bottom: 4px; }
  .suburb-index a,
  .suburb-blurbs a.sname { display: inline-block; padding-block: 4px; }
  .crumbs a { display: inline-block; padding-block: 5px; }
  .footer-legal a { display: inline-block; padding-block: 4px; }
  .terms-meta a { display: inline-block; padding-block: 4px; }
  .prose li > a:first-child { display: inline-block; padding-block: 3px; }
}

/* The full navigation needs about 930px alongside the logo. Below that it
   collapses to the menu button, which is well above the 760px breakpoint the
   rest of the mobile layout uses. */
@media (max-width: 1200px) {
  .nav { gap: 20px; }
  .nav a, .lang-btn { font-size: 15.5px; }
  .nav a.btn { padding: 12px 18px; }
}
@media (max-width: 1110px) {
  .nav { display: none; }
  .nav.is-open {
    display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
    position: absolute; left: 0; right: 0; top: 100%;
    background: #fff; border-bottom: 1px solid var(--cc-border); padding: 18px 28px 26px;
    z-index: 40;
  }
  .nav.is-open a { padding: 10px 0; width: 100%; }
  /* The link rule above and .nav a.btn have equal specificity, so this one
     wins on order and strips the quote button's horizontal padding. Restore
     it, and centre the label since the button spans the menu width. */
  .nav.is-open a.btn {
    padding: 14px 22px; justify-content: center;
    margin-top: 10px; box-sizing: border-box;
  }
  .nav-toggle { display: block; }
  .header-inner { position: relative; }
}

/* Widow control. text-wrap: pretty asks the browser to reflow so a paragraph
   does not end on a single word; balance evens out short headings. Browsers
   without support ignore both and wrap as they did before. */
p, li, dd, dt, figcaption, legend, label, .lede, .hint, blockquote {
  text-wrap: pretty;
}
h1, h2, h3, h4, .page-kicker, .eyebrow, .strip-heading, .standard-step p {
  text-wrap: balance;
}

/* The breadcrumb sits outside the section, so the section's own top padding
   stacks on top of it and leaves a large empty band above the H1. Sections
   that directly follow a breadcrumb get a tighter top. */
.crumbs + .section, .crumbs + .section--tight { padding-top: 28px; }
@media (max-width: 760px) {
  .crumbs + .section, .crumbs + .section--tight { padding-top: 20px; }
}

/* Trust badges in the footer's About column, filling the space under the
   short link list. Held slightly back from full white so they read as marks
   rather than competing with the links above them. */

/* Handset mark on the header number: signals "callable" rather than "page
   link" without competing with the quote button beside it. */
.nav .tel { display: inline-flex; align-items: center; gap: 8px; }
.tel-icon { width: 16px; height: 16px; flex: 0 0 auto; color: var(--cc-cyan); }
.nav .tel:hover .tel-icon { color: var(--cc-navy); }

/* Photo credit under suburb images. Deliberately small but legible: Creative
   Commons attribution has to be visible to be valid, not hidden in source. */
.photo-credit {
  margin: 8px 0 0; font-size: 13px; line-height: 1.45; color: var(--cc-muted);
}
.photo-credit a { color: var(--cc-muted); text-decoration: underline; text-underline-offset: 2px; }
.photo-credit a:hover { color: var(--cc-navy); }

.footer-more { color: #fff; font-weight: 600; }

/* --- Trust & Credentials (unlisted page) ---------------------------------- */
.cred-summary { list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: 14px 40px; }
.cred-item { display: flex; flex-direction: column; gap: 3px;
  padding-left: 30px; position: relative; }
.cred-item::before {
  content: ""; position: absolute; left: 0; top: 6px;
  width: 15px; height: 15px; border-radius: 50%;
}
.cred-item--ok::before { background: var(--cc-cyan); }
.cred-item--pending::before { border: 2px solid var(--cc-border); }
.cred-label { font-weight: 600; color: var(--cc-navy); }
.cred-note, .cred-status { font-size: 14.5px; color: var(--cc-muted); }
.cred-docs { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; margin-top: 8px; }
.cred-doc { border: 1px solid var(--cc-border); border-radius: var(--cc-radius);
  padding: 30px 32px; background: #fff; }
.cred-doc h3 { margin: 0 0 12px; }
.cred-doc p { margin: 0 0 10px; }
.cred-doc p:last-child { margin-bottom: 0; }
.cred-meta { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 10px 28px; }
.cred-meta dt { color: var(--cc-muted); }
.cred-meta dd { margin: 0; color: var(--cc-navy); font-weight: 600; }
.cred-meta--business dd { font-weight: 500; }
.cred-preview img { max-width: 100%; height: auto; border: 1px solid var(--cc-border);
  border-radius: 6px; margin-top: 16px; }
.cred-privacy { font-size: 14.5px; color: var(--cc-muted); max-width: var(--cc-reading);
  margin-top: 26px; }
@media (max-width: 860px) {
  .cred-summary, .cred-docs { grid-template-columns: 1fr; }
  .cred-meta { grid-template-columns: 1fr; gap: 2px 0; }
  .cred-meta dd { margin-bottom: 12px; }
}

/* --- QR campaign landing pages (/offer, /loyalty) --------------------------
   Scoped to .camp-* so nothing here can leak into the main site. These pages
   reuse the site tokens, buttons, .field and .check-grid styles; what is added
   below is only the stripped-back header and the few campaign-specific blocks. */
.camp-header { border-bottom: 1px solid var(--cc-border); background: var(--cc-white); }
.camp-header-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  /* padding-block only: the horizontal padding belongs to .wrap, and
     overriding it here pushed the logo out of line with the footer logo. */
  padding-block: 14px;
}
.camp-header .logo img { width: var(--logo-w); height: auto; display: block; }
.camp-hero { padding: 44px 0 8px; }
.camp-eyebrow {
  margin: 0 0 14px; font-size: 13px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--cc-cyan);
}
.camp-hero h1 { margin: 0 0 18px; }
.camp-hero .lede { max-width: 34rem; }
/* The hero and success CTAs use the site's own .btn-row / .btn--ghost pattern.
   The only campaign change is that on a phone the pair goes full width and
   stacks, because these pages are opened one-handed after a QR scan. */
.camp-hero .btn-row .btn, .camp-success .btn-row .btn { flex: 1 1 100%; text-align: center; }
.camp-cta-note { margin: 16px 0 0; font-size: 15px; color: var(--cc-muted); max-width: 30rem; }
/* Hero mark. Hidden on phones on purpose: after a QR scan the offer and its two
   buttons must be reachable without scrolling, and art above them costs that. */
.camp-hero-art { display: none; }
.camp-hero-icon { width: 100%; height: auto; color: var(--cc-navy); }
.camp-benefits { list-style: none; margin: 30px 0 0; padding: 0; display: grid; gap: 22px; }
.camp-benefits li { display: flex; align-items: flex-start; gap: 14px; }
.camp-benefits .icon {
  flex: 0 0 auto; width: 34px; height: 34px;
  /* icons inherit currentColor, which in a text block is the ink grey.
     Set it to navy so they read as the logo does: navy with cyan accents. */
  color: var(--cc-navy);
}
.camp-benefits b { display: block; font-weight: 700; }
.camp-benefits p { margin: 2px 0 0; font-size: 16px; color: var(--cc-muted); }
.camp-services { list-style: none; margin: 26px 0 0; padding: 0; display: grid; gap: 12px; }
/* Direct children only: a bare `span` selector here also matched the label
   span inside each link, so every card drew its border and background twice. */
.camp-services > li > a, .camp-services > li > span {
  display: flex; align-items: center; gap: 12px; padding: 14px 16px;
  border: 1px solid var(--cc-border); border-radius: var(--cc-radius);
  color: var(--cc-ink); text-decoration: none; font-weight: 700; background: var(--cc-white);
}
.camp-services > li > a:hover, .camp-services > li > a:focus-visible { border-color: var(--cc-cyan); }
.camp-services .icon { width: 28px; height: 28px; flex: 0 0 auto; color: var(--cc-navy); }
.camp-form-card {
  background: var(--cc-off-white); border: 1px solid var(--cc-border);
  border-radius: var(--cc-radius); padding: 26px 20px;
}
.camp-form-card .btn { width: 100%; justify-content: center; }
.camp-terms { margin: 20px 0 0; font-size: 13px; line-height: 1.6; color: var(--cc-muted); }
.camp-success { display: none; }
.camp-success[data-shown="true"] { display: block; }
.camp-success h2 {
  text-transform: uppercase; letter-spacing: .04em; margin: 0 0 14px; color: var(--cc-navy);
}
.camp-error {
  display: none; margin: 0 0 18px; padding: 12px 14px; border-radius: var(--cc-radius);
  border: 1px solid var(--cc-alert); color: var(--cc-alert); font-size: 16px;
}
.camp-error[data-shown="true"] { display: block; }
@media (min-width: 700px) {
  .camp-hero { padding: 64px 0 8px; }
  .camp-benefits { grid-template-columns: repeat(3, 1fr); gap: 26px; }
  .camp-benefits li { display: block; }
  .camp-benefits .icon { margin-bottom: 10px; }
  .camp-services { grid-template-columns: repeat(3, 1fr); }
  .camp-form-card { padding: 34px 32px; }
  .camp-form-card .btn { width: auto; min-width: 15rem; }
  .camp-hero .btn-row .btn, .camp-success .btn-row .btn { flex: 0 0 auto; }
}
@media (min-width: 960px) {
  .camp-hero-grid {
    display: grid; grid-template-columns: minmax(0, 1fr) 300px;
    gap: 56px; align-items: center;
  }
  .camp-hero-art { display: block; }

}

/* --- Multilingual ----------------------------------------------------------
   Nothing here changes the English site: every rule is either scoped to the
   language control, to a non-Latin font class, or to [dir="rtl"]. */

/* Script coverage. Creato Display is Latin-only, so each non-Latin language
   falls back to the best system face for that script and keeps Creato for any
   Latin that appears inside the text (phone numbers, "Carpet Clinic - Cleaner Carpets, Healthier Spaces."). Sizes
   are nudged because CJK and Devanagari read small at Latin metrics. */
.font-sc   { --cc-font: "Creato Display", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", sans-serif; }
.font-tc   { --cc-font: "Creato Display", "PingFang TC", "Microsoft JhengHei", "Noto Sans TC", sans-serif; }
.font-arabic { --cc-font: "Creato Display", "SF Arabic", "Geeza Pro", "Segoe UI", "Noto Naskh Arabic", sans-serif; }
.font-greek  { --cc-font: "Creato Display", "Helvetica Neue", "Segoe UI", "Noto Sans", sans-serif; }
.font-devanagari { --cc-font: "Creato Display", "Kohinoor Devanagari", "Nirmala UI", "Noto Sans Devanagari", sans-serif; }
.font-sc body, .font-tc body, .font-devanagari body { font-size: 17px; }
.font-arabic body { font-size: 17.5px; line-height: 1.75; }

/* The language control. Deliberately the weight of a nav item, never the CTA. */
.lang { position: relative; }
.lang-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 10px; border: 0; border-bottom: 2px solid transparent; background: none; cursor: pointer;
  font: inherit; font-size: 16px; font-weight: 500; color: var(--cc-navy);
  border-radius: var(--cc-radius);
}
.lang-btn:hover { color: var(--cc-navy); }
.lang-btn:focus-visible { outline: 2px solid var(--cc-cyan); outline-offset: 2px; }
.lang-globe { width: 18px; height: 18px; flex: 0 0 auto; color: var(--cc-cyan); }
.lang-chev { width: 14px; height: 14px; flex: 0 0 auto; transition: transform .15s ease; }
.lang-btn[aria-expanded="true"] .lang-chev { transform: rotate(180deg); }
.lang-code { font-weight: 500; }

.lang-menu {
  position: absolute; z-index: 60; top: calc(100% + 8px);
  /* logical, so the menu hangs from the correct edge in both directions */
  inset-inline-end: 0;
  min-width: 9.5rem; margin: 0; padding: 6px; list-style: none;
  background: var(--cc-white); border: 1px solid var(--cc-border);
  border-radius: var(--cc-radius); box-shadow: 0 10px 30px rgba(12, 60, 136, .12);
}
.lang-menu[hidden] { display: none; }
.lang-menu a {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 9px 12px; border-radius: 8px;
  color: var(--cc-ink); text-decoration: none; font-size: 15px;
  /* Every row reads as a list of choices, not as running text, so they all
     align left regardless of the script. Without this the Arabic row inherits
     RTL from its lang attribute and flips, tick and all, which looks like a
     fault in an otherwise even list. */
  direction: ltr; text-align: left;
}
.lang-menu a > span { unicode-bidi: isolate; }
/* Optical size, in this menu only. Arabic and Devanagari sit on a smaller
   apparent height than Latin at the same point size, so at 15px they read as
   smaller items in an otherwise even list. */
.lang-menu a[lang="ar"] span { font-size: 17px; }
.lang-menu a[lang="hi"] span { font-size: 16px; }

.lang-menu a:hover, .lang-menu a:focus-visible { background: var(--cc-off-white); color: var(--cc-navy); }
.lang-menu a:focus-visible { outline: 2px solid var(--cc-cyan); outline-offset: -2px; }
.lang-menu a[aria-current="true"] { font-weight: 700; color: var(--cc-navy); }
.lang-tick { width: 16px; height: 16px; flex: 0 0 auto; color: var(--cc-cyan); }

/* A note, shown on translated pages only, about what language the job runs in. */
.lang-note {
  margin: 18px 0 0; padding: 12px 14px; font-size: 15px;
  color: var(--cc-muted); background: var(--cc-off-white);
  border-radius: var(--cc-radius);
}

/* Right-to-left. The layout is mirrored by logical properties; the logo,
   the phone number and the icons are NOT mirrored - a reversed logo or a
   backwards wand would be wrong, not localised. */
[dir="rtl"] .header-inner,
[dir="rtl"] .nav { direction: rtl; }
[dir="rtl"] .logo img,
[dir="rtl"] .footer-logo img { transform: none; }
[dir="rtl"] .tel, [dir="rtl"] .header-call,
[dir="rtl"] .lang-code { direction: ltr; unicode-bidi: embed; }
[dir="rtl"] .prose ul, [dir="rtl"] .prose ol { padding-inline-start: 1.2em; padding-inline-end: 0; }
[dir="rtl"] .page-head, [dir="rtl"] .prose, [dir="rtl"] .lede { text-align: start; }
/* Mixed Arabic and Latin. `plaintext` sets each paragraph's direction from its
   own first strong character, so an English line inside an Arabic page renders
   left-to-right with its full stop in the right place, while Arabic paragraphs
   stay right-to-left. Without this, "Cleaner Carpets." renders as
   ".Cleaner Carpets" - the classic bidi punctuation flip. */
[dir="rtl"] :is(h1, h2, h3, h4, p, li, dt, dd, figcaption, label, legend, blockquote, td, th) {
  unicode-bidi: plaintext;
}
[dir="rtl"] .btn .icon, [dir="rtl"] .lang-chev { transform: scaleX(-1); }
[dir="rtl"] .lang-btn[aria-expanded="true"] .lang-chev { transform: scaleX(-1) rotate(180deg); }

/* Mobile: the control is a row inside the open menu, not a header item. The
   header keeps its logo, call button and hamburger exactly as it was. */
@media (max-width: 1110px) {
  .lang { width: 100%; border-top: 1px solid var(--cc-border); margin-top: 6px; padding-top: 6px; }
  .lang-btn { width: 100%; justify-content: space-between; padding: 14px 4px; }
  .lang-menu {
    position: static; min-width: 0; margin-top: 4px;
    border: 0; box-shadow: none; padding: 0 0 6px;
  }
  .lang-menu a { padding: 12px 4px; }
}

/* Between the nav's collapse point (1110px) and roughly 1300px the row is
   tight: adding the language control pushed Get a Quote off-screen on 1280px
   laptops. Rather than hiding the phone number - the strongest conversion
   element in the header - the control drops to the globe alone and the nav
   gap tightens. Both revert above 1300px. */
@media (min-width: 1111px) and (max-width: 1300px) {
  .nav { gap: 12px; }
  .lang-code { display: none; }
  .lang-btn { padding: 8px 6px; gap: 4px; }
}

/* Translated pages only. Grid and flex children default to min-width:auto, so
   a long word cannot shrink its column - English happens to fit at 320px,
   Greek does not. Scoped off .lang-en so English wrapping cannot change. */
html:not(.lang-en) :is(.strip-item, .card, .camp-benefits li, .assurances li) { min-width: 0; }
html:not(.lang-en) :is(h1, h2, h3, p, li) { overflow-wrap: break-word; }

/* Marks the legal links on translated pages as English documents. */
.legal-note { opacity: .75; font-size: .95em; }

/* Campaign header: selector and call button sit together on the right. */
.camp-header-right { display: flex; align-items: center; gap: 4px; }
.camp-header .lang { width: auto; border: 0; margin: 0; padding: 0; }
.camp-header .lang-btn { width: auto; padding: 8px 10px; }
.camp-header .lang-menu {
  position: absolute; inset-inline-end: 0; min-width: 12rem;
  border: 1px solid var(--cc-border); box-shadow: 0 10px 30px rgba(12, 60, 136, .12);
  padding: 6px; margin-top: 8px;
}

/* Article byline. A named author is the visible half of the E-E-A-T signal;
   the other half is the Person in the Article schema. */
.byline {
  margin: 14px 0 0; font-size: 15px; color: var(--cc-muted);
  display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline;
}
.byline-author { font-weight: 500; color: var(--cc-ink); }
.byline-sep { color: var(--cc-muted); }
.byline-date { color: var(--cc-muted); }

/* A single, quiet mention of the operator on the homepage. The detail belongs
   on About; here it just makes clear a named person stands behind the work. */
.owner-line { color: var(--cc-muted); font-size: 16px; }

/* The ABN sits inline with the other legal items rather than claiming its own
   row; it only goes full width at the phone breakpoint below. */
.footer-legal > .footer-business-identity {
  flex: 0 1 auto;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 24px;
  justify-content: flex-start;
  text-align: start;
  color: rgba(255,255,255,.85);
}
.footer-business-identity > span { min-width: 0; }



/* --- Credentials list (About) ---------------------------------------------
   Two facts set as a definition list between hairlines. Kept at the page's
   own type size and reading measure: the surrounding panels are 18px prose in
   a single column, so a denser multi-column strip read as a foreign element. */
.credentials { margin: 22px 0; padding: 20px 0; border-top: 1px solid var(--cc-border); border-bottom: 1px solid var(--cc-border); display: flex; flex-direction: column; gap: 14px; max-width: 68ch; }
.credentials > div { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; }
.credentials dt { font-weight: 700; color: var(--cc-navy); flex: 0 0 auto; }
.credentials dt { display: inline-flex; align-items: center; gap: 8px; }
.cred-ico { width: 20px; height: 20px; flex: 0 0 auto; color: var(--cc-navy); }
.cred-ico .acc { stroke: var(--cc-cyan); }
.credentials dd { margin: 0; color: var(--cc-muted); flex: 1 1 260px; }
/* Desktop: labels in one column, descriptions lined up in a second. */
@media (min-width: 621px) {
  .credentials { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 14px 18px; }
  .credentials > div { display: contents; }
}
@media (max-width: 620px) {
  /* Stacked, the dd's flex-basis was still reserving its row height and
     leaving a large gap under each term. Drop out of flex entirely. */
  .credentials > div { display: block; }
  .credentials dt { margin-bottom: 2px; }
  .credentials dd { flex: none; }
}

/* Refined photo sequence, service-card interaction and founder-name accent. */
html.anim .hero-media { animation: cc-rise .55s ease both; }
html.anim .hero h1 { animation-delay: .08s; }
html.anim .hero .lede { animation-delay: .16s; }
.btn { transition: background-color .22s ease, color .22s ease, border-color .22s ease, transform .18s ease; }
/* The founder paragraph had no rule of its own, so it ran the full container
   width (~150 characters a line) while the lede above and the prose below both
   wrapped near 65. Give it the reading measure and a little space above so it
   reads as the personal note it is rather than a stray block. */
.founder-ethos {
  max-width: var(--cc-reading);
  margin-top: 26px;
}
/* The gap between the founder note and the prose below came from the section's
   own top padding stacking on the paragraph's margin, which left a hole twice
   the size of every other paragraph break. */
.page-head + .prose.block-gap { margin-top: 0; }
.page-head .founder-ethos { margin-bottom: 0; }

.cc-name-underline {
  background-image: linear-gradient(var(--cc-cyan), var(--cc-cyan));
  background-repeat: no-repeat;
  background-position: left bottom;
  background-size: 100% 2px;
  padding-bottom: 3px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
@keyframes cc-underline { from { background-size: 0% 2px; } to { background-size: 100% 2px; } }
@media (prefers-reduced-motion: no-preference) {
  .cc-name-underline.cc-drawn { animation: cc-underline 1.3s cubic-bezier(.22,.61,.36,1) both; }
  .card:focus-within { transform: translateY(-3px); box-shadow: 0 12px 28px rgba(12,60,136,.10); border-color: var(--cc-cyan); }
}
@media (hover: none) {
  .card:hover, .btn:hover { transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  html.anim .hero-media { animation: none; }
  .cc-name-underline.cc-drawn { animation: none; }
  .card:focus-within { transform: none; }
}
