/* ==========================================================================
   Make My Theme — main.css
   Design tokens (Claude Design handoff), reset, typography, layout,
   page-level styles. There is no legacy-alias layer: the old-vocabulary
   --z-* aliases were deleted in the 2026-08-10 token migration and must not
   be reintroduced.
   Component styles (.btn, .card, .badge, .input, .swatch, .chip, etc.)
   live ONLY in design-base.css (enqueued after this file) — this file no
   longer defines any component layer of its own (CSS consolidation 2026-07-15).
   ========================================================================== */

/* ── 1. Design Tokens ───────────────────────────────────────────────────────
   Based on the Claude Design handoff token set, retinted onto the 2026-08
   brand package's primary palette (Branding/Brand Guidelines). Single source
   of truth for colour, type, spacing, radii, shadows, motion and layout
   constants. */

:root {
    /* ---------- Colour: brand primaries (2026-08 brand package) ----------
       The four primary colours — Coal text on White / Pebble / Stone
       surfaces. The secondary/product colours live in the accents block
       below (B2). */
    --brand-white:  #ffffff;
    --brand-pebble: #ebebe9;
    --brand-stone:  #c5cac7;
    --brand-coal:   #231f1f;

    /* ---------- Colour: neutrals (brand surfaces + Coal-derived inks) ----
       Ink/rule steps keep the old handoff lightness scale (soft ≈33 /
       muted ≈53 / faint ≈73 / rule ≈90 oklch) but carry Coal's warm hue.
       email-helpers.php mirrors these as literal hex — keep in lockstep. */
    --paper:        var(--brand-white);
    --paper-soft:   var(--brand-pebble);
    --paper-sunk:   var(--brand-stone);

    /* Single source of truth for every product-preview surface — the 2D
       technical drawing, the 3D scene, and the room-planner previews all read
       this one token (configurator CSS, room CSS and the CorePreview3D scene
       derive from it). White to match the page; retint here to change every
       product's preview background at once. */
    --core-preview-bg: var(--paper);
    --ink:          var(--brand-coal);
    --ink-soft:     color-mix(in oklch, var(--brand-coal) 88%, var(--brand-white));
    --ink-muted:    color-mix(in oklch, var(--brand-coal) 62%, var(--brand-white));
    --ink-faint:    color-mix(in oklch, var(--brand-coal) 36%, var(--brand-white));
    --rule:         color-mix(in oklch, var(--brand-stone) 60%, var(--brand-white));
    --rule-strong:  var(--brand-stone);
    /* The border of anything a customer OPERATES — inputs, chips, secondary
       buttons, steppers, swatch tiles (Design.md §3.4). Rule Strong measures
       1.66:1 on white and fails WCAG 2.2 §1.4.11's 3:1 for interactive
       boundaries; this step clears it while staying in the warm-grey family.
       Rule / Rule Strong stay structural-only. */
    --rule-interactive: #8e9691;
    /* The ink scale on a DARK band (Coal — §16d).
       The same recipes as the scale above, run from the other end: Paper at
       the top, stepping towards Coal. §16d swaps these in for --ink and
       friends inside a .band--dark, so a block's own var(--ink) text turns
       light without the block knowing. Measured against Coal in
       design-contrast.test.js. */
    --ink-on-dark:         var(--brand-white);
    --ink-soft-on-dark:    color-mix(in oklch, var(--brand-white) 88%, var(--brand-coal));
    --ink-muted-on-dark:   color-mix(in oklch, var(--brand-white) 72%, var(--brand-coal));
    --ink-faint-on-dark:   color-mix(in oklch, var(--brand-white) 40%, var(--brand-coal));
    --rule-on-dark:        color-mix(in oklch, var(--brand-white) 18%, var(--brand-coal));
    --rule-strong-on-dark: color-mix(in oklch, var(--brand-white) 32%, var(--brand-coal));

    /* ---------- Colour: accents (2026-08 brand secondary palette) --------
       One token per brand colour, named after the designer's swatch name
       (hex verbatim from Branding/Brand Guidelines — the PDF's "Lavendar"
       is spelled lavender here). Module assignment is the comment; Lime
       is defined but unassigned, reserved for a future module. */
    --accent-squash:     #C2664F;               /* Make My Desk */
    --accent-moss:       #5C8144;               /* Make My Door */
    --accent-corn:       #F3A602;               /* Make My Cabinet */
    --accent-sky:        #677692;               /* Make My Panelling */
    --accent-grape:      #44283C;               /* Make My Face Frame */
    --accent-lavender:   #7C5B81;               /* Make My Table */
    --accent-wren:       #6E5C4C;               /* Make My Sheet */
    --accent-forest:     #3E5547;               /* Make My Trim */
    --accent-deep:       #243671;               /* Make My Wardrobe */
    --accent-lime:       #CFB539;               /* unassigned */

    /* There is deliberately no darkened "-strong" companion to any accent.
       The ten hexes above are the designer's delivered palette and are the
       ONLY accent values the network paints (ruled 2026-08-10) — a derived
       variant is a colour the brand does not own. Accent therefore carries
       accent-coloured text and accent fills at every size, and the
       sub-4.5:1 sites are a documented waiver, not an oversight
       (Design.md §3.5). Never reintroduce an --accent-*-strong token. */

    /* The hub has NO accent of its own (Design.md §2.2) — it runs on the
       primary palette, so its accent slot resolves to Ink. Sub-sites
       override it via [data-site] below. */
    --accent:        var(--ink);
    --accent-fg:   var(--paper);
    --accent-tint: color-mix(in oklch, var(--accent) 12%, transparent);
    --accent-wash: color-mix(in oklch, var(--accent)  6%, var(--paper));

    /* ---------- Signal colours ------------------------------------------- */
    --ok:   oklch(55% 0.10 150);
    --warn: oklch(68% 0.13 75);
    --err:  oklch(55% 0.17 25);

    /* ---------- Type scale ----------------------------------------------- */
    --font-sans: "Lexend Deca", ui-sans-serif, system-ui, sans-serif;

    --fs-11: 0.6875rem;
    --fs-12: 0.75rem;
    --fs-13: 0.8125rem;
    --fs-14: 0.875rem;
    --fs-16: 1rem;
    --fs-18: 1.125rem;
    --fs-22: 1.375rem;
    --fs-28: 1.75rem;
    --fs-36: 2.25rem;
    --fs-48: 3rem;
    --fs-64: 4rem;
    --fs-96: 6rem;

    --lh-tight: 1.05;
    --lh-snug:  1.2;
    --lh-body:  1.55;

    --tracking-display: -0.03em;
    --tracking-tight:   -0.03em;
    --tracking-normal:  -0.03em; /* designer spec: Illustrator tracking −30 = −30/1000 em */
    --tracking-label:    0.08em;

    /* The brand ships two weights only (Lexend Deca Regular 400 + Semibold
       600 — see fonts.css), so these two tokens are the whole weight
       vocabulary; body { font-synthesis-weight: none } keeps literal 500/700s
       in older stylesheets collapsing onto them instead of faux-bolding. */
    --fw-regular:  400;
    --fw-semibold: 600;

    /* ---------- Spacing (4px base) --------------------------------------- */
    --sp-1:  4px;
    --sp-2:  8px;
    --sp-3:  12px;
    --sp-4:  16px;
    --sp-5:  20px;
    --sp-6:  24px;
    --sp-8:  32px;
    --sp-10: 40px;
    --sp-12: 48px;
    --sp-16: 64px;
    --sp-20: 80px;
    --sp-24: 96px;

    /* ---------- Band spacing (Design.md §8.3) ---------------------------- */
    /* Two vertical paddings, and no third: every page band takes one and never
       sets its own. Band is 48 → 96px (8vw reaches 96 at 1200px wide); Strip is
       32 → 64px for the slim rows that support the band above them (6vw
       reaches 64 at 1067px). */
    --band-pad:  clamp(var(--sp-12), 8vw, var(--sp-24));
    --strip-pad: clamp(var(--sp-8), 6vw, var(--sp-16));

    /* ---------- Control heights (Design.md §5.4) ------------------------- */
    --h-badge:   22px;
    --h-btn-sm:  32px;
    --h-chip:    36px;
    --h-control: 44px;  /* the default — and the floor for anything a finger touches */
    --h-btn-lg:  52px;
    /* (--summary-bar-h, the 84px rung, lives under Layout below.) */

    /* ---------- Radii ---------------------------------------------------- */
    --r-0:    0px;
    --r-xs:   2px;
    --r-sm:   4px;
    --r-md:   6px;
    --r-lg:   10px;
    --r-pill: 999px;

    /* ---------- Elevation ------------------------------------------------ */
    --shadow-1: 0 1px 0 rgb(0 0 0 / 0.04);
    --shadow-2: 0 1px 2px rgb(0 0 0 / 0.04), 0 2px 8px rgb(0 0 0 / 0.04);
    --shadow-3: 0 2px 4px rgb(0 0 0 / 0.06), 0 12px 32px rgb(0 0 0 / 0.08);

    /* The one scrim tone behind a modal, dialog or drawer (§7.10) — Ink at
       40%. Surfaces that also blur what's behind add `backdrop-filter`
       themselves; the tone is the shared part. */
    --scrim: color-mix(in oklch, var(--ink) 40%, transparent);

    /* ---------- Focus ----------------------------------------------------- */
    --focus-ring: 0 0 0 3px var(--accent-tint);

    /* ---------- Motion --------------------------------------------------- */
    --ease:      cubic-bezier(0.2, 0.7, 0.2, 1);
    --dur-fast:  140ms;
    --dur-base:  220ms;
    --dur-slow:  420ms;

    /* ---------- Layout --------------------------------------------------- */
    /* Three sanctioned narrow measures, widest to tightest (Design.md §5.3).
       Every text max-width in the theme (and in the block SCSS, via
       `var(--token, px)`) picks one of these — don't introduce a fourth.
         narrow — long-form article body / the .container--narrow utility
         copy   — intro & hero/CTA copy, form column, post excerpts
         blurb  — one-or-two-line supporting text under a heading, captions
       Each is a share of the page container with a cap; below 768px every
       measure is the full container (the override follows this block). The
       percentage resolves at the CONSUMER — a custom property substitutes as
       text — so it means "of the page container" only on an element whose
       parent spans the container. An element nested in anything narrower (a
       grid column, a capped wrapper, a dialog) reads the `-cap` token
       instead, or the share compounds against its parent. The Narrow cap is
       the value theme.json mirrors. */
    --container-max:     clamp(1440px, 92vw, 2000px);
    --container-narrow-cap: 680px;
    --container-copy-cap:   620px;
    --container-blurb-cap:  560px;
    --container-narrow:  min(70%, var(--container-narrow-cap));
    --container-copy:    min(60%, var(--container-copy-cap));
    --container-blurb:   min(50%, var(--container-blurb-cap));
    --container-pad:     clamp(20px, 4vw, 40px);
    --summary-bar-h:     84px;
}

