/* components.css — all shared component styles in one file (Design-Direction §7).
   Grows as components are built (Phases 3+). Naming: .c-<component>, BEM elements/modifiers.
   Phase 1 seeds the button so the brand button mapping can be verified on /_dev/swatches. */

/* --- Button (Visual-Reference §6) --- */
.c-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.75rem 1.5rem;
    font-family: var(--font-body);
    font-size: var(--text-sm);
    text-transform: uppercase;
    letter-spacing: 0.02em;
    line-height: 1;
    border: 1px solid transparent;
    border-radius: var(--radius-button);
    cursor: pointer;
    text-decoration: none;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

    .c-button:hover {
        text-decoration: none;
    }

.c-button--primary {
    background: var(--button-primary-bg);
    color: var(--button-primary-text);
    border-color: var(--button-primary-border);
}

    .c-button--primary:hover {
        background: var(--button-primary-hover-bg);
        color: var(--button-primary-hover-text);
        border-color: var(--button-primary-hover-border);
    }

.c-button--secondary {
    background: var(--button-secondary-bg);
    color: var(--button-secondary-text);
    border-color: var(--button-secondary-border);
}

    .c-button--secondary:hover {
        background: var(--button-secondary-hover-bg);
        color: var(--button-secondary-hover-text);
        border-color: var(--button-secondary-hover-border);
    }

.c-button--link {
    padding: 0;
    background: none;
    border: none;
    text-transform: none;
    letter-spacing: 0;
    color: var(--color-text);
    text-decoration: underline;
}

.c-button:disabled,
.c-button[aria-disabled="true"] {
    background: var(--color-disabled-bg);
    color: var(--color-disabled-text);
    border-color: var(--color-disabled-bg);
    cursor: not-allowed;
}

/* ===================== Header (Visual-Reference §2) ===================== */
.c-header {
    background: var(--color-header-bg);
    position: relative; /* anchor for the full-width mega-menu band */
}

.c-header__top {
    display: grid;
    /* Canonical "centre the middle track" pattern: the centre column is `auto` (it hugs the
       search), flanked by two EQUAL flexible `1fr` side columns. Equal sides guarantee the
       search is viewport-centred no matter how wide the logo or the icon cluster are. The
       nav row below is also viewport-centred, so the two line up vertically. */
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: var(--space-4);
    /* Smaller gap above the search (owner request 2026-06-17). */
    padding-block: var(--space-2) 0;
}

.c-header__logo img {
    max-height: 64px;
    width: auto;
}

/* Centre column holds the search (top) and the primary nav (bottom) as one centred stack.
   Because it sits in the grid's `auto` track flanked by equal 1fr sides, the whole block is
   viewport-centred regardless of logo / icon width — and search + nav share the same axis. */
.c-header__center {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    /* Bottom-align the search+nav stack so the nav underline reaches the header's bottom edge (the row is as
       tall as the 64px logo). Works together with .c-nav__link display:block (no inline descender gap). */
    align-self: end;
    gap: var(--space-1);
    /* The band shrinks to the NAV's natural width (first letter of the first item to the last
       letter of the last item — no outer padding). The search bar then fills 100% of that band.
       The grid's equal 1fr sides keep the whole band viewport-centred. */
    width: fit-content;
    max-width: 100%;
    min-width: 0;
}

.c-header__wordmark {
    font-family: var(--font-display);
    font-size: var(--title-md);
    color: var(--color-title);
}

/* Search — underline-only (Visual-Reference §2). Capped to ~the nav width and centred so it
   doesn't stretch the full column on large screens (aligns search edges with first/last nav item). */
.c-search-wrap { }   /* plain wrapper; the popup anchors to .c-header (drops below the whole header, uncut) */
.c-search {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    border-bottom: 1px solid var(--color-border-input);
    padding-block: var(--space-1);
    /* Fills the centre band so the underline spans the same width as the nav below it. */
    width: 100%;
    /* Keep the search bar itself above the popup's dim backdrop (so the search row is never darkened). */
    position: relative;
    z-index: 46;
    background: var(--color-header-bg);
}

.c-search__icon { flex: none; height: 20px; width: auto; color: var(--color-muted); }

/* DB-driven header icons (already brand-coloured PNGs) */
.c-headericon { height: 21.6px; width: auto; display: block; } /* 90% of 24px (owner request) */

.c-search__input {
    flex: 1;
    border: 0;
    background: transparent;
    font-size: var(--text-base);
    padding: var(--space-1) 0;
}

    .c-search__input:focus { outline: none; }
    /* Suppress the browser's native type=search clear button — we render our own. */
    .c-search__input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }

.c-search__clear { flex: none; border: 0; background: none; cursor: pointer; color: var(--color-muted); font-size: 1.4rem; line-height: 1; padding: 0 var(--space-1); }
    .c-search__clear:hover { color: var(--color-text); }

/* Header search-focus popup — curated card overlay (SearchInput.razor). Anchored below the whole header like the
   mega menu (.c-header is the positioned ancestor); dims the page behind. */
/* No dim — a transparent full-screen catcher just so a click outside the popup closes it. */
.c-searchpop__backdrop { position: fixed; inset: 0; background: transparent; z-index: 45; }
/* Drops from just below the search bar (anchored to .c-search-wrap), full viewport width, over the nav. */
.c-searchpop {
    position: absolute; top: 100%; left: 0; right: 0; z-index: 60;
    background: var(--color-header-bg); box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18);
    max-height: 80vh; overflow-y: auto;
}
.c-searchpop .c-searchpop__inner { position: relative; padding-block: var(--space-5); max-width: 68rem; margin-inline: auto; }
.c-searchpop__close { position: absolute; top: var(--space-3); right: var(--space-3); border: 0; background: none; font-size: 1.6rem; line-height: 1; color: var(--color-muted); cursor: pointer; }
    .c-searchpop__close:hover { color: var(--color-text); }
.c-searchpop__group { margin-bottom: var(--space-5); }
.c-searchpop__title { font-size: var(--title-sm); margin: 0 0 var(--space-3); text-align: center; }
.c-searchpop__cards { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-4); }
.c-searchpop__card { display: block; flex: 0 1 260px; text-decoration: none; color: var(--color-text); }
    .c-searchpop__card-img { display: block; width: 100%; aspect-ratio: 3 / 2; object-fit: cover; border-radius: var(--radius-image); }
    .c-searchpop__card-label { display: block; margin-top: var(--space-2); color: var(--color-accent); }
    .c-searchpop__card:hover .c-searchpop__card-label { text-decoration: underline; }
.c-searchpop__info { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--space-5); border-top: 1px solid var(--color-underline); padding-top: var(--space-4); }
.c-searchpop__infohead { display: flex; align-items: center; justify-content: center; gap: var(--space-2); }
    .c-searchpop__infoicon { height: 26px; width: auto; }
    .c-searchpop__infotitle { margin: 0; font-size: var(--text-md); }
.c-searchpop__infohtml { color: var(--color-muted); margin-top: var(--space-2); text-align: center; }
    .c-searchpop__infohtml address { font-style: normal; }
    .c-searchpop__infohtml p { margin: 0 0 var(--space-2); }
    .c-searchpop__infohtml a { color: var(--color-text); text-decoration: underline; }

/* Search results page (/search) — matched pages/topics + a tile preview handing off to ShopTiles. */
.c-searchres { padding-block: var(--space-6); }
.c-searchres__head { margin-bottom: var(--space-5); }
.c-searchres__title { margin: 0 0 var(--space-2); }
.c-searchres__sub { margin: 0; color: var(--color-muted); }
/* Count/jump nav — same tab style as the cart drawer (.c-cartjump): bold links, a "|" separator. */
.c-searchres__nav { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); font-size: var(--text-base); }
    .c-searchres__nav a { color: var(--color-text); font-weight: 600; text-decoration: underline; }
    .c-searchres__nav a:hover { text-decoration: none; }
    .c-searchres__nav-sep { color: var(--color-muted); }
.c-searchres__section { margin-bottom: var(--space-6); scroll-margin-top: var(--space-6); }
.c-searchres__more-topics { margin-top: var(--space-4); }
    .c-searchres__more-topics > summary { cursor: pointer; width: fit-content; color: var(--color-text); text-decoration: underline; list-style: none; }
    .c-searchres__more-topics > summary:hover { text-decoration: none; }
    .c-searchres__more-topics > summary::-webkit-details-marker { display: none; }
    .c-searchres__more-topics .c-searchres__topics { margin-top: var(--space-4); }
    /* CSS-only Show/Hide swap driven by the <details> open state. */
    .c-searchres__more-hide { display: none; }
    .c-searchres__more-topics[open] > summary .c-searchres__more-show { display: none; }
    .c-searchres__more-topics[open] > summary .c-searchres__more-hide { display: inline; }
.c-searchres__totop { margin-top: var(--space-5); padding-top: var(--space-4); border-top: 1px solid var(--color-underline); text-align: center; }
    .c-searchres__totop a { color: var(--color-text); font-weight: 600; text-decoration: underline; }
    .c-searchres__totop a:hover { text-decoration: none; }
.c-searchres__heading { font-size: var(--title-sm); margin: 0 0 var(--space-3); }
.c-searchres__heading-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-3); }
    .c-searchres__heading-row .c-searchres__heading { margin-bottom: 0; }
.c-searchres__seeall { color: var(--color-text); text-decoration: underline; white-space: nowrap; }
.c-searchres__more { margin-top: var(--space-4); text-align: center; }
.c-searchres__topics { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-4); }
.c-searchres-topic { border-bottom: 1px solid var(--color-underline); padding-bottom: var(--space-4); }
    .c-searchres-topic__link { display: inline-block; font-size: var(--text-md); color: var(--color-text); text-decoration: underline; }
    .c-searchres-topic__snippet { margin: var(--space-1) 0 0; color: var(--color-muted); max-width: 60rem; }

.c-header__right {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--space-3);
}

.c-header__wholesale {
    font-size: var(--text-sm);
    color: var(--color-accent);
    text-decoration: underline;
}

.c-header__icons {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin: 0;
    padding: 0;
    list-style: none;
}

    /* Icons render in the brand colour (Visual-Reference §9) */
    .c-header__icons a { color: var(--color-brand); display: inline-flex; }

/* Primary nav — underline appears on hover only (Visual-Reference §2).
   Items sit in a single row with uniform gaps; the first item is flush-left and the last
   flush-right (no outer padding/margin), so the row's width defines the centre band. */
.c-nav {
    display: flex;
    justify-content: flex-start;
    flex-wrap: nowrap;
    gap: clamp(var(--space-3), 2.5vw, var(--space-5));
    margin: 0;
    /* padding-inline:0 clears the browser-default <ul> left padding so the first item is flush-left.
       No bottom padding so the nav link's hover underline sits flush with the header's bottom edge. */
    padding: var(--space-2) 0 0;
    list-style: none;
}

.c-nav__item { position: static; } /* the mega-menu band anchors to .c-header, not the item */

.c-nav__link {
    /* block + line-height:1 so there's no inline-box descender space below the underline — the
       hover border-bottom then sits flush with the header's bottom edge. */
    display: block;
    line-height: 1;
    /* Extra bottom padding = visible space between the nav text and its underline (owner request);
       +2px nudges the underline flush with the header's bottom edge. */
    padding: var(--space-1) 0 calc(var(--space-3) + 2px);
    color: var(--color-text);
    /* Marginally fluid: scales between ~13.6px and 16px with viewport width. */
    font-size: clamp(0.85rem, 0.6rem + 0.7vw, var(--menulink-font-size));
    font-weight: 500;
    border-bottom: 3px solid transparent;
    text-decoration: none;
    white-space: nowrap;
}

    .c-nav__link:hover {
        text-decoration: none;
        border-bottom-color: var(--color-accent);
    }

/* Mega menu — full-width band below the header, revealed on hover (static SSR, CSS-only).
   The panel is anchored to .c-header (set position:relative) so it spans the viewport width; the
   nav item/megamenu are NOT positioned so they don't become the anchor. */
.c-megamenu { position: static; }
/* Desktop: the head wrapper is layout-neutral (link flows as before) and the mobile expander is hidden. */
.c-megamenu__head { display: contents; }
.c-mega-expander { display: none; }

.c-megamenu__panel {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 50;
    background: var(--color-white);
    min-width: 360px;   /* same floor as the page (body min-width) — scrolls with the page below that */
    /* Fluid text (scales with the viewport like the rest of the site; floor = the 0.82rem site min). */
    font-size: clamp(0.82rem, 0.62rem + 0.45vw, 1rem);
    box-shadow: var(--shadow-md);
    border-top: 1px solid var(--color-underline);
    padding: var(--space-5) 0;
    opacity: 0;
    visibility: hidden;
    transform: translateY(4px);
    transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
    /* Hover-intent: keep the panel up for ~0.3s after the mouse leaves, so a momentary mouse-out and
       back (≤0.3s) doesn't close it. Opening is immediate (delay reset to 0 on hover, below). */
    transition-delay: 0.3s;
}
/* Invisible bridge over any gap between the nav link and the band, so hover doesn't drop in between. */
.c-megamenu__panel::before { content: ""; position: absolute; bottom: 100%; left: 0; right: 0; height: var(--space-3); }

.c-megamenu:hover .c-megamenu__panel,
.c-megamenu:focus-within .c-megamenu__panel {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    transition-delay: 0s;
}
/* 🔒 Sliding between nav items must NOT show two panels at once (owner, 10 Aug 2026).
   The 0.3s hold above is hover-intent for leaving the nav — but it fired when moving from one mega item
   to the next as well, so the outgoing panel stayed FULLY OPAQUE for 0.3s while the incoming one was
   already up. Two menus overlapping for ~0.45s.
   While the pointer is anywhere inside the nav (a panel counts — it's a DOM descendant of .c-nav even
   though it's positioned against .c-header), drop the outgoing panel instantly: no delay, no fade. The
   panel actually being hovered re-asserts its own fade on the next rule, so opening still eases in and
   only ONE panel is ever visible. Leaving the nav entirely doesn't match .c-nav:hover, so the 0.3s
   hover-intent hold is untouched — don't "simplify" these two rules into one, that's the whole trick. */
