/* ==========================================================================
   CACTUS STATE PLUMBING — THEME STYLESHEET
   ==========================================================================

   This file carries the approved design over directly. The design supplied
   its styling as inline style="" attributes on each element; those have been
   lifted into the named classes below without changing any value, because
   inline styles cannot carry media queries and the design needs a responsive
   layer that it did not itself specify.

   Read this file top to bottom:
     1. Tokens          — colours, fonts, spacing. The design's variables.
     2. Reset & base    — from the design system stylesheet.
     3. Layout          — page shell, sections, grids.
     4. Components      — buttons, tags, blueprint frames, image slots.
     5. Header & footer
     6. Responsive      — the mobile-first layer, authored for this build.
     7. Accessibility   — focus, reduced motion, skip link.

   WP Rocket minifies this in production. Do not minify it by hand.
   ========================================================================== */


/* ==========================================================================
   1. TOKENS
   ==========================================================================
   Values below come from the design system stylesheet
   (_ds/industry-.../styles.css) with the page-level overrides that the
   approved design applied on top of it.

   THREE VALUES WERE ADJUSTED FOR ACCESSIBILITY. Each is marked "AA NUDGE"
   with the before/after contrast ratio. Nothing else was changed.
   ========================================================================== */

:root {
  /* --- Ground ------------------------------------------------------------ */
  --color-bg:      #f2f2f3;
  --color-surface: #e9e9ea;
  --color-text:    #1d1f20;
  --color-divider: color-mix(in srgb, #1d1f20 16%, transparent);

  /* --- Accent: the green ------------------------------------------------- */
  --color-accent:     #35806a;
  --color-accent-100: #e8f2ee;
  --color-accent-200: #cbe3da;
  --color-accent-300: #a6cfc1;
  --color-accent-400: #6fae9b;
  --color-accent-500: #3f8a74;
  --color-accent-600: #2f6f5e;
  --color-accent-700: #235445;
  --color-accent-800: #173d31;
  --color-accent-900: #0f2d24;

  /* --- Accent 2: the tan ------------------------------------------------- */
  --color-accent-2:     #bb8355;
  --color-accent-2-100: #f6ece3;
  --color-accent-2-200: #ecd7c4;
  --color-accent-2-300: #ddb99b;
  --color-accent-2-400: #c99b74;
  --color-accent-2-500: #bb8355;
  --color-accent-2-600: #a76d40;
  --color-accent-2-700: #855433;
  --color-accent-2-800: #5f3c25;
  --color-accent-2-900: #45291b;

  /* --- AA NUDGE #1 -------------------------------------------------------
     Interactive green, used for the primary button background and link
     hover. The design used --color-accent (#35806a), which gives 4.22:1
     against #f2f2f3 — below the 4.5:1 AA minimum for text under 18.66px.
     --color-accent-600 (#2f6f5e) gives 5.28:1 and is visually near-identical.
     ---------------------------------------------------------------------- */
  --color-interactive:       #2f6f5e;
  --color-interactive-hover: #235445; /* accent-700, 7.74:1 */

  /* --- Muted text ramps ---------------------------------------------------
     The design mixed the text colour with transparent at various percentages.
     These are those exact mixes, named so they stay consistent.

     AA NUDGE #2: the design used 60% for footer column headings and the
     copyright bar (4.25:1 — fails). The lowest step here is 65% (4.92:1),
     which the design already uses elsewhere. All 60% uses map to --text-soft.
     ---------------------------------------------------------------------- */
  --text-strong: color-mix(in srgb, var(--color-text) 82%, transparent); /*  8.62:1 */
  --text-body:   color-mix(in srgb, var(--color-text) 80%, transparent); /*  8.06:1 */
  --text-muted:  color-mix(in srgb, var(--color-text) 72%, transparent); /*  6.18:1 */
  --text-soft:   color-mix(in srgb, var(--color-text) 65%, transparent); /*  4.92:1 — AA floor */

  /* On the dark green sections, muted text is the background colour mixed
     down instead. All of these clear AA comfortably. */
  --text-on-dark:        color-mix(in srgb, var(--color-bg) 88%, transparent); /* 10.51:1 */
  --text-on-dark-muted:  color-mix(in srgb, var(--color-bg) 82%, transparent); /*  9.36:1 */
  --text-on-dark-soft:   color-mix(in srgb, var(--color-bg) 72%, transparent); /*  7.53:1 */

  /* --- Type -------------------------------------------------------------- */
  --font-heading: "Barlow Condensed", system-ui, -apple-system, sans-serif;
  --font-heading-weight: 600;
  --font-body: "Barlow", system-ui, -apple-system, sans-serif;

  /* --- Spacing ----------------------------------------------------------- */
  --space-1: 3.4px;
  --space-2: 6.8px;
  --space-3: 10.2px;
  --space-4: 13.6px;
  --space-6: 20.4px;
  --space-8: 27.2px;

  /* --- Layout -------------------------------------------------------------
     The design's container: max 1200px with a fluid gutter that runs from
     20px on a phone to 72px on a wide screen. */
  --container:  1200px;
  --container-narrow: 900px;
  --gutter: clamp(20px, 5vw, 72px);

  /* Vertical rhythm, taken from the design's repeated clamp() values. */
  --section-y:       clamp(44px, 6vw, 80px);
  --section-y-large: clamp(48px, 6vw, 88px);

  /* --- Shape ------------------------------------------------------------- */
  /* The design system sets every component to square corners: the whole look
     is wireframe / blueprint. Radius tokens exist but resolve to 0. */
  --radius-sm: 0;
  --radius-md: 0;
  --radius-lg: 0;

  /* Minimum tap target. Referenced rather than repeated. */
  --tap: 44px;
}


/* ==========================================================================
   2. FONTS — self-hosted
   ==========================================================================
   No request goes to Google. The files sit in assets/fonts.
   font-display:swap shows the fallback immediately and swaps when the webfont
   lands, which avoids invisible text on a slow connection.
   ========================================================================== */

@font-face {
  font-family: "Barlow";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/barlow-400.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Barlow";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/barlow-500.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Barlow";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/barlow-700.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/barlow-condensed-400.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/barlow-condensed-600.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}


/* ==========================================================================
   3. RESET & BASE
   ==========================================================================
   Carried from the design system stylesheet.
   ========================================================================== */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.55;
  font-weight: 400;
  text-wrap: pretty;
  /* Belt and braces against horizontal scroll at any width. The responsive
     rules below are what actually prevent it; this catches anything missed. */
  overflow-x: hidden;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  line-height: 1.12;
  letter-spacing: -0.015em;
  margin: 0 0 var(--space-2);
}