/* Phones: every measure is the full container (Design.md §5.3). */
@media (max-width: 767px) {
    :root {
        --container-narrow: 100%;
        --container-copy:   100%;
        --container-blurb:  100%;
    }
}

/* Per-site accent override — stamped onto <html> via header.php. */
[data-site="main"]      { --accent: var(--ink); }  /* accentless hub — Design.md §2.2 */
[data-site="desk"]      { --accent: var(--accent-squash); }
[data-site="door"]      { --accent: var(--accent-moss); }
/* Corn is the one accent light enough that Paper text on it is unreadable
   (2.05:1). Coal on Corn measures 7.98:1, so Cabinet flips --accent-fg rather
   than darkening the accent — brand hexes stay immutable. */
[data-site="cabinet"]   { --accent: var(--accent-corn);     --accent-fg: var(--ink); }
[data-site="panelling"] { --accent: var(--accent-sky); }
[data-site="wardrobe"]  { --accent: var(--accent-deep); }
[data-site="table"]     { --accent: var(--accent-lavender); }
[data-site="sheet"]     { --accent: var(--accent-wren); }
[data-site="trim"]      { --accent: var(--accent-forest); }


/* ── 1b. Z-index scale ─────────────────────────────────────────────────────
   Canonical definitions (never aliases) — plugin CSS reads these too. The
   legacy token-alias block that used to live here died with Phase 2
   (2026-08-10): every theme sheet and every block source is on the new
   token names. Don't reintroduce old-vocabulary aliases. */