@media (min-width: 901px) {
    .c-nav:hover .c-megamenu__panel { transition-delay: 0s; transition-duration: 0s; }
    .c-nav:hover .c-megamenu:hover .c-megamenu__panel { transition-duration: 0.15s; }
}

/* Set by menu-dismiss.js: suppress the hover/focus panel until the pointer moves (stops it re-opening
   after a navigation when the cursor rests on the nav, and on a mega-link click). Desktop only — on the
   ≤900px accordion the panel is display-driven, so this must not touch it. */
@media (min-width: 901px) {
    .u-nohover .c-megamenu__panel { opacity: 0 !important; visibility: hidden !important; transition-delay: 0s !important; }
}

/* Products panel: one column per filter axis. Column count steps down as the screen narrows
   (6 → 5 → 4), then the mobile drawer (≤900px) stacks to a single column. */
.c-megamenu__columns { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: var(--space-4) var(--space-5); }
@media (max-width: 1500px) { .c-megamenu__columns { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@media (max-width: 1200px) { .c-megamenu__columns { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.c-megamenu__col-title { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); margin: 0 0 var(--space-2); font-size: clamp(0.95rem, 0.78rem + 0.45vw, 1.15rem); cursor: default; }
.c-megamenu__col-title--close { display: none; }   /* the collapse-label + chevron are mobile-only */
.c-megamenu__cat-icon { display: none; }
.c-megamenu__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
/* Each option is a row card: label on the left, thumbnail flush right at its natural aspect (fixed height,
   width follows the image — wide tile photos read wide, small app icons stay small). */
.c-megamenu__opt { display: flex; align-items: center; gap: var(--space-2); min-height: 3rem; background: var(--color-neutral-5); border-radius: var(--radius-sm); overflow: hidden; color: var(--color-text); text-decoration: none; }
    .c-megamenu__opt:hover { background: var(--color-neutral-10); }
    .c-megamenu__opt:hover .c-megamenu__opt-label { text-decoration: underline; }
.c-megamenu__opt-label { flex: 1 1 auto; min-width: 0; padding: var(--space-2) var(--space-3); }
.c-megamenu__thumb { flex: 0 0 auto; height: 3rem; width: auto; max-width: 55%; object-fit: contain; display: block; }
/* "View All …" link at the foot of a column (e.g. Range). */
.c-megamenu__viewall { display: inline-block; padding: var(--space-1) var(--space-2); color: var(--color-text); font-weight: 600; text-decoration: underline; }
    .c-megamenu__viewall:hover { text-decoration: none; }

/* Hero panel: copy on the left, featured image on the right at its natural aspect ratio (no crop/stretch).
   Content is narrower than the page content width (overrides .l-container's max-width; centred) — the
   products panel keeps full width. */
.c-megamenu__hero { display: grid; grid-template-columns: minmax(16rem, 1fr) minmax(0, 1.4fr); gap: var(--space-5); align-items: center; max-width: 92rem; }
.c-megamenu__hero-text { align-self: center; }
.c-megamenu__hero-title { margin: 0 0 var(--space-2); font-size: clamp(1.2rem, 0.95rem + 0.7vw, 1.5rem); }
.c-megamenu__hero-body { color: var(--color-text); }
.c-megamenu__hero-link { display: inline-block; margin-top: var(--space-3); text-decoration: underline; color: var(--color-text); }
.c-megamenu__hero-media { display: block; }
    .c-megamenu__hero-media img { width: 100%; height: auto; border-radius: var(--radius-md); display: block; }

/* ===================== Footer (Visual-Reference §3) ===================== */
.c-footer {
    background: var(--color-footer-bg);
    color: var(--color-white);
    padding-block: var(--space-6) var(--space-4);
}

.c-footer__columns {
    display: grid;
    /* Auto-reflow: columns stay >=240px wide, otherwise the count drops (down to 1)
       so headings/links never get cramped. Replaces hand-tuned breakpoints. */
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
    gap: var(--space-5);
}

.c-footer__heading {
    color: var(--color-white);
    font-size: var(--text-lg);
    font-weight: 400;
    padding-bottom: var(--space-2);
    margin-bottom: var(--space-4);
    border-bottom: 1px solid rgba(255, 255, 255, 0.25);
}

.c-footer__links,
.c-footer__social-links {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.c-footer a { color: var(--color-white); }

/* FOLLOW US: small social glyphs in a horizontal row (CMS link text is blank; icon comes from the URL). */
.c-footer__social-links { flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
    .c-footer__social-links a { display: inline-flex; }
    .c-footer__social-icon { width: 22px; height: 22px; display: block; transition: opacity 0.15s ease; }
    .c-footer__social-links a:hover .c-footer__social-icon { opacity: 0.7; }

.c-footer__contact-line {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
    overflow-wrap: anywhere;
}

    .c-footer__contact-line svg { flex: none; }

.c-footer__logo {
    margin-top: var(--space-4);
    max-height: 56px;
    width: auto;
}

.c-footer__legal {
    margin-top: var(--space-5);
    padding-top: var(--space-4);
    border-top: 1px solid rgba(255, 255, 255, 0.15);
    text-align: center;
    font-size: var(--text-sm);
}

/* Small phones: keep logo / hamburger / icons proportional */
@media (max-width: 480px) {
    .c-header__logo img { max-height: 44px; }
    .c-headericon { height: 18px; }
    .c-header__icons { gap: var(--space-2); }
    .c-hamburger svg { width: 22px; height: 22px; }
}

/* ===================== Interactive chrome (Phase 3B) ===================== */

/* Header icon buttons + count badges */
.c-iconbtn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: none;
    border: 0;
    color: var(--color-brand);
    cursor: pointer;
}

/* Signed-in indicator on the account icon. The header icons are DB-supplied images, so the icon itself can't
   be recoloured or swapped without new artwork — a dot is the cheapest honest signal. Uses --color-accent
   (navy), deliberately NOT --color-brand: the green would sit next to the green favourites heart and read as
   another "favourited" state rather than "signed in". */
.c-iconbtn__dot {
    position: absolute;
    top: -2px;
    right: -3px;
    width: 8px;
    height: 8px;
    border-radius: 999px;
    background: var(--color-accent);
    border: 1.5px solid var(--color-header-bg);   /* separates the dot from the icon behind it */
    pointer-events: none;
}

.c-iconbtn__badge {
    position: absolute;
    top: -6px;
    right: -8px;
    min-width: 16px;
    height: 16px;
    padding: 0 3px;
    border-radius: 999px;
    /* Original badge styling: light (header) fill with a dark outline + dark count, not white-on-dark. */
    background: var(--color-header-bg);
    border: 1px solid var(--color-text);
    color: var(--color-text);
    font-size: var(--text-2xs); /* badge count: ~83% of the site min, owner-requested smaller (exception to the 0.82rem floor) */
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Side menu — slide from right (Visual-Reference §4) */
.c-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease, visibility 0.2s;
    z-index: 90;
}

    .c-backdrop.is-open { opacity: 1; visibility: visible; }

.c-sidemenu {
    position: fixed;
    top: 0;
    right: 0;
    height: 100vh;
    width: min(480px, 100vw);
    background: var(--color-white);
    box-shadow: var(--shadow-md);
    transform: translateX(100%);
    transition: transform 0.25s ease;
    z-index: 100;
    display: flex;
    flex-direction: column;
}

    .c-sidemenu.is-open { transform: translateX(0); }

.c-sidemenu__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-4);
    border-bottom: 1px solid var(--color-underline);
}

.c-sidemenu__title { margin: 0; font-size: var(--title-sm); }

.c-sidemenu__close {
    background: none;
    border: 0;
    font-size: 1.75rem;
    line-height: 1;
    cursor: pointer;
    color: var(--color-text);
}

.c-sidemenu__body { padding: var(--space-4); overflow-y: auto; scroll-behavior: smooth; }

.c-cartmenu,
.c-accountmenu { display: flex; flex-direction: column; gap: var(--space-3); align-items: stretch; }
.c-accountmenu__greeting { margin: 0; font-weight: 600; }
.c-accountmenu__logout { width: 100%; }
.c-accountmenu__links { display: flex; flex-direction: column; gap: var(--space-1); }
.c-accountmenu__links a { color: var(--color-text); text-decoration: none; padding-block: var(--space-2); border-bottom: 1px solid var(--color-underline); }
.c-accountmenu__links a:hover { text-decoration: underline; }
.c-cartmenu__empty { color: var(--color-muted); }
/* Themed confirm dialog (site replacement for window.confirm). Above the side-menu overlays (~110). */
.c-confirm__backdrop { position: fixed; inset: 0; z-index: 1100; background: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; padding: var(--space-4); }
.c-confirm { width: 100%; max-width: 26rem; background: #fff; border-radius: var(--radius-image); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-4); box-shadow: var(--shadow-md); }
.c-confirm__msg { margin: 0; color: var(--color-text); }
.c-confirm__actions { display: flex; justify-content: flex-end; gap: var(--space-2); flex-wrap: wrap; }

.c-cartmenu__heading { margin: var(--space-2) 0 0; font-size: var(--text-lg); }
/* Section heading row: title on the left, "Clear all …" on the right. */
.c-cartmenu__sectionhead { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); }
.c-cartmenu__clear { flex: 0 0 auto; border: 0; background: none; padding: 0; color: var(--color-muted); text-decoration: underline; font-size: var(--text-sm); cursor: pointer; }
    .c-cartmenu__clear:hover { color: var(--color-error); }
/* Cart line */
.c-cartline { display: grid; grid-template-columns: 4.75rem 1fr auto; gap: var(--space-3); align-items: start; padding-block: var(--space-2); border-top: 1px solid var(--color-underline); }
.c-cartline__img { width: 4.75rem; height: 4.75rem; object-fit: cover; border-radius: var(--radius-sm); }
.c-cartline__info { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.c-cartline__name { color: var(--color-text); text-decoration: none; font-size: var(--text-sm); }
    .c-cartline__name:hover { text-decoration: underline; }
.c-cartline__sku { color: var(--color-muted); font-size: var(--text-xs); white-space: nowrap; }
.c-cartline__meta { color: var(--color-muted); font-size: var(--text-xs); }
.c-cartline__price { font-weight: 700; font-size: var(--text-base); }
/* Right-hand column on a product line: remove × on top, line total at the bottom-right (matches Item Total size). */
.c-cartline__end { display: flex; flex-direction: column; align-items: flex-end; justify-content: space-between; align-self: stretch; gap: var(--space-2); }
    .c-cartline__end .c-cartline__remove { align-self: flex-end; }
/* Compact inline quantity editor on a product line: Tile / Sqm (editable) + Box (read-only). */
/* Tile / or / Sqm / Box grouped at the left (not spread across the row) so they stay tidy when wide. */
.c-cartline__qty { display: flex; align-items: flex-start; justify-content: flex-start; flex-wrap: wrap; gap: var(--space-3); margin: var(--space-1) 0; }
.c-cartline__or { align-self: center; color: var(--color-muted); font-size: var(--text-sm); }
.c-cartline__qtyfield { display: flex; flex-direction: column; gap: 1px; }
    .c-cartline__qtyfield label { color: var(--color-muted); font-size: var(--text-xs); }
    .c-cartline__qtyfield input { width: 3.25rem; padding: var(--space-1); border: 1px solid var(--color-border-input); border-radius: var(--radius-sm); font: inherit; font-size: var(--text-xs); text-align: center; }
/* Box is read-only info: a plain label, vertically aligned with the Tile/Sqm input boxes. */
.c-cartline__boxval { padding: var(--space-1) 0; font-size: var(--text-xs); }
.c-cartline__unitprice { font-weight: 400; font-size: var(--text-xs); white-space: nowrap; }
    .c-cartline__unitprice small { color: var(--color-muted); font-weight: 400; }
.c-cartline__remove { align-self: start; border: 0; background: none; color: var(--color-muted); font-size: 1.25rem; line-height: 1; cursor: pointer; padding: 0 var(--space-1); }
    .c-cartline__remove:hover { color: var(--color-text); }
/* Quick-jump anchor bar (jumps to the Products / Sample Box section — useful for large carts). */
.c-cartjump { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); padding-bottom: var(--space-2); border-bottom: 1px solid var(--color-underline); font-size: var(--text-sm); }
.c-cartjump__link { color: var(--color-text); font-weight: 600; text-decoration: underline; }
    .c-cartjump__link:hover { text-decoration: none; }
.c-cartjump__sep { color: var(--color-muted); }

/* Products and the sample box are separate orders — each section gets its own footer/total/checkout. */
.c-cartmenu__section { scroll-margin-top: var(--space-3); }
.c-cartmenu__section + .c-cartmenu__section { margin-top: calc(var(--space-5) * 1.25); }
.c-cartmenu__footer { margin-top: var(--space-3); padding-top: var(--space-3); border-top: 2px solid var(--color-underline); display: flex; flex-direction: column; gap: var(--space-3); }
.c-cartmenu__subtotal { display: flex; justify-content: space-between; align-items: baseline; }
.c-cartmenu__subtotal strong { font-size: var(--text-md); }
.c-cartmenu__gst { color: var(--color-muted); font-size: var(--text-xs); margin-top: calc(-1 * var(--space-2)); }

/* Per-order totals block (Item Total / Shipping / Total + GST + note), matching the original cart. */
.c-carttotal__title { margin: 0; font-size: var(--title-sm); }
.c-carttotal { display: flex; flex-direction: column; gap: var(--space-1); }
.c-carttotal__row { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3); }
.c-carttotal__row--total { font-weight: 700; font-size: var(--text-md); margin-top: var(--space-1); }
.c-carttotal__pending { color: var(--color-text); }
.c-carttotal__gst { margin: var(--space-1) 0 0; color: var(--color-muted); font-size: var(--text-xs); }
.c-carttotal__note { margin: var(--space-2) 0 0; color: var(--color-text); font-size: var(--text-xs); }
.c-carttotal__account { margin: 0; font-size: var(--text-sm); }
    .c-carttotal__account a { color: var(--color-text); font-weight: 600; text-decoration: underline; }
    .c-carttotal__account a:hover { text-decoration: none; }

/* Modal (Add-to-cart quantity dialog). Overlay + centred dialog; backdrop click closes (handled in razor). */
.c-modal { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; padding: var(--space-4); background: rgba(0, 0, 0, 0.45); }
.c-modal__dialog { position: relative; width: 100%; max-width: 26rem; background: #fff; border-radius: var(--radius-lg); padding: var(--space-5); box-shadow: 0 10px 40px rgba(0, 0, 0, 0.25); }
.c-modal__dialog--wide { max-width: 36rem; padding: var(--space-4) var(--space-5) var(--space-5); --mthumb: 12rem; }
.c-modal__header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding-bottom: var(--space-3); border-bottom: 1px solid var(--color-underline); margin-bottom: var(--space-4); }
.c-modal__close { border: 0; background: none; font-size: 1.6rem; line-height: 1; color: var(--color-muted); cursor: pointer; }
    .c-modal__close:hover { color: var(--color-text); }
.c-modal__title { margin: 0; }
.c-modal__loading { color: var(--color-muted); }

/* Body: square thumbnail on the left, kept at its natural 1:1 ratio (no stretch) and vertically
   centred against the taller details column (name + quantities + note + wastage) on the right. */
.c-modal__body { display: flex; gap: var(--space-4); align-items: stretch; }
.c-modal__thumb { flex: 0 0 var(--mthumb); width: var(--mthumb); aspect-ratio: 1 / 1; align-self: center; border-radius: var(--radius-image); overflow: hidden; background: var(--color-neutral-5); }
    .c-modal__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.c-modal__details { flex: 1 1 auto; min-width: 0; }
.c-modal__desc { margin: 0 0 var(--space-4); color: var(--color-text); }
.c-modal__sku { color: var(--color-text); font-weight: 400; white-space: nowrap; }

/* Dual quantity entry: Tile  [or]  Sqm, each with the rounded unit price under it. */
.c-modal__units { display: flex; align-items: flex-start; justify-content: flex-start; gap: var(--space-3); }
/* Left-aligned column so the unit price's "$" lines up with the textbox's left edge. */
.c-modal__unit { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-1); text-align: left; }
.c-modal__unit-label { font-weight: 600; }
    .c-modal__unit input { width: 5.5rem; padding: var(--space-1) var(--space-2); border: 1px solid var(--color-border-input); border-radius: var(--radius-button); font: inherit; text-align: center; }