p { margin: 0 0 var(--space-3); }
p:last-child { margin-bottom: 0; }

a { color: var(--color-accent-700); text-underline-offset: 3px; }
a:hover { color: var(--color-interactive-hover); } /* AA NUDGE #1 */

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

/* Uppercase heading treatment used throughout the design. */
.u-caps {
  text-transform: uppercase;
  letter-spacing: 0.01em;
}

/* The small uppercase label above most headings. */
.eyebrow {
  display: block;
  font-family: var(--font-heading);
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent-700);
  font-weight: 600;
  margin: 0 0 12px;
}
.eyebrow--hero {
  display: inline-block;
  letter-spacing: 0.16em;
  margin-bottom: 18px;
}
.eyebrow--on-dark { color: var(--color-accent-2-400); }

/* The hairline rule under an eyebrow. */
.rule {
  height: 1px;
  border: 0;
  background: var(--color-divider);
  margin: 0 0 30px;
}

.text-muted { color: var(--text-muted); }
.text-soft  { color: var(--text-soft); }


/* ==========================================================================
   4. LAYOUT
   ========================================================================== */

/* The centred content column used by every section in the design. */
.container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--narrow { max-width: var(--container-narrow); }
.container--mid    { max-width: 1000px; }

.section        { padding-block: var(--section-y); }
.section--large { padding-block: var(--section-y-large); }
.section--edge  { border-bottom: 1px solid var(--color-divider); }

/* The dark green full-bleed band. */
.section--dark {
  background: var(--color-accent-900);
  color: var(--color-bg);
}
.section--dark a { color: var(--color-accent-2-300); }
.section--dark .rule { background: color-mix(in srgb, var(--color-bg) 22%, transparent); }


/* ==========================================================================
   5. COMPONENTS
   ========================================================================== */