:root {
    --z-base:    0;
    --z-raised:  10;
    --z-sticky:  100;
    --z-header:  200;
    --z-overlay: 300;
    --z-drawer:  400;
    --z-modal:   500;
}


/* ── 2. Reset ───────────────────────────────────────────────────────────────── */

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

html {
    font-size: 16px;
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

body {
    font-family: var(--font-sans);
    font-size: var(--fs-16);
    font-weight: var(--fw-regular);
    letter-spacing: var(--tracking-normal);
    line-height: var(--lh-body);
    color: var(--ink);
    background-color: var(--paper);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    font-synthesis: none; /* two-weight, no-italic brand set (Design.md §4.1–4.2) — no faux bold, no synthetic oblique */
}

img,
picture,
video,
canvas,
svg {
    display: block;
    max-width: 100%;
}

/* Bare form-element rules sit at zero specificity (`:where()`) throughout
   this sheet, so any single component class — `.input`, `.core-input`,
   `.core-select` — outranks them. At (0,0,1)+ they beat single-class
   selectors and re-impose theme padding/type inside components (the live
   unit-popover clipping, 2026-08-10). */
:where(input, button, textarea, select) {
    font: inherit;
}

p,
h1, h2, h3, h4, h5, h6 {
    overflow-wrap: break-word;
}

ul, ol {
    list-style: none;
}

a {
    color: inherit;
    text-decoration: none;
}

/* ::selection lives in design-base.css (ink-on-paper). */

/* Scrollbar — subtle accent track thumb */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--accent) transparent;
}

::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    background-color: var(--accent);
    border-radius: var(--r-pill);
}

button {
    cursor: pointer;
    background: none;
    border: none;
}

/* Remove animations for reduced-motion users */
@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;
    }
}


/* ── 3. Typography ──────────────────────────────────────────────────────────── */

/* Displays are Regular, not Semibold (Design.md §4.4) — large type at 400
   with tight tracking reads as considered. Semibold does structural work
   only at Title size and below (h4–h6), where small type must hold its own. */
h1, h2, h3 {
    font-weight: var(--fw-regular);
}
h4, h5, h6 {
    font-weight: var(--fw-semibold);
}
h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-sans);
    line-height: var(--lh-tight);
    letter-spacing: var(--tracking-tight);
    color: var(--ink);
}

h1 { font-size: clamp(2rem, 5vw, var(--fs-48)); }
h2 { font-size: clamp(1.5rem, 3vw, var(--fs-36)); letter-spacing: var(--tracking-tight); }
h3 { font-size: clamp(1.25rem, 2vw, var(--fs-28)); letter-spacing: var(--tracking-tight); }
h4 { font-size: var(--fs-22); letter-spacing: var(--tracking-normal); }
h5 { font-size: var(--fs-18); letter-spacing: var(--tracking-normal); }
h6 { font-size: var(--fs-16); letter-spacing: var(--tracking-normal); }

p { line-height: var(--lh-body); }
p + p { margin-top: var(--sp-4); }

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

.eyebrow {
    display: block;
    font-size: var(--fs-12);
    font-weight: var(--fw-semibold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: var(--sp-3);
}

strong { font-weight: var(--fw-semibold); }

/* Rich-text areas are `.entry-content` (§17 below) — there is deliberately no
   second name for the same concern. */


/* ── 4. Layout ──────────────────────────────────────────────────────────────── */

.container {
    width: 100%;
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--container-pad);
}

.container--narrow {
    max-width: var(--container-narrow);
}

/* Section spacing */
.section {
    padding-block: clamp(3rem, 8vw, 6rem);
}

.section--sm {
    padding-block: clamp(2rem, 5vw, 4rem);
}


/* ── 5. Buttons ─────────────────────────────────────────────────────────────── */
/* The .btn family lives in design-base.css (single button language). */


/* ── 6. Forms ───────────────────────────────────────────────────────────────── */

.form-field {
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
}

.form-label {
    font-size: var(--fs-14);
    font-weight: var(--fw-regular);
    color: var(--ink);
}

/* The bare-element half is `:where()`-wrapped (0,0,0): it styles unclassed
   WP/editor forms, while any component class (`.core-input` at (0,1,0), the
   design-base `.input`) outranks it. Unwrapped, `input[type="…"]` is (0,1,1)
   and beats those classes regardless of load order — which re-imposed this
   block's 12/16px padding + 16px type inside plugin controls network-wide
   (the planner unit-popover clipping, fixed per-surface in PR #808; fixed at
   the source here). Don't unwrap. */