.c-modal__unit-price { color: var(--color-text); font-weight: 600; white-space: nowrap; }
    .c-modal__unit-price small { color: var(--color-muted); font-weight: 400; }
.c-modal__or { align-self: center; color: var(--color-muted); padding-top: 1.6rem; }
.c-modal__note { margin: var(--space-3) 0 0; color: var(--color-muted); font-size: var(--text-xs); }

/* Two dividers bracket the wastage row (one above, one below); kept tight. */
.c-modal__divider { border: 0; border-top: 1px solid var(--color-underline); margin: var(--space-3) 0; }

/* Wastage now lives inside the details column (right of the image), so it needs no extra offset.
   Total sits below the body full-width, indented to the details column so it lines up under "Add". */
.c-modal__waste { display: flex; align-items: center; justify-content: flex-start; gap: var(--space-2); }
    .c-modal__waste select { padding: var(--space-1) var(--space-2); border: 1px solid var(--color-border-input); border-radius: var(--radius-button); background: #fff; font: inherit; cursor: pointer; }
/* Box-count info line, sits above the precision note in the details column. */
.c-modal__boxes { margin: calc(var(--space-3) * 0.75) 0 0; color: var(--color-text); }
    .c-modal__boxes small { color: var(--color-muted); }
.c-modal__total { text-align: right; margin: calc(var(--space-4) / 2) 0; font-size: var(--text-lg); }
    .c-modal__total small { color: var(--color-muted); font-size: var(--text-xs); }
.c-modal__ok { display: block; width: 100%; }

@media (max-width: 480px) {
    .c-modal__body { flex-direction: column; align-items: stretch; }
    .c-modal__thumb { width: 100%; flex-basis: auto; max-width: 12rem; aspect-ratio: 1 / 1; margin: 0 auto; }
    .c-modal__total { padding-left: 0; }
}

/* Sample-box tracker tray (Visual-Reference §3): fixed at the bottom, grows upward when expanded. */
.c-samplebox {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 80;
    background: var(--color-neutral-5);
    border-top: 1px solid var(--color-underline);
    box-shadow: 0 -2px 8px rgba(29, 37, 45, 0.06);
}
.c-samplebox__inner { display: flex; flex-direction: column; }
.c-samplebox__bar {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
    width: 100%; padding: var(--space-3) 0; background: none; border: 0; cursor: pointer;
    font: inherit; color: var(--color-text); text-align: left;
}
.c-samplebox__title { font-size: var(--text-lg); font-weight: 400; }   /* one tier below --title-sm; fluid via --type-scale. Only the count is bold. */
    .c-samplebox__title strong { font-weight: 700; }
/* Same CSS chevron as the accordions (consistent site-wide). Bottom bar: points up when collapsed
   (click to open upward), flips down when open. */
.c-samplebox__chevron { display: inline-flex; align-items: center; justify-content: center; width: 1em; height: 1em; }
    .c-samplebox__chevron::after {
        content: ""; width: 0.5em; height: 0.5em;
        border-right: 2px solid var(--color-muted); border-bottom: 2px solid var(--color-muted);
        transform: rotate(-135deg); transition: transform 0.2s ease;
    }
.c-samplebox.is-open .c-samplebox__chevron::after { transform: rotate(45deg); }

.c-samplebox__panel { padding-bottom: var(--space-4); max-height: 70vh; overflow-y: auto; }
.c-samplebox__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-3); }
.c-samplebox__hint { margin: 0; color: var(--color-muted); }
/* Same line, stated as a fact once the box is full. Not --color-error: nothing has gone wrong, the customer
   has simply reached the limit. --color-text so it reads as information rather than a failure. */
.c-samplebox__hint--full { color: var(--color-text); font-weight: 600; }

/* "Sample box is full" note in the cart drawer. The equivalent on the Get Sample buttons is the themed
   dialog (ConfirmService.Alert), not inline text — owner asked for a popup, 7 Aug 2026. */
.c-cartmenu__full {
    margin: var(--space-2) 0 0;
    font-size: var(--text-xs);
    line-height: 1.35;
    color: var(--color-text);
    background: var(--color-neutral-10);
    border-left: 3px solid var(--color-accent);
    border-radius: var(--radius-sm);
    padding: var(--space-2) var(--space-3);
}
.c-samplebox__clear { text-decoration: underline; cursor: pointer; color: var(--color-text); }
    .c-samplebox__clear:hover { color: var(--color-muted); }

/* Cap each slot at ~300px so the thumbnails don't balloon on wide screens (they shrink on narrow ones). */
.c-samplebox__slots { display: grid; grid-template-columns: repeat(4, minmax(0, 220px)); gap: var(--space-4); }
.c-samplebox__slot { text-align: center; }
.c-samplebox__thumb { position: relative; aspect-ratio: 1 / 1; border: 1px solid var(--color-underline); border-radius: var(--radius-sm); overflow: hidden; background: #fff; }
    .c-samplebox__thumb a { display: block; height: 100%; }
    .c-samplebox__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.c-samplebox__thumb--empty { display: flex; align-items: center; justify-content: center; color: var(--color-muted); border-style: dashed; }
.c-samplebox__remove { position: absolute; top: var(--space-1); right: var(--space-1); width: 1.6rem; height: 1.6rem; border-radius: 50%; border: 0; background: rgba(255, 255, 255, 0.85); color: var(--color-text); font-size: var(--text-base); line-height: 1; cursor: pointer; }
    .c-samplebox__remove:hover { background: #fff; }
.c-samplebox__label { margin-top: var(--space-2); font-size: var(--text-xs); }
.c-samplebox__sku { color: var(--color-muted); white-space: nowrap; }

.c-samplebox__foot { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-4); margin-top: var(--space-4); }
    .c-samplebox__foot .c-button { min-width: 18rem; }
.c-samplebox__total { font-size: var(--text-md); }
    .c-samplebox__total small { color: var(--color-muted); font-size: var(--text-xs); }

@media (max-width: 600px) {
    .c-samplebox__slots { grid-template-columns: repeat(2, 1fr); }
    .c-samplebox__foot { flex-direction: column; align-items: stretch; gap: var(--space-2); }
    .c-samplebox__foot .c-button { min-width: 0; width: 100%; }
}

/* Hamburger + CSS-only mobile nav drawer (desktop hidden by default) */
.c-hamburger { display: none; align-items: center; background: none; border: 0; cursor: pointer; color: var(--color-text); margin-right: var(--space-2); }
.c-nav-close,
.c-nav-backdrop { display: none; }

@media (max-width: 900px) {
    /* Mobile header layout: [logo+hamburger | icons] over a full-width search row.
       Restore the bottom padding (search is the last row here) so it isn't flush
       against the header edge — matches the top padding. */
    .c-header__top {
        grid-template-columns: 1fr auto;
        grid-template-areas: "left right" "search search";
        row-gap: var(--space-2);
        padding-bottom: var(--space-3);
    }
    .c-header__left { grid-area: left; display: flex; align-items: center; }
    .c-header__right { grid-area: right; }
    /* Override the desktop fixed band: full-width search row on mobile. */
    .c-header__center { grid-area: search; width: 100%; max-width: none; }
    .c-search { width: 100%; max-width: none; } /* full-width search row on mobile */

    .c-hamburger { display: inline-flex; }

    /* Nav becomes a slide-in drawer from the left. */
    .c-header__nav {
        position: fixed;
        inset: 0;            /* full-screen drawer */
        width: 100vw;
        background: var(--color-header-bg);
        box-shadow: var(--shadow-md);
        transform: translateX(-100%);
        transition: transform 0.25s ease;
        z-index: 110;
        overflow-y: auto;
        padding: var(--space-5) var(--space-3);
    }

    .c-nav-toggle:checked ~ .c-header__top .c-header__nav { transform: translateX(0); }

    .c-nav {
        flex-direction: column;
        align-items: stretch; /* items span the full drawer width */
        justify-content: flex-start; /* reset desktop space-between for the vertical drawer */
        gap: var(--space-3);
        padding: 0;
        max-width: none;
    }

    .c-nav__link { font-size: 1.1rem; }
    .c-megamenu { width: 100%; }

    /* Accordion: each item's panel is collapsed; tapping the item (a full-row label over the link)
       toggles its checkbox and reveals/hides that panel (tap again to collapse). */
    .c-megamenu__head { display: flex; position: relative; align-items: center; min-height: 2.5rem; }
    .c-mega-expander {
        display: flex; align-items: center; justify-content: flex-end;
        position: absolute; inset: 0; padding-right: var(--space-1); cursor: pointer; color: var(--color-text);
    }
    .c-mega-expander__icon { font-size: var(--text-lg); line-height: 1; transition: transform 0.15s ease; }
    .c-mega-radio:checked ~ .c-megamenu__head .c-mega-expander__icon { transform: rotate(90deg); }

    .c-megamenu__panel { display: none; }   /* collapsed by default */
    .c-mega-radio:checked ~ .c-megamenu__panel {
        display: block; position: static; opacity: 1; visibility: visible; transform: none;
        box-shadow: none; border-top: 0; padding: var(--space-2) 0 var(--space-3);
    }
    .c-megamenu__panel::before { content: none; }
    /* Small horizontal inset so the white panel shows around the grey item cards. */
    .c-megamenu__columns, .c-megamenu__hero { padding-left: var(--space-2); padding-right: var(--space-2); max-width: none; }
    .c-megamenu__columns { grid-template-columns: 1fr; gap: var(--space-2); }
    .c-megamenu__hero { grid-template-columns: 1fr; gap: var(--space-3); max-width: none; }

    /* Level 2: each category title is a tappable bar; its options (level 3) are collapsed until its
       radio is checked. Shared radio name = one category open at a time. */
    .c-megamenu__col-title {
        font-size: var(--text-sm); margin: 0; cursor: pointer;
        padding: var(--space-2) var(--space-3); background: var(--color-neutral-10);
        border-radius: var(--radius-sm); font-weight: 600;
    }
    .c-megamenu__cat-icon { display: inline; }
    .c-megamenu__col-title--close { display: none; }                 /* collapsed: show the "open" label */
    .c-megamenu__col-title--close .c-megamenu__cat-icon { transform: rotate(90deg); } /* ⌄ when open */
    .c-megamenu__list { display: none; }
    /* Open state: hide the open-label, show the collapse-label (taps to collapse), reveal the indented options. */
    .c-mega-cat:checked ~ .c-megamenu__col-title--open { display: none; }
    .c-mega-cat:checked ~ .c-megamenu__col-title--close { display: flex; }
    .c-mega-cat:checked ~ .c-megamenu__list { display: flex; margin-top: var(--space-2); padding-left: var(--space-3); }

    .c-nav-close {
        display: block;
        text-align: right;          /* × in the top-right of the full-screen drawer */
        margin-bottom: var(--space-3);
        padding: 0 var(--space-1);
        font-size: 1.75rem;
        line-height: 1;
        color: var(--color-text);
        cursor: pointer;
    }

    .c-nav-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 105;
        background: rgba(0, 0, 0, 0.4);
        opacity: 0;
        visibility: hidden;
        transition: opacity 0.2s ease, visibility 0.2s;
    }

    .c-nav-toggle:checked ~ .c-nav-backdrop { opacity: 1; visibility: visible; }
}