/* --- Buttons -------------------------------------------------------------
   From the design system, with the blueprint override that squares the
   corners and adds the hairline border. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  cursor: pointer;
  text-decoration: none;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 15px;
  line-height: 1.2;
  color: var(--color-text);
  background: transparent;
  border: 1px solid var(--color-divider);
  border-radius: 0;
  /* Padding is set so the button clears the 44px minimum tap target without
     changing the design's visual proportions. */
  padding: 12px 20px;
  min-height: var(--tap);
}
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

.btn-primary {
  background: var(--color-interactive);       /* AA NUDGE #1 */
  border-color: var(--color-interactive);
  color: var(--color-bg);
}
.btn-primary:hover,
.btn-primary:focus-visible {
  background: var(--color-interactive-hover);
  border-color: var(--color-interactive-hover);
  color: var(--color-bg);
}

.btn-secondary { border-color: var(--color-divider); color: var(--color-text); }
.btn-secondary:hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }

/* On the dark band the secondary button needs a light outline instead. */
.section--dark .btn-secondary {
  border-color: color-mix(in srgb, var(--color-bg) 45%, transparent);
  color: var(--color-bg);
}
.section--dark .btn-secondary:hover {
  background: color-mix(in srgb, var(--color-bg) 12%, transparent);
}

/* The inline "View service page →" text link. */
.btn-inline {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  align-self: flex-start;
  background: none;
  border: 0;
  padding: 10px 0;          /* Vertical padding gives it a 44px tap height. */
  min-height: var(--tap);
  cursor: pointer;
  font-family: var(--font-heading);
  font-size: 14px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent-700);
  font-weight: 600;
  text-decoration: none;
}
.btn-inline:hover { color: var(--color-interactive-hover); text-decoration: underline; }

.csp-icon { display: block; flex: none; }


/* --- Tags ---------------------------------------------------------------- */
.tag {
  display: inline-flex;
  align-items: center;
  font-size: 12px;
  letter-spacing: 0.02em;
  padding: 5px 10px;
  border-radius: 0;
}
.tag-accent  { background: var(--color-accent-100); color: var(--color-accent-800); }
.tag-outline { border: 1px solid var(--color-accent-700); color: var(--color-accent-700); }


/* --- Blueprint frame -----------------------------------------------------
   The registration-mark corners that give the design its drafting-table
   character. Carried over from the design system exactly. */
.blueprint {
  position: relative;
  border: 1px solid var(--color-divider);
  border-radius: 0;
}
.blueprint > .corner {
  position: absolute;
  width: 11px;
  height: 11px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.blueprint > .corner::before,
.blueprint > .corner::after { content: ""; position: absolute; background: currentColor; }
.blueprint > .corner::before { left: 5px; top: 0; width: 1px; height: 100%; }
.blueprint > .corner::after  { top: 5px; left: 0; width: 100%; height: 1px; }
.blueprint > .corner.tl { top: -6px; left: -6px; }
.blueprint > .corner.tr { top: -6px; right: -6px; }
.blueprint > .corner.bl { bottom: -6px; left: -6px; }
.blueprint > .corner.br { bottom: -6px; right: -6px; }

/* On the dark band the corner marks need to be light to stay visible. */
.section--dark .blueprint { border-color: color-mix(in srgb, var(--color-bg) 26%, transparent); }
.section--dark .blueprint > .corner { color: color-mix(in srgb, var(--color-bg) 60%, transparent); }

/* The duotone photo treatment: a green colour wash over the image. */
.duotone { position: relative; overflow: hidden; }
.duotone::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: var(--color-accent);
  mix-blend-mode: color;
}
/* The blueprint corners sit outside the box, so the frame must not clip. */
.blueprint.duotone { overflow: visible; }
.blueprint.duotone > img,
.blueprint.duotone > .csp-image-slot { overflow: hidden; }


/* --- Unfilled image placeholder ------------------------------------------
   Deliberately loud. This is not a neutral grey box that can survive to
   launch unnoticed — it is hazard striping and a caps warning, sized to be
   legible in a screenshot. inc/helpers.php explains the reasoning; the Launch
   Readiness screen counts every one of these.
   -------------------------------------------------------------------------- */
.csp-image-slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: 20px;
  text-align: center;
  border: 2px dashed color-mix(in srgb, var(--color-text) 45%, transparent);
  color: var(--text-muted);

  /* Diagonal hazard striping, drawn in CSS so it costs no request and scales
     to any slot size. */
  background-color: var(--color-surface);
  background-image: repeating-linear-gradient(
    45deg,
    transparent 0 14px,
    color-mix(in srgb, var(--color-text) 7%, transparent) 14px 28px
  );
}