.form-input,
.form-textarea,
.form-select,
:where(input[type="text"],
    input[type="email"],
    input[type="tel"],
    input[type="url"],
    input[type="password"],
    input[type="search"],
    input[type="number"],
    textarea,
    select) {
    width: 100%;
    /* §7.2 — a single-line field is 44px: the block padding is whatever the
       44px rung leaves after the border and one line box (it was 12px, which
       made an unclassed field ~50px). Padding rather than a min-height,
       because this rule is `:where()`-zeroed and a min-height here would
       override every component input that sets a smaller explicit height (a
       dense table row's 32px cell). The first line is the fallback for an
       engine without the `lh` unit. Textareas keep the roomier padding below. */
    padding: 0.5625rem 1rem;
    padding-block: calc((var(--h-control) - 2px - 1lh) / 2);
    font-family: var(--font-sans);
    font-size: var(--fs-16);
    color: var(--ink);
    background-color: var(--paper);
    border: 1px solid var(--rule-interactive);
    border-radius: var(--r-sm);
    appearance: none;
    transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
    line-height: var(--lh-body);
}

.form-textarea,
:where(textarea) {
    padding-block: 0.75rem;
}

.form-input:focus,
.form-textarea:focus,
.form-select:focus,
:where(input:focus, textarea:focus, select:focus) {
    outline: none;
    border-color: var(--ink);
    box-shadow: var(--focus-ring);
}

.form-textarea,
:where(textarea) {
    resize: vertical;
    min-height: 140px;
}

/* ── 7. Cards / 8. Badges ───────────────────────────────────────────────────── */
/* .card and .badge live in design-base.css. */

/* ── 9. Dividers ────────────────────────────────────────────────────────────── */

/* The bare element only. The theme's named divider is the brand-device
   `.mm-divider` in logo-motion.css, not a second hairline class here. */
hr {
    border: none;
    border-top: 1px solid var(--rule);
    margin-block: var(--sp-8);
}

/* ── 10. Scroll Reveal ──────────────────────────────────────────────────────── */

.reveal {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
}

.reveal.is-visible {
    opacity: 1;
    transform: none;
}

/* ── 11. Overlay ────────────────────────────────────────────────────────────── */

.overlay {
    position: fixed;
    inset: 0;
    background-color: var(--scrim);
    z-index: var(--z-overlay);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dur-base) var(--ease);
}

.overlay.is-active {
    opacity: 1;
    pointer-events: all;
}

/* ── 12. Accessibility ──────────────────────────────────────────────────────── */

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* :focus-visible lives in design-base.css (2px offset + radius). */

/* ── 12b. VAT display ──────────────────────────────────────────────────────
   Every price is rendered in both forms (Core_Vat_Display / window.CoreVat);
   <html data-vat> — set before paint by makemy_vat_head_bootstrap() — picks
   the lead figure. Inc (default): only the inc figure shows, exactly as
   before. Ex: the ex figure leads and the inc figure drops beneath it as a
   small "£x inc VAT". The customer is always charged the inc figure. */
.mm-price__ex { display: none; }
.mm-price__inc { display: inline; }

html[data-vat="ex"] .mm-price__ex { display: inline; }
html[data-vat="ex"] .mm-price__inc {
    display: block;
    font-family: var(--font-sans);
    letter-spacing: var(--tracking-normal);
    font-size: var(--fs-12);
    font-weight: var(--fw-regular);
    color: var(--ink-muted);
    text-decoration: none;
}
html[data-vat="ex"] .mm-price__inc::after { content: " inc VAT"; }

/* Tight contexts (unit rates, struck RRPs, ± deltas): secondary stays on the line. */
html[data-vat="ex"] .mm-price--inline .mm-price__inc { display: inline; margin-left: var(--sp-1); }
html[data-vat="ex"] .mm-price--inline .mm-price__inc::before { content: "("; }
html[data-vat="ex"] .mm-price--inline .mm-price__inc::after { content: " inc VAT)"; }
/* A struck RRP carries only its lead figure: the parent's line-through can't be
   lifted off a child, and a struck "(£x inc VAT)" reads as noise. */
html[data-vat="ex"] del .mm-price .mm-price__inc,
html[data-vat="ex"] [style*="line-through"] .mm-price .mm-price__inc { display: none; }

/* Mode-only content: labels and summary rows that belong to one mode. */
html:not([data-vat="ex"]) [data-vat-only="ex"],
html[data-vat="ex"] [data-vat-only="inc"] { display: none !important; }

/* ── 13. WordPress Core Overrides ───────────────────────────────────────────── */

.wp-block-image img {
    border-radius: 0;
}

/* `.alignwide` is editor-generated markup on saved post content, so the rule
   stays even though its max-width now matches the wrapping `.container`; the
   `margin-inline: auto` is the load-bearing half. */
.alignwide {
    max-width: var(--container-max);
    margin-inline: auto;
}

.alignfull {
    width: 100%;
    max-width: none;
}

/* ── 14. Breadcrumb ─────────────────────────────────────────────────────────── */

.breadcrumb {
    font-size: var(--fs-14);
    color: var(--ink-muted);
    margin-bottom: var(--sp-6);
}

.breadcrumb a:hover {
    color: var(--accent);
}

/* ── 15. Skip Link ──────────────────────────────────────────────────────────── */

.skip-link {
    position: absolute;
    top: -100%;
    left: var(--sp-4);
    z-index: var(--z-modal);
    padding: var(--sp-3) var(--sp-6);
    background-color: var(--accent);
    color: var(--accent-fg);
    font-weight: var(--fw-semibold);
    text-decoration: none;
    transition: top var(--dur-fast) var(--ease);
}