/* ===================== Auth (Phase 4) ===================== */
.c-auth { display: flex; justify-content: center; padding-block: var(--space-6); }

/* Auth card = the canonical form panel (same grey panel as the checkout form), centred and a container
   so the field grid pairs/collapses on its own width. */
.c-auth__card {
    width: 100%;
    max-width: 36rem;
    background: var(--color-neutral-5);
    border-radius: var(--radius-image);
    padding: var(--space-5);
    container-type: inline-size;
}

/* Wider variant for multi-field public forms (e.g. Contact Us) so the 2-col field grid breathes. */
.c-auth__card--wide { max-width: 48rem; }

/* Multi-line input (Contact Us message). Inherits .c-field__input borders/focus; just sizing. */
.c-field__textarea { min-height: 7.5rem; resize: vertical; line-height: 1.5; font-family: inherit; }

/* Admin — Site Maintenance (cache invalidation) */
.c-admin { padding-block: var(--space-5); }
.c-admin__title { margin: 0 0 var(--space-3); }
.c-admin__warn {
    margin: 0 0 var(--space-4);
    padding: var(--space-3) var(--space-4);
    background: var(--color-neutral-5);
    border-left: 3px solid var(--color-accent);
    border-radius: var(--radius-image);
    color: var(--color-muted);
    font-size: var(--text-sm);
}
.c-admin__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
    gap: var(--space-4);
}
.c-cachecard {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-4);
    background: var(--color-neutral-5);
    border-radius: var(--radius-image);
}
.c-cachecard__title { margin: 0; font-size: var(--text-md); }
.c-cachecard__desc { margin: 0; color: var(--color-muted); font-size: var(--text-xs); }
.c-cachecard__stats { display: flex; gap: var(--space-4); margin: var(--space-1) 0 var(--space-2); }
.c-cachecard__stats dt { color: var(--color-muted); font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: .04em; }
.c-cachecard__stats dd { margin: 0; font-size: var(--text-sm); }
.c-cachecard__btn { margin-top: auto; align-self: flex-start; }
.c-cachecard__toast { margin: var(--space-1) 0 0; color: var(--color-success); font-size: var(--text-xs); }

/* Intro line under the auth-card title (login / reset / sign-up) — lead/intro size.
   Bottom gap to the form is 150% of --space-4 (owner-tuned) so the title block breathes. */
.c-auth__intro { margin: 0 0 calc(var(--space-4) * 1.5); font-size: var(--text-md); color: var(--color-text); }

.c-auth__links {
    margin-top: var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    font-size: var(--text-base);
}

/* Auth content links (notice + footer links) read as links — body colour + rest-state underline (standard). */
/* Content links inside auth cards get the underlined body-text treatment — but NOT anchors that are buttons.
   `.c-auth a` is (0,1,1) and beats `.c-button--primary` at (0,1,0), so without the :not() a button inside an
   auth card renders dark-on-dark and underlined: invisible. That is what happened to "Go to log in" on the
   password-reset success screen (reported 6 Aug 2026). */
.c-auth a:not(.c-button), .c-loginform__notice a:not(.c-button) { color: var(--color-text); text-decoration: underline; }

/* Belt and braces: an anchor styled as a button is a BUTTON. Any future container rule that colours or
   underlines its links must not be able to reach inside one. Cheap, and this class of bug recurs. */
a.c-button { text-decoration: none; }
a.c-button--primary { color: var(--button-primary-text); }
a.c-button--secondary { color: var(--button-secondary-text); }
a.c-button--primary:hover { color: var(--button-primary-hover-text); }
a.c-button--secondary:hover { color: var(--button-secondary-hover-text); }
.c-auth a:hover, .c-loginform__notice a:hover { text-decoration: none; }

.c-loginform { display: flex; flex-direction: column; gap: var(--space-3); }
.c-loginform__error { margin: 0; color: var(--color-error); font-size: var(--text-sm); }
.c-loginform__notice { margin: 0; color: var(--color-text); font-size: var(--text-sm); }
.c-loginform__submit { margin-top: var(--space-2); }

/* Form fields use the ONE canonical .c-field* set (see "Forms (site-wide)" below). Only the checkbox-row
   modifier is auth-specific here — the old duplicate .c-field/.c-field__label/.c-field__input were removed
   so login/sign-up render identically to the checkout form. */
/* Compound selector so it beats the canonical .c-field (column) regardless of source order: checkbox + label
   on one left-aligned row. */
.c-field.c-field--check { flex-direction: row; align-items: center; justify-content: flex-start; gap: var(--space-2); }

/* ===================== ComponentZone engine (Phase 5) ===================== */
.c-zone { margin-bottom: var(--space-6); }

/* Zone content is contained + centred by default. container-type makes the zone the "control"
   for zone-level fluid text (cqi units scale with the zone's own width). */
.c-zone__inner {
    width: 100%;
    max-width: var(--content-max-width);
    margin-inline: auto;
    padding-inline: var(--space-4);
    container-type: inline-size;
}

/* IsFullWidth zones (e.g. a banner ImageSlider) span the full page width — no max-width, no gutters. */
.c-zone__inner--full { max-width: none; padding-inline: 0; }
    .c-zone__inner--full .c-slider__slide { background: var(--color-neutral-5); } /* skeleton while loading */
    .c-zone__inner--full .c-slider__img {
        border-radius: 0;                       /* square corners for a full-bleed banner */
        aspect-ratio: var(--banner-ratio, 12 / 5); /* reserve the banner box up front (≈ the 1280×500 art) */
        object-fit: cover;
    }

.c-zone-header { margin-bottom: var(--space-4); }
/* Title + (optional) link sit above the underline; subtitle below it (matches the original). */
.c-zone-header__top {
    margin-bottom: var(--space-2);
    padding-bottom: var(--space-2);
    border-bottom: 1px solid var(--color-underline);
}
.c-zone-header__title {
    margin: 0;
    /* Fluid: scales with the zone width (cqi), caps at the h2 size (--text-2xl 2.4rem). Higher floor
       (2rem) + steeper curve so the section title doesn't shrink below the card overlay headings. */
    font-size: clamp(2rem, 4cqi, 2.4rem);
}
/* Link directly under the title, with a chevron; same size as the subtitle/header text. */
.c-zone-header__link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    margin-top: var(--space-1);
    font-size: clamp(1rem, 1.73cqi, 1.3rem);
    color: var(--color-accent);
    transition: transform 0.15s ease;
}
    /* Hover: nudge right instead of underlining. */
    .c-zone-header__link:hover { transform: translateX(var(--space-1)); text-decoration: none; }
    .c-zone-header__chevron { width: 0.8em; height: 0.8em; flex: none; }
/* Subtitle: body-text colour, fluid (caps at --text-md 1.3rem) like the original c_headline-text2. */
.c-zone-header__text { color: var(--color-text); font-size: clamp(1rem, 1.73cqi, 1.3rem); }

/* Text/Image template */
.c-textimage__row { margin-bottom: var(--space-5); }

.c-textimage__row--split {
    display: grid;
    /* Ratio from the CMS Layout column (--ti-cols, e.g. "2fr 1fr"); the image side is placed by
       ImagePositionIndex via the --second order swap. */
    grid-template-columns: var(--ti-cols, 1fr 1fr);
    gap: var(--space-5);
    align-items: center;
}

.c-textimage__media--second { order: 2; }
.c-textimage__media img { width: 100%; height: auto; border-radius: var(--radius-image); }
/* Body fluid too (was fixed 1rem): scales with the zone width (cqi), floor 0.82rem; the heading
   keeps its own size below. */
.c-textimage__text { font-size: clamp(0.82rem, 1.8cqi, 1rem); }
/* Heading fluid: scales with the zone width (cqi), caps at the h3 size (--text-xl 1.8rem). */
.c-textimage__text h3 { font-size: clamp(1.2rem, 2.4cqi, 1.8rem); }

/* Stack on smaller screens (the original splits only at the lg breakpoint). */
@media (max-width: 991px) {
    .c-textimage__row--split { grid-template-columns: 1fr; }
    .c-textimage__media--second { order: 0; }
}

/* Zone card (shared by grid / scroll / carousel templates). container-type makes the card the
   "control" for card-level fluid text (overlay + card title/text scale with the card's own width). */
.c-zone-card { display: flex; flex-direction: column; gap: var(--space-2); position: relative; container-type: inline-size; }
/* Media box reserves its space up front (aspect-ratio from --card-ratio, keyed to column count),
   with a neutral skeleton while the image loads — prevents the card collapsing and the overlay
   text/buttons overlapping on slow networks (Option B, owner 2026-06-18). */
.c-zone-card__media {
    display: block;
    aspect-ratio: var(--card-ratio, 3 / 2);
    overflow: hidden;
    background: var(--color-neutral-5);
    border-radius: var(--radius-image);
}
    .c-zone-card__media picture { display: block; width: 100%; height: 100%; }
.c-zone-card__img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* Card title/text fluid: scale with the card width (cqi), caps at current sizes. */
.c-zone-card__title { font-family: var(--font-display); font-size: clamp(1rem, 4.3cqi, 1.3rem); }
.c-zone-card__text { font-size: clamp(0.85rem, 3.3cqi, 1rem); }

/* CMS page-scope wrapper (ShellPage) — layout-neutral; a per-page hook for page-specific overrides. */
.c-cmspage { display: contents; }

/* SCC Downloads page (/topics/downloads): the flyer/image card grids already want 5 small square cards
   (--zone-cols 1fr×5, --card-ratio 1/1), but the shared `.c-grid--reduce` collapses them to 2-up below
   1200px. Keep them as small, ShopTiles-style cards at all widths (owner). The 3-class selector out-specifies
   the reduce media rules so it wins regardless of viewport. Does NOT touch the intro/info-sheet single-row grids. */
.c-cmspage--topics-downloads .c-grid--reduce.c-grid--fixed {
    grid-template-columns: repeat(5, minmax(0, 1fr)); /* max 5, same as the ShopTiles product grid */
    gap: var(--space-4) var(--space-3);
}
/* Same responsive step-down as ShopTiles (.c-product-grid): 5 → 4 → 3 → 2 → 1. 3-class specificity beats
   the shared .c-grid--reduce media rules at every breakpoint. */