.csp-image-slot__flag {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(13px, 1.6vw, 17px);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1.2;
  padding: 7px 14px;
  color: var(--color-bg);
  background: var(--color-text);
}

.csp-image-slot__label {
  font-size: 13px;
  line-height: 1.4;
  max-width: 34ch;
}

/* On the dark band the placeholder inverts so it stays just as loud. */
.section--dark .csp-image-slot {
  border-color: color-mix(in srgb, var(--color-bg) 55%, transparent);
  color: var(--text-on-dark-soft);
  background-color: color-mix(in srgb, var(--color-bg) 8%, transparent);
  background-image: repeating-linear-gradient(
    45deg,
    transparent 0 14px,
    color-mix(in srgb, var(--color-bg) 10%, transparent) 14px 28px
  );
}
.section--dark .csp-image-slot__flag {
  color: var(--color-accent-900);
  background: var(--color-bg);
}

/* The duotone wash must not tint a placeholder — there is no photo to tint. */
.duotone:has(> .csp-image-slot)::after { display: none; }


/* --- FAQ accordion -------------------------------------------------------
   Uses native <details>/<summary>, so it works with no JavaScript and is
   keyboard accessible for free. */
.faq-item {
  border-top: 1px solid var(--color-divider);
  padding: 18px 0;
}
.faq-item:last-of-type { border-bottom: 1px solid var(--color-divider); }

.faq-item > summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  list-style: none;
  cursor: pointer;
  font-family: var(--font-heading);
  font-size: clamp(17px, 2.2vw, 20px);
  letter-spacing: 0.01em;
  text-transform: uppercase;
  min-height: var(--tap);
}
.faq-item > summary::-webkit-details-marker { display: none; }

.faq-plus {
  flex: none;
  color: var(--color-interactive);
  font-size: 24px;
  line-height: 1;
  transition: transform 0.2s;
}
.faq-item[open] .faq-plus { transform: rotate(45deg); }

.faq-item__answer {
  font-size: 15px;
  line-height: 1.6;
  margin: 14px 0 0;
  color: var(--text-body);
}


/* --- Heading scale -------------------------------------------------------
   The approved design sets every heading size inline, per instance. Those
   exact values live here instead, so no template carries a style attribute.
   The four section modifiers are the four sizes the design actually uses —
   they look nearly identical but they are not, so they are kept apart rather
   than averaged into one.
   -------------------------------------------------------------------------- */
.h-hero {
  font-size: clamp(38px, 5.2vw, 66px);
  line-height: 1.0;
  letter-spacing: 0.01em;
  margin: 0;
}

/* Service and city pages: one step down from the home page hero. */
.h-page {
  font-size: clamp(36px, 4.8vw, 60px);
  line-height: 1.0;
  letter-spacing: 0.01em;
  margin: 0;
}

.h-section {
  font-size: clamp(26px, 3.2vw, 40px);
  line-height: 1.03;
  letter-spacing: 0.01em;
  margin: 0;
}
.h-section--services { font-size: clamp(28px, 3.6vw, 42px); line-height: 1.02; margin: 0 0 34px; max-width: 20ch; }
.h-section--about    { font-size: clamp(26px, 3.2vw, 38px); line-height: 1.05; margin: 0 0 22px; }
.h-section--faq      { margin: 0 0 26px; }
.h-section--cta      { font-size: clamp(26px, 3.4vw, 42px); line-height: 1.02; }

.h-card {
  font-size: 22px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  margin: 0;
}


/* --- Hero ----------------------------------------------------------------- */

/* The text column of a hero. The figure beside it carries its own margin. */
.hero-col { padding-block: clamp(44px, 6vw, 80px); }

.hero-lead {
  font-size: 17px;
  line-height: 1.6;
  max-width: 52ch;
  margin: 22px 0 0;
  color: var(--text-strong);
}

/* The row of buttons under the hero copy, and the row of chips under those. */
.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 30px;
}
.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 26px;
}


/* --- Framed figure -------------------------------------------------------
   The blueprint-and-duotone photo frame used in the hero, the about section
   and the service-area map.
   -------------------------------------------------------------------------- */
.figure-frame { margin-block: clamp(24px, 4vw, 56px); }

