/*
Theme Name: Clever Dog Base
Theme URI: https://cleverdogdesign.com
Author: Clever Dog Design
Author URI: https://cleverdogdesign.com
Description: Clever Dog Design's lean core-block base theme — the foundation of the block-theme provisioning pipeline. Brand lands via theme.json preset overrides; layouts land as core-block patterns; every client site stays editable in the standard editor.
Requires at least: 6.5
Tested up to: 6.9
Requires PHP: 8.0
Version: 0.1.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: cleverdog-base
*/

/* =====================================================================
   EVERYTHING in this stylesheet colours/typesets through the theme.json
   PRESETS (var(--wp--preset--…)). No hardcoded brand hex anywhere —
   the engine rebrands a whole site by overriding preset VALUES only.
   Derived tones (lines, deep hovers, tints) use color-mix() over the
   presets so they re-derive automatically when the brand changes.
   ===================================================================== */

:root {
  --cdd-line: color-mix(in srgb, var(--wp--preset--color--primary) 14%, var(--wp--preset--color--base));
  --cdd-accent-deep: color-mix(in srgb, var(--wp--preset--color--accent) 82%, black);
  --cdd-primary-mid: color-mix(in srgb, var(--wp--preset--color--primary) 82%, white 6%);
  --cdd-radius: 14px;
  --cdd-ease: cubic-bezier(.22, .61, .36, 1);

  /* ══ #631 — THREE TOKENS FOR THREE RENDERING FAULTS ═══════════════════════════════════
     Rick measured all three on the live Hartley build, 1 Aug. Every one is CSS, none is
     content, which is why the copy, image and palette checks all pass the site clean.

     --cdd-num-ink   The step/benefit counters render the accent on `surface`. MEASURED:
                     #C25F1C on #EEF4F8 = 3.83:1. AA wants 4.5. `--cdd-accent-deep` already
                     existed, is the LIGHTEST darkened accent we define, and measures 5.29 on
                     surface and 5.87 on white — so this is a re-POINT, not a new colour, and
                     the accent keeps its character rather than being thrown away for a
                     neutral (#554 §1's rule).
     --cdd-band-gap  The vertical rhythm. The trust band carried `margin-bottom:
                     var(--wp--preset--spacing--80)` inline and NO margin-top, so it measured
                     20px above and 80.96px below — Rick's *"a thin white band above and a
                     much larger one below"*. One token, used for both edges, so the two can
                     no longer drift apart.
     --cdd-pill-gap  The gap in a wrapping pill row, so the row and its wrap use one value. */
  --cdd-num-ink: var(--cdd-accent-deep);
  /* ⚠ AND A SECOND INK, BECAUSE ONE CANNOT DO BOTH — this is #554 §1's rule arriving as a
     measurement rather than an opinion. The counters appear on a PALE band and on a DARK
     one, and NO single colour passes on both: accent-deep is 5.29 on #EEF4F8 and 2.38 on
     #082F45; white is 13.97 on the dark and 1.11 on the pale. The dark-band check caught a
     THIRD contrast failure nobody had reported — muted on secondary, measuring 2.78:1.
     75% accent is the LIGHTEST tint of the client's own accent that clears 4.5 on the dark
     band (4.86). Derived by walking the mix, not chosen — same method as the overlay. */
  --cdd-num-ink-dark: color-mix(in srgb, var(--wp--preset--color--accent) 75%, white);
  --cdd-band-gap: var(--wp--preset--spacing--60, 56px);
  --cdd-pill-gap: var(--wp--preset--spacing--30, 16px);
}

/* ══ #631 (1) — A COUNTER IS A NUMBER, AND A NUMBER NEVER BREAKS ════════════════════════
   MEASURED at 1440 and 390 with a real browser: "01", "02" and "03" each rendered across
   TWO LINES — `0` above, `1` below — in a box 21.9px wide holding 22px type. "04" was the
   only one that held, and only at 1440; at 390 it broke too.

   ⚠ THE CAUSE IS NOT A MISSING WIDTH, IT IS `word-break` INHERITED FROM WORDPRESS.
   Computed style on those elements: `overflow-wrap: break-word` AND `word-break: break-word`,
   neither of them ours. That permission is what lets a two-character token split at all; the
   flex item's `min-width: auto` then squeezes the box under its own min-content and the break
   is taken. **Setting a width alone would not have fixed it** — the browser would still have
   been allowed to break, and a narrower column would bring it straight back.

   So all three are stated: the number may not break, it may not be squeezed under two
   digits, and its digits are tabular so 01 and 04 measure the same. */
.cdd-num {
  white-space: nowrap;
  word-break: keep-all;
  overflow-wrap: normal;
  min-width: 2.5ch;
  font-variant-numeric: tabular-nums;
  color: var(--cdd-num-ink);
}

/* The dark band's counters take the light ink. `.cdd-on-dark` is the convention #619
   established for exactly this — the band, not the element, decides what is readable. */
.cdd-on-dark .cdd-num,
.has-secondary-background-color .cdd-num,
.has-primary-background-color .cdd-num {
  color: var(--cdd-num-ink-dark);
}

/* ══ #631 (2) — ONE ROW; AND WHEN IT CANNOT BE ONE, EVEN ROWS ═══════════════════════════
   MEASURED: four trust pills at 1440 laid out 3 + 1 — three across and one stranded below.
   The container is a wrapping flex row of natural-width items, so the fourth pill falls
   whenever the four natural widths exceed the line. Rick: *"they should sit on one row and
   wrap evenly when they cannot."*

   `flex: 1 1 auto` makes the four share the line, so at 1440 they sit on one row. Below the
   breakpoint a 50% basis forces 2 + 2 — **even by construction rather than by luck of the
   text lengths**, which is the half a plain `flex-wrap: wrap` can never promise. */
.cdd-pill-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--cdd-pill-gap);
}
/* ⚠ `1 1 0`, NOT `1 1 auto` — MEASURED, and the difference is the whole fix. `auto` bases
   each pill on its own content, so flex-grow can only stretch what already fits; four pills
   whose natural widths overrun the line still wrap 3 + 1, which is exactly what the first
   attempt measured. A zero basis makes the four SHARE the line, and `min-width: 0` is what
   permits the share — without it `min-width: auto` floors each item at its content width and
   the wrap comes straight back. */
.cdd-pill-row > * {
  flex: 1 1 0;
  min-width: 0;
  justify-content: center;
}
/* Below this, four across is not honest at any font size — two even rows instead of a
   lopsided one. `calc(50% - gap)` rather than `50%` because the gap is part of the line. */
@media (max-width: 900px) {
  .cdd-pill-row > * { flex: 0 1 calc(50% - var(--cdd-pill-gap)); }
}