@media (max-width: 1700px) { .c-cmspage--topics-downloads .c-grid--reduce.c-grid--fixed { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (max-width: 1400px) { .c-cmspage--topics-downloads .c-grid--reduce.c-grid--fixed { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 1024px) { .c-cmspage--topics-downloads .c-grid--reduce.c-grid--fixed { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* A single column is fine on small screens (owner). */
@media (max-width: 600px) { .c-cmspage--topics-downloads .c-grid--reduce.c-grid--fixed { grid-template-columns: 1fr; } }
/* Show the flyer/product images in their NATURAL proportions — no forced square, no cover-crop/stretch (owner). */
.c-cmspage--topics-downloads .c-zone-card__media { aspect-ratio: auto; background: none; }
.c-cmspage--topics-downloads .c-zone-card__img { height: auto; object-fit: contain; }

/* Information Sheets: render the single-row--cols zones as a simple vertical list (range heading + PDF link)
   rather than a horizontal card scroll (owner: match the picture). The intro is a single full-width item, so
   stacking it as one block leaves it unchanged. */
.c-cmspage--topics-downloads .c-grid--single-row--cols { display: block; overflow: visible; }
.c-cmspage--topics-downloads .c-grid--single-row--cols > .c-zone-card { width: auto; margin-bottom: var(--space-3); }
/* Each range entry is a <p> row inside the card's HTML — give them a gap, dark range name, accent PDF link. */
.c-cmspage--topics-downloads .c-zone-card__text p { margin: 0 0 var(--space-4); color: var(--color-text); }
.c-cmspage--topics-downloads .c-zone-card__text a { color: var(--color-accent); text-decoration: underline; }
    .c-cmspage--topics-downloads .c-zone-card__text a:hover { text-decoration: none; }

/* ---- Card overlay (CMS image+text overlay). Class names on OverlayPositionCSS / OverlayButton*Style
   / OverlayButtonInlineAlignCSS are CMS-authored — these rules honour them, mapped to our tokens.
   See Implementation-Log "Card overlays". ---- */
.c-overlay {
    display: flex;
    padding: var(--space-3);
    pointer-events: none; /* clicks pass through the empty frame, not the content */
}
/* Layered over an image → fill it; standalone (no image) → normal flow, no frame padding. */
.c-zone-card--has-image .c-overlay { position: absolute; inset: 0; }
.c-zone-card--has-overlay:not(.c-zone-card--has-image) .c-overlay { padding: 0; }

.c-overlay__content {
    pointer-events: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-2);
    /* Card-relative box: width + padding scale with the card (same reference as the cqi font), so the
       box and the text stay in proportion and the heading no longer wraps unpredictably. */
    width: 100%;
    max-width: 40rem; /* cap the text block on wide/full-bleed slides; cards are narrower so unaffected */
    padding: clamp(0.4rem, 3cqi, 1rem);
    min-width: 0;
    box-sizing: border-box;
    overflow-wrap: break-word;
}
/* Full-width so the CMS text-align (on the heading/text) governs alignment — matching the buttons
   (which span full width and use the CMS OverlayButtonInlineAlignCSS). Without this, align-items:center
   shrink-centres the text while left-aligned buttons sit at the edge → they diverge. */
.c-overlay__heading { margin: 0; width: 100%; text-wrap: balance; }
.c-overlay__text { margin: 0; width: 100%; text-wrap: balance; }
    .c-overlay__text > * { margin: 0; }
/* Banner/slider overlay keeps its CMS box width (the 40rem card cap must not clamp it). */
.c-overlay--banner .c-overlay__content { max-width: none; }
.c-overlay__line { display: block; height: 3px; width: 100%; }
.c-overlay__buttons { display: flex; flex-wrap: wrap; gap: var(--space-2); width: 100%; margin-top: var(--space-1); }

/* Button-row alignment utilities (CMS class names on OverlayButtonInlineAlignCSS). */
.justify-content-center { justify-content: center; }
.justify-content-start  { justify-content: flex-start; }
.justify-content-end    { justify-content: flex-end; }

/* Overlay buttons — ported CMS class names mapped to our brand button tokens. */
.c-overlay__btn {
    display: inline-block;
    /* Fluid padding (cqi) so buttons get smaller on narrow cards. */
    padding: clamp(0.35rem, 1.5cqi, 0.5rem) clamp(0.75rem, 4cqi, 1.5rem);
    border-radius: var(--radius-button);
    text-decoration: none;
    /* Start ~1.15× larger (0.92rem) on wide containers, scaling down to the 0.82rem min (owner 2026-06-18).
       Buttons that carry a DB font-size override this via the inline style from CardOverlay. */
    font-size: clamp(0.82rem, 2.5cqi, 0.92rem);
    cursor: pointer;
    transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.c_standard-tall-dark-background {
    background-color: var(--button-primary-bg);
    color: var(--button-primary-text);
    border: 1px solid var(--button-primary-border);
}
    .c_standard-tall-dark-background:hover {
        background-color: var(--button-primary-hover-bg);
        color: var(--button-primary-hover-text);
        border-color: var(--button-primary-hover-border);
        text-decoration: none;
    }
.c_standard-tall-light-background {
    background-color: var(--button-secondary-bg);
    color: var(--button-secondary-text);
    border: 1px solid var(--button-secondary-border);
}
    .c_standard-tall-light-background:hover {
        background-color: var(--button-secondary-hover-bg);
        color: var(--button-secondary-hover-text);
        border-color: var(--button-secondary-hover-border);
        text-decoration: none;
    }

/* CMS button base — HTML bodies use `c_standard-button` + a `c_standard-tall-{dark,light}-background`
   colour class (the colours are defined above). Matches the text-overlay button look, with fixed sizing
   since it's used outside container-query zones (e.g. the mega-menu hero). */
.c_standard-button {
    display: inline-block;
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-button);
    font-family: inherit;
    font-size: var(--text-sm);
    line-height: 1.2;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

/* CMS body-text class used inside OverlayHtmlText. */
.c_standard-text1 { margin: 0; color: var(--color-text); font-size: inherit; } /* inherit overlay's fluid size */
    .c_standard-text1 p { margin: 0; }

/* CMS-authored Html (product name/price etc.) uses a handful of Bootstrap utility classes. The new
   site doesn't ship Bootstrap, so shim only the ones the database actually emits — don't expand into a
   full utility set. (Product price comes through as <span class="fw-bold">…</span>.) */
.fw-bold { font-weight: 700; }
.mt-1 { margin-top: var(--space-1); }
.my-4 { margin-top: var(--space-4); margin-bottom: var(--space-4); }
.m-0 { margin: 0; }
.my-0 { margin-top: 0; margin-bottom: 0; }
.mx-auto { margin-left: auto; margin-right: auto; }
.px-1 { padding-left: var(--space-1); padding-right: var(--space-1); }
.text-start { text-align: left; }
/* CMS "subtext" brand class (e.g. the " per sqm" suffix) — slightly muted. */
.c_standard-subtext2 { color: var(--color-muted); }

/* 9 overlay positions (CMS class names; align-items = vertical, justify-content = horizontal). */
.c_component-image-overlay-pos-tl, .c_component-text-overlay-pos-tl { align-items: flex-start; justify-content: flex-start; }
.c_component-image-overlay-pos-tc, .c_component-text-overlay-pos-tc { align-items: flex-start; justify-content: center; }
.c_component-image-overlay-pos-tr, .c_component-text-overlay-pos-tr { align-items: flex-start; justify-content: flex-end; }
.c_component-image-overlay-pos-ml, .c_component-text-overlay-pos-ml { align-items: center; justify-content: flex-start; }
.c_component-image-overlay-pos-mc, .c_component-text-overlay-pos-mc { align-items: center; justify-content: center; }
.c_component-image-overlay-pos-mr, .c_component-text-overlay-pos-mr { align-items: center; justify-content: flex-end; }
.c_component-image-overlay-pos-bl, .c_component-text-overlay-pos-bl { align-items: flex-end; justify-content: flex-start; }
.c_component-image-overlay-pos-bc, .c_component-text-overlay-pos-bc { align-items: flex-end; justify-content: center; }
.c_component-image-overlay-pos-br, .c_component-text-overlay-pos-br { align-items: flex-end; justify-content: flex-end; }

/* Grid gallery + single row */
.c-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
    gap: var(--space-4);
}

/* GridGallery honours the CMS Layout column count via --zone-cols (e.g. "1fr 1fr" for "1/2-1/2"). */
.c-grid--fixed { grid-template-columns: var(--zone-cols, 1fr); }

.c-grid--single-row { display: flex; gap: var(--space-4); overflow-x: auto; }
.c-grid--single-row > .c-zone-card { flex: 0 0 auto; width: min(280px, 80%); }
/* GridSingleRow honours the CMS column count: cards sized to 1/N of one row. */
.c-grid--single-row--cols > .c-zone-card {
    width: calc((100% - (var(--cols, 1) - 1) * var(--space-4)) / var(--cols, 1));
}

/* Horizontal scroll row + carousel (CSS scroll-snap) */
.c-scroll-row { display: flex; gap: var(--space-4); overflow-x: auto; padding-bottom: var(--space-2); }
.c-scroll-row--snap { scroll-snap-type: x mandatory; }
.c-scroll-row__item { flex: 0 0 auto; width: min(280px, 80%); }
.c-scroll-row--snap .c-scroll-row__item { scroll-snap-align: start; }

/* CarouselScroll / GridScrollBar: show N cards (from the CMS Layout) across the full component
   width; extra cards scroll. N comes from --cols on the row. */
.c-scroll-row--cols .c-scroll-row__item {
    width: calc((100% - (var(--cols, 1) - 1) * var(--space-4)) / var(--cols, 1));
}

/* Responsive column reduction: multi-column grids (≥3) drop to 2 below 1200px (owner request
   2026-06-18 — 3-up cards get cramped under ~1200px); scroll rows show ~2; everything drops to
   1 / a peek below 768px. */
@media (max-width: 1200px) {
    .c-grid--reduce.c-grid--fixed { grid-template-columns: 1fr 1fr; }
    /* Clamp to the real column count with min(--cols, 2): a 1-col zone stays 1 col (never a blank slot). */
    .c-grid--single-row--cols > .c-zone-card,
    .c-scroll-row--cols .c-scroll-row__item {
        width: calc((100% - (min(var(--cols, 1), 2) - 1) * var(--space-4)) / min(var(--cols, 1), 2));
    }
}
/* Drop to a single column earlier (owner request 2026-06-18): 768px, not 576px — two cards get
   cramped below ~770px. GridGallery / GridSingleRow / carousel all switch together here. */
@media (max-width: 768px) {
    /* Both selectors so this beats the ≤1200px `.c-grid--reduce.c-grid--fixed` rule (equal specificity, later). */
    .c-grid--fixed,
    .c-grid--reduce.c-grid--fixed { grid-template-columns: 1fr; }
    /* Full width (1 col) — a 1-item single row stays full width, no blank peek. */
    .c-grid--single-row--cols > .c-zone-card,
    .c-scroll-row--cols .c-scroll-row__item { width: 100%; }
    /* GridSingleRow: stack into a single column like GridGallery (owner) — the flex row must switch to a
       vertical stack, otherwise the 100%-wide cards sit side by side and force a horizontal scrollbar. */
    .c-grid--single-row--cols { flex-direction: column; overflow-x: visible; }
}

/* Product card (Product* templates; ported from the original c2_product-card): square image that
   cross-fades to a rollover shot, favourite heart, then name/price with the actions ALWAYS below.
   NOTE: intentionally NOT a container — the name/price text scales against the zone (cqi), same as the
   TextImage/overlay text, so product text matches the rest of the page rather than the (narrow) card. */
.c-product-card { display: flex; flex-direction: column; gap: var(--space-2); height: 100%; position: relative; }
/* Square media so cards are uniform height (matches the original product grid) and the carousel arrows
   line up across the row. */
.c-product-card__media { display: block; position: relative; overflow: hidden; border-radius: var(--radius-image); aspect-ratio: 1 / 1; }
.c-product-card__imglink { display: block; position: absolute; inset: 0; }
/* Main + rollover stack on top of each other and fill the square; we cross-fade opacity. */
.c-product-card__img { display: block; width: 100%; height: 100%; object-fit: cover; }
.c-product-card__img--main,
.c-product-card__img--rollover { position: absolute; inset: 0; transition: opacity 0.3s ease; }
.c-product-card__img--main { opacity: 1; z-index: 1; }
.c-product-card__img--rollover { opacity: 0; z-index: 2; }
/* Desktop: hovering a card with a rollover cross-fades to it. */
@media (hover: hover) and (pointer: fine) {
    .c-product-card__media.has-rollover:hover .c-product-card__img--main { opacity: 0; }
    .c-product-card__media.has-rollover:hover .c-product-card__img--rollover { opacity: 1; }
}
/* Touch: product-card.js toggles .show-rollover on first tap (second tap navigates). */
.c-product-card__media.has-rollover.show-rollover .c-product-card__img--main { opacity: 0; }
.c-product-card__media.has-rollover.show-rollover .c-product-card__img--rollover { opacity: 1; }
.c-product-card__fav {
    position: absolute;
    top: var(--space-2);
    right: var(--space-2);
    z-index: 3;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.85);
    color: var(--color-text);
    cursor: pointer;
}
    .c-product-card__fav svg { width: 1.1rem; height: 1.1rem; fill: none; stroke: currentColor; stroke-width: 1.2; }
    /* Favourited: filled green heart (swaps from the outline). */
    .c-product-card__fav.is-fav { color: var(--color-fav); }
    .c-product-card__fav.is-fav svg { fill: var(--color-fav); stroke: var(--color-fav); }
.c-product-card__info { display: flex; flex: 1 1 auto; flex-direction: column; gap: var(--space-2); }
/* Name/price (CMS Html uses c_standard-text1) — SAME fluid scale as the template/overlay body text
   (clamp(0.82rem, 1.8cqi, 1rem) against the zone), so product text matches the rest of the page. */
.c-product-card__name { display: block; color: var(--color-text); text-decoration: none; }
    .c-product-card__name:hover { text-decoration: none; }
    .c-product-card__name .c_standard-text1 { font-size: clamp(0.82rem, 1.8cqi, 1rem); }
/* Actions: always shown beneath the text. The wrap is a container so the buttons stack based on the
   CARD's width (not the page columns) — they go side by side while both fit, and stack to one-per-row
   once the card is too narrow (which is when "ADD TO CART" would otherwise wrap to two lines). */
.c-product-card__actions-wrap { container-type: inline-size; margin-top: auto; }
.c-product-card__actions { display: flex; gap: var(--space-2); }
    /* Marginally smaller label so the buttons don't stand out (owner request 2026-06-19) — dropped to
       the 0.82rem site floor, not below. Button box size unchanged. Applies to shop grid + carousel. */
    .c-product-card__actions .c-button { flex: 1; padding-inline: var(--space-2); white-space: nowrap; font-size: var(--text-xs); }
@container (max-width: 260px) {
    .c-product-card__actions { flex-direction: column; }
}

/* Infinite arrow carousel (CarouselScroll). JS clips/loops; CSS sizes the cards and arrows. */
.c-carousel { position: relative; display: flex; align-items: center; gap: var(--space-2); }
.c-carousel__viewport { overflow: hidden; flex: 1 1 auto; min-width: 0; }

/* Product carousel variant: cards span the full section (first at x=0, last at the section edge) with
   the arrows overlaid on the edge images instead of taking space beside them. */
.c-carousel--over { display: block; }
    .c-carousel--over .c-carousel__viewport { width: 100%; }
    .c-carousel--over .c-carousel__arrow {
        position: absolute;
        /* carousel.js sets --arrow-y to half the card image height so the arrow centres on the image
           (which sits above the name/price/buttons); 42% is the pre-JS fallback. */
        top: var(--arrow-y, 42%);
        transform: translateY(-50%);
        z-index: 3;
    }
    .c-carousel--over .c-carousel__arrow--prev { left: 0; }
    .c-carousel--over .c-carousel__arrow--next { right: 0; }
.c-carousel--static .c-carousel__viewport { overflow: visible; }
/* Real gap between cards (not item padding) so the first card sits flush at x=0 and the last flush
   at the right edge; item width accounts for the gaps. JS measures the true item-to-item step. */
.c-carousel__track { display: flex; align-items: stretch; gap: var(--space-4); }
.c-carousel__item {
    flex: 0 0 calc((100% - (var(--cols, 1) - 1) * var(--space-4)) / var(--cols, 1));
    max-width: calc((100% - (var(--cols, 1) - 1) * var(--space-4)) / var(--cols, 1));
    box-sizing: border-box;
}
.c-carousel__arrow {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Thin rectangle (owner request): ~26px wide, ~40px tall, ~60% transparent so the image shows through. */
    width: 1.625rem;
    height: 2.5rem;
    padding: 0;
    /* Lighter border — same light rule colour as the zone header underline. */
    border: 1px solid var(--color-underline);
    background: rgba(255, 255, 255, 0.4);
    color: var(--color-text);
    border-radius: var(--radius-button);
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}
    .c-carousel__arrow:hover { background: rgba(255, 255, 255, 0.7); }
    .c-carousel__arrow[hidden] { display: none; }
    .c-carousel__arrow svg { width: 1.1rem; height: 1.1rem; }

/* Image slider (CSS scroll-snap, full-width slides) */
/* overflow-y:hidden stops a stray vertical scrollbar (overflow-x:auto would otherwise compute
   overflow-y to auto) and the focus ring that a scrollable slider would take. */
.c-slider { display: flex; gap: var(--space-3); overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; }
/* Hide the native horizontal scrollbar — navigation is the dots below (owner). Scroll/swipe still works. */
.c-slider { scrollbar-width: none; -ms-overflow-style: none; }
    .c-slider::-webkit-scrollbar { display: none; height: 0; }

/* Slide pagination dots (rendered when >1 slide; wired by slider.js). */
.c-slider__dots { display: flex; justify-content: center; gap: var(--space-2); margin-top: var(--space-3); }
.c-slider__dot {
    width: 10px; height: 10px; padding: 0; border-radius: 50%;
    /* Same colour as the template header title (--color-title, brand-swappable): hollow when inactive,
       filled for the current slide. */
    border: 1px solid var(--color-title); background: transparent; cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}
    .c-slider__dot.is-active { background: var(--color-title); border-color: var(--color-title); }
/* position:relative + container so the overlay can sit over the slide and its text scales with the
   slide width (cqi); skeleton bg holds the box while the image loads. */
.c-slider__slide {
    flex: 0 0 100%;
    scroll-snap-align: start;
    position: relative;
    container-type: inline-size;
    background: var(--color-neutral-5);
}
    .c-slider__slide .c-overlay { position: absolute; inset: 0; }
/* Fit by width only — keep the image's natural aspect ratio, no stretch/crop (owner 2026-06-18).
   (The full-width banner below keeps a fixed hero ratio.) */
.c-slider__img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--radius-image);
}

/* Mobile (≤768px, the image-swap point): the overlay can't fit over the small image, so it drops
   BELOW the image — image, then text/buttons in normal flow, left-aligned (owner 2026-06-18). */
@media (max-width: 768px) {
    .c-slider__slide { display: flex; flex-direction: column; }
    /* Show the mobile image at its natural ratio (no wide-banner crop). */
    .c-slider__img,
    .c-zone__inner--full .c-slider__img { aspect-ratio: auto; height: auto; }
    .c-slider__slide .c-overlay { position: static; inset: auto; padding: var(--space-3) 0; }
    /* Full-bleed banner: add a page gutter so the below-image text isn't flush to the screen edge. */
    .c-zone__inner--full .c-slider__slide .c-overlay { padding-inline: var(--space-4); }
    .c-slider__slide .c-overlay__content {
        width: 100% !important;       /* override the CMS box width (its 27rem min would overflow a phone) */
        max-width: 100% !important;
        padding: 0 !important;        /* ignore the CMS top/left padding when stacked below the image */
        align-items: flex-start;
        text-align: left;
    }
    .c-slider__slide .c-overlay__buttons { justify-content: flex-start; }
}

/* Accordion (native <details>) */
.c-accordion { display: flex; flex-direction: column; gap: var(--space-2); }
.c-accordion__item { border-bottom: 1px solid var(--color-underline); }
/* Fluid like the other templates (scale with the zone width; floors ≥ 0.82rem). */
.c-accordion__summary { cursor: pointer; padding: var(--space-3) 0; font-family: var(--font-display); list-style: none; font-size: clamp(1rem, 2cqi, 1.3rem); display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
    .c-accordion__summary::-webkit-details-marker { display: none; }
.c-accordion__body { padding-bottom: var(--space-3); font-size: clamp(0.82rem, 1.8cqi, 1rem); }
.c-accordion__img { display: block; width: 100%; height: auto; border-radius: var(--radius-image); margin-bottom: var(--space-2); }

/* Static thank-you panels (submitted pages) */
/* Status / message pages (thank-you, email verification, not-found, errors): one friendly centred card. */
.c-status { max-width: 52rem; margin: var(--space-6) auto; background: var(--color-neutral-5); border-radius: var(--radius-image); padding: var(--space-6) var(--space-5); text-align: center; display: flex; flex-direction: column; align-items: center; gap: var(--space-4); }
.c-status__title { margin: 0; }
/* Darker than --color-muted, still lighter than the title (owner) — uses the existing neutral-80 ramp step. */
.c-status__text { margin: 0; color: var(--color-neutral-80); max-width: 38rem; }
.c-status__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); justify-content: center; }