.skip-link:focus {
    top: var(--sp-4);
}

/* ── 16. Page-level wrappers ────────────────────────────────────────────────── */

.site-main {
    min-height: 60vh;
}

/* ── 16b. Home page bands ───────────────────────────────────────────────────
   front-page.php renders the_content() bare — no .container, no band wrapper —
   because most of what the home page composes IS a band and carries its own
   container: hero, product card grid, step process, split feature, CTA banner.

   Three of the composed blocks are not bands at all. The reveal, the section
   header and the stat cluster are designed to sit INSIDE one, so on a template
   that supplies none they land flush against the viewport edge with no band
   padding. This section gives them the band they are missing.

   Everything is scoped to DIRECT children of .site-main.home, so the same
   blocks are untouched on page.php, where .entry-content already sits inside a
   .container and the bands come from the page itself.

   Nothing here sets a band's COLOUR. Colour is each band block's own
   Background setting (§16d) — the home page used to alternate Paper and
   Pebble by position from this section, and that was removed on 2026-09-27 by
   maintainer ruling. What stays is spacing: which block opens a band and takes
   its top padding, and which closes it.
     1  reveal + hero
     2  section header + cards   (the header wears the grid's colour, below)
     3  section header + stats
     4  step process
     5  divider + split
     6  CTA banner */

.site-main.home > .wp-block-makemy-logo-reveal,
.home-lead > .wp-block-makemy-logo-reveal,
.site-main.home > .wp-block-makemy-section-header,
.site-main.home > .wp-block-makemy-stat-cluster {
    width: 100%;
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--container-pad);
}

/* Band 1 — the reveal and the hero are one band, not two. The reveal opens it
   (so it takes the top padding) and the hero closes it, which is why the gap
   between them is zero. The hero's colour is its own Background setting. */
.site-main.home > .wp-block-makemy-logo-reveal,
.home-lead > .wp-block-makemy-logo-reveal {
    padding-top: var(--home-lead-top);
    margin-bottom: 0;
}

.site-main.home > .wp-block-makemy-hero.hero--simple,
.home-lead > .wp-block-makemy-hero.hero--simple {
    padding-top: var(--sp-4);
}

.site-main.home {
    --home-lead-top: clamp(var(--sp-10), 6vw, var(--sp-16));
}

/* Band 1 fills the first screen (maintainer ruling 2026-09-27). The reveal
   and the hero are flat siblings, so inc/home-lead.php wraps the pair in
   .home-lead at render time and paints it in the hero's Background colour.
   The screen is the viewport less the sticky header (measured into
   --mm-header-h by main.js) and the admin bar when one is showing. svh, not
   dvh: the small viewport is the one with the phone's address bar showing,
   so the band never jumps as the bar slides away. min-height, never height —
   on a short screen (a phone on its side) the band grows past the fold rather
   than clipping its own copy. The page scrolls on normally below it. */
.home-lead {
    position: relative;
    display: flex;
    flex-direction: column;
    min-height: calc(100vh - var(--mm-header-h) - var(--wp-admin--admin-bar--height, 0px));
    min-height: calc(100svh - var(--mm-header-h) - var(--wp-admin--admin-bar--height, 0px));
}

/* The hero takes whatever the reveal leaves and centres its copy in it. */
.home-lead > .wp-block-makemy-hero.hero--simple {
    flex: 1 0 auto;
    padding-bottom: var(--sp-20);
}

/* The scroll cue — a stylised uppercase label, so it keeps its positive
   tracking. Sits clear of the seam divider's mark, which overhangs the band's
   bottom edge by half its height. */
.home-lead__cue {
    position: absolute;
    left: 50%;
    bottom: var(--sp-8);
    transform: translateX(-50%);
    font-family: var(--font-sans);
    font-size: var(--fs-11);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-muted);
    pointer-events: none;
    white-space: nowrap;
}

/* Below the hero's own stacking point (899px, hero/style.scss) the render
   moves up beside the logo instead of under the copy — mock-up A1: logo left,
   render right, then the heading at full width. The hero and its container
   drop out of the box tree so the reveal, the render and the copy can share
   one grid; the hero's band colour carries on because .home-lead paints it.
   Only when there IS a render — a hero without one keeps the column above. */
@media (max-width: 899px) {
    .home-lead:has(> .hero--has-aside) {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        grid-template-rows: auto 1fr;
        column-gap: var(--sp-4);
    }

    .home-lead > .wp-block-makemy-hero.hero--has-aside,
    .home-lead > .wp-block-makemy-hero.hero--has-aside .hero__content {
        display: contents;
    }

    .home-lead > .wp-block-makemy-logo-reveal:has(~ .hero--has-aside) {
        grid-column: 1;
        grid-row: 1;
        align-self: start;
        padding-inline-end: 0;
    }

    .home-lead:has(> .hero--has-aside) .mm-reveal {
        width: 80%;
    }

    .home-lead > .wp-block-makemy-hero.hero--has-aside .hero__aside {
        grid-column: 2;
        grid-row: 1;
        margin-top: 0;
        padding-top: var(--home-lead-top);
        padding-inline-end: var(--container-pad);
    }

    .home-lead > .wp-block-makemy-hero.hero--has-aside .hero__specs {
        flex-wrap: wrap;
    }

    .home-lead > .wp-block-makemy-hero.hero--has-aside .hero__text {
        grid-column: 1 / -1;
        grid-row: 2;
        align-self: end;
        padding: var(--sp-10) var(--container-pad) var(--sp-20);
    }
}