/* ══ #631 (3) — A BAND'S TWO EDGES COME FROM ONE TOKEN ══════════════════════════════════
   They were 20px and 80.96px. They are now the same value because they are the same value —
   the only way two numbers stay equal is to stop being two numbers. */
.cdd-band {
  margin-top: var(--cdd-band-gap);
  margin-bottom: var(--cdd-band-gap);
}

body {
  -webkit-font-smoothing: antialiased;
  line-height: 1.6;
}

/* =====================================================================
   FULL-WIDTH SECTION MODEL (5 Jul fix — Sydney bed rendered ~680 narrow).
   Every pattern section = an alignfull OUTER band + a .cdd-inner rail.
   The rail is constrained HERE, deterministically, so the 1180 layout
   never depends on WP's generated layout CSS; and an alignfull band must
   never be capped by a parent rail (the old page.html wrapped post-content
   in a constrained main, which clamped the whole page to contentSize).
   ===================================================================== */
.cdd-inner {
  max-width: 1180px;
  margin-left: auto;
  margin-right: auto;
  padding-left: clamp(20px, 4vw, 32px);
  padding-right: clamp(20px, 4vw, 32px);
}
main > .alignfull,
.wp-block-post-content > .alignfull {
  max-width: none;
  margin-left: 0;
  margin-right: 0;
}

/* 6 Jul render fix #4: theme.json blockGap injected 1.25rem WHITE strips
   between adjacent alignfull colour bands (header→hero, section→section).
   Bands butt seamlessly, like the demos; spacing INSIDE sections is
   authored explicitly in this file. */
main.wp-block-group > * { margin-block-start: 0 !important; }
.wp-block-post-content > .alignfull { margin-block-start: 0 !important; margin-block-end: 0 !important; }
/* 6 Jul (the gaps that SURVIVED the first fix): WP's ROOT layout also gaps
   the top-level template elements — .wp-site-blocks > * + * gets the block
   gap, which is the header→hero strip and the footer→last-band strip. Zero
   it at the root; every visible rhythm inside sections is authored here. */
.wp-site-blocks > * { margin-block-start: 0 !important; margin-block-end: 0 !important; }
body { margin: 0; }
/* The under-footer / overscroll canvas matches the dark chrome instead of
   flashing white on short pages and rubber-band scrolls. */
html { background: var(--wp--preset--color--secondary); }

h1, h2, h3, h4 {
  line-height: 1.05;
  letter-spacing: -.01em;
}

/* ------ signature safety-stripe divider (Local Service motif) ------
   Authored as a wp:separator (an empty group collapses/normalises away —
   the 4 Jul "renders flat" issue). Every core/theme separator default is
   overridden hard: no border, no opacity fade, no max-width cap. */
hr.cdd-stripe,
.cdd-stripe {
  display: block;
  height: 8px;
  margin: 0;
  border: 0;
  max-width: none;
  width: 100%;
  opacity: 1;
  background: repeating-linear-gradient(-45deg,
    var(--wp--preset--color--accent) 0 18px,
    var(--wp--preset--color--primary) 18px 36px);
}

/* 6 Jul render fix #8 — the stripe is a TRADES motif token. Non-trades
   recipes (body class cdd-recipe-* set from the provisioning recipe) get a
   quiet accent hairline instead of hazard stripes. */
/* SEAM-CORNER FIX (7 Jul batch 9, recurring): the stripe is the ONE piece
   of between-band chrome, and a seam divider's unpainted window exposed
   its diagonals as a stray orange/navy sliver (hero→trust on cd269902).
   Rule: a stripe immediately followed by a seam overlay never renders —
   the curve IS that boundary's motif. Blocky/no-seam builds keep it. */
hr.cdd-stripe:has(+ .cdd-shape),
.cdd-stripe:has(+ .cdd-shape) { display: none; }

body[class*="cdd-recipe-"]:not(.cdd-recipe-local_service) hr.cdd-stripe,
body[class*="cdd-recipe-"]:not(.cdd-recipe-local_service) .cdd-stripe {
  height: 4px;
  /* SYMMETRIC fade (6 Jul): the old left-to-right gradient hit the viewport
     edge at full-strength accent and read as a pink BLEED, not a divider.
     Centre-weighted, it reads deliberate — and the section break stays. */
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--wp--preset--color--accent) 15%, transparent),
    var(--wp--preset--color--accent) 25% 75%,
    color-mix(in srgb, var(--wp--preset--color--accent) 15%, transparent));
}

/* ------ image slots: never look broken ------ */
/* A raw pattern (inserted before provisioning fills it) still carries a
   {{TOKEN}} src — paint the slot as a quiet surface tile instead of a
   broken-image icon. The bundled placeholder SVG covers the filled-but-
   no-photo-yet case; this covers the not-even-filled case. */
.wp-block-image img[src^="{{"],
.wp-block-image img[src=""] {
  min-height: 220px;
  width: 100%;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--wp--preset--color--surface) 88%, var(--wp--preset--color--muted)),
    var(--wp--preset--color--surface));
  color: transparent;
}

/* ------ eyebrow kicker ------ */
.cdd-eyebrow {
  font-family: var(--wp--preset--font-family--heading);
  text-transform: uppercase;
  font-weight: 700;
  letter-spacing: .16em;
  font-size: 13px;
  color: var(--wp--preset--color--accent);
}

/* ------ HERO ------ */
.cdd-hero {
  background:
    radial-gradient(1100px 600px at 78% -10%, var(--cdd-primary-mid), var(--wp--preset--color--secondary) 60%);
  color: var(--wp--preset--color--base);
  overflow: hidden;
}
.cdd-hero h1,
.cdd-hero h2,
.cdd-hero h3 { color: var(--wp--preset--color--base); }
.cdd-hero .cdd-hero-sub { color: var(--wp--preset--color--accent); }
.cdd-hero h1,
.cdd-hero .cdd-hero-sub {
  font-size: clamp(52px, 8vw, 92px);
  font-weight: 800;
}
.cdd-hero-flag {
  display: inline-block;
  background: color-mix(in srgb, var(--wp--preset--color--accent) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--wp--preset--color--accent) 40%, transparent);
  color: color-mix(in srgb, var(--wp--preset--color--accent) 35%, white);
  padding: 7px 14px;
  border-radius: 100px;
  font-size: 13px;
  font-weight: 600;
}
.cdd-hero-lead {
  font-size: 19px;
  color: color-mix(in srgb, var(--wp--preset--color--base) 78%, var(--wp--preset--color--muted));
  max-width: 33ch;
}
.cdd-hero-chips {
  color: color-mix(in srgb, var(--wp--preset--color--base) 62%, var(--wp--preset--color--muted));
  font-size: 14.5px;
  font-weight: 500;
}
.cdd-hero-card {
  background: linear-gradient(160deg,
    color-mix(in srgb, var(--wp--preset--color--primary) 92%, white),
    var(--wp--preset--color--secondary));
  border: 1px solid color-mix(in srgb, var(--wp--preset--color--base) 10%, transparent);
  border-radius: 20px;
  box-shadow: 0 30px 60px -20px rgba(0, 0, 0, .6);
}
.cdd-hero-card h3 { font-size: 24px; }
.cdd-hero-card img { border-radius: 12px; }
.cdd-hero-rate {
  color: var(--wp--preset--color--accent);
  font-weight: 700;
  font-size: 15px;
}
.cdd-hero-card ul {
  list-style: none;
  padding-left: 0;
  display: grid;
  gap: 11px;
  color: color-mix(in srgb, var(--wp--preset--color--base) 82%, var(--wp--preset--color--muted));
  font-size: 15px;
}
.cdd-hero-card ul li::before {
  content: "✓ ";
  color: var(--wp--preset--color--accent);
  font-weight: 800;
}