/* ===================== Account area (Phase 8) — shared shell (AccountShell.razor) ===================== */
/* Desktop: a sticky left sub-nav + content (two columns). Mobile: the nav is a CSS-only off-canvas drawer
   (same pattern as the Shop-Tiles filter drawer) — the "My Account" button toggles it. /account/* is gated. */
.c-account { display: grid; grid-template-columns: 15rem 1fr; gap: var(--space-5); padding-block: var(--space-6); align-items: start; }
/* Lighter than the form/cart cards — a hairline-bordered nav, not a filled grey panel (owner: it's a menu). */
.c-account__nav { position: sticky; top: var(--space-4); align-self: start; max-height: calc(100vh - var(--space-5)); overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-3); background: transparent; border: 1px solid var(--color-underline); border-radius: var(--radius-image); padding: var(--space-3) var(--space-4); }
.c-account__nav-head { display: flex; align-items: center; justify-content: space-between; }
.c-account__heading { margin: 0; font-size: var(--title-sm); }
.c-account__user { margin: 0; font-size: var(--text-sm); color: var(--color-muted); word-break: break-word; }
.c-account__links { display: flex; flex-direction: column; }
.c-account__link { color: var(--color-text); text-decoration: none; padding: var(--space-2) 0; border-bottom: 1px solid var(--color-underline); }
.c-account__link:hover { text-decoration: underline; }
.c-account__link.is-active { font-weight: 600; }
.c-account__logout { width: 100%; margin-top: var(--space-2); }
.c-account__main { min-width: 0; }
.c-account__panel { background: var(--color-neutral-5); border-radius: var(--radius-image); padding: var(--space-5); container-type: inline-size; max-width: 36rem; }
.c-account__panel--wide { max-width: 48rem; }   /* My Details — wider, two-column field grid */
/* Extra breathing room before each form section title (Shipping / Billing) in the account panel. */
.c-account__panel .c-form__title { margin-top: var(--space-4); }
.c-account__notice { margin: 0 0 var(--space-3); font-size: var(--text-sm); }
/* Reads as a status banner, not a caption. It was a bare line of muted text and looked like form furniture —
   easy to miss entirely. The colour stays --color-success (owner-ruled, success messaging only); the band and
   left rule are what make it register. */
.c-account__notice--ok {
    color: var(--color-success);
    font-weight: 600;
    background: var(--color-neutral-10);
    border-left: 3px solid var(--color-success);
    border-radius: var(--radius-sm);
    padding: var(--space-2) var(--space-3);
}