/* Band 2 — runs from the section header through the cards, in whichever
   colour the grid's Background setting picks (§16d). The header takes the
   band's top padding, so the grid's own is zeroed or the pair reads as two
   bands with a hole between them.

   The header's gap to the cards is PADDING, not margin: a margin sits outside
   the header's background, so the page showed through it as a white strip
   across a grey band. */
.site-main.home > .wp-block-makemy-section-header:has(+ .wp-block-makemy-product-card-grid) {
    padding-top: var(--band-pad);
    padding-bottom: var(--sp-8);
    margin-bottom: 0;
}

/* The header wears the colour of the band that follows it. It is a
   container-width box, not a full-width band, so the fill is extended to the
   viewport edges with a spread shadow clipped to its own height — otherwise,
   on a screen wider than the container, it would sit as a panel above a
   full-width band. The dark-text swap comes from §16d's `:has(+ .band--dark)`. */
.site-main.home > .wp-block-makemy-section-header:has(+ .band--paper)  { --band-bg: var(--paper); }
.site-main.home > .wp-block-makemy-section-header:has(+ .band--pebble) { --band-bg: var(--paper-soft); }
.site-main.home > .wp-block-makemy-section-header:has(+ .band--coal)   { --band-bg: var(--brand-coal); }

.site-main.home > .wp-block-makemy-section-header:has(+ .band) {
    background-color: var(--band-bg, transparent);
    box-shadow: 0 0 0 100vmax var(--band-bg, transparent);
    clip-path: inset(0 -100vmax);
}

.site-main.home > .wp-block-makemy-section-header + .wp-block-makemy-product-card-grid {
    padding-top: 0;
}

/* Band 3 — Paper. Same shape: header opens it, the stat cluster closes it and
   therefore owns the bottom padding. */
.site-main.home > .wp-block-makemy-section-header:has(+ .wp-block-makemy-stat-cluster) {
    padding-top: var(--band-pad);
    padding-bottom: 0;
    margin-bottom: var(--sp-10);
}

.site-main.home > .wp-block-makemy-stat-cluster {
    padding-bottom: var(--band-pad);
}

/* Band pages (inc/band-pages.php — Trade Overview, How it Works, About) have
   no .container either, so the stat cluster needs the same container box the
   home page gives it, or its figures run to the viewport edge. Descendant,
   not child: on a sub-site the blocks arrive inside a [network_page] stub.
   It follows a band that already carries its own bottom padding, so it only
   closes its own band. */
.site-main.band-page .wp-block-makemy-stat-cluster {
    width: 100%;
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--container-pad);
    padding-bottom: var(--sp-12);
}

/* The band seams used to need a correction here, twice over: the seam divider
   positioned itself absolutely against the band it opens, which required the
   block to be that band's first child, and no template in this theme has band
   elements to be a child of. So the block's `:has()` rule matched a page-level
   wrapper and the mark printed under the site header.

   It was corrected here for the home page (`.site-main.home >`), then widened
   to `.site-main >` when the products page reproduced it — which still missed,
   because page.php nests content in .entry-content > article > .container and
   front-page.php does not. Both attempts named a context instead of removing
   the dependency on context.

   The geometry now lives in the block's own style.scss and needs no ancestor:
   the wrapper collapses to zero height in normal flow and IS the join. Nothing
   is restated here, deliberately — a rule in this file scoped to a template is
   what produced two regressions, so the block owns its own positioning and
   every template gets it for free. */

/* ── 16d. Band backgrounds ─────────────────────────────────────────────────
   The Background setting on the band blocks (hero, product card grid, how it
   works, item grid) — Theme/inc/band-background.php and its JS twin emit:
     .band .band--{paper|pebble|coal}  the colour
     .band--dark                        Paper text instead of Ink (Coal only)
   The three swatches are Design.md §8.2's band surfaces, and the only three
   (ruled 2026-09-29 — the custom colour was removed). A retired `custom`
   renders as Paper; see band-background.php for the legacy markup rewrite.

   `.band.band--x` is (0,2,0) so it outranks a block's own one-class root fill
   (how-it-works paints Pebble on its root) whatever order the sheets load in.
   Coal is the brand hex, not var(--ink): inside a dark band --ink is Paper. */
.band.band--paper  { background-color: var(--paper); }
.band.band--pebble { background-color: var(--paper-soft); }
.band.band--coal   { background-color: var(--brand-coal); }

/* Dark band: the ink scale swaps to its on-dark twin, and Paper swaps to Coal
   so anything filled with Paper and lettered in Ink (a primary button) turns
   over as a pair rather than going white-on-white. The section header ahead
   of a dark grid takes the same swap, since the two are one band. */
.band--dark,
.site-main.home > .wp-block-makemy-section-header:has(+ .band--dark) {
    --ink:         var(--ink-on-dark);
    --ink-soft:    var(--ink-soft-on-dark);
    --ink-muted:   var(--ink-muted-on-dark);
    --ink-faint:   var(--ink-faint-on-dark);
    --rule:        var(--rule-on-dark);
    --rule-strong: var(--rule-strong-on-dark);
    --paper:       var(--brand-coal);
    color: var(--ink);
}

/* The hub is accentless — its --accent is Ink (§2.2), resolved at the root to
   Coal, which would vanish on a Coal band. Paper stands in for it there. */
[data-site="main"] .band--dark {
    --accent:    var(--brand-white);
    --accent-fg: var(--brand-coal);
}

/* Cards are Paper surfaces lettered in Ink wherever they sit, so inside a dark
   band they take the light scale back — otherwise their text would turn white
   on their own white face. */