/* ------ TRUST BAR ------ */
.cdd-trust {
  background: var(--wp--preset--color--secondary);
  color: color-mix(in srgb, var(--wp--preset--color--base) 85%, var(--wp--preset--color--muted));
  border-top: 1px solid color-mix(in srgb, var(--wp--preset--color--base) 7%, transparent);
}
.cdd-trust p {
  font-size: 15px;
  font-weight: 600;
  margin: 0;
}
.cdd-trust .cdd-stars,
.cdd-quote-stars {
  color: var(--wp--preset--color--accent);
  letter-spacing: 2px;
}

/* ------ section heads ------ */
.cdd-sec-head h2 {
  font-size: clamp(36px, 4.6vw, 54px);
  font-weight: 800;
  color: var(--wp--preset--color--primary);
}
.cdd-sec-head p {
  font-size: 18px;
  color: var(--wp--preset--color--muted);
}
.cdd-on-dark h2,
.cdd-on-dark h3 { color: var(--wp--preset--color--base); }
.cdd-on-dark p { color: color-mix(in srgb, var(--wp--preset--color--base) 65%, var(--wp--preset--color--muted)); }

/* ------ service cards ------ */
.cdd-card {
  background: var(--wp--preset--color--base);
  border: 1px solid var(--cdd-line);
  border-radius: var(--cdd-radius);
  transition: transform .25s var(--cdd-ease), box-shadow .25s, border-color .25s;
  height: 100%;
}
/* #364 DEFECT 4 — the "Good to know" aside overflowing its own section.
   Rick: "we've been having the same issue right from the start, since the
   first demos we ever did." Never fixed because never diagnosed — only seen.

   MEASURED on the real served /treatments/ page at 1440: the aside runs
   1014→1598 while the row it belongs to runs 641→1225. A 373px spill, which
   is why a tall empty white box sits over the next section's heading.

   CAUSE: `height: 100%` above. It is correct for a card that is the ONLY
   thing in its column — that is what makes card grids line up — but this
   aside SHARES its column with a 327px photo above it. 100% resolves against
   the column's stretched height, so the card claims the whole row height
   starting from below the photo: 327 + 24 (its margin) + 22 (the in-flight
   reveal transform) = 373.

   A card that has siblings must size to its own content. Card grids put one
   card per column and are untouched. */
.cdd-card:not(:only-child) { height: auto; }
.cdd-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 20px 40px -22px color-mix(in srgb, var(--wp--preset--color--primary) 40%, transparent);
}
.cdd-card h3 {
  font-size: 22px;
  font-weight: 700;
  color: var(--wp--preset--color--primary);
}
.cdd-card p {
  font-size: 15px;
  color: var(--wp--preset--color--muted);
}

/* ⚠⚠ #619 (#607) — THE DARK BAND, AND THE CASCADE FAULT THAT MADE IT
   UNREADABLE. MEASURED FROM RENDERED PIXELS on run rh-260731-163450, the
   "Common plumbing problems we solve" cards:

     card heading  #1F5078 on #0C1B2A = 2.05:1   (large text needs 3.0)
     card body     #54697C on #0C1B2A = 3.06:1   (body needs 4.5)

   Rick: "light blue check over dark blue in boxes."

   THE CAUSE IS SOURCE ORDER, NOT A MISSING RULE. The correct rule already
   existed — `.cdd-on-dark h3 { color: base }` at the top of this file — and
   `.cdd-card h3 { color: primary }` immediately above has THE SAME
   SPECIFICITY (0,1,1) and comes LATER, so it wins. A card inside a dark band
   therefore kept its light-band text colours over a dark background. Same
   story for `p` and `muted`.

   ⚠ AND NO PALETTE CLAUSE COULD EVER HAVE CAUGHT THIS. The palette guarantees
   PAIRINGS; this is a pattern putting `primary` text on a `secondary` band —
   a pairing the palette was never asked about. #607's own point (c).

   The fix is scoped and explicit rather than a specificity war: a card inside
   a dark band takes the COMPUTED readable colour for that band
   (`--wp--custom--text-on-secondary`, which SiteAssembler already calculates
   per client and cdd_merge_brand already emits), falling back to `base`. */
.cdd-on-dark .cdd-card h3 {
  color: var(--wp--custom--text-on-secondary, var(--wp--preset--color--base));
}
.cdd-on-dark .cdd-card p {
  color: color-mix(in srgb, var(--wp--custom--text-on-secondary, var(--wp--preset--color--base)) 78%, transparent);
}
.cdd-card-hot { background: var(--wp--preset--color--primary); border-color: var(--wp--preset--color--primary); }
.cdd-card-hot h3 { color: var(--wp--preset--color--base); }
.cdd-card-hot p { color: color-mix(in srgb, var(--wp--preset--color--base) 65%, var(--wp--preset--color--muted)); }
.cdd-card-badge {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--wp--preset--color--accent);
}

/* ------ about + guarantee ------ */
.cdd-about-photo img { border-radius: 20px; }
.cdd-guarantee {
  background: var(--wp--preset--color--surface);
  border-left: 4px solid var(--wp--preset--color--accent);
  border-radius: 0 12px 12px 0;
}
.cdd-guarantee h4 {
  color: var(--wp--preset--color--primary);
  font-size: 19px;
  margin: 0 0 2px;
}
.cdd-guarantee p { font-size: 15px; margin: 0; }