/* Save + Cancel row. Wraps on narrow screens rather than squashing the buttons. */
.c-account__actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-4);
}
/* The inline confirmation beside the buttons — where the eye already is after clicking Save. */
.c-account__saved {
    color: var(--color-success);
    font-weight: 600;
    font-size: var(--text-sm);
}
/* Drawer chrome is desktop-hidden (the checkbox stays functional but invisible). */
.c-account__toggle { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.c-account__menu-btn, .c-account__backdrop, .c-account__nav-close { display: none; }

/* My Orders — order list with CSS-only expandable line items. */
.c-orders__list { list-style: none; margin: var(--space-5) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.c-orders__pager { display: flex; align-items: center; justify-content: center; gap: var(--space-4); margin-top: var(--space-5); }
.c-orders__pageinfo { color: var(--color-muted); font-size: var(--text-sm); }
.c-orders__pagelink { color: var(--color-text); text-decoration: underline; font-size: var(--text-sm); }
.c-orders__pagelink:hover { color: var(--color-title); }
.c-order { background: var(--color-neutral-5); border-radius: var(--radius-image); }
.c-order__toggle { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.c-order__head { display: flex; align-items: center; gap: var(--space-3) var(--space-4); padding: var(--space-3) var(--space-4); cursor: pointer; flex-wrap: wrap; }
.c-order__cell { font-size: var(--text-sm); }
.c-order__id { font-weight: 600; margin-right: auto; }
.c-order__k { color: var(--color-muted); margin-right: var(--space-1); font-size: var(--text-xs); }
.c-order__chevron { width: 0.55rem; height: 0.55rem; border-right: 2px solid var(--color-text); border-bottom: 2px solid var(--color-text); transform: rotate(45deg); transition: transform 0.2s ease; flex: none; }
.c-order__toggle:checked ~ .c-order__head .c-order__chevron { transform: rotate(-135deg); }
.c-order__body { display: none; padding: 0 var(--space-4) var(--space-4); }
.c-order__toggle:checked ~ .c-order__body { display: block; }
.c-order__meta { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); font-size: var(--text-sm); padding-block: var(--space-3); border-top: 1px solid var(--color-underline); }
.c-order__lines { display: flex; flex-direction: column; }
.c-order__line { display: grid; grid-template-columns: 4.75rem 1fr auto auto auto; gap: var(--space-3) var(--space-4); align-items: start; padding: var(--space-3) 0; border-top: 1px solid var(--color-underline); }
.c-order__img { width: 4.75rem; height: 4.75rem; object-fit: cover; border-radius: var(--radius-sm); }
.c-order__prod { min-width: 0; }
.c-order__name { font-weight: 600; display: block; }
.c-order__sub { color: var(--color-muted); font-size: var(--text-sm); display: block; }
.c-order__sku { color: var(--color-muted); font-size: var(--text-xs); display: block; }
.c-order__num { font-size: var(--text-sm); white-space: nowrap; text-align: right; }
/* In line-item cells the label sits on its own line above the value (the accordion header keeps it inline). */
.c-order__num .c-order__k { display: block; margin-right: 0; }
.c-order__qline { display: block; }
.c-order__qtysub { display: block; color: var(--color-muted); font-size: var(--text-xs); }
.c-order__empty { color: var(--color-muted); }
@media (max-width: 640px) {
    .c-order__line { grid-template-columns: 4.75rem 1fr; gap: var(--space-1) var(--space-3); }
    .c-order__num { grid-column: 2; text-align: left; }
}

@media (max-width: 900px) {
    .c-account { grid-template-columns: 1fr; }
    /* Menu is collapsed to the drawer — centre the form panel in the freed-up width. */
    .c-account__panel { margin-inline: auto; }
    .c-account__menu-btn {
        display: inline-flex; align-items: center; gap: var(--space-2);
        position: sticky; top: var(--space-2); z-index: 30; align-self: start; width: fit-content;
        padding: var(--space-2) var(--space-3);
        border: 1px solid var(--color-border-button); border-radius: var(--radius-button);
        background: #fff; color: var(--color-text); cursor: pointer; font: inherit;
    }
    .c-account__nav {
        position: fixed; inset: 0 auto 0 0; z-index: 60;
        width: min(18rem, 85vw); height: 100%; max-height: none;
        margin: 0; border: 0; border-radius: 0;
        /* Off-canvas drawer needs a solid fill so page content doesn't show through. */
        background: #fff; box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
        transform: translateX(-100%); transition: transform 0.25s ease;
    }
    .c-account__toggle:checked ~ .c-account__nav { transform: translateX(0); }
    .c-account__nav-close { display: inline-flex; cursor: pointer; font-size: 1.6rem; line-height: 1; padding: 0 var(--space-1); }
    .c-account__backdrop {
        display: block; position: fixed; inset: 0; z-index: 55;
        background: rgba(0, 0, 0, 0.4); opacity: 0; visibility: hidden; transition: opacity 0.25s ease;
    }
    .c-account__toggle:checked ~ .c-account__backdrop { opacity: 1; visibility: visible; }
}

/* ===================== ProductDetail (PDP) ===================== */
/* Top gutter only — the bottom is kept tight so the footer follows the panes immediately once both
   have scrolled to the end (a tall bottom pad would leave a dead zone below the pinned panes). */
.c-pdp { padding-block: var(--space-4) var(--space-2); }
.c-pdp__crumbs { display: flex; flex-wrap: wrap; gap: var(--space-1); align-items: center; font-size: var(--text-sm); color: var(--color-muted); margin-bottom: var(--space-4); }
    .c-pdp__crumbs a { color: var(--color-text); text-decoration: none; }
    .c-pdp__crumbs a:hover { text-decoration: underline; }
.c-pdp__crumbs-current { color: var(--color-muted); }

/* Two coordinated full-height panes pinned to the viewport: both scroll internally, and pdp-scroll.js
   drives them from one wheel delta (both together → the longer one alone → the page/footer). Their
   scrollbars are hidden; the JS owns the scrolling. */
.c-pdp__main { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: var(--space-5); align-items: stretch; position: sticky; top: 0; height: 100vh; }

/* Left: scrolling gallery — desktop shows a 2-up grid of product + room shots (the gallery is the
   vertical scroller; the grid lives on .c-pdp__shots). The arrows + thumbnail strip are mobile-only. */
.c-pdp__gallery { position: relative; height: 100%; min-height: 0; overflow-y: auto; padding: var(--space-1) var(--space-1) var(--space-5); scrollbar-width: none; -ms-overflow-style: none; }
    .c-pdp__gallery::-webkit-scrollbar { width: 0; height: 0; }
.c-pdp__shots { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); align-content: start; }
.c-pdp__shot { position: relative; margin: 0; border-radius: var(--radius-image); overflow: hidden; background: var(--color-neutral-5); aspect-ratio: 1 / 1; cursor: zoom-in; }
    .c-pdp__shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
    /* Magnifier badge — the "click to zoom" affordance (there is no zoom-on-hover; a click opens the
       fullscreen zoom frame, see pdp-zoom.js). pointer-events:none so the click still reaches the figure. */
    .c-pdp__shot::after {
        content: ""; position: absolute; right: var(--space-2); bottom: var(--space-2);
        width: 2.25rem; height: 2.25rem; border-radius: 50%; pointer-events: none;
        background-color: rgba(0, 0, 0, 0.5);
        background-repeat: no-repeat; background-position: center; background-size: 1.15rem;
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cline x1='16' y1='16' x2='21' y2='21'/%3E%3Cline x1='11' y1='8' x2='11' y2='14'/%3E%3Cline x1='8' y1='11' x2='14' y2='11'/%3E%3C/svg%3E");
        opacity: 0.8; transition: opacity 0.15s ease, transform 0.15s ease;
    }
    .c-pdp__shot:hover::after { opacity: 1; transform: translateY(-2px); }
    /* On pointer/mouse devices the zoom-in cursor is the primary cue, so keep the badge out of the way
       until hover (avoids cluttering the photo at rest). On touch there is no cursor, so it stays visible
       as the only affordance. */
    @media (hover: hover) and (pointer: fine) {
        .c-pdp__shot::after { opacity: 0; }
        .c-pdp__shot:hover::after { opacity: 1; }
    }
.c-pdp__nav, .c-pdp__thumbs, .c-pdp__counter { display: none; }   /* carousel chrome: mobile only */
/* Favourite heart on the hero shot's corner — reuses the card's .c-product-card__fav (same 2rem size +
   top/right inset as Shop Tiles), so it matches the card exactly. The shot is its positioning context. */

/* Fullscreen image lightbox: click/tap a shot → overlay. Desktop: wheel/double-click to zoom, drag to
   pan, prev/next arrows or Arrow keys to change image. Mobile: pinch/double-tap to zoom, drag to pan,
   swipe or arrows to change image. Built + driven by pdp-zoom.js; shown only while open. */
.c-pdp-lightbox { position: fixed; inset: 0; z-index: 200; background: rgba(0, 0, 0, 0.92); display: flex; align-items: center; justify-content: center; }
    .c-pdp-lightbox[hidden] { display: none; }
.c-pdp-lightbox__stage { position: relative; width: 100%; height: 100%; overflow: hidden; display: flex; align-items: center; justify-content: center; touch-action: none; }
.c-pdp-lightbox__img { max-width: 100%; max-height: 100%; object-fit: contain; transform-origin: center center; will-change: transform; user-select: none; -webkit-user-select: none; }
.c-pdp-lightbox__close { position: absolute; top: var(--space-3); right: var(--space-3); z-index: 2; width: 2.75rem; height: 2.75rem; display: inline-flex; align-items: center; justify-content: center; border: 0; border-radius: 999px; background: rgba(0, 0, 0, 0.5); color: var(--color-white); font-size: 1.6rem; line-height: 1; cursor: pointer; }
.c-pdp-lightbox__count { position: absolute; bottom: var(--space-3); left: 0; right: 0; text-align: center; color: var(--color-on-dark-muted); font-size: var(--text-sm); pointer-events: none; }
/* Prev/next arrows — centred on each side, above the stage. Hidden (via [hidden]) for single-image products. */
.c-pdp-lightbox__nav { position: absolute; top: 50%; transform: translateY(-50%); z-index: 2; width: 4.25rem; height: 4.25rem; display: inline-flex; align-items: center; justify-content: center; border: 0; border-radius: 999px; background: rgba(0, 0, 0, 0.5); color: var(--color-white); font-size: 3.25rem; line-height: 1; cursor: pointer; transition: background 0.15s ease; }
    .c-pdp-lightbox__nav:hover { background: rgba(0, 0, 0, 0.75); }
    .c-pdp-lightbox__nav[hidden] { display: none; }
.c-pdp-lightbox__nav--prev { left: var(--space-3); }
.c-pdp-lightbox__nav--next { right: var(--space-3); }

/* Right: details pane — scrolls internally; coordinated with the gallery (see pdp-scroll.js). */
.c-pdp__details { height: 100%; min-height: 0; overflow-y: auto; padding-right: var(--space-2); padding-bottom: var(--space-5); scrollbar-width: none; -ms-overflow-style: none; }
    .c-pdp__details::-webkit-scrollbar { width: 0; height: 0; }
.c-pdp__title { margin: 0 0 var(--space-1); font-size: var(--title-md); }
.c-pdp__subline { margin: 0 0 var(--space-4); color: var(--color-muted); }
.c-pdp__links { display: flex; flex-direction: column; gap: var(--space-1); margin: var(--space-4) 0; }
    .c-pdp__links a { color: var(--color-text); text-decoration: underline; }
    .c-pdp__links a:hover { text-decoration: none; }
/* PDP "Pack Contains" — a scheme sample pack's child tiles (in place of the colour swatches). */
.c-pdp__pack { margin: var(--space-4) 0; }
.c-pdp__pack-title { font-size: var(--text-base); margin: 0 0 var(--space-2); }
.c-pdp__pack-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.c-pdp__pack-link { display: flex; align-items: center; gap: var(--space-3); text-decoration: none; color: var(--color-text); }
    .c-pdp__pack-link > picture { flex-shrink: 0; line-height: 0; }
    .c-pdp__pack-img { width: 4rem; height: 4rem; object-fit: cover; border-radius: var(--radius-image); }
    .c-pdp__pack-desc { font-size: var(--text-sm); }
    .c-pdp__pack-link:hover .c-pdp__pack-desc { color: var(--color-title); }
/* PDP variant pickers — Colour swatch grid + Size/Finish/Design dropdowns (above Product Attribute). */
.c-pdp__picker { margin: var(--space-4) 0; }
.c-pdp__picker-label { display: block; font-size: var(--text-sm); color: var(--color-text); }
/* Colour swatches: 5 per row, dropping to 4 when there's less room. Hybrid so it works in both layouts:
   - TWO-COLUMN (desktop): a container query on the colour block → 4 when the right pane is narrow (≤480px).
   - SINGLE-COLUMN: the pane is full-width, so use the viewport — stays 5 down to ~600px, then 4 below.
     (Source-ordered after the container query so it wins where it applies.) */
.c-pdp__picker-colour { margin-bottom: var(--space-4); container-type: inline-size; }
.c-pdp__swatches { display: grid; grid-template-columns: repeat(5, 1fr); gap: calc(var(--space-3) * 1.5) calc(var(--space-2) * 1.5); margin-top: var(--space-2); }
@container (max-width: 480px) { .c-pdp__swatches { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 600px) { .c-pdp__swatches { grid-template-columns: repeat(4, 1fr); } }
.c-pdp__swatch { display: flex; flex-direction: column; gap: var(--space-1); text-decoration: none; color: var(--color-text); }
.c-pdp__swatch-img { display: block; aspect-ratio: 1 / 1; overflow: hidden; border-radius: var(--radius-image); border: 2px solid transparent; }
.c-pdp__swatch-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.c-pdp__swatch:hover .c-pdp__swatch-img { border-color: var(--color-underline); }
.c-pdp__swatch.is-active .c-pdp__swatch-img { border-color: var(--color-accent); }
.c-pdp__swatch-name { font-size: var(--text-xs); line-height: 1.2; }
.c-pdp__picker-row { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-2); }
.c-pdp__picker-row .c-pdp__picker-label { flex: 0 0 6.5rem; }
.c-pdp__picker-select {
    flex: 0 1 auto;
    padding: var(--space-2) var(--space-3);
    border: 1.5px solid var(--color-underline);
    border-radius: 8px;
    background: var(--color-white);
    font-size: var(--text-sm);
    color: var(--color-text);
}
.c-pdp__picker-select:focus { outline: none; border-color: var(--color-accent); }

.c-pdp__section-title { margin: var(--space-4) 0 var(--space-2); font-size: var(--title-sm); }

/* Compact product cards — the narrow right-pane "Complete the look" carousel. Smaller name/price font,
   tighter spacing, and the Get Sample / Add to Cart buttons stacked one-per-row (full width). */
.c-carousel.is-compact .c-carousel__track { gap: var(--space-2); }
.c-carousel.is-compact .c-product-card__name .c_standard-text1 { font-size: var(--text-xs); }
.c-carousel.is-compact .c-product-card__info { gap: var(--space-1); }
.c-carousel.is-compact .c-product-card__actions { flex-direction: column; gap: var(--space-1); }
.c-carousel.is-compact .c-product-card__actions .c-button { flex: none; width: 100%; }
.c-pdp__table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
    .c-pdp__table th, .c-pdp__table td { text-align: left; padding: var(--space-2); border-bottom: 1px solid var(--color-underline); vertical-align: top; }
    .c-pdp__table th { font-weight: 600; color: var(--color-muted); width: 22%; }
.c-pdp__desc { margin-top: var(--space-4); }
.c-pdp__accordion { border-top: 1px solid var(--color-underline); }
.c-pdp__accordion-summary { cursor: pointer; padding: var(--space-3) 0; font-weight: 600; list-style: none; display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
    .c-pdp__accordion-summary::-webkit-details-marker { display: none; }
.c-pdp__accordion-body { padding-bottom: var(--space-3); }

/* Consistent accordion chevron (CMS template + PDP): a CSS chevron — down when collapsed, up when open. */
.c-accordion__summary::after,
.c-pdp__accordion-summary::after {
    content: ""; flex: 0 0 auto; width: 0.5em; height: 0.5em; margin-right: 0.2em;
    border-right: 2px solid var(--color-muted); border-bottom: 2px solid var(--color-muted);
    transform: rotate(45deg); transition: transform 0.2s ease;
}
.c-accordion__item[open] > .c-accordion__summary::after,
.c-pdp__accordion[open] > .c-pdp__accordion-summary::after { transform: rotate(-135deg); }

@media (max-width: 900px) {
    /* Single column: drop the pinned dual-pane behaviour and let the page scroll normally. */
    .c-pdp__main { grid-template-columns: 1fr; position: static; height: auto; }
    .c-pdp__gallery { height: auto; min-height: 0; overflow: visible; padding: 0; }
    .c-pdp__details { height: auto; min-height: 0; overflow: visible; padding-right: 0; padding-bottom: 0; }

    /* Gallery becomes a one-image-at-a-time carousel: swipe or scroll (scroll-snap), prev/next arrows,
       and a thumbnail strip underneath. Active thumb + arrow state are tracked by pdp-gallery.js. */
    .c-pdp__stage { position: relative; overflow: hidden; border-radius: var(--radius-image); }
    /* One slide at a time; pdp-gallery.js translates the track and clones the edge slides for a
       seamless infinite loop (last → first, first → last), same as CarouselScrollTemplate. */
    .c-pdp__shots { display: flex; gap: 0; }
    .c-pdp__shot { flex: 0 0 100%; border-radius: 0; }

    /* Same arrow style as CarouselScrollTemplate (.c-carousel__arrow): thin + tall, ~60% transparent
       with a light rule border, overlaid flush on the image edges. */
    .c-pdp__nav { display: inline-flex; align-items: center; justify-content: center; position: absolute; top: 50%; transform: translateY(-50%); width: 1.625rem; height: 2.5rem; padding: 0; border: 1px solid var(--color-underline); background: rgba(255, 255, 255, 0.4); color: var(--color-text); border-radius: var(--radius-button); cursor: pointer; z-index: 2; transition: background-color 0.15s ease, color 0.15s ease; }
        .c-pdp__nav:hover { background: rgba(255, 255, 255, 0.7); }
        .c-pdp__nav svg { width: 1.1rem; height: 1.1rem; }
        .c-pdp__nav--prev { left: 0; }
        .c-pdp__nav--next { right: 0; }
        .c-pdp__nav:disabled { opacity: 0.35; pointer-events: none; }

    /* "X / 7" position + count, shown below the image (not overlaid) so it never blocks the photo. */
    .c-pdp__counter { display: block; margin: var(--space-2) 0 0; text-align: right; color: var(--color-muted); font-size: var(--text-sm); }

    .c-pdp__thumbs { display: flex; gap: var(--space-2); overflow-x: auto; padding: 0.2rem 0 var(--space-1); scrollbar-width: none; -ms-overflow-style: none; }
        .c-pdp__thumbs::-webkit-scrollbar { width: 0; height: 0; }
        /* When there are more thumbnails than fit, fade the right edge so it's clear the row scrolls
           (pdp-gallery.js toggles .is-scrollable, and .is-end once you reach the far right). */
        .c-pdp__thumbs.is-scrollable { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 1.75rem), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 1.75rem), transparent); }
        .c-pdp__thumbs.is-scrollable.is-end { -webkit-mask-image: none; mask-image: none; }
    .c-pdp__thumb { flex: 0 0 auto; width: 3.25rem; height: 3.25rem; padding: 0; border: 2px solid transparent; border-radius: var(--radius-image); overflow: hidden; background: var(--color-neutral-5); cursor: pointer; }
        .c-pdp__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
        .c-pdp__thumb.is-active { border-color: var(--color-text); }
}

/* Inline order panel (PDP) — the Add-to-Cart modal's content, on the page. */
.c-orderpanel { display: flex; flex-direction: column; gap: var(--space-3); }
.c-orderpanel__loading { color: var(--color-muted); }
.c-orderpanel__sample, .c-orderpanel__add { width: 100%; }
/* Inputs + box-info stay on one row; the box-info column shrinks (its text stacks) instead of dropping below. */
.c-orderpanel__qty { display: flex; align-items: flex-start; gap: var(--space-3); flex-wrap: nowrap; }
.c-orderpanel__field { display: flex; flex-direction: column; gap: var(--space-1); flex: 0 0 auto; }
.c-orderpanel__label { font-weight: 600; }
    .c-orderpanel__field input { width: 5rem; padding: var(--space-1) var(--space-2); border: 1px solid var(--color-border-input); border-radius: var(--radius-button); font: inherit; text-align: center; }
.c-orderpanel__unit { font-size: var(--text-xs); white-space: nowrap; }
    .c-orderpanel__unit small { color: var(--color-muted); }
.c-orderpanel__or { align-self: center; color: var(--color-muted); padding-top: 1.4rem; }
.c-orderpanel__total { display: flex; align-items: baseline; justify-content: flex-end; gap: var(--space-2); }
    .c-orderpanel__total strong { font-size: var(--text-lg); }