.band--dark .product-card,
.band--dark .pg__card {
    --ink:         var(--brand-coal);
    --ink-soft:    color-mix(in oklch, var(--brand-coal) 88%, var(--brand-white));
    --ink-muted:   color-mix(in oklch, var(--brand-coal) 62%, var(--brand-white));
    --ink-faint:   color-mix(in oklch, var(--brand-coal) 36%, var(--brand-white));
    --rule:        color-mix(in oklch, var(--brand-stone) 60%, var(--brand-white));
    --rule-strong: var(--brand-stone);
    --paper:       var(--brand-white);
    color: var(--ink);
}

/* ── 16c. Two block fallbacks the blocks themselves can't express ───────────
   Both live here rather than in the blocks' own style.scss so they ship with a
   stylesheet rather than a block rebuild. Fold them into the block sources
   next time those are built. */

/* Split feature with no media yet. The body is hard-placed at columns 9–12 of
   the 7/5 field, so an empty media slot leaves eight dead columns rather than
   collapsing. Give the prose the measure until a photograph is uploaded. */
.wp-block-makemy-split-feature:not(:has(.split-feature__media)) .split-feature__body {
    grid-column: 1 / span 7;
}

/* The range grid's column rule moved into the block's own style.scss when the
   range cards gained their images — this section says to fold these in next
   time the block is built, and that was the time. Nothing to state here. */

/* Configurator page */
.configurator-embed-area {
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--container-pad);
}

/* 404 — a recovery page: search plus a row of routes out (404.php). The
   accent only ever draws lines here, never text, so the sub-4.5:1 accents
   (Door, Desk, Cabinet) cost nothing; the hub's accent is Ink. */
.error-404 {
    padding-block: var(--sp-20) var(--sp-24);
}

.error-404::before {
    content: "";
    display: block;
    width: var(--sp-8);
    height: 3px;
    margin-bottom: var(--sp-4);
    background: var(--accent);
}

.error-404__title {
    font-size: var(--fs-36);
    line-height: 1.15;
    margin-bottom: var(--sp-2);
}

.error-404__message {
    max-width: var(--container-blurb);
    font-size: var(--fs-16);
    color: var(--ink-muted);
    margin-bottom: var(--sp-6);
}

.error-404__search {
    max-width: var(--container-blurb);
    margin-bottom: var(--sp-10);
}

.error-404__routes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--sp-3);
    max-width: var(--container-narrow);
    margin: 0;
    padding: 0;
    list-style: none;
}

.error-404__route {
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
    height: 100%;
    padding: var(--sp-4);
    border: 1px solid var(--rule-interactive);
    border-top: 3px solid var(--accent);
    color: var(--ink);
    text-decoration: none;
    transition: border-color var(--dur-fast) var(--ease);
}

.error-404__route:hover {
    border-color: var(--ink);
    border-top-color: var(--accent);
}

.error-404__route-title {
    font-size: var(--fs-16);
    font-weight: var(--fw-semibold);
}

.error-404__route-text {
    font-size: var(--fs-13);
    color: var(--ink-muted);
}

/* ── 17. Blog — Single Post ────────────────────────────────────────────────── */

.single-post__header {
    text-align: center;
}

.single-post__meta {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-3);
    font-size: var(--fs-12);
    text-transform: uppercase;
    letter-spacing: var(--tracking-label);
    color: var(--ink-muted);
    margin-bottom: var(--sp-4);
}

.single-post__category {
    color: var(--accent);
    font-weight: var(--fw-semibold);
}

.single-post__title {
    font-size: clamp(1.75rem, 4vw, 3rem);
    font-weight: var(--fw-regular);
    line-height: 1.15;
    letter-spacing: var(--tracking-tight);
    margin-bottom: var(--sp-4);
}

.single-post__excerpt {
    font-size: var(--fs-22);
    color: var(--ink-muted);
    line-height: var(--lh-body);
    max-width: var(--container-copy-cap);   /* inside .container--narrow */
    margin-inline: auto;
}

.single-post__featured-image {
    margin-bottom: var(--sp-8);
}

.single-post__image {
    width: 100%;
    height: auto; /* images sit at 0 radius (Design.md §5.2) */
}

/* Entry content (shared between single & page) */
.entry-content > * + * {
    margin-top: var(--sp-6);
}

.entry-content img {
    max-width: 100%;
    height: auto; /* images sit at 0 radius (Design.md §5.2) */
}

.entry-content blockquote {
    border-left: 3px solid var(--accent);
    padding-left: var(--sp-6);
    margin-left: 0;
    color: var(--ink-muted);
    font-size: var(--fs-22);
}

/* Long-form core blocks (heading / paragraph / list) on a content page.
   Two things need fixing for them to read as an article:
   1. `.container` is 1440px+ — fine for the full-bleed custom blocks, far too
      wide as a measure for prose, so text children get --container-narrow.
   2. The global `ul, ol { list-style: none }` reset strips list markers, so a
      core/list block renders as unbulleted lines.
   Scoped to DIRECT children so full-bleed custom blocks (section-header,
   cta-banner, rich-text-image, …) still span the container as they do today. */
.entry-content > p,
.entry-content > ul,
.entry-content > ol,
.entry-content > h2,
.entry-content > h3,
.entry-content > h4 {
    max-width: var(--container-narrow);
    margin-inline: auto;
}

/* On a single post .container--narrow has already taken the Narrow share, so
   its prose takes the cap — a second 70% would compound to ~420px. */
.container--narrow .entry-content > p,
.container--narrow .entry-content > ul,
.container--narrow .entry-content > ol,
.container--narrow .entry-content > h2,
.container--narrow .entry-content > h3,
.container--narrow .entry-content > h4 {
    max-width: var(--container-narrow-cap);
}

.entry-content > ul,
.entry-content > ol {
    list-style: revert;
    padding-left: var(--sp-6);
}

.entry-content > ul li + li,
.entry-content > ol li + li {
    margin-top: var(--sp-2);
}