/* ------ service areas (dark) ------ */
.cdd-areas { background: var(--wp--preset--color--primary); color: var(--wp--preset--color--base); }
.cdd-area {
  background: color-mix(in srgb, var(--wp--preset--color--base) 5%, transparent);
  border: 1px solid color-mix(in srgb, var(--wp--preset--color--base) 10%, transparent);
  border-radius: 10px;
  font-weight: 600;
  font-size: 16px;
  transition: background .2s;
}
.cdd-area:hover { background: color-mix(in srgb, var(--wp--preset--color--accent) 16%, transparent); }
.cdd-area p { margin: 0; padding: 15px 18px; }
.cdd-area p::before { content: "📍 "; }
.cdd-areas-note { color: color-mix(in srgb, var(--wp--preset--color--base) 65%, var(--wp--preset--color--muted)); }
.cdd-areas-note strong { color: var(--wp--preset--color--base); }

/* ------ testimonials ------ */
.cdd-quote {
  background: var(--wp--preset--color--base);
  border: 1px solid var(--cdd-line);
  border-radius: var(--cdd-radius);
  height: 100%;
}
/* #480 — the row carries the number of reviews the client actually has: three,
   two or one. A single card left to span 1180px reads as a layout that broke,
   so it is centred at a readable measure. Two share the width as they always
   did. Nothing here pads the row out — the section is dropped entirely at
   zero (cdd:block HAS_TESTIMONIALS). */
.cdd-quotes .wp-block-column:only-child { max-width: 680px; margin-inline: auto; }
.cdd-quote p { font-size: 16.5px; }
.cdd-quote-who { font-size: 14px; color: var(--wp--preset--color--muted); }
.cdd-quote-who strong { color: var(--wp--preset--color--primary); font-size: 15px; }
.cdd-quote-who a { color: inherit; }
/* #447 — the review-source notice. Quiet, but never hidden: Google requires the
   source and the ordering/filtering disclosure to be visible beside the reviews,
   so this must not be display:none'd or collapsed to zero. Empty for every
   source other than Google, where the paragraph renders with nothing in it. */
.cdd-review-source { font-size: 13px; color: var(--wp--preset--color--muted); margin-top: 22px; }
.cdd-review-source:empty { display: none; }

/* ------ contact / CTA ------ */
.cdd-contact { background: var(--wp--preset--color--surface); }
.cdd-crow {
  border-top: 1px solid var(--cdd-line);
  font-size: 16px;
  color: var(--wp--preset--color--muted);
}
.cdd-crow strong {
  display: block;
  color: var(--wp--preset--color--primary);
  font-family: var(--wp--preset--font-family--heading);
  font-size: 18px;
  font-weight: 700;
}
.cdd-emerg {
  background: var(--wp--preset--color--primary);
  color: var(--wp--preset--color--base);
  border-radius: 12px;
}
.cdd-emerg p { margin: 0; }
.cdd-emerg strong { font-family: var(--wp--preset--font-family--heading); font-size: 18px; }
.cdd-form-card {
  background: var(--wp--preset--color--base);
  border: 1px solid var(--cdd-line);
  border-radius: 18px;
  box-shadow: 0 24px 50px -30px color-mix(in srgb, var(--wp--preset--color--primary) 40%, transparent);
}
.cdd-form-card h3 {
  font-size: 26px;
  font-weight: 800;
  color: var(--wp--preset--color--primary);
}
.cdd-form-slot { margin-top: 18px; }
/* The pre-#19 "form goes here" state — an intentional labelled box, only
   when the slot holds the placeholder (a real embed carries no
   .cdd-form-pending and gets none of this chrome). */
.cdd-form-pending {
  display: block;
  border: 2px dashed color-mix(in srgb, var(--wp--preset--color--primary) 25%, var(--wp--preset--color--surface));
  border-radius: 12px;
  background: var(--wp--preset--color--surface);
  padding: 34px 26px;
  text-align: center;
  font-size: 15px;
  color: var(--wp--preset--color--muted);
}
.cdd-form-pending strong {
  display: block;
  margin-bottom: 6px;
  font-family: var(--wp--preset--font-family--heading);
  font-size: 18px;
  color: var(--wp--preset--color--primary);
  text-transform: uppercase;
  letter-spacing: .06em;
}

/* ------ buttons: solid accent + ghost outline (core button styles) ------ */
.wp-block-button__link {
  font-weight: 700;
  border-radius: 12px;
  transition: transform .2s, background .2s, border-color .2s;
}
.wp-block-button .wp-block-button__link:hover { transform: translateY(-2px); }
.cdd-btn-ghost .wp-block-button__link {
  background: transparent;
  border: 2px solid color-mix(in srgb, var(--wp--preset--color--base) 28%, transparent);
  color: var(--wp--preset--color--base);
}
.cdd-btn-ghost .wp-block-button__link:hover {
  border-color: var(--wp--preset--color--base);
  background: color-mix(in srgb, var(--wp--preset--color--base) 6%, transparent);
}

/* ------ pattern chrome: spacing lives HERE, not in per-block style
   attributes — hand-authored pattern markup stays valid-by-construction
   (no attr/inline-style pairs to keep in sync). ------ */
.cdd-section { padding: 92px 0; }
.cdd-hero { padding: 88px 0 96px; }
.cdd-trust { padding: 22px 0; }
.cdd-sec-head { max-width: 640px; margin-bottom: 52px; }
.cdd-sec-head-center { margin-left: auto; margin-right: auto; }
.cdd-services { background: var(--wp--preset--color--surface); }
.cdd-card { padding: 26px 24px; }
.cdd-hero-card { padding: 30px; }
.cdd-quote { padding: 30px; }
.cdd-guarantee { padding: 20px 22px; margin-top: 26px; }
.cdd-form-card { padding: 32px; }
.cdd-crow { padding: 18px 0; margin: 0; }
.cdd-crow a { display: block; }
.cdd-emerg { padding: 18px 20px; margin-top: 8px; }
.cdd-areas-note { margin-top: 28px; font-size: 16px; }

/* ------ interior page header (service / about / contact pages) ------ */
.cdd-page-header {
  background:
    radial-gradient(900px 420px at 80% -20%, var(--cdd-primary-mid), var(--wp--preset--color--secondary) 62%);
  color: var(--wp--preset--color--base);
  padding: 64px 0 60px;
  overflow: hidden;
}
.cdd-page-header h1 {
  color: var(--wp--preset--color--base);
  font-size: clamp(40px, 6vw, 68px);
  font-weight: 800;
  margin: 14px 0 10px;
}
/* #364 DEFECT 3 — the lead paragraph shares the H1's left edge.
   MEASURED on the real served /treatments/ page at 1440: H1 left 155px,
   paragraph left 382px — a 227px indent, with the chips line underneath back
   at 155. Rick: "you got right text going over to one side and then it comes
   back."
   CAUSE: the paragraph is the only thing in this header with a max-width, and
   WordPress's `is-layout-constrained` parent auto-centres any child narrower
   than the content width via `margin-inline: auto`. (1116 - 661) / 2 = 227.4.
   The max-width stays — a 58ch measure is right for reading. The auto-centring
   goes, because nothing else in this header is centred.

   `!important` is not laziness here and it is the reason this survived from
   the first demos. WordPress's own rule is:

     .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull))
     { margin-left: auto !important; margin-right: auto !important; }

   It ships `!important`, so NO ordinary declaration can win, at any
   specificity. Verified against the served page with CSS.getMatchedStylesForNode
   — the plain `margin-inline: 0` was matched and lost. */