/* In the service-area grid the figure sits flush with the top of the column. */
.figure-frame--flush { margin: 0; }


/* --- Facts panel ---------------------------------------------------------
   The bordered table of business facts under the home page hero. Every cell
   is optional: a fact with no value in Business Info is not rendered, and the
   grid closes up around it.
   -------------------------------------------------------------------------- */
.facts-panel { padding: 0; }

.facts-panel__head {
  display: flex;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--color-divider);
}
.facts-panel__title,
.facts-panel__meta {
  padding: 12px 22px;
  font-family: var(--font-heading);
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.facts-panel__title {
  flex: 1;
  min-width: 16ch;
  font-weight: 600;
}
.facts-panel__meta {
  border-left: 1px solid var(--color-divider);
  color: var(--text-soft);
}

.fact {
  padding: 22px;
  border-right: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
}

/* The right-hand cell of each row has no border to double up with the frame.
   Which cell that is changes with the column count, so it is set per
   breakpoint alongside the grid itself, at the bottom of section 9. */

.fact__label {
  font-family: var(--font-heading);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-accent-700);
  margin-bottom: 8px;
}
.fact__value { font-size: 15px; line-height: 1.5; }
.fact__note  { color: var(--text-soft); }

/* The phone number is the one fact rendered at display size. */
.fact__value--phone {
  font-family: var(--font-heading);
  font-size: 26px;
  letter-spacing: 0.01em;
  text-decoration: none;
  color: var(--color-text);
}
.fact__value--phone:hover { color: var(--color-interactive-hover); }


/* --- Service card --------------------------------------------------------- */
.svc-card {
  padding: 24px;
  display: flex;
  flex-direction: column;
}
.svc-card__text {
  font-size: 15px;
  line-height: 1.55;
  margin: 14px 0 0;
  color: var(--text-body);
}
/* The "View service page" link is pushed to the foot of the card so the links
   line up across a row of cards of unequal length. */
.svc-card__link {
  margin-top: auto;
  padding-top: 18px;
  align-self: flex-start;
}


/* --- About statistics ----------------------------------------------------- */
.about-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
  margin-top: 32px;
}
.about-stat__value {
  font-family: var(--font-heading);
  font-size: 30px;
  color: var(--color-accent-2-400);
}
.about-stat__label {
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-on-dark-soft);
}


/* --- Service-area city list ----------------------------------------------- */
.city-chips {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 16px;
  margin-top: 26px;
}
.city-chip {
  font-family: var(--font-heading);
  font-size: 16px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
a.city-chip { text-decoration: none; color: var(--color-text); }
a.city-chip:hover { color: var(--color-interactive-hover); text-decoration: underline; }


/* --- Small print ---------------------------------------------------------
   The qualifying lines under the services grid and the city list — what is
   and is not covered. Deliberately quiet, deliberately present.
   -------------------------------------------------------------------------- */
.note {
  font-size: 13px;
  line-height: 1.5;
  margin: 22px 0 0;
  color: var(--text-soft);
}
.note--lead { font-size: 16px; line-height: 1.6; margin: 18px 0 0; color: var(--text-body); }


/* --- Closing CTA band ----------------------------------------------------- */
.cta-band__inner {
  display: flex;
  flex-wrap: wrap;
  gap: 24px 40px;
  align-items: center;
  justify-content: space-between;
  padding-block: clamp(44px, 6vw, 72px);
}
.cta-band__text {
  font-size: 16px;
  line-height: 1.5;
  margin: 12px 0 0;
  color: var(--text-on-dark-muted);
}
.cta-band .btn-primary { font-size: 18px; padding: 14px 26px; }


/* ==========================================================================
   6. HEADER
   ========================================================================== */

/* --- Promotion bar (only exists when a promotion is set) ----------------- */
.promo-bar {
  background: var(--color-accent-900);
  color: var(--color-bg);
  font-family: var(--font-heading);
  font-size: 14px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.promo-bar__inner {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  align-items: center;
  justify-content: space-between;
  padding-block: 9px;
}
.promo-bar__claim {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.promo-bar__highlight { color: var(--color-accent-2-400); }
.promo-bar__sep { opacity: 0.5; }
.promo-bar a {
  color: var(--color-bg);
  text-decoration: none;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.promo-bar a:hover { color: var(--color-accent-2-300); text-decoration: underline; }


/* --- Main header --------------------------------------------------------- */
.site-header {
  border-bottom: 1px solid var(--color-divider);
  background: var(--color-bg);
  position: sticky;
  top: 0;
  z-index: 20;
}
.site-header__inner {
  display: flex;
  align-items: center;
  gap: 16px;
  justify-content: space-between;
  padding-block: 12px;
}

/* --- Brand lockup -------------------------------------------------------- */
.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  color: inherit;
  flex: none;
}
.brand__mark {
  width: 46px;
  height: 46px;
  object-fit: cover;
  display: block;
  flex: none;
}
.brand__text { display: flex; flex-direction: column; line-height: 1; min-width: 0; }
.brand__name {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(17px, 2.4vw, 21px);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--color-text);
}
.brand__strap {
  font-family: var(--font-heading);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-accent-700);
  margin-top: 3px;
}

/* --- Header actions: nav + phone ---------------------------------------- */
.site-header__actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* The header call button. This element is never hidden at any width — it is
   the conversion on this site. Below the nav breakpoint it collapses to the
   icon plus the number, but it stays in the header bar, outside the menu. */
.header-call {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}

/* --- Primary navigation -------------------------------------------------- */
.primary-nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  gap: 26px;
}
.primary-nav a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  text-decoration: none;
  font-family: var(--font-heading);
  font-size: 15px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text);
}
.primary-nav a:hover,
.primary-nav .current-menu-item > a,
.primary-nav .current-menu-ancestor > a {
  color: var(--color-accent-700);
  text-decoration: underline;
  text-underline-offset: 6px;
}