/* Section breathing room — beats the generic `> * + *` rule on specificity. */
.entry-content > h2,
.entry-content > h3 {
    margin-top: var(--sp-10);
}

.entry-content > p a,
.entry-content > ul a,
.entry-content > ol a {
    color: var(--accent);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}

.single-post__footer {
    border-top: 1px solid var(--rule);
    padding-top: var(--sp-6);
    margin-top: var(--sp-8);
}

.single-post__tags {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
}

/* §5.2 puts a badge on 2px and reserves the pill for status dots and pips; a
   tag is small chrome, not a pip, so it takes --r-xs. */
.single-post__tag {
    display: inline-block;
    padding: var(--sp-1) var(--sp-3);
    font-size: var(--fs-12);
    color: var(--ink-muted);
    border: 1px solid var(--rule);
    border-radius: var(--r-xs);
    transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.single-post__tag:hover {
    color: var(--accent);
    border-color: var(--accent);
}

/* Post navigation */
.post-nav {
    border-top: 1px solid var(--rule);
}

.post-nav__links {
    display: flex;
    justify-content: space-between;
    gap: var(--sp-8);
}

.post-nav__link {
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
    max-width: 50%;
    transition: color var(--dur-fast) var(--ease);
}

.post-nav__link--next {
    margin-left: auto;
    text-align: right;
}

.post-nav__label {
    font-size: var(--fs-12);
    color: var(--ink-muted);
    text-transform: uppercase;
    letter-spacing: var(--tracking-label);
}

.post-nav__title {
    font-size: var(--fs-18);
    font-weight: var(--fw-semibold);
    color: var(--ink);
}

.post-nav__link:hover .post-nav__title {
    color: var(--accent);
}


/* ── 18. Blog — Archive / Post Grid ───────────────────────────────────────── */

.archive-header {
    border-bottom: 1px solid var(--rule);
}

.archive-header__title {
    font-size: clamp(1.5rem, 3vw, 2.5rem);
    font-weight: var(--fw-regular);
    letter-spacing: var(--tracking-tight);
}

.archive-header__description {
    margin-top: var(--sp-3);
    color: var(--ink-muted);
    max-width: var(--container-copy);
}

.post-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--sp-8);
}

/* 3 → 2 → 1. Kept beside the rule they reshape rather than in a shared
   responsive section: .post-grid is the only grid left that needs them. */
@media (max-width: 1199px) {
    .post-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 767px) {
    .post-grid { grid-template-columns: 1fr; }
}

.post-card {
    display: flex;
    flex-direction: column;
    background: var(--paper);
    border: 1px solid var(--rule);
    border-radius: var(--r-md);
    overflow: hidden;
    transition: box-shadow var(--dur-base) var(--ease);
}

.post-card:hover {
    box-shadow: var(--shadow-3);
}

.post-card__image-link {
    display: block;
    overflow: hidden;
    aspect-ratio: 16 / 10;
}

.post-card__image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--dur-base) var(--ease);
}

.post-card:hover .post-card__image {
    transform: scale(1.04);
}

.post-card__body {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: var(--sp-6);
}

.post-card__category {
    font-size: var(--fs-12);
    font-weight: var(--fw-semibold);
    text-transform: uppercase;
    letter-spacing: var(--tracking-label);
    color: var(--accent);
    margin-bottom: var(--sp-2);
}

.post-card__title {
    font-size: var(--fs-22);
    font-weight: var(--fw-semibold);
    line-height: var(--lh-snug);
    margin-bottom: var(--sp-3);
}

.post-card__title a {
    color: inherit;
    transition: color var(--dur-fast) var(--ease);
}

.post-card__title a:hover {
    color: var(--accent);
}

.post-card__excerpt {
    color: var(--ink-muted);
    font-size: var(--fs-14);
    line-height: var(--lh-body);
    flex: 1;
}

.post-card__meta {
    margin-top: var(--sp-4);
    padding-top: var(--sp-4);
    border-top: 1px solid var(--rule);
    font-size: var(--fs-12);
    color: var(--ink-muted);
}

/* Archive pagination */
.archive-pagination {
    margin-top: var(--sp-12);
    display: flex;
    justify-content: center;
}

.archive-pagination .nav-links {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
}

.archive-pagination .page-numbers {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    height: 40px;
    padding: 0 var(--sp-2);
    font-size: var(--fs-14);
    font-weight: var(--fw-regular);
    color: var(--ink);
    border: 1px solid var(--rule);
    border-radius: var(--r-sm);
    transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.archive-pagination .page-numbers:hover {
    border-color: var(--accent);
    color: var(--accent);
}

/* Selected state inverts to Coal fill with Paper text (Design.md §3.5) —
   accent never fills a control that carries text. */
.archive-pagination .page-numbers.current {
    background-color: var(--ink);
    border-color: var(--ink);
    color: var(--paper);
}

.archive-pagination .page-numbers.dots {
    border: none;
    pointer-events: none;
}

/* Search results */
.search-header {
    margin-bottom: var(--sp-8);
}

.search-title {
    font-size: clamp(1.25rem, 3vw, 2rem);
    margin-bottom: var(--sp-6);
}

.search-title span {
    color: var(--accent);
}

.search-result-item {
    padding-block: var(--sp-6);
    border-bottom: 1px solid var(--rule);
}

.search-result-item__title {
    font-size: var(--fs-22);
    margin-bottom: var(--sp-2);
}

.search-result-item__title a {
    color: var(--ink);
    transition: color var(--dur-fast) var(--ease);
}

.search-result-item__title a:hover {
    color: var(--accent);
}

.search-result-item__excerpt {
    color: var(--ink-muted);
    font-size: var(--fs-14);
}