.cdd-page-header .cdd-hero-lead { max-width: 58ch; margin-inline: 0 !important; }

/* ------ service detail bands ------ */
.cdd-svc-who { background: var(--wp--preset--color--surface); }
.cdd-svc-expect { background: var(--wp--preset--color--primary); color: var(--wp--preset--color--base); }
.cdd-svc-list {
  list-style: none;
  padding-left: 0;
  display: grid;
  gap: 12px;
  font-size: 16.5px;
  color: color-mix(in srgb, var(--wp--preset--color--contrast) 80%, var(--wp--preset--color--muted));
}
.cdd-svc-list li {
  border-top: 1px solid var(--cdd-line);
  padding-top: 12px;
}
.cdd-svc-list li::before {
  content: "✓ ";
  color: var(--wp--preset--color--accent);
  font-weight: 800;
}
.cdd-svc-note { font-size: 15px; color: var(--wp--preset--color--muted); margin-top: 18px; }
.cdd-svc-note a { color: var(--wp--preset--color--accent); font-weight: 600; }
.cdd-svc-facts { margin-top: 24px; }
.cdd-svc-facts-list {
  list-style: none;
  padding-left: 0;
  display: grid;
  gap: 10px;
  font-size: 15px;
  color: var(--wp--preset--color--muted);
}
.cdd-svc-facts-list li::before {
  content: "✓ ";
  color: var(--wp--preset--color--accent);
  font-weight: 800;
}

/* ------ what-to-expect steps (dark band) ------ */
.cdd-step {
  background: color-mix(in srgb, var(--wp--preset--color--base) 5%, transparent);
  border: 1px solid color-mix(in srgb, var(--wp--preset--color--base) 10%, transparent);
  border-radius: var(--cdd-radius);
  padding: 26px 24px;
  height: 100%;
}
.cdd-step h3 { font-size: 21px; color: var(--wp--preset--color--base); }
.cdd-step p { font-size: 15px; }
/* ⚠ #631 — THE SAME MEASUREMENT CAUGHT OUR OWN COUNTER, WHICH NOBODY HAD REPORTED.
   `.cdd-step-num` was `secondary` on `accent`: #082F45 on #C25F1C = **3.29:1**, and the ink
   the browser actually computed measured 2.64. Even white on the raw accent is only 4.24 —
   **there is no ink that passes on that background**, so the BACKGROUND is what had to move.
   `--cdd-accent-deep` with white measures 5.87 and is the same token the wrapping counter now
   uses, so the two counters agree instead of each being darkened by hand.

   It also takes the no-break rules: it holds "1" today and would split on "10". */
.cdd-step-num {
  display: inline-block;
  min-width: 38px;
  height: 38px;
  line-height: 38px;
  padding: 0 6px;
  box-sizing: border-box;
  text-align: center;
  border-radius: 100px;
  white-space: nowrap;
  word-break: keep-all;
  overflow-wrap: normal;
  font-variant-numeric: tabular-nums;
  background: var(--cdd-accent-deep);
  color: var(--wp--preset--color--base);
  font-family: var(--wp--preset--font-family--heading);
  font-weight: 800;
  font-size: 18px;
  margin: 0 0 6px;
}

/* ------ home how-it-works: light-band variant of the steps ------ */
.cdd-how .cdd-step {
  background: var(--wp--preset--color--surface);
  border-color: var(--cdd-line);
}
.cdd-how .cdd-step h3 { color: var(--wp--preset--color--primary); }
.cdd-how .cdd-step p { color: var(--wp--preset--color--muted); }

/* ------ home service-card "more" links + about values band ------ */
.cdd-card-more { margin-top: 10px; }
.cdd-card-more a {
  color: var(--wp--preset--color--accent);
  font-weight: 700;
  font-size: 14px;
  text-decoration: none;
}
.cdd-card-more a:hover { text-decoration: underline; }
.cdd-card-hot .cdd-card-more a { color: var(--wp--preset--color--accent); }
.cdd-values { background: var(--wp--preset--color--surface); }
.cdd-values .cdd-guarantee { max-width: 760px; }

/* ------ mini FAQ ------ */
.cdd-faq-item {
  border-top: 1px solid var(--cdd-line);
  padding: 22px 0;
  max-width: 760px;
}
.cdd-faq-item h3 {
  font-size: 20px;
  font-weight: 700;
  color: var(--wp--preset--color--primary);
  margin: 0 0 8px;
}
.cdd-faq-item p { font-size: 16px; color: var(--wp--preset--color--muted); margin: 0; }

/* ------ interior CTA band ------ */
.cdd-cta-band {
  background:
    radial-gradient(800px 380px at 20% -30%, var(--cdd-primary-mid), var(--wp--preset--color--secondary) 65%);
  color: var(--wp--preset--color--base);
  padding: 72px 0;
  text-align: center;
}
.cdd-cta-band h2 {
  color: var(--wp--preset--color--base);
  font-size: clamp(32px, 4.4vw, 48px);
  font-weight: 800;
}
.cdd-cta-band p {
  color: color-mix(in srgb, var(--wp--preset--color--base) 72%, var(--wp--preset--color--muted));
  font-size: 18px;
  max-width: 56ch;
  margin: 12px auto 22px;
}
.cdd-cta-band .wp-block-buttons { justify-content: center; }

/* ------ header / footer chrome (all spacing HERE, none in part attrs) ------ */
.cdd-site-header {
  /* SOLID (6 Jul render fix #3): the translucent gamble made nav contrast
     depend on whatever the header floated over (invisible on light 404s). */
  background: var(--wp--preset--color--secondary);
  /* no border-bottom (6 Jul): the 1px light line read as a hairline SEAM
     between the header and the hero photo — the bands meet clean instead. */
  backdrop-filter: blur(10px);
  position: sticky;
  top: 0;
  z-index: 50;
}
.cdd-header-bar { padding-top: 14px; padding-bottom: 14px; gap: 18px; }
.cdd-header-brand { gap: 12px; }
.cdd-site-header .wp-block-site-logo img { max-height: 44px; width: auto; }
.cdd-site-header .wp-block-site-title a {
  color: var(--wp--preset--color--base);
  font-family: var(--wp--preset--font-family--heading);
  font-weight: 800;
  font-size: 22px;
  text-decoration: none;
}
/* 6 Jul: NO uploaded logo → a DELIBERATE brand mark, never a blank space.
   WP stamps body.wp-custom-logo only when a real logo exists; without it
   the site-title becomes a palette-coloured badge in the heading font —
   holds the logo's space, looks intentional. The go-live logo gate and
   the Production work item still stand; this is staging dignity only. */