/* Dropdown parents (Services, Service Areas). */
.primary-nav li { position: relative; }
.primary-nav .sub-menu {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 240px;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  background: var(--color-bg);
  border: 1px solid var(--color-divider);
  padding: 6px 0;
  z-index: 30;
}
.primary-nav .sub-menu a {
  display: flex;
  padding: 8px 18px;
  font-size: 14px;
  letter-spacing: 0.04em;
  width: 100%;
}
.primary-nav .sub-menu a:hover { background: var(--color-accent-100); text-decoration: none; }

/* Open the dropdown on hover, on keyboard focus anywhere inside it, and when
   the toggle button reports itself as expanded. All three matter: hover for
   the mouse, focus-within for the keyboard, aria-expanded for touch. */
.primary-nav li:hover > .sub-menu,
.primary-nav li:focus-within > .sub-menu,
.primary-nav li.is-open > .sub-menu { display: flex; }

/* --- Menu toggle (hidden on desktop, shown at the nav breakpoint) -------- */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: var(--tap);
  height: var(--tap);
  padding: 0;
  background: transparent;
  border: 1px solid var(--color-divider);
  cursor: pointer;
  color: var(--color-text);
}
.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  display: block;
  width: 20px;
  height: 2px;
  background: currentColor;
  transition: transform 0.2s, opacity 0.2s;
}
.nav-toggle__bars { position: relative; }
.nav-toggle__bars::before,
.nav-toggle__bars::after { content: ""; position: absolute; left: 0; }
.nav-toggle__bars::before { top: -6px; }
.nav-toggle__bars::after  { top: 6px; }

/* The X state when the menu is open. */
.nav-toggle[aria-expanded="true"] .nav-toggle__bars { background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after  { transform: translateY(-6px) rotate(-45deg); }


/* ==========================================================================
   7. FOOTER
   ========================================================================== */

.site-footer {
  background: var(--color-bg);
  border-top: 1px solid var(--color-divider);
}
/* Mobile-first: one column. Widens in the responsive section below.
   The design shows 2fr 1fr 1fr; that returns at 900px. */
.site-footer__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 32px;
  padding-block: clamp(40px, 5vw, 64px);
}
.site-footer__brand {
  display: flex;
  align-items: center;
  gap: 12px;
}
.site-footer__brand-name {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 20px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.site-footer__blurb {
  font-size: 14px;
  line-height: 1.6;
  margin: 16px 0 0;
  max-width: 44ch;
  color: var(--text-muted);
}
.site-footer__roc {
  margin-top: 16px;
  font-family: var(--font-heading);
  font-size: 14px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent-700);
}
.site-footer__heading {
  font-family: var(--font-heading);
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-soft);          /* AA NUDGE #2 — was 60% */
  margin-bottom: 14px;
}
.site-footer__list { list-style: none; margin: 0; padding: 0; }
.site-footer__list a,
.site-footer a.site-footer__link {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  font-size: 15px;
  text-decoration: none;
  color: var(--color-text);
  word-break: break-word;
}
.site-footer__list a:hover,
.site-footer a.site-footer__link:hover {
  color: var(--color-accent-700);
  text-decoration: underline;
}
.site-footer__hours {
  font-size: 14px;
  line-height: 1.6;
  margin-top: 12px;
  color: var(--text-muted);
}
.site-footer__bar { border-top: 1px solid var(--color-divider); }
.site-footer__bar-inner {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  justify-content: space-between;
  padding-block: 18px;
  font-size: 13px;
  color: var(--text-soft);          /* AA NUDGE #2 — was 60% */
}