.c-orderpanel__note { margin: 0; color: var(--color-muted); font-size: var(--text-xs); }
.c-orderpanel__waste { display: flex; align-items: center; gap: var(--space-2); }
    .c-orderpanel__waste select { padding: var(--space-1) var(--space-2); border: 1px solid var(--color-border-input); border-radius: var(--radius-button); background: #fff; font: inherit; cursor: pointer; }
/* Box-count sits to the right of the Tile/Sqm inputs, on two lines. */
.c-orderpanel__boxes { margin: 0 0 0 auto; align-self: flex-start; min-width: 0; display: flex; flex-direction: column; gap: var(--space-1); text-align: left; }
.c-orderpanel__boxes-count { font-weight: 600; }
    .c-orderpanel__boxes small { color: var(--color-muted); }
.c-orderpanel__nb { white-space: nowrap; }

/* ===================== Checkout (/checkout/{product|sample}) ===================== */
.c-checkout { padding-block: var(--space-4) var(--space-6); }
.c-checkout__title { margin: 0 0 var(--space-4); }
/* Items (left) + order summary (right); stacks on small screens. */
/* Right (summary) column is capped at 30rem on wide screens but shrinks proportionally (40% of the row)
   as the window narrows, so both panes get narrower together instead of only the left squeezing. */
.c-checkout__grid { display: grid; grid-template-columns: minmax(0, 1fr) min(30rem, 40%); gap: var(--space-5); align-items: start; }
.c-checkout__section-title { margin: 0 0 var(--space-3); font-size: var(--title-sm); }
.c-checkout__loading, .c-checkout__empty { color: var(--color-muted); }
.c-checkout__empty { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-3); }
/* Summary card — sticky beside the items on desktop. */
.c-checkout__summary { position: sticky; top: var(--space-4); border: 1px solid var(--color-underline); border-radius: var(--radius-image); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-3); }
.c-checkout__place { width: 100%; }
.c-checkout__soon { margin: 0; color: var(--color-muted); font-size: var(--text-sm); text-align: center; }
.c-checkout__continue { color: var(--color-text); text-decoration: underline; font-size: var(--text-sm); }
    .c-checkout__continue:hover { text-decoration: none; }

@media (max-width: 768px) {
    .c-checkout__grid { grid-template-columns: 1fr; }
    .c-checkout__summary { position: static; }
}

/* ===================== Order Payment (magic-link) ===================== */
/* One consistent centred column (~the original's container col-lg-10) so the wide email-template body tables
   line up with the total + payment block instead of overflowing a narrower cap. */
.c-orderpay { max-width: 60rem; margin-inline: auto; padding-block: var(--space-5) var(--space-6); display: flex; flex-direction: column; gap: var(--space-4); }
.c-orderpay__title { margin: 0; text-align: center; }
.c-orderpay__body { color: var(--color-text); }
/* Keep the admin-authored email tables within the column (no break-out, no scrollbars). */
.c-orderpay__body table { max-width: 100%; }
/* Gap so the Pay button clears the drop-in's green "valid card" border (scoped to this page). */
.c-orderpay .c-checkout__place { margin-top: 0.75rem; }
/* Payment-received confirmation (matches the original OrderPayment wording). */
.c-orderpay__thanks { text-align: center; display: flex; flex-direction: column; gap: var(--space-3); }
.c-orderpay__thanks-title, .c-orderpay__thanks-sub { color: var(--color-success); margin: 0; }
.c-orderpay__thanks-next { font-weight: 600; margin: 0; }
.c-orderpay__thanks .c-orderplaced__steps { max-width: 40rem; margin-inline: auto; text-align: left; }
.c-orderpay__thanks-contact { color: var(--color-muted); margin: 0; }

/* ===================== Quote Response (magic-link) ===================== */
.c-quote__review { display: flex; flex-direction: column; gap: var(--space-3); }
.c-quote__lead { margin: 0 0 var(--space-2); text-align: center; }
.c-quote__confirm { padding: var(--space-2) var(--space-3); border: 1px solid var(--color-underline); border-radius: var(--radius-button); background: #fffdf5; transition: background-color 0.15s, border-color 0.15s, color 0.15s; }
/* Ticked → "confirmed" state (success token, blue-grey — the sanctioned success colour). */
.c-quote__confirm.is-confirmed { border-color: var(--color-success); background: color-mix(in srgb, var(--color-success) 8%, #fff); color: var(--color-success); }
    .c-quote__confirm.is-confirmed strong { color: var(--color-success); }
    .c-quote__confirm.is-confirmed input { accent-color: var(--color-success); }
.c-quote__confirm.is-error { border-color: var(--color-error); background: color-mix(in srgb, var(--color-error) 6%, #fff); }
.c-quote__confirm--final { border-width: 2px; font-weight: 600; }
.c-quote__rule { width: 100%; border: 0; border-top: 1px solid var(--color-underline); margin: var(--space-2) 0; }
.c-quote__name { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); }
    .c-quote__name .c-field__input { flex: 1 1 16rem; }
.c-quote__date { color: var(--color-muted); white-space: nowrap; }
.c-quote__actions { display: flex; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
/* Decline modal */
.c-quote__modal-backdrop { position: fixed; inset: 0; z-index: 1000; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; padding: var(--space-4); }
.c-quote__modal { width: 100%; max-width: 32rem; background: #fff; border-radius: var(--radius-image); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-3); }
.c-quote__modal-title { margin: 0; }
.c-orderpay__total { display: flex; justify-content: space-between; align-items: baseline; padding-top: var(--space-3); border-top: 1px solid var(--color-underline); font-size: var(--text-md); }
    .c-orderpay__total strong { font-size: var(--text-lg); }

/* ===================== Forms (site-wide) ===================== */
/* Canonical form style — reuse for checkout, login/signup, contact, account, etc. Matches the original
   look: soft 8px-rounded inputs with a light 1.5px border that turns accent on focus (no glow/outline),
   labels in the page text colour, red error text, muted hints. Lay fields out with .c-field-grid; wrap a
   form block in .c-form-panel for the light grey card. */
/* The panel is a container so the field grid collapses on the FORM's width, not the viewport (the form
   shares a row with the order summary, so it can be narrow even on a wide screen). */
.c-form-panel { background: var(--color-neutral-5); border-radius: var(--radius-image); padding: var(--space-4); container-type: inline-size; }
.c-form__title { margin: 0 0 var(--space-4); font-size: var(--title-sm); }
.c-field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3) var(--space-4); }
.c-field { display: flex; flex-direction: column; gap: var(--space-1); }
.c-field--full { grid-column: 1 / -1; }
.c-field__label { font-size: var(--text-sm); color: var(--color-text); }
.c-field__req { color: var(--color-error); margin-left: 0.1em; }
.c-field__input { width: 100%; padding: 0.5rem 0.6rem; border: 1.5px solid var(--color-underline); border-radius: 8px; font: inherit; color: var(--color-text); background: #fff; }
    .c-field__input:focus { border-color: var(--color-accent); outline: none; box-shadow: none; }
.c-field__hint { font-size: var(--text-xs); color: var(--color-muted); }
/* The ONE field-error text style, used everywhere — manual `.c-field__error` spans (checkout) AND Blazor's
   `<ValidationMessage>` output (`.validation-message`, e.g. the auth forms). Red, fine-print size. */
.c-field__error, .validation-message { font-size: var(--text-xs); color: var(--color-error); }
/* Password field with a show/hide toggle (the button sits inside the input on the right). */
.c-field__password { position: relative; }
    .c-field__password .c-field__input { padding-right: 2.75rem; }
.c-field__reveal { position: absolute; top: 0; right: 0; height: 100%; width: 2.75rem; display: inline-flex; align-items: center; justify-content: center; border: 0; background: none; color: var(--color-muted); cursor: pointer; }
    .c-field__reveal:hover, .c-field__reveal.is-on { color: var(--color-text); }
    .c-field__reveal svg { width: 1.15rem; height: 1.15rem; }

/* Checkout-specific form chrome */
.c-checkout__form { margin-top: var(--space-5); }
.c-checkout__samebill { display: flex; align-items: center; gap: var(--space-2); margin: var(--space-3) 0; font-size: var(--text-sm); cursor: pointer; }

/* Collapse to one column when the form panel itself is narrow (container query, not viewport). */
@container (max-width: 30rem) {
    .c-field-grid { grid-template-columns: 1fr; }
    .c-field--full { grid-column: auto; }
}

/* Checkout — shipping method, log-in link, terms, final checks */
.c-checkout__shipmethod { margin-top: var(--space-5); }
.c-checkout__method { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) 0; cursor: pointer; }
.c-checkout__haveaccount { margin: 0 0 var(--space-3); text-align: right; font-size: var(--text-sm); }
    .c-checkout__haveaccount a { color: var(--color-text); text-decoration: underline; }
    .c-checkout__haveaccount a:hover { text-decoration: none; }
.c-checkout__terms { display: flex; align-items: flex-start; gap: var(--space-2); font-size: var(--text-base); cursor: pointer; }
    .c-checkout__terms a { color: var(--color-text); text-decoration: underline; }
    .c-checkout__terms a:hover { text-decoration: none; }
/* Extra breathing room before the first checkbox (1.2× the summary's --space-3 gap): gap (1rem) + 0.2rem. */
.c-checkout__finalchecks + .c-checkout__terms { margin-top: calc(var(--space-3) * 0.2); }
/* Sample checkout hides the final-checks block (owner, 10 Aug 2026), so the terms checkbox follows the
   payment box directly. It inherits the same rule + spacing the hidden block used to supply, otherwise the
   checkbox butts straight up against the PayPal option. Matches .c-checkout__finalchecks exactly. */
.c-checkout__terms--divided { margin-top: var(--space-2); padding-top: var(--space-3); border-top: 1px solid var(--color-underline); }

/* Why Place Order is disabled — a plain-language checklist so customers aren't left guessing. Soft red tint
   (derived from --color-error) so it stands out a little without shouting. */
.c-checkout__blockers { margin: 0; padding: var(--space-3); border: 1px solid color-mix(in srgb, var(--color-error) 35%, #fff); border-radius: var(--radius-image); background: color-mix(in srgb, var(--color-error) 7%, #fff); font-size: var(--text-sm); }
.c-checkout__blockers-title { margin: 0 0 var(--space-2); font-weight: 600; color: color-mix(in srgb, var(--color-error) 72%, #000); }
.c-checkout__blockers ul { margin: 0; padding-left: 1.2em; display: flex; flex-direction: column; gap: var(--space-1); color: color-mix(in srgb, var(--color-error) 65%, #000); }
.c-checkout__finalchecks { margin-top: var(--space-2); padding-top: var(--space-3); border-top: 1px solid var(--color-underline); font-size: var(--text-base); color: var(--color-text); }
.c-checkout__finalchecks-title { margin: 0 0 var(--space-2); font-weight: 600; color: var(--color-text); }
.c-checkout__finalchecks ul { margin: 0; padding-left: 1.1em; display: flex; flex-direction: column; gap: var(--space-2); }
    .c-checkout__finalchecks strong { color: var(--color-text); }

/* Checkout — "Choose a way to pay" selector (visual placeholder; real payment is the parked step) */
.c-checkout__pay { margin-top: var(--space-2); }
.c-checkout__pay-title { margin: 0 0 var(--space-2); font-size: var(--text-sm); }
.c-paylist { display: flex; flex-direction: column; border: 1px solid var(--color-underline); border-radius: var(--radius-image); overflow: hidden; }
.c-payopt { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3); cursor: pointer; border-top: 1px solid var(--color-underline); }
    .c-payopt:first-child { border-top: 0; }
    .c-payopt input { margin: 0; }
    .c-payopt.is-selected { background: var(--color-neutral-5); }
.c-payopt__badge { display: inline-flex; align-items: center; justify-content: center; min-width: 3rem; height: 1.6rem; padding: 0 var(--space-1); border: 1px solid var(--color-underline); border-radius: var(--radius-button); background: #fff; font-size: var(--text-xs); font-weight: 600; color: var(--color-text); }
.c-payopt__label { font-size: var(--text-sm); }
/* Braintree Drop-in container + states (the JS toggles valid/invalid-payment). */
.c-checkout__dropin { margin-top: var(--space-2); border-radius: var(--radius-md); }
#dropin-container.valid-payment { outline: 2px solid var(--color-fav); outline-offset: 3px; border-radius: var(--radius-md); }
.c-checkout__pay-note { margin: var(--space-2) 0 0; color: var(--color-muted); font-size: var(--text-sm); }

/* Order placed confirmation page. */
.c-orderplaced { display: flex; justify-content: center; padding: var(--space-6) var(--space-4); }
.c-orderplaced__card { max-width: 40rem; width: 100%; text-align: center; background: #fff; border: 1px solid var(--color-underline); border-radius: var(--radius-lg); padding: var(--space-6) var(--space-5); }
.c-orderplaced__check { width: 3.5rem; height: 3.5rem; margin: 0 auto var(--space-4); border-radius: 50%; background: var(--color-fav); color: #fff; display: flex; align-items: center; justify-content: center; }
.c-orderplaced__check svg { width: 1.75rem; height: 1.75rem; }
.c-orderplaced__title { margin: 0 0 var(--space-2); }
.c-orderplaced__order { margin: 0 0 var(--space-4); font-size: var(--text-lg); }
.c-orderplaced__lead { color: var(--color-muted); margin: 0; }
.c-orderplaced__steps { text-align: left; max-width: 30rem; margin: var(--space-4) auto; display: flex; flex-direction: column; gap: var(--space-2); padding-left: var(--space-4); }
.c-orderplaced__help { margin-top: var(--space-4); color: var(--color-muted); font-size: var(--text-sm); }
.c-orderplaced__cta { margin-top: var(--space-5); }