body:not(.wp-custom-logo) .cdd-site-header .wp-block-site-title a {
  display: inline-block;
  background: var(--wp--preset--color--accent);
  color: var(--wp--preset--color--secondary);
  padding: 8px 14px;
  border-radius: 10px;
  font-size: 18px;
  line-height: 1.15;
  letter-spacing: .03em;
  text-transform: uppercase;
}
body:not(.wp-custom-logo) .cdd-site-header .wp-block-site-title a:hover {
  filter: brightness(1.08);
}
/* 7 Jul: a REAL logo replaces the wordmark entirely — never both. The
   header part always renders both blocks; when body.wp-custom-logo is
   stamped the site-title must vanish (the double-identity bug on
   cd260032: approved logo image + leftover wordmark text side by side).
   The text wordmark is ONLY the no-logo fallback above. */
body.wp-custom-logo .cdd-site-header .wp-block-site-title {
  display: none;
}
.cdd-site-header .wp-block-navigation a {
  position: relative;
  color: color-mix(in srgb, var(--wp--preset--color--base) 82%, var(--wp--preset--color--muted));
  font-weight: 500;
  font-size: 15px;
  text-decoration: none;
  transition: color .15s ease;
}
/* 6 Jul nav states: accent slide-underline on hover; the CURRENT page sits
   bold + underlined — real interaction states, demo-grade, palette-aware. */
.cdd-site-header .wp-block-navigation a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -6px;
  height: 2px;
  background: var(--wp--preset--color--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .18s ease;
}
.cdd-site-header .wp-block-navigation a:hover { color: var(--wp--preset--color--accent); }
.cdd-site-header .wp-block-navigation a:hover::after { transform: scaleX(1); }
.cdd-site-header .wp-block-navigation a[aria-current="page"],
.cdd-site-header .wp-block-navigation .current-menu-item > a {
  color: var(--wp--preset--color--base);
  font-weight: 700;
}
.cdd-site-header .wp-block-navigation a[aria-current="page"]::after,
.cdd-site-header .wp-block-navigation .current-menu-item > a::after { transform: scaleX(1); }

/* 6 Jul: the Services DROPDOWN — a solid brand panel so nested service
   links read cleanly over anything; the slide-underline stays a top-level
   affordance only (it looks broken inside a stacked list). */
.cdd-site-header .wp-block-navigation .wp-block-navigation__submenu-container {
  background: var(--wp--preset--color--secondary);
  border: 1px solid color-mix(in srgb, var(--wp--preset--color--base) 12%, transparent);
  border-radius: 12px;
  padding: 8px;
  min-width: 250px;
  box-shadow: 0 18px 40px -18px rgba(0, 0, 0, .55);
}
.cdd-site-header .wp-block-navigation .wp-block-navigation__submenu-container a {
  padding: 9px 12px;
  border-radius: 8px;
}
.cdd-site-header .wp-block-navigation .wp-block-navigation__submenu-container a::after { display: none; }
.cdd-site-header .wp-block-navigation .wp-block-navigation__submenu-container a:hover {
  background: color-mix(in srgb, var(--wp--preset--color--accent) 18%, transparent);
  color: var(--wp--preset--color--base);
}

/* Buttons everywhere get a consistent hover (palette-safe: brightness, no
   hardcoded colour) — Call now / Get in touch / pattern CTAs alike. */
.wp-block-button__link {
  transition: filter .15s ease, transform .12s ease;
}
.wp-block-button__link:hover {
  filter: brightness(1.12);
  transform: translateY(-1px);
}
.cdd-header-call .wp-block-button__link {
  padding: 10px 20px;
  font-size: 15px;
  white-space: nowrap;
}

.cdd-site-footer {
  background: var(--wp--preset--color--secondary);
  color: color-mix(in srgb, var(--wp--preset--color--base) 56%, var(--wp--preset--color--muted));
  font-size: 15px;
}
.cdd-footer-bar { padding-top: 52px; padding-bottom: 40px; gap: 24px; }
.cdd-site-footer a { color: inherit; }
.cdd-site-footer a:hover { color: var(--wp--preset--color--accent); }
.cdd-site-footer .wp-block-site-title a {
  color: var(--wp--preset--color--base);
  font-family: var(--wp--preset--font-family--heading);
  font-weight: 800;
  text-decoration: none;
}
.cdd-site-footer .wp-block-site-tagline {
  margin-top: 6px;
  color: color-mix(in srgb, var(--wp--preset--color--base) 56%, var(--wp--preset--color--muted));
}
.cdd-footer-credit { margin: 0; align-self: flex-end; }

/* ------ TRADES LONG (screenshot pipeline #1, 7 Jul) ------
   The plumber-PDF rhythm: problems + systems share ONE primary band (the
   dark super-section), about+areas is a light two-column, benefits is an
   image-left bullet band, and the quote CTA is the split image/pitch
   panel the optional parallax treatment moves. */
.cdd-problems,
.cdd-systems { background: var(--wp--preset--color--primary); }
.cdd-problems { padding-bottom: 44px; }
.cdd-systems { padding-top: 0; }
.cdd-system-card h3 { font-size: 18px; }
.cdd-system-card p { font-size: 14px; }

.cdd-areas-card {
  background: var(--wp--preset--color--surface);
  border: 1px solid var(--cdd-line);
  border-radius: 18px;
  padding: 30px;
  box-shadow: 0 24px 50px -30px color-mix(in srgb, var(--wp--preset--color--primary) 40%, transparent);
}
.cdd-areas-card h3 {
  font-size: 24px;
  font-weight: 800;
  color: var(--wp--preset--color--primary);
  margin: 0 0 6px;
}
.cdd-areas-card > p { font-size: 15px; color: var(--wp--preset--color--muted); }
.cdd-areas-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 18px;
}
.cdd-areas-chips .cdd-area {
  margin: 0;
  padding: 10px 14px;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--wp--preset--color--primary);
  background: color-mix(in srgb, var(--wp--preset--color--primary) 6%, var(--wp--preset--color--base));
  border: 1px solid var(--cdd-line);
  border-radius: 10px;
}
.cdd-areas-chips .cdd-area::before { content: "📍 "; }
.cdd-areas-card .cdd-areas-note {
  margin-top: 20px;
  font-size: 15px;
  color: var(--wp--preset--color--muted);
}
.cdd-areas-card .cdd-areas-note strong { color: var(--wp--preset--color--primary); }