/* ==========================================================================
   8. STICKY MOBILE CALL BAR
   ==========================================================================
   The design shows a persistent header CTA. On a phone that intent becomes a
   fixed bar at the bottom of the screen — the thumb reaches it without
   scrolling, which is the whole point for someone standing in a flooding
   laundry room.
   Only rendered below the nav breakpoint. See the responsive section.
   ========================================================================== */

.sticky-call {
  display: none;                 /* Turned on in the responsive layer. */
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  background: var(--color-accent-900);
  border-top: 1px solid var(--color-accent-800);
  padding: 8px 12px;
  padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px));
}
.sticky-call__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.sticky-call .btn {
  width: 100%;
  min-height: 48px;
  font-size: 16px;
}
.sticky-call .btn-secondary {
  border-color: color-mix(in srgb, var(--color-bg) 45%, transparent);
  color: var(--color-bg);
}
/* When only one button is present, let it fill the bar. */
.sticky-call__grid > :only-child { grid-column: 1 / -1; }


/* ==========================================================================
   9. RESPONSIVE
   ==========================================================================
   AUTHORED FOR THIS BUILD. The approved design contains no media queries —
   it specifies the desktop rendering only. These rules build up from a 360px
   baseline to that desktop rendering, using the design's own grid class
   names as the hooks.

   Tested widths: 360, 390, 768, 1024, 1280, 1440.

   Breakpoints:
     up to 899px  — single column, mobile nav, sticky call bar
     900px+       — two-column grids return, nav goes horizontal
     1024px+      — three-column service grid returns
   ========================================================================== */

/* --- The grids the design declares but never styles ----------------------
   At the desktop widths these produce exactly what the design shows. Below
   the breakpoints they stack, which the design does not specify. */

.hero-grid,
.about-grid,
.area-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);   /* Mobile: one column. */
  gap: clamp(28px, 5vw, 72px);
  align-items: center;
}

.svc-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);   /* Mobile: one column. */
  gap: clamp(20px, 3vw, 40px);
}

.signs-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);   /* Mobile: one column. */
  gap: 16px 40px;
}

.facts-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);   /* Mobile: stacked cards. */
}

/* --- Tablet and up ------------------------------------------------------- */
@media (min-width: 700px) {
  .svc-grid   { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .signs-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .facts-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* Footer: brand block spans the full width, the two link columns pair up.
     Three columns at 768px would be too cramped to tap comfortably. */
  .site-footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .site-footer__grid > :first-child { grid-column: 1 / -1; }
}

/* --- The nav breakpoint --------------------------------------------------
   900px is where the four nav items plus the call button stop fitting on one
   line without crowding. */
@media (min-width: 900px) {
  .hero-grid  { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .about-grid { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
  .area-grid  { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); align-items: start; }
}

@media (min-width: 900px) {
  /* The design's footer proportions return here. */
  .site-footer__grid { grid-template-columns: 2fr 1fr 1fr; }
  .site-footer__grid > :first-child { grid-column: auto; }
}

@media (min-width: 1024px) {
  .svc-grid   { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .facts-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* The facts panel draws its own cell borders, which would double up with the
   blueprint frame on whichever cell ends a row. That cell changes with the
   column count, so it is cleared per breakpoint. */
.facts-grid > .fact:last-child { border-right: 0; }

@media (min-width: 700px) {
  .facts-grid > .fact:nth-child(2n) { border-right: 0; }
}

@media (min-width: 1024px) {
  .facts-grid > .fact:nth-child(2n) { border-right: 1px solid var(--color-divider); }
  .facts-grid > .fact:nth-child(3n) { border-right: 0; }
}


/* --- Mobile navigation ---------------------------------------------------
   Below 900px the nav links collapse into a toggle panel.
   The PHONE NUMBER DOES NOT COLLAPSE — .header-call stays in the header bar
   at every width. That is a hard requirement: the call button is the
   conversion on this site. */
@media (max-width: 899px) {

  .nav-toggle { display: inline-flex; }

  .primary-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-divider);
    box-shadow: 0 12px 32px color-mix(in srgb, #2b2b2d 22%, transparent);
    max-height: calc(100vh - 100%);
    overflow-y: auto;
  }
  .primary-nav.is-open { display: block; }

  .site-header__inner { position: relative; flex-wrap: wrap; }

  .primary-nav ul {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 8px var(--gutter) 16px;
  }
  .primary-nav li { width: 100%; }
  .primary-nav a {
    width: 100%;
    padding-block: 6px;
    border-bottom: 1px solid var(--color-divider);
  }

  /* Sub-menus stack inline rather than floating. */
  .primary-nav .sub-menu {
    display: block;
    position: static;
    border: 0;
    padding: 0 0 0 18px;
    min-width: 0;
    box-shadow: none;
  }
  .primary-nav .sub-menu a { padding: 6px 0; font-size: 14px; }

  /* The sticky bottom call bar appears only at these widths. */
  .sticky-call { display: block; }

  /* Leave room for the bar so it never covers the last line of the footer. */
  body { padding-bottom: 76px; }
}

/* --- Narrow phones (360–420px) -------------------------------------------
   At 360px the brand lockup plus a full "Call 602.884.7771" button will not
   fit. The button keeps the icon and the number but drops to a tighter size;
   the strapline under the logo is hidden because the footer repeats it. */
@media (max-width: 480px) {

  .brand__mark  { width: 38px; height: 38px; }
  .brand__strap { display: none; }

  .header-call.btn {
    padding: 10px 12px;
    font-size: 14px;
  }

  .site-footer__grid { gap: 28px; }

  .promo-bar { font-size: 12px; }
  .promo-bar__inner { justify-content: center; text-align: center; }
}

/* At the very narrowest, the header call button shows the number only. */
@media (max-width: 380px) {
  .header-call .csp-icon { display: none; }
}


/* --- Tables reflow to cards ----------------------------------------------
   No sideways scrolling on a phone. Any table in editor content becomes a
   stack of labelled rows. */
@media (max-width: 700px) {
  .entry-content table,
  .entry-content thead,
  .entry-content tbody,
  .entry-content th,
  .entry-content td,
  .entry-content tr { display: block; width: 100%; }

  .entry-content thead { position: absolute; left: -9999px; }

  .entry-content tr {
    border: 1px solid var(--color-divider);
    margin-bottom: 12px;
    padding: 8px 12px;
  }
  .entry-content td { border: 0; padding: 6px 0; }
}


/* ==========================================================================
   10. ACCESSIBILITY
   ========================================================================== */

/* --- Skip link -----------------------------------------------------------
   Off-screen until focused, then it appears at the top of the page. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 12px 20px;
  background: var(--color-accent-900);
  color: var(--color-bg);
  font-family: var(--font-heading);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-decoration: none;
}
.skip-link:focus {
  left: 0;
  color: var(--color-bg);
}

/* --- Focus ---------------------------------------------------------------
   A visible focus ring on every interactive element. The 2px offset keeps it
   clear of the element's own border. */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--color-interactive);
  outline-offset: 2px;
}
/* On the dark band the green ring would disappear, so use the tan. */
.section--dark :focus-visible,
.promo-bar :focus-visible,
.sticky-call :focus-visible {
  outline-color: var(--color-accent-2-300);
}

::selection { background: color-mix(in srgb, var(--color-accent) 30%, transparent); }

/* --- Screen-reader-only text --------------------------------------------- */
.screen-reader-text {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --- Reduced motion ------------------------------------------------------
   Respect the operating-system preference. Nothing animates for anyone who
   has asked for that. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- Print ---------------------------------------------------------------
   Somebody will print a service page. Drop the chrome. */
@media print {
  .site-header, .site-footer, .sticky-call, .promo-bar, .skip-link { display: none !important; }
  body { padding-bottom: 0; }
}