.cdd-benefits-photo img { border-radius: 20px; }
.cdd-benefits-list {
  list-style: none;
  padding-left: 0;
  display: grid;
  gap: 14px;
  font-size: 16px;
  color: color-mix(in srgb, var(--wp--preset--color--contrast) 80%, var(--wp--preset--color--muted));
}
.cdd-benefits-list li::before {
  content: "✓ ";
  color: var(--wp--preset--color--accent);
  font-weight: 800;
}
.cdd-benefits-list li strong { color: var(--wp--preset--color--primary); }

.cdd-quote-cta {
  background:
    radial-gradient(900px 460px at 15% -20%, var(--cdd-primary-mid), var(--wp--preset--color--secondary) 62%);
  color: var(--wp--preset--color--base);
  padding: 88px 0;
  overflow: hidden;
}
.cdd-qcta-media {
  border-radius: 20px;
  overflow: hidden;
  box-shadow: 0 30px 60px -24px rgba(0, 0, 0, .55);
}
.cdd-qcta-media img { display: block; width: 100%; border-radius: 0; }
.cdd-qcta-panel h2 {
  color: var(--wp--preset--color--base);
  font-size: clamp(34px, 4.6vw, 52px);
  font-weight: 800;
}
.cdd-qcta-panel p {
  color: color-mix(in srgb, var(--wp--preset--color--base) 72%, var(--wp--preset--color--muted));
  font-size: 18px;
  max-width: 48ch;
  margin: 12px 0 22px;
}

/* ------ STANDARD DELIGHT (7 Jul): sticky call + rating badge ------
   Rendered by functions.php's wp_footer hook from the cdd_phone_* /
   cdd_rating_* options the inject step stamps — no option, no element.
   The call button carries a gentle pulse (killed under reduced motion);
   body.cdd-has-sticky pads the footer so the bar never hides content. */
.cdd-sticky-call {
  position: fixed;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  z-index: 60;
  background: var(--wp--preset--color--accent);
  color: var(--wp--preset--color--base);
  font-family: var(--wp--preset--font-family--heading);
  font-weight: 700;
  font-size: 16px;
  text-decoration: none;
  padding: 13px 30px;
  border-radius: 100px;
  white-space: nowrap;
  box-shadow: 0 12px 28px -10px rgba(0, 0, 0, .45);
  animation: cdd-call-pulse 2.6s var(--cdd-ease) infinite;
}
.cdd-sticky-call:hover { filter: brightness(1.1); color: var(--wp--preset--color--base); }
@keyframes cdd-call-pulse {
  0%   { box-shadow: 0 12px 28px -10px rgba(0, 0, 0, .45), 0 0 0 0 color-mix(in srgb, var(--wp--preset--color--accent) 45%, transparent); }
  70%  { box-shadow: 0 12px 28px -10px rgba(0, 0, 0, .45), 0 0 0 14px transparent; }
  100% { box-shadow: 0 12px 28px -10px rgba(0, 0, 0, .45), 0 0 0 0 transparent; }
}
.cdd-sticky-rating {
  position: fixed;
  left: 18px;
  bottom: 18px;
  z-index: 60;
  display: grid;
  gap: 1px;
  background: var(--wp--preset--color--base);
  border: 1px solid var(--cdd-line);
  border-radius: 12px;
  padding: 10px 14px;
  box-shadow: 0 12px 28px -12px rgba(0, 0, 0, .35);
  font-size: 12px;
  color: var(--wp--preset--color--muted);
  line-height: 1.35;
}
.cdd-sticky-rating strong {
  color: var(--wp--preset--color--primary);
  font-family: var(--wp--preset--font-family--heading);
  font-size: 17px;
}
.cdd-sticky-rating .cdd-sticky-stars {
  color: var(--wp--preset--color--accent);
  letter-spacing: 2px;
  font-size: 13px;
}
body.cdd-has-sticky .cdd-site-footer { padding-bottom: 76px; }
@media (max-width: 640px) {
  .cdd-sticky-call {
    left: 12px;
    right: 12px;
    bottom: 12px;
    transform: none;
    text-align: center;
  }
  .cdd-sticky-rating { bottom: 72px; left: 12px; padding: 8px 12px; }
  body.cdd-has-sticky .cdd-site-footer { padding-bottom: 96px; }
}
@media (prefers-reduced-motion: reduce) {
  .cdd-sticky-call { animation: none; }
}

/* ------ OPTIONAL MOTION (upsell family, 7 Jul): quote-CTA parallax ------
   OFF by default: only body.cdd-motion-parallax (the cdd_motion_parallax
   option) arms it, functions.php's tiny scroll script drives --cdd-plx,
   and reduced-motion kills the transform entirely. The scale gives the
   shift headroom so edges never expose. */
.cdd-motion-parallax .cdd-qcta-media img:not(.cdd-parallax-figure),
.cdd-motion-parallax .cdd-parallax-media > img:not(.cdd-parallax-figure),
.cdd-motion-parallax .cdd-parallax-media .wp-block-image img:not(.cdd-parallax-figure) {
  transform: translate3d(0, var(--cdd-plx, 0px), 0) scale(1.14);
  will-change: transform;
}
/* Layered parallax (7 Jul feature layer): an optional transparent
   foreground figure drifts the OPPOSITE way to its background layer
   (--cdd-plxf, driven by the same scroll script). Perfectly still —
   base transform only — when the motion flag is off. */
.cdd-qcta-media,
.cdd-parallax-media { position: relative; }
.cdd-parallax-figure {
  /* PANEL-LAYERING FIX (7 Jul batch 9): the figure lives INSIDE the
     panel — anchored to its bottom edge (physically grounded by the
     crop) instead of overhanging two edges like a sticker, smaller,
     with a tighter contact shadow. Its drift is now the SAME direction
     as the background at half speed (multiplane depth), not a 2×
     counter-motion. */
  position: absolute;
  right: 5%;
  bottom: 0;
  width: 34%;
  max-width: 300px;
  pointer-events: none;
  filter: drop-shadow(0 10px 16px rgba(0, 0, 0, .45));
}
.cdd-motion-parallax .cdd-parallax-figure,
.cdd-motion-parallax .cdd-parallax-media img.cdd-parallax-figure,
.cdd-motion-parallax .cdd-qcta-media img.cdd-parallax-figure {
  transform: translate3d(0, var(--cdd-plxf, 0px), 0);
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
  .cdd-motion-parallax .cdd-qcta-media img,
  .cdd-motion-parallax .cdd-parallax-media > img,
  .cdd-motion-parallax .cdd-parallax-media .wp-block-image img,
  .cdd-motion-parallax .cdd-parallax-figure { transform: none; will-change: auto; }
}

/* ------ SMART STICKY HEADER (feature layer, 7 Jul batch 7) ------
   body.cdd-smart-header + html.cdd-js (the head script's no-JS gate):
   the header floats transparent over the dark hero, then solidifies
   (.cdd-header-solid, toggled by the scroll script) with a soft shadow.
   Without JS — or without the flag — the original solid sticky header
   stands untouched. The opening dark band gets taller top padding so
   its content clears the now out-of-flow header. */
.cdd-js body.cdd-smart-header .cdd-site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  background: transparent;
  backdrop-filter: none;
  transition: background .35s ease, box-shadow .35s ease;
}
.cdd-js body.cdd-smart-header .cdd-site-header.cdd-header-solid {
  background: var(--wp--preset--color--secondary);
  box-shadow: 0 12px 30px -18px rgba(0, 0, 0, .55);
}
.cdd-js body.cdd-smart-header .cdd-hero { padding-top: 164px; }
.cdd-js body.cdd-smart-header .cdd-page-header { padding-top: 140px; }

/* ------ SCROLL REVEAL (feature layer, 7 Jul batch 7) ------
   The reveal class is assigned by JS at runtime (stored markup never
   carries it), so nothing can be hidden for a no-JS visitor; the CSS
   additionally requires html.cdd-js. Reduced motion = instant show. */
.cdd-js body.cdd-scroll-reveal .cdd-reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .6s var(--cdd-ease), transform .6s var(--cdd-ease);
}
.cdd-js body.cdd-scroll-reveal .cdd-reveal.cdd-in {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .cdd-js body.cdd-scroll-reveal .cdd-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ------ VIDEO HERO (feature layer — the 'video-bg-hero' upsell) ------
   The baked <video> sits behind .cdd-inner under the same dark overlay
   the photo treatment uses; the static HERO_BG_STYLE photo remains the
   layer beneath, so mobile (<700px), reduced-motion and no-JS visitors
   simply see the still hero. */
.cdd-hero { position: relative; }
.cdd-hero .cdd-inner { position: relative; z-index: 1; }
.cdd-hero-video {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: 0;
  /* TOP-GAP FIX (7 Jul batch 9): WP's flow gap gives this div a 20px
     margin-block-start (it follows the bg <style> tag in the same html
     block), which pushed the video + overlay down and exposed a bare
     strip of hero gradient at the very top of the page on load. An
     inset:0 overlay must never carry flow margins. */
  margin: 0 !important;
}
.cdd-hero-video video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.cdd-hero-video::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    color-mix(in srgb, var(--wp--preset--color--secondary) 78%, transparent),
    color-mix(in srgb, var(--wp--preset--color--secondary) 90%, transparent));
}
@media (max-width: 699px), (prefers-reduced-motion: reduce) {
  .cdd-hero-video { display: none; }
}

/* ------ SVG shape dividers (7 Jul, seam model v2 — overlay cut) ------
   A divider is a ZERO-HEIGHT overlay: the group adds nothing to flow (the
   two sections butt directly) and the band absolutely overlaps the section
   it cuts INTO — rise (default) = up over the section above; --dip =
   flipped, down over the section below (used when the LOWER band is the
   gradient one). The band paints NO background of its own: the overlapped
   section's REAL background (radial gradient, photo, anything) runs
   beneath the curve, and the path's solid edge overpaints the section
   junction itself — so neither a white hairline nor a flat-vs-gradient
   colour step can exist at any seam. Markup lives in pattern-library/
   shapes/ (assemble-time only); only these classes ship with the theme. */
:root {
  --cd-primary: var(--wp--preset--color--primary);
  --cd-secondary: var(--wp--preset--color--secondary);
  --cd-accent: var(--wp--preset--color--accent);
  --cd-base: var(--wp--preset--color--base);
  --cd-contrast: var(--wp--preset--color--contrast);
  --cd-muted: var(--wp--preset--color--muted);
  --cd-surface: var(--wp--preset--color--surface);
  /* The WASH (batch 8): the soft primary tint curvy mode paints across
     same-colour section boundaries — the planner's PHP twin
     (cdd_shape_mix_hex, 10% primary into base) WCAG-checks this exact
     value before ever placing a wash seam. */
  --cd-wash: color-mix(in srgb, var(--wp--preset--color--primary) 10%, var(--wp--preset--color--base));
  --cd-wash-deep: color-mix(in srgb, var(--wp--preset--color--primary) 25%, var(--wp--preset--color--base));
}
.cdd-shape { position: relative; height: 0; line-height: 0; font-size: 0; }
.cdd-shape .cdd-shape-band {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: var(--cd-shape-h, clamp(40px, 7vw, 96px));
  pointer-events: none;
  z-index: 1;
}
.cdd-shape .cdd-shape-band--dip { bottom: auto; top: 0; transform: scaleY(-1); }
/* Flip horizontal (batch 8, Divi parity): mirrors asymmetric seams so a
   repeated shape doesn't visibly repeat; combines with --dip. */
.cdd-shape .cdd-shape-band--flipx { transform: scaleX(-1); }
.cdd-shape .cdd-shape-band--dip.cdd-shape-band--flipx { transform: scale(-1, -1); }
.cdd-shape .cdd-shape-band svg { display: block; width: 100%; height: 100%; }
.cdd-shape .cdd-shape-band path { fill: var(--cd-shape-fill, currentColor); }

/* #364 — the visible image-credit line is GONE. #343 rendered it because
   docs/image-engine-spec.md claimed Pexels' terms required attribution; the
   licence says the opposite ("Attribution is not required"). The credit is now
   an HTML comment in wp_head and the ImageSelection row. No rule here, because
   nothing renders. */

/* #573 — THE SOCIAL ROW FINALLY HAS SOMEWHERE TO RENDER.
   `cdd_site_tokens()` has built {{SOCIAL_LINKS}} and HAS_SOCIAL since #434 and a
   repo-wide grep on 31 Jul found them read by NOTHING but their own test — so a
   client's Facebook and Instagram answers, collected since the beginning, have
   never appeared on their site. Two library patterns now render them, and this is
   the styling those anchors need. `cdd_social_links_html()` emits one <a
   class="cdd-social cdd-social--{platform}"> per link carrying an inline SVG at
   currentColor, so the row inherits whatever band it sits in and needs no per-
   platform colour. No hover-only affordance: the target is 44px, which is the
   mobile tap size, and the accessible name is on the anchor already. */
.cdd-social-row { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1.5rem; }
.cdd-social {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 50%;
  color: inherit; text-decoration: none;
  border: 1px solid currentColor; opacity: .8;
  transition: opacity .15s ease, transform .15s ease;
}
.cdd-social:hover, .cdd-social:focus-visible { opacity: 1; transform: translateY(-1px); }
.cdd-social svg { display: block; }
