/* Design tokens. Visual refresh 2026-10-23 (soulpuzzles-visual-refresh-spec.md
   §2.1): the --sp-* set is the new palette and type; the older --color-*
   names now point at it, so every rule not yet restyled moves with it.
   Fonts are self-hosted (static/fonts, OFL): the CSP allows only 'self'
   for styles and fonts, so Google's stylesheet would be blocked. */

@font-face {
    font-family: "Fraunces";
    font-style: normal;
    font-weight: 500 600;
    font-display: swap;
    src: url("/static/fonts/fraunces-latin.woff2") format("woff2");
}
@font-face {
    font-family: "Nunito Sans";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("/static/fonts/nunito-sans-latin.woff2") format("woff2");
}

:root {
    --sp-bg: #FBF7F1;
    --sp-surface: #FFFFFF;
    --sp-surface-alt: #F3EBDF;
    --sp-ink: #1F2A44;
    --sp-ink-soft: #5B6478;
    --sp-accent: #E8792B;
    --sp-accent-dark: #C55F17;
    --sp-heart: #C2415B;
    /* --sp-heart is 4.2:1 on birch, short of AA for small text; words and
       outlines use this darker rose, icons and big numbers the spec one. */
    --sp-heart-ink: #A6324B;
    --sp-sage: #7C9A7E;
    --sp-line: #E7DDD0;
    --sp-font-display: "Fraunces", Georgia, serif;
    --sp-font-body: "Nunito Sans", system-ui, -apple-system, sans-serif;
    --sp-radius-sm: 8px;
    --sp-radius: 16px;
    --sp-radius-lg: 24px;
    --sp-shadow: 0 1px 2px rgba(31,42,68,.06), 0 6px 20px rgba(31,42,68,.06);
    --sp-shadow-hover: 0 4px 10px rgba(31,42,68,.08), 0 16px 36px rgba(31,42,68,.12);

    --color-bg: var(--sp-bg);
    --color-surface: var(--sp-surface);
    --color-text: var(--sp-ink);
    --color-text-muted: var(--sp-ink-soft);
    --color-heading: var(--sp-ink);
    --color-accent: var(--sp-accent);
    --color-accent-hover: var(--sp-accent-dark);
    --color-link: var(--sp-ink);
    --color-link-hover: #A84E10;
    --color-border: var(--sp-line);
    --color-outofstock: #8A8F9C;
    --color-success: #2E7D63;
    --color-success-bg: #E7F5F0;
    --color-error: #B3261E;
    --color-error-bg: #FBEAE9;

    --font-sans: var(--sp-font-body);
    --text-xs: 13px;
    --text-sm: 14px;
    --text-base: 17px;
    --text-lg: 20px;
    --text-xl: 28px;
    --text-2xl: 36px;
    --font-weight-body: 400;
    --font-weight-medium: 600;
    --font-weight-bold: 700;

    --space-1: 4px;
    --space-2: 8px;
    --space-3: 16px;
    --space-4: 24px;
    --space-5: 32px;
    --space-6: 48px;
    --space-7: 64px;

    --radius-sm: var(--sp-radius-sm);
    --radius-md: var(--sp-radius);
    --shadow-card: var(--sp-shadow);
    --shadow-card-hover: var(--sp-shadow-hover);
}

h1, h2, h3 {
    font-family: var(--sp-font-display);
    font-weight: 500;
    color: var(--color-heading);
    letter-spacing: -0.01em;
}
h1 { font-weight: 600; }

* { box-sizing: border-box; }

/* Global img reset — WooCommerce description/short_description HTML embeds
   raw <img width="300" height="300"> tags (WordPress's own convention).
   Without this, an unstyled image with only an HTML width attribute keeps
   that literal pixel size regardless of viewport, which blows out any
   grid/flex ancestor whose track sizing defaults to minmax(auto, 1fr) —
   the actual cause of the mobile horizontal-scroll bug on product pages. */
img { max-width: 100%; height: auto; display: block; }

body {
    margin: 0;
    font-family: var(--font-sans);
    font-size: var(--text-base);
    background: var(--color-bg);
    color: var(--color-text);
}

/* Links — override browser defaults site-wide. Was previously unstyled
   (#0000EE, underlined, purple-once-visited) everywhere text sat inside an
   <a>, which is why product titles/nav read as plain hyperlinks. */
a {
    color: var(--color-link);
    text-decoration: none;
}
a:hover { color: var(--color-link-hover); }
a:visited { color: var(--color-link); }

:focus-visible {
    outline: 2px solid var(--sp-ink);
    outline-offset: 2px;
    border-radius: 4px;
}

.site-footer-inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: var(--space-3) var(--space-4);
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    justify-content: space-between;
}

/* ===== Header (visual refresh spec §3) =================================== */
.announcement-bar {
    display: block;
    padding: 7px var(--space-3);
    background: var(--sp-ink);
    color: #fff;
    font-size: 13px;
    font-weight: 600;
    text-align: center;
}
a.announcement-bar:visited, a.announcement-bar:hover { color: #fff; }
.announcement-bar .icon { width: 14px; height: 14px; color: #E57A90; vertical-align: -2px; margin: 0 4px; }
.announcement-link { text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; }
@media (max-width: 600px) {
    .announcement-bar { font-size: 12px; }
    .announcement-long { display: none; }
}

.site-header {
    position: sticky;
    top: 0;
    z-index: 40;
    background: var(--sp-surface);
    border-bottom: 1px solid var(--sp-line);
    transition: box-shadow 0.2s ease;
}
.site-header.is-scrolled { box-shadow: 0 4px 18px rgba(31,42,68,.08); }
.site-header-inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 10px var(--space-4);
    display: flex;
    align-items: center;
    gap: 20px;
}

.logo-link { display: inline-block; flex: none; }
.site-logo { height: 64px; width: auto; display: block; }

.main-nav { display: flex; align-items: center; gap: 2px; flex: 1; flex-wrap: nowrap; }
.nav-tab {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 8px 10px;
    border: none;
    border-radius: 999px;
    background: none;
    font: inherit;
    font-size: 15px;
    font-weight: 700;
    color: var(--sp-ink);
    cursor: pointer;
    white-space: nowrap;
}
a.nav-tab:visited { color: var(--sp-ink); }
.nav-tab:hover, .nav-dropdown.open > .nav-tab { background: var(--sp-surface-alt); color: var(--sp-ink); }
.nav-tab.active { background: var(--sp-accent); color: var(--sp-ink); }
.nav-tab-purpose .icon { width: 15px; height: 15px; color: var(--sp-heart); }
/* "Our Purpose" never goes orange: its rose heart can't sit on orange. */
.nav-tab-purpose.active { background: var(--sp-surface-alt); }

/* Dropdowns open on hover, and on click/Enter via ui.js (touch, keyboard). */
.nav-dropdown { position: relative; }
.nav-dropdown-menu {
    display: none;
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 45;
    gap: var(--space-4);
    padding: var(--space-4);
    background: var(--sp-surface);
    border: 1px solid var(--sp-line);
    border-radius: var(--sp-radius);
    box-shadow: var(--sp-shadow-hover);
    min-width: 240px;
}
/* A hover bridge over the 6px gap so the menu doesn't close on the way. */
.nav-dropdown-menu::before { content: ""; position: absolute; left: 0; right: 0; top: -8px; height: 8px; }
@media (hover: hover) {
    .nav-dropdown:hover .nav-dropdown-menu { display: flex; }
}
.nav-dropdown.open .nav-dropdown-menu { display: flex; }
.nav-dropdown-wide .nav-dropdown-menu { width: max-content; max-width: min(860px, calc(100vw - 48px)); flex-wrap: wrap; }
.nav-dropdown-list { flex-direction: column; max-height: 70vh; overflow-y: auto; gap: 0; }
.nav-col { display: flex; flex-direction: column; min-width: 170px; max-width: 220px; }
.nav-col-head {
    font-family: var(--sp-font-display);
    font-size: 16px;
    font-weight: 600;
    color: var(--sp-ink);
    margin-bottom: 6px;
}
.nav-dropdown-menu a {
    display: block;
    padding: 4px 0;
    font-size: 14px;
    color: var(--sp-ink-soft);
}
.nav-dropdown-menu a.nav-col-head { color: var(--sp-ink); font-size: 16px; }
.nav-dropdown-menu a:hover, .nav-dropdown-menu a.active { color: var(--sp-ink); text-decoration: underline; text-underline-offset: 3px; }
.nav-dropdown-menu a.nav-col-more { font-weight: 700; color: var(--sp-ink); }

.header-actions { display: flex; align-items: center; gap: var(--space-2); margin-left: auto; flex: none; }
.icon-link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 8px;
    border-radius: 999px;
    color: var(--sp-ink);
}
a.icon-link:visited { color: var(--sp-ink); }
.icon-link:hover { background: var(--sp-surface-alt); color: var(--sp-ink); }
.header-admin-link {
    font-size: var(--text-sm);
    color: var(--color-text-muted) !important;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: 4px 10px;
    white-space: nowrap;
}
.header-admin-link:hover { color: var(--color-heading) !important; border-color: var(--color-heading); }

.cart-badge {
    display: inline-block;
    min-width: 20px;
    background: var(--sp-accent);
    color: var(--sp-ink);
    border-radius: 999px;
    padding: 1px 6px;
    font-size: 12px;
    font-weight: 700;
    text-align: center;
}

.mobile-menu-toggle { display: none; }

/* Below 1180px the tabs move into a slide-in drawer; each tab becomes an
   accordion of its collections (spec §3.3). */
@media (max-width: 1180px) {
    .site-header-inner { gap: var(--space-2); padding: 8px var(--space-3); }
    .site-logo { height: 44px; }
    .mobile-menu-toggle {
        display: inline-flex;
        padding: 8px;
        border: none;
        background: none;
        color: var(--sp-ink);
        cursor: pointer;
    }
    .main-nav {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        z-index: 60;
        width: min(340px, 88vw);
        flex-direction: column;
        flex-wrap: nowrap;
        align-items: stretch;
        gap: 2px;
        padding: var(--space-3) var(--space-3) var(--space-5);
        background: var(--sp-surface);
        box-shadow: 0 0 40px rgba(31,42,68,.25);
        overflow-y: auto;
        transform: translateX(-105%);
        transition: transform 0.25s ease;
        visibility: hidden;
    }
    .main-nav.open { transform: none; visibility: visible; }
    .nav-tab { justify-content: space-between; width: 100%; border-radius: var(--sp-radius-sm); padding: 12px; font-size: 16px; }
    .nav-dropdown-menu {
        position: static;
        box-shadow: none;
        border: none;
        padding: 4px 12px 12px;
        min-width: 0;
        flex-direction: column;
        gap: var(--space-3);
    }
    .nav-dropdown-menu::before { display: none; }
    .nav-dropdown:hover .nav-dropdown-menu { display: none; }
    .nav-dropdown.open .nav-dropdown-menu { display: flex; }
    .nav-dropdown-wide .nav-dropdown-menu { width: auto; max-width: none; }
    .nav-col { max-width: none; }
    .nav-dropdown-list { max-height: none; }
}
.nav-scrim { display: none; }
@media (max-width: 1180px) {
    /* Under the sticky header (z 40), whose stacking context holds the drawer. */
    .nav-scrim.open { display: block; position: fixed; inset: 0; z-index: 39; background: rgba(31,42,68,.35); }
}

.page-content {
    max-width: 1200px;
    margin: 0 auto;
    padding: var(--space-4);
}

/* ===== Hero — split layout (visual refresh 2026-10-23) ==================
   Headline and buttons on calm paper on the left, the artwork on the
   right, so text never sits on a busy picture. Replaced a full-bleed
   5-tile collage with white text over it. */
.hero-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    align-items: center;
    gap: var(--space-6);
    padding: var(--space-6) 0 var(--space-7);
}
.hero-text { max-width: 520px; }
.eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 0 0 var(--space-3);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--sp-ink-soft);
}
.eyebrow-heart { color: var(--sp-heart-ink); }
.eyebrow .icon { width: 16px; height: 16px; }
.hero-split h1 {
    font-size: 56px;
    line-height: 1.05;
    margin: 0 0 var(--space-4);
}
.hero-lede {
    font-size: 19px;
    line-height: 1.6;
    color: var(--sp-ink-soft);
    margin: 0 0 var(--space-5);
}
.hero-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }

/* A small gallery wall: three framed prints, slightly turned, as if hung
   by hand. Matches homepage_content.HERO_IMAGES' order. */
.hero-gallery {
    position: relative;
    aspect-ratio: 1 / 0.86;
}
.hero-gallery-item {
    position: absolute;
    margin: 0;
    padding: 10px;
    background: #fff;
    border-radius: var(--sp-radius);
    box-shadow: var(--sp-shadow-hover);
}
.hero-gallery-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 10px;
}
.hero-gallery-item-1 { left: 0;   top: 4%;  width: 62%; aspect-ratio: 1; transform: rotate(-2.5deg); z-index: 2; }
.hero-gallery-item-2 { right: 0;  top: 0;   width: 40%; aspect-ratio: 768 / 1066; transform: rotate(3deg); z-index: 1; }
.hero-gallery-item-3 { right: 8%; bottom: 0; width: 34%; aspect-ratio: 1; transform: rotate(-4deg); z-index: 3; }

/* Puzzles with Purpose: two dog-shaped puzzles as cut-outs. multiply
   drops their white photo background into the paper colour. */
.hero-purpose { position: relative; }
.hero-cutouts {
    position: relative;
    aspect-ratio: 1 / 0.9;
}
.hero-cutouts::before {
    content: "";
    position: absolute;
    inset: 8% 10% 4% 6%;
    border-radius: 50%;
    background: radial-gradient(closest-side, rgba(194,65,91,.12), rgba(194,65,91,0));
}
.hero-cutout {
    position: absolute;
    mix-blend-mode: multiply;
}
.hero-cutout-1 { left: 0; top: 0; width: 66%; transform: rotate(-4deg); }
.hero-cutout-2 { right: 0; bottom: 0; width: 42%; transform: rotate(3deg); }

/* Trust strip under the hero. Icons stay navy: the orange buttons sit
   just above (spec §2.1, no rose beside orange). */
.trust-strip {
    list-style: none;
    margin: 0 0 var(--space-6);
    padding: var(--space-4) var(--space-4);
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-3);
    background: var(--sp-surface-alt);
    border-radius: var(--sp-radius);
}
.trust-strip li {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    font-weight: 600;
    font-size: 15px;
    color: var(--sp-ink);
}
.trust-strip .icon { flex: none; color: var(--sp-ink); }

/* ===== Purpose band — the charity story (partials/purpose_band.html) ==== */
.purpose-band {
    position: relative;
    width: 100vw;
    left: 50%;
    transform: translateX(-50%);
    margin: var(--space-7) 0;
    padding: var(--space-7) var(--space-4);
    background: var(--sp-surface-alt);
}
/* Last thing on the home page: a thin paper line before the birch footer. */
.purpose-band:last-child { margin-bottom: 0; }
.purpose-band-inner {
    max-width: 1100px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    gap: var(--space-6);
    align-items: center;
}
.purpose-band-media {
    margin: 0;
    padding: 12px;
    background: #fff;
    border-radius: var(--sp-radius-lg);
    box-shadow: var(--sp-shadow-hover);
    transform: rotate(-1.5deg);
}
.purpose-band-media img { width: 100%; height: auto; border-radius: var(--sp-radius); }
.purpose-band h2 { font-size: 40px; line-height: 1.1; margin: 0 0 var(--space-3); }
.purpose-band-stat {
    display: flex;
    align-items: baseline;
    gap: 12px;
    margin: 0 0 var(--space-2);
    font-weight: 600;
    color: var(--sp-ink);
}
.purpose-band-stat span {
    font-family: var(--sp-font-display);
    font-size: 64px;
    line-height: 1;
    color: var(--sp-heart);
}
.purpose-band-cause { font-size: 17px; line-height: 1.6; color: var(--sp-ink-soft); margin: 0 0 var(--space-4); }
.purpose-band-quote {
    margin: 0 0 var(--space-5);
    padding-left: var(--space-4);
    border-left: 3px solid var(--sp-heart);
    font-family: var(--sp-font-display);
    font-size: 21px;
    line-height: 1.45;
    color: var(--sp-ink);
}
.btn-outline-heart {
    display: inline-block;
    padding: 12px 24px;
    border: 2px solid var(--sp-heart-ink);
    border-radius: var(--sp-radius-sm);
    color: var(--sp-heart-ink);
    font-weight: 700;
}
a.btn-outline-heart:visited { color: var(--sp-heart-ink); }
.btn-outline-heart:hover { background: var(--sp-heart-ink); color: #fff; }

.section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    margin: 0 0 var(--space-4);
}
.section-head h2 { margin: 0; }
.section-head-link { font-weight: 700; color: var(--sp-ink); white-space: nowrap; }

@media (max-width: 900px) {
    .hero-split { grid-template-columns: 1fr; gap: var(--space-5); padding: var(--space-4) 0 var(--space-5); }
    .hero-split h1 { font-size: 38px; }
    .hero-lede { font-size: 17px; }
    .hero-gallery, .hero-cutouts { max-width: 520px; width: 100%; margin: 0 auto; }
    .trust-strip { grid-template-columns: repeat(2, 1fr); }
    .trust-strip li { justify-content: flex-start; font-size: 14px; }
    .purpose-band { padding: var(--space-6) var(--space-3); }
    .purpose-band-inner { grid-template-columns: 1fr; gap: var(--space-5); }
    .purpose-band-media { max-width: 420px; margin: 0 auto; }
    .purpose-band h2 { font-size: 30px; }
    .purpose-band-stat span { font-size: 52px; }
}

/* Buttons. Navy text on the brand orange: white on it is 2.9:1 and
   fails AA, navy is 4.9:1 (spec §2.1 asks for the check). a:visited used
   to turn the label navy anyway, which is what the live site showed. */
.btn-primary, .hero-cta, .checkout-cta, .add-to-cart-button {
    display: inline-block;
    background: var(--sp-accent);
    color: var(--sp-ink);
    padding: 13px 26px;
    border-radius: var(--radius-sm);
    text-decoration: none;
    border: none;
    cursor: pointer;
    font-family: var(--sp-font-body);
    font-size: 16px;
    font-weight: 700;
    transition: background 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
}
a.btn-primary:visited, a.hero-cta:visited, a.checkout-cta:visited { color: var(--sp-ink); }
.btn-primary:hover, .hero-cta:hover, .checkout-cta:hover, .add-to-cart-button:hover {
    background: #F08A3E;
    color: var(--sp-ink);
    box-shadow: 0 4px 14px rgba(232,121,43,.35);
}
.btn-primary:active, .add-to-cart-button:active { transform: scale(0.98); }

.btn-secondary {
    display: inline-block;
    background: transparent;
    color: var(--color-heading);
    border: 2px solid var(--color-heading);
    border-radius: var(--radius-sm);
    padding: 11px 24px;
    text-decoration: none;
    font-weight: 700;
}
a.btn-secondary:visited { color: var(--color-heading); }
.btn-secondary:hover { background: var(--color-heading); color: #fff; }

.featured-products { margin: var(--space-6) 0; }
.featured-products h2 { color: var(--color-heading); margin: 0 0 var(--space-4); font-size: 36px; }
.category-strip h2 { font-size: 36px; }
@media (max-width: 900px) {
    .featured-products h2, .category-strip h2 { font-size: 28px; }
}

.purpose-products-intro { color: var(--color-text-muted); margin: 0 0 var(--space-4); font-size: var(--text-lg); }

/* "Puzzles with Purpose" founder's note */
.founder-note-section { margin: var(--space-6) 0; display: flex; justify-content: center; }
.founder-note {
    max-width: 720px;
    margin: 0;
    padding: var(--space-5) var(--space-6);
    border-left: 4px solid var(--color-heading);
    background: var(--color-surface);
    border-radius: 0 12px 12px 0;
    box-shadow: 0 6px 24px rgba(0,0,0,0.06);
}
.founder-note p { font-size: var(--text-lg); line-height: 1.6; color: var(--color-text); margin: 0 0 var(--space-3); font-style: italic; }
.founder-note-signature { font-style: normal; font-weight: 600; color: var(--color-heading); }

/* Product grid + cards (visual refresh spec §6) */
.product-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--space-4);
}

.product-card {
    background: var(--color-surface);
    border-radius: var(--sp-radius);
    box-shadow: var(--sp-shadow);
    padding: 0 0 var(--space-3);
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
    transition: box-shadow 0.2s ease, transform 0.2s ease;
}
.product-card:hover { box-shadow: var(--sp-shadow-hover); transform: translateY(-3px); }

.product-card > a {
    display: flex;
    flex-direction: column;
    flex: 1;
    text-decoration: none;
    color: inherit;
}
.product-card > a > :not(.product-card-image-wrap):not(.product-image-placeholder),
.product-card > form, .product-card > .out-of-stock-badge, .product-card > .enquire-button {
    margin-left: var(--space-3);
    margin-right: var(--space-3);
}

/* contain, not cover (2026-10-23): the owner's photos are every shape — a
   1824x616 banner, a tall shot of ten tins, a catalogue cover — and cover
   cropped them to "UTTING OF WOO". The whole picture now sits in the
   square, on birch so a white-backed photo still reads as framed. */
.product-card-image, .product-detail-gallery-main img {
    max-width: 100%;
    aspect-ratio: 1 / 1;
    object-fit: contain;
    background: #fff;
    border-radius: var(--radius-sm);
}
.product-image-placeholder {
    aspect-ratio: 1 / 1;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--sp-surface-alt);
    color: var(--color-text);
    opacity: 0.6;
    font-size: var(--text-sm);
}

/* Card image micro-zoom while in view (design brief §B) — wrapper clips
   the scale so it never nudges layout; the scale itself only progresses
   while data-zoom-in-view is intersecting (see scroll-effects.js) and
   reverses on its own via the transition when it scrolls back out. */
.product-card-image-wrap {
    overflow: hidden;
    background: #fff;
    border-bottom: 1px solid var(--sp-line);
}
.product-card-image-wrap .product-card-image {
    width: 100%;
    height: 100%;
    border-radius: 0;
    transition: transform 0.5s ease;
}
.product-card-image-wrap.is-in-view .product-card-image { transform: scale(1.0); }
.product-card:hover .product-card-image-wrap .product-card-image { transform: scale(1.03); }

.product-card-name {
    color: var(--color-heading);
    font-weight: 700;
    font-size: 16px;
    line-height: 1.3;
    margin-top: var(--space-3);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.product-card:hover .product-card-name { color: var(--color-link-hover); }
.product-card-meta {
    color: var(--sp-ink-soft);
    font-size: 13px;
    line-height: 1.4;
    margin-top: 2px;
    min-height: calc(1.4em * 2);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Pieces pill left, price right. The pill is always rendered (possibly
   empty) so price rows line up across a grid row. */
.product-card-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    margin-top: var(--space-3);
}
.product-card-row .product-card-pieces {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--sp-ink-soft);
}
.product-card-row .product-card-pieces:not(:empty) {
    padding: 3px 9px;
    background: var(--sp-surface-alt);
    border-radius: 999px;
}
.product-card-pieces { color: var(--color-text-muted); font-size: var(--text-sm); }
.product-card-price {
    font-family: var(--sp-font-display);
    font-weight: 600;
    font-size: 19px;
    color: var(--color-heading);
    white-space: nowrap;
}
.product-card-price-on-request { font-family: var(--sp-font-body); font-size: 14px; font-weight: 600; }
.product-card .add-to-cart-button { width: 100%; text-align: center; }

@media (max-width: 600px) {
    .product-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
    .product-card > a > :not(.product-card-image-wrap):not(.product-image-placeholder),
    .product-card > form, .product-card > .out-of-stock-badge, .product-card > .enquire-button {
        margin-left: 12px;
        margin-right: 12px;
    }
    .product-card-row { flex-wrap: wrap; row-gap: 6px; }
    .product-card-price { font-size: 17px; }
    .product-card .add-to-cart-button { padding: 11px 6px; font-size: 15px; white-space: nowrap; }
}

@media (prefers-reduced-motion: reduce) {
    .product-card, .product-card:hover { transform: none; }
    .product-card:hover .product-card-image-wrap .product-card-image { transform: none; }
}

.add-to-cart-form { margin-top: auto; padding-top: var(--space-3); }

/* Was completely unstyled — the only feedback on "Add to Basket" was the
   cart badge count ticking up, easy to miss. A small success pill under
   the button gives an actual visible confirmation. */
.add-to-cart-confirmation {
    margin-top: var(--space-2);
    padding: 6px 12px;
    background: var(--color-success-bg);
    color: var(--color-success);
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    font-weight: var(--font-weight-medium);
    text-align: center;
    animation: add-to-cart-fade-in 250ms ease;
}
@keyframes add-to-cart-fade-in {
    from { opacity: 0; transform: translateY(4px); }
    to { opacity: 1; transform: translateY(0); }
}

.out-of-stock-badge {
    margin-top: auto;
    padding-top: var(--space-3);
}
.out-of-stock-badge span {
    display: block;
    color: var(--color-outofstock);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: 12px 24px;
    text-align: center;
}

/* ===== /shop (visual refresh spec §5) ==================================== */
.catalogue-top { margin: var(--space-3) 0 var(--space-5); }
.catalogue-top .catalogue-heading { font-size: 40px; line-height: 1.1; margin: 0; }
.catalogue-count { margin: 6px 0 var(--space-4); color: var(--sp-ink-soft); font-weight: 600; }
.browse-tabs {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    padding-bottom: 4px;
    margin-bottom: var(--space-3);
    scrollbar-width: none;
}
.browse-tab {
    flex: none;
    padding: 9px 16px;
    border: 1px solid var(--sp-line);
    border-radius: 999px;
    background: var(--sp-surface);
    font: inherit;
    font-weight: 700;
    font-size: 15px;
    color: var(--sp-ink);
    cursor: pointer;
}
.browse-tab:hover { border-color: var(--sp-ink); }
.browse-tab[aria-selected="true"] { background: var(--sp-ink); border-color: var(--sp-ink); color: #fff; }
.browse-tab.has-active:not([aria-selected="true"])::after { content: " •"; color: var(--sp-accent-dark); }
.browse-panel { display: flex; flex-wrap: wrap; gap: 8px; }
.browse-panel[hidden] { display: none; }
.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 14px;
    border-radius: 999px;
    background: var(--sp-surface-alt);
    color: var(--sp-ink);
    font-size: 14px;
    font-weight: 600;
}
a.chip:visited { color: var(--sp-ink); }
.chip span { font-weight: 400; color: var(--sp-ink-soft); font-size: 13px; }
.chip:hover { background: var(--sp-line); color: var(--sp-ink); }
.chip.active { background: var(--sp-accent); color: var(--sp-ink); }
.chip.active span { color: var(--sp-ink); }
.chip-sub { background: var(--sp-surface); border: 1px solid var(--sp-line); }

.catalogue-layout {
    display: grid;
    grid-template-columns: 230px minmax(0, 1fr);
    gap: var(--space-5);
}
.filters details { border-bottom: 1px solid var(--sp-line); padding: 4px 0; }
.filters summary {
    list-style: none;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 0;
    font-family: var(--sp-font-display);
    font-size: 18px;
    font-weight: 600;
    color: var(--color-heading);
    cursor: pointer;
}
.filters summary::-webkit-details-marker { display: none; }
.filters summary::after { content: "+"; font-family: var(--sp-font-body); font-weight: 400; font-size: 20px; color: var(--sp-ink-soft); }
.filters details[open] > summary::after { content: "–"; }
.filters ul { list-style: none; padding: 0; margin: 0 0 var(--space-3); }
.filters li { padding: 3px 0; font-size: 15px; }
.filters a { color: var(--sp-ink-soft); }
.filters a:visited { color: var(--sp-ink-soft); }
.filters a:hover { color: var(--sp-ink); }
.filters a.active {
    color: var(--sp-ink);
    font-weight: 700;
    box-shadow: inset 3px 0 0 var(--sp-accent);
    padding-left: 8px;
}
.filters li.zero-count { opacity: 0.4; pointer-events: none; }
.filters-clear { display: inline-block; margin-bottom: var(--space-2); font-size: var(--text-sm); font-weight: 700; }
.filters-close { display: none; }

.filters-toggle-button { display: none; }

/* ===== Product page (visual refresh spec §7) ============================= */
.product-detail {
    display: grid;
    grid-template-columns: minmax(0, 55fr) minmax(0, 45fr);
    gap: var(--space-6);
    align-items: start;
    margin-top: var(--space-3);
}
.product-detail-gallery-main {
    background: #fff;
    border-radius: var(--sp-radius-lg);
    box-shadow: var(--sp-shadow);
    padding: var(--space-3);
}
.product-detail-gallery-main img { width: 100%; display: block; border-radius: var(--sp-radius); }
.product-detail-gallery-thumbs {
    display: flex;
    gap: var(--space-2);
    margin-top: var(--space-3);
    flex-wrap: wrap;
}
.product-detail-gallery-thumbs img {
    width: 76px;
    height: 76px;
    object-fit: cover;
    border-radius: var(--sp-radius-sm);
    cursor: pointer;
    border: 2px solid transparent;
    background: #fff;
}
.product-detail-gallery-thumbs img.active { border-color: var(--sp-ink); }

/* The buy box stays in view while the gallery scrolls (below the header). */
.product-detail-info { position: sticky; top: 104px; }
.product-eyebrow {
    display: inline-block;
    margin: 0 0 var(--space-3);
    padding: 4px 12px;
    border: 1.5px solid var(--sp-ink);
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--sp-ink);
}
.product-detail-info h1 { font-size: 40px; line-height: 1.15; margin: 0; }
.product-subtitle { font-size: 18px; color: var(--sp-ink-soft); margin: 8px 0 0; }
.product-chips { margin: var(--space-3) 0 0; }
.product-chips .product-card-pieces {
    display: inline-block;
    padding: 4px 12px;
    background: var(--sp-surface-alt);
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--sp-ink-soft);
}
.product-detail-price {
    font-family: var(--sp-font-display);
    font-size: 28px;
    font-weight: 600;
    color: var(--sp-ink);
    margin: var(--space-3) 0 0;
}

.purchase-panel { margin-top: var(--space-4); }
.purchase-panel .add-to-cart-form { display: flex; gap: var(--space-2); padding-top: 0; }
.purchase-panel .add-to-cart-button { flex: 1; padding: 15px 24px; font-size: 17px; }
.qty-field input {
    width: 72px;
    height: 100%;
    min-height: 50px;
    padding: 0 8px;
    border: 1.5px solid var(--sp-line);
    border-radius: var(--sp-radius-sm);
    background: #fff;
    font: inherit;
    font-weight: 700;
    text-align: center;
    color: var(--sp-ink);
}
.purchase-panel .out-of-stock-badge { padding-top: 0; }
.purchase-panel .out-of-stock-badge span {
    display: inline-block;
    padding: 8px 18px;
    border: none;
    border-radius: 999px;
    background: #E4E1DC;
    color: var(--sp-ink);
    font-weight: 700;
}
.purchase-panel .out-of-stock-badge p { margin: var(--space-2) 0 0; color: var(--sp-ink-soft); }
.purchase-panel .out-of-stock-badge a { font-weight: 700; text-decoration: underline; }

.product-copy { margin-top: var(--space-5); max-width: 60ch; }
.product-copy p { font-size: 17px; line-height: 1.65; color: var(--sp-ink); margin: 0 0 var(--space-3); }
.copy-figure {
    max-width: 440px;
    margin: var(--space-4) 0 0;
    padding: var(--space-2);
    background: #fff;
    border-radius: var(--sp-radius);
    box-shadow: var(--sp-shadow);
}
.copy-figure img { width: 100%; height: auto; border-radius: var(--sp-radius-sm); }

/* Details tabs */
.product-tabs { margin-top: var(--space-7); }
.detail-panel {
    padding: var(--space-5);
    background: var(--sp-surface);
    border-radius: var(--sp-radius);
    box-shadow: var(--sp-shadow);
}
.detail-panel[hidden] { display: none; }
.detail-panel p { line-height: 1.65; max-width: 68ch; }
.detail-panel a { text-decoration: underline; text-underline-offset: 3px; }
.product-metadata-section { margin-bottom: var(--space-4); }
.product-metadata-section:last-child { margin-bottom: 0; }
.product-metadata-section h2:not(.visually-hidden) { font-size: 22px; margin: 0 0 var(--space-3); }
.about-lead { font-weight: 700; margin: 0 0 var(--space-3); }
.checklist { list-style: none; padding: 0; margin: 0 0 var(--space-3); max-width: 68ch; }
.checklist:empty { display: none; }
.checklist li {
    position: relative;
    padding: 6px 0 6px 32px;
    line-height: 1.55;
}
.checklist li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 9px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--sp-surface-alt) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5.5 10.5l3 3 6-7' fill='none' stroke='%231F2A44' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 20px no-repeat;
}

.product-specs dl {
    display: grid;
    grid-template-columns: 140px 1fr;
    max-width: 460px;
    margin: 0;
}
.product-specs dt, .product-specs dd { padding: 10px 0; border-bottom: 1px solid var(--sp-line); margin: 0; }
.product-specs dt { color: var(--sp-ink-soft); font-weight: 600; }
.product-specs dd { color: var(--sp-ink); }

.purpose-callout {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin: var(--space-6) 0 0;
    padding: var(--space-4) var(--space-5);
    background: var(--sp-surface-alt);
    border-radius: var(--sp-radius);
    color: var(--sp-ink);
    font-weight: 600;
}
.purpose-callout .icon { color: var(--sp-heart); }
.purpose-callout a { text-decoration: underline; text-underline-offset: 3px; }

@media (max-width: 900px) {
    .product-detail-info { position: static; }
    .product-detail-info h1 { font-size: 30px; }
    .detail-panel { padding: var(--space-4); }
}

/* Cart */
.cart-line {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--color-border);
}
.cart-line-image { width: 60px; border-radius: var(--radius-sm); }
.cart-line-info { flex: 1; }

.cart-error {
    background: var(--color-error-bg);
    color: var(--color-error);
    border-radius: var(--radius-sm);
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-sm);
    margin: var(--space-2) 0;
}

/* Deliberately calmer than .cart-error: this is a transient upstream
   problem the visitor did nothing to cause and can do nothing about
   except retry, and nothing of theirs has been lost. Styling it in the
   same alarm-red as a real rejection would overstate it. */
.cart-unavailable {
    background: var(--color-surface-alt, #F4F1EC);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: var(--space-3);
    font-size: var(--text-sm);
    margin: var(--space-3) 0;
}

.out-of-stock { color: var(--color-outofstock); font-style: italic; }

.site-footer {
    margin-top: var(--space-6);
    background: var(--color-heading);
    color: rgba(255,255,255,0.75);
}
.site-footer h3 { color: #fff; font-size: var(--text-sm); margin: 0 0 var(--space-2); }
.site-footer-inner { align-items: center; }
.site-footer-mission { max-width: 560px; }
.site-footer-mission-tagline {
    color: #fff;
    font-weight: var(--font-weight-bold);
    font-size: var(--text-lg);
    margin: 0 0 var(--space-1);
}
.site-footer-mission-line { margin: 0; line-height: 1.5; }
.site-footer-meta {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--space-2);
    flex-shrink: 0;
}
.site-footer-copyright { margin: 0; font-size: var(--text-sm); }
.site-footer-admin-link {
    margin-left: var(--space-2);
    color: rgba(255,255,255,0.45);
    font-size: var(--text-xs);
    text-decoration: none;
    border-left: 1px solid rgba(255,255,255,0.25);
    padding-left: var(--space-2);
}
.site-footer-admin-link:hover { color: rgba(255,255,255,0.85); }
.social-links { display: flex; gap: var(--space-3); }
.social-links a { color: rgba(255,255,255,0.85); }
.social-links a:hover { color: #fff; }

@media (max-width: 600px) {
    .site-footer-inner { flex-direction: column; align-items: flex-start; }
    .site-footer-meta { align-items: flex-start; }
}

.htmx-indicator { display: none; }
.htmx-request .htmx-indicator { display: inline; }

/* ===== Scroll-reveal + lazy-image fade utility (used across sections) ===== */
[data-reveal] {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 300ms ease-out, transform 300ms ease-out;
    transition-delay: var(--reveal-delay, 0ms);
}
[data-reveal].is-revealed { opacity: 1; transform: translateY(0); }

img[loading="lazy"] { opacity: 0; transition: opacity 320ms ease; }
img[loading="lazy"].is-loaded { opacity: 1; }

/* ===== Category storytelling strip (design brief §D) ====================== */
.category-strip { margin: var(--space-6) 0; }
.category-strip h2 { color: var(--color-heading); margin: 0 0 var(--space-4); }
.category-strip-track {
    display: flex;
    gap: var(--space-4);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding-bottom: var(--space-2);
    -webkit-overflow-scrolling: touch;
}
.category-tile {
    position: relative;
    flex: 0 0 240px;
    aspect-ratio: 3 / 4;
    border-radius: var(--radius-md);
    overflow: hidden;
    scroll-snap-align: start;
    display: block;
}
.category-tile img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 1.1s ease, opacity 320ms ease;
}
.category-tile.is-in-view img,
.category-tile:hover img { transform: scale(1.05); }
.category-tile-scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(27,42,74,0) 45%, rgba(27,42,74,0.8) 100%);
}
.category-tile-name {
    position: absolute;
    left: var(--space-3);
    right: var(--space-3);
    bottom: var(--space-3);
    z-index: 1;
    color: #fff;
    font-weight: var(--font-weight-bold);
    font-size: var(--text-lg);
}

/* ===== Connective background flow layer (design brief §4 + §E) ============
   One low-opacity, page-level watermark of puzzle-piece/dog-silhouette
   shapes, mounted once on the homepage (templates/partials/bg_flow_layer.html)
   and given a single continuous scroll-linked drift by scroll-effects.js —
   this is what makes the hero/grid/mission/category sections read as one
   continuous space instead of a stack of separately-styled blocks. */
.bg-flow-layer {
    /* Disabled 2026-08-26: reported as a visible "overlay issue" (stray
       gray shapes) on the live preview, by more than one person looking
       at it independently. Confirmed via direct DOM inspection this was
       genuinely rendering at its coded opacity (0.06), not a bug in the
       opacity itself — the puzzle-piece silhouette's scalloped edges just
       created enough local contrast against the light background to read
       as a visible artifact rather than a subtle watermark, especially in
       a screenshot/photo. Rather than keep tuning a number that already
       failed once, retiring the whole effect — same call already made for
       viewports under 768px (see the media query below), now applied
       everywhere. Markup/JS (templates/partials/bg_flow_layer.html,
       static/js/scroll-effects.js's flow-layer block) left in place but
       inert; safe to delete outright next time this file is touched. */
    display: none;
    position: fixed;
    inset: 0;
    z-index: -1;
    overflow: hidden;
    pointer-events: none;
    will-change: transform;
}
.bg-flow-shape {
    position: absolute;
    color: var(--color-heading);
    opacity: 0.06;
}
.bg-flow-shape svg { width: 100%; height: 100%; display: block; }
.bg-flow-shape-piece { width: 90px; height: 90px; }
.bg-flow-shape-dog { width: 130px; height: 130px; }

.bg-flow-pos-1 { top: 4%;  left: 8%;  transform: rotate(-12deg); }
.bg-flow-pos-2 { top: 16%; left: 78%; transform: rotate(8deg); }
.bg-flow-pos-3 { top: 32%; left: 42%; transform: rotate(20deg); }
.bg-flow-pos-4 { top: 50%; left: 12%; transform: rotate(-6deg); }
.bg-flow-pos-5 { top: 58%; left: 68%; transform: rotate(-15deg); }
.bg-flow-pos-6 { top: 74%; left: 30%; transform: rotate(10deg); }
.bg-flow-pos-7 { top: 86%; left: 82%; transform: rotate(-20deg); }
.bg-flow-pos-8 { top: 96%; left: 4%;  transform: rotate(14deg); }

/* Responsive */

@media (max-width: 900px) {
    .product-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .catalogue-layout { grid-template-columns: 1fr; }
    .product-detail { grid-template-columns: 1fr; }

    /* Bug found 2026-08-26 via a real tablet-width (768px) check: this is
       also where .catalogue-layout above goes single-column, stacking the
       filter sidebar ABOVE the product grid instead of beside it. The
       collapsible filters-behind-a-button treatment below used to only
       kick in at 600px, so from 601-900px a shopper got the full,
       uncollapsed Piece Count + Category filter list (dozens of items)
       sitting on top of the grid — measured at ~2 full screen-heights of
       scrolling before the first product appeared. Moved here so the
       toggle covers the whole single-column range, not just phone width. */
    .filters { display: none; }
    .filters.open {
        display: block;
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        max-height: 85vh;
        z-index: 70;
        background: var(--sp-surface);
        border-radius: var(--sp-radius-lg) var(--sp-radius-lg) 0 0;
        box-shadow: 0 -10px 40px rgba(31,42,68,.25);
        overflow-y: auto;
        padding: var(--space-5) var(--space-4) var(--space-4);
    }
    .filters-close {
        display: block;
        position: sticky;
        top: 0;
        margin: -12px -8px 0 auto;
        border: none;
        background: var(--sp-surface-alt);
        width: 36px;
        height: 36px;
        border-radius: 50%;
        font-size: 22px;
        line-height: 1;
        color: var(--sp-ink);
        cursor: pointer;
    }
    /* Sticky "Browse" button (spec §5.2) opening the grouped list. */
    .filters-toggle-button {
        display: block;
        position: sticky;
        top: 72px;
        z-index: 30;
        width: 100%;
        margin-bottom: var(--space-3);
        background: var(--sp-ink);
        color: #fff;
        border: none;
        border-radius: 999px;
        padding: 12px var(--space-3);
        font: inherit;
        font-weight: 700;
        box-shadow: var(--sp-shadow);
    }
    .catalogue-top .catalogue-heading { font-size: 30px; }
}

/* Mobile gets less, not the same amount tuned down: the background flow
   layer and hero/category-strip parallax travel are dropped entirely
   below this width (scroll-effects.js also gates its own listeners on the
   same ~768px breakpoint) rather than just scaled down — phones scroll
   fast and jittery parallax reads as broken there, not elegant. */
@media (max-width: 768px) {
    .bg-flow-layer { display: none; }
    .hero { min-height: 380px; }
    .mission-band { min-height: 320px; }
    .category-tile { flex-basis: 180px; }
}

@media (max-width: 600px) {
    .product-grid { grid-template-columns: 1fr 1fr; gap: var(--space-3); }
}

@media (prefers-reduced-motion: reduce) {
    * { transition: none !important; }
}

/* ---------------------------------------------------------------------
   Tranche 1 (2026-09-03) — front-end audit remediation.
   --------------------------------------------------------------------- */

/* Screen-reader-only labels. Used by the cart quantity input and the 404
   page's search box, both of which are visually self-evident but were
   unlabelled for assistive tech. */
.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* Products this storefront can't sell itself (Mix-and-Match bundles).
   Deliberately styled as a secondary action so it reads as a different
   kind of step from "Add to Basket", not a broken version of it. */
.enquire-button {
    background: transparent;
    border: 1px solid currentColor;
    text-decoration: none;
    display: inline-block;
    text-align: center;
}
.enquire-note {
    font-size: 0.9rem;
    opacity: 0.85;
    margin: 0 0 0.5rem;
}

/* "Price on request" — for the gift vouchers, the free catalogue and the
   bundles, which have no price in WooCommerce and used to render R0.00. */
.product-card-price-on-request {
    font-style: italic;
    opacity: 0.75;
}

/* Search field: a magnifying glass so a bare input reads as a search box
   before you click into it. */
.search-input-wrap { position: relative; display: block; }
.search-input-wrap .search-input-icon {
    position: absolute;
    left: 0.75rem;
    top: 50%;
    transform: translateY(-50%);
    pointer-events: none;
    opacity: 0.6;
    font-size: 0.95rem;
}
.search-input-wrap input[type="search"] { padding-left: 2.4rem; width: 100%; }

/* 404 / 500 page. */
.error-page { max-width: 40rem; margin: 3rem auto; text-align: center; padding: 0 1rem; }
.error-page-message { opacity: 0.85; margin-bottom: 1.75rem; }
.error-page-search { display: flex; gap: 0.5rem; margin-bottom: 1.75rem; }
.error-page-search input { flex: 1; }
.error-page-links { display: flex; flex-wrap: wrap; gap: 1.25rem; justify-content: center; }

/* Footer: content and policy page links. */
.site-footer-links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem 1.5rem;
    justify-content: center;
    margin-bottom: 1rem;
    font-size: 0.9rem;
}
/* Without this the links inherit --color-link (#1B2A4A), which is also the
   footer background — they were in the HTML but invisible until 2026-09-15. */
.site-footer-links a { color: rgba(255,255,255,0.85); }
.site-footer-links a:hover { color: #fff; }

/* Policy pages (Contact Us, Shipping & Delivery, Returns & Refunds): plain
   prose inside the storefront layout. See templates/pages/policy_page.html. */
.policy-page { max-width: 46rem; margin: var(--space-5) auto var(--space-7); padding: 0 var(--space-3); line-height: 1.6; }
.policy-page h1 { font-size: var(--text-2xl); margin: 0 0 var(--space-4); }
.policy-page h2 { font-size: var(--text-lg); margin: var(--space-5) 0 var(--space-2); }
.policy-page h3 { font-size: var(--text-base); margin: var(--space-4) 0 var(--space-2); }
.policy-page p, .policy-page ul, .policy-page ol { margin: 0 0 var(--space-3); }
.policy-page li { margin-bottom: var(--space-1); }
.policy-page a { text-decoration: underline; }

/* Ratings — render only when a product actually has a review, so these
   rules sit unused until the first one lands. */
.product-card-rating, .product-detail-rating { display: flex; align-items: center; gap: 0.4rem; }
.product-card-rating { justify-content: center; font-size: 0.85rem; }
.stars { letter-spacing: 0.05em; color: #c9a227; }
.rating-count { opacity: 0.7; font-size: 0.85rem; }

/* Cross-sell strip on the product page. */
.related-products { margin: var(--space-7) 0 0; }
.related-products h2 { font-size: 36px; margin: 0 0 var(--space-4); }

/* Puzzle Club signup in the footer. */
.site-footer-newsletter { text-align: center; margin-bottom: 1.5rem; }
.site-footer-newsletter-title { font-weight: 600; margin: 0 0 0.25rem; }
.site-footer-newsletter-blurb { margin: 0 0 0.75rem; opacity: 0.8; font-size: 0.9rem; }
.newsletter-form { display: flex; gap: 0.5rem; justify-content: center; flex-wrap: wrap; }
.newsletter-form input[type="email"] { min-width: 15rem; }

/* Reviews — display and submission. Honeypot must be genuinely invisible
   but NOT display:none, which some bots skip. */
.review-list { list-style: none; padding: 0; margin: 0 0 1.5rem; }
.review { padding: 1rem 0; border-bottom: 1px solid rgba(0,0,0,0.08); }
.review-head { display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap; margin-bottom: 0.35rem; }
.review-author { font-weight: 600; }
.review-verified {
    font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em;
    background: #d8efdc; color: #1c5b2c; padding: 0.1rem 0.4rem; border-radius: 3px;
}
.review-date { opacity: 0.6; font-size: 0.85rem; margin-left: auto; }
.review-body { line-height: 1.6; }
.review-empty { opacity: 0.75; }
.review-form-wrap summary { cursor: pointer; font-weight: 600; padding: 0.5rem 0; }
.review-form { display: flex; flex-direction: column; gap: 0.35rem; max-width: 32rem; margin-top: 0.75rem; }
.review-form label { font-weight: 600; margin-top: 0.5rem; }
.review-form .field-hint { font-size: 0.85rem; opacity: 0.7; margin: 0; }
.review-form button { margin-top: 0.75rem; align-self: flex-start; }
.review-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.review-thanks { margin-top: 0.75rem; padding: 0.75rem 1rem; background: #d8efdc; color: #1c5b2c; border-radius: 4px; }
.review-error { margin-top: 0.75rem; }

/* Shop menu from the admin (2026-10-23): a collection opens to its themes. */
.filter-themes { list-style: none; margin: var(--space-1) 0 var(--space-1) var(--space-3); padding: 0; }
.filter-themes li { padding: 2px 0; font-size: var(--text-sm); }
.catalogue-heading { font-size: var(--text-xl, 1.5rem); color: var(--color-heading); margin: 0 0 var(--space-3); }

/* ===== Footer, cart, search, content pages (visual refresh §4.8, §8) ===== */
.site-footer {
    margin-top: var(--space-5);
    background: var(--sp-surface-alt);
    color: var(--sp-ink);
    padding: var(--space-6) 0 var(--space-4);
    border-top: 1px solid var(--sp-line);
}
.site-footer .site-footer-inner {
    display: grid;
    grid-template-columns: 1.4fr 1fr 1fr 1.4fr;
    gap: var(--space-5);
    align-items: start;
    padding: 0 var(--space-4);
}
.footer-col { display: flex; flex-direction: column; gap: 8px; }
.site-footer h3, .site-footer .site-footer-newsletter-title {
    font-family: var(--sp-font-display);
    font-size: 18px;
    font-weight: 600;
    color: var(--sp-ink);
    margin: 0 0 4px;
}
.site-footer a, .site-footer a:visited { color: var(--sp-ink-soft); }
.site-footer a:hover { color: var(--sp-ink); text-decoration: underline; }
.site-footer .site-footer-mission-tagline { font-family: var(--sp-font-display); font-size: 22px; font-weight: 600; color: var(--sp-ink); margin: 0; }
.site-footer .site-footer-mission-line { color: var(--sp-ink-soft); font-size: 15px; line-height: 1.6; margin: 0; }
.footer-heart-link { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; }
.site-footer a.footer-heart-link, .site-footer a.footer-heart-link:visited { color: var(--sp-heart-ink); }
.footer-heart-link .icon { width: 16px; height: 16px; }
.site-footer .site-footer-newsletter { text-align: left; margin: 0; }
.site-footer .site-footer-newsletter-blurb { color: var(--sp-ink-soft); opacity: 1; margin: 0; font-size: 15px; }
.site-footer .newsletter-form { justify-content: flex-start; flex-wrap: nowrap; margin-top: 6px; }
.site-footer .newsletter-form input[type="email"] {
    flex: 1;
    min-width: 0;
    padding: 11px 14px;
    border: 1.5px solid var(--sp-line);
    border-radius: var(--sp-radius-sm);
    background: #fff;
    font: inherit;
    font-size: 15px;
}
.site-footer .newsletter-form button {
    padding: 11px 16px;
    border: none;
    border-radius: var(--sp-radius-sm);
    background: var(--sp-ink);
    color: #fff;
    font: inherit;
    font-weight: 700;
    cursor: pointer;
}
.site-footer .social-links { display: flex; gap: 8px; margin-top: var(--space-3); }
.site-footer .social-links a {
    display: inline-flex;
    padding: 9px;
    border-radius: 50%;
    background: #fff;
    color: var(--sp-ink);
}
.site-footer .social-links a:hover { background: var(--sp-ink); color: #fff; }
.site-footer .site-footer-copyright {
    max-width: 1200px;
    margin: var(--space-5) auto 0;
    padding: var(--space-3) var(--space-4) 0;
    border-top: 1px solid var(--sp-line);
    color: var(--sp-ink-soft);
    font-size: 13px;
}
@media (max-width: 900px) {
    .site-footer .site-footer-inner { grid-template-columns: 1fr 1fr; }
    .footer-about, .site-footer-newsletter { grid-column: 1 / -1; }
}

/* Cart: lines as cards, totals on birch */
.cart-page h1 { font-size: 40px; margin: var(--space-3) 0 var(--space-4); }
.cart-line {
    gap: var(--space-3);
    padding: var(--space-3);
    margin-bottom: var(--space-3);
    background: var(--sp-surface);
    border: none;
    border-radius: var(--sp-radius);
    box-shadow: var(--sp-shadow);
}
.cart-line-image { width: 84px; height: 84px; object-fit: contain; background: #fff; border-radius: var(--sp-radius-sm); }
.cart-line-name { font-weight: 700; margin-bottom: 6px; }
.cart-line-qty-form input {
    width: 70px;
    padding: 8px;
    border: 1.5px solid var(--sp-line);
    border-radius: var(--sp-radius-sm);
    font: inherit;
    font-weight: 700;
    text-align: center;
}
.cart-line-remove { background: none; border: none; padding: 4px 0; color: var(--sp-ink-soft); text-decoration: underline; cursor: pointer; font: inherit; font-size: 14px; }
.cart-line-total { font-family: var(--sp-font-display); font-weight: 600; font-size: 19px; }
.cart-totals {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
    max-width: 420px;
    margin: var(--space-4) 0 0 auto;
    padding: var(--space-4);
    background: var(--sp-surface-alt);
    border-radius: var(--sp-radius);
}
.cart-totals .cart-subtotal { font-family: var(--sp-font-display); font-size: 22px; font-weight: 600; margin: 0; }
.cart-totals .checkout-cta { text-align: center; padding: 15px 24px; font-size: 17px; }
.shipping-note { color: var(--sp-ink-soft); text-align: right; }
@media (max-width: 600px) {
    .cart-line { flex-wrap: wrap; }
    .cart-totals { max-width: none; }
    .shipping-note { text-align: left; }
}

/* Search */
.search-page h1 { font-size: 40px; margin: var(--space-3) 0 var(--space-4); }
.search-input-wrap { max-width: 640px; margin-bottom: var(--space-5); }
.search-input-wrap .search-input-icon { left: 18px; color: var(--sp-ink-soft); }
.search-input-wrap input[type="search"] {
    padding: 16px 20px 16px 52px;
    border: 1.5px solid var(--sp-line);
    border-radius: 999px;
    background: #fff;
    font: inherit;
    font-size: 18px;
    box-shadow: var(--sp-shadow);
}
.search-input-wrap input[type="search"]:focus { outline: 2px solid var(--sp-ink); outline-offset: 2px; }

/* Our Story, policy pages: readable prose */
.policy-page { max-width: 68ch; font-size: 17px; line-height: 1.7; }
.policy-page h1 { font-size: 44px; line-height: 1.1; }
.policy-page h2 { font-size: 26px; }
.policy-page h3 { font-size: 20px; }
.policy-page img { border-radius: var(--sp-radius); }
.policy-page blockquote {
    margin: var(--space-4) 0;
    padding-left: var(--space-4);
    border-left: 3px solid var(--sp-line);
    font-family: var(--sp-font-display);
    font-size: 21px;
    color: var(--sp-ink);
}

/* Card out-of-stock: the same calm grey pill as the product page, not an
   empty-looking outlined box (spec §7.3). */
.product-card .out-of-stock-badge span {
    border: none;
    border-radius: var(--sp-radius-sm);
    background: #E4E1DC;
    color: var(--sp-ink);
    font-weight: 700;
}

/* Catalogue page (/catalogue, 2026-10-24): the whole range from the admin as
   one sortable table — the owner's catalogue, in the site's design. */
.owner-catalogue-top .eyebrow { margin-bottom: var(--space-2); }
.owner-catalogue-lead { max-width: 62ch; margin: var(--space-3) 0 0; color: var(--sp-ink-soft); font-size: var(--text-lg); }
.owner-catalogue-download { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); margin: var(--space-4) 0 0; }
.owner-catalogue-download small { color: var(--sp-ink-soft); font-size: var(--text-sm); }
.owner-catalogue {
    background: var(--sp-surface); border: 1px solid var(--sp-line);
    border-radius: var(--sp-radius); box-shadow: var(--sp-shadow); overflow: hidden;
}
.owner-catalogue-tools {
    display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center;
    padding: var(--space-4); border-bottom: 1px solid var(--sp-line); background: var(--sp-surface-alt);
}
.owner-catalogue-tools label { display: inline-flex; gap: var(--space-2); align-items: center; max-width: 100%; font-weight: 600; color: var(--sp-ink); }
.owner-catalogue-tools input[type="search"], .owner-catalogue-tools select {
    font: inherit; font-weight: 400; color: var(--sp-ink); background: var(--sp-surface);
    border: 1px solid var(--sp-line); border-radius: 999px; padding: 8px 16px; max-width: 100%;
}
.owner-catalogue-tools input[type="search"] { flex: 1 1 240px; }
.owner-catalogue-tools input:focus-visible, .owner-catalogue-tools select:focus-visible { outline: 2px solid var(--sp-accent); outline-offset: 2px; }
.owner-catalogue-check input { accent-color: var(--sp-accent); width: 18px; height: 18px; }
.owner-catalogue-tools .catalogue-count { margin: 0 0 0 auto; }
.owner-catalogue-scroll { overflow-x: auto; max-height: 78vh; }
.owner-catalogue table { width: 100%; border-collapse: collapse; font-size: var(--text-base); }
.owner-catalogue thead th {
    position: sticky; top: 0; z-index: 1; background: var(--sp-surface);
    border-bottom: 2px solid var(--sp-line); padding: 0; text-align: left; white-space: nowrap;
}
.owner-catalogue thead th button {
    font: inherit; font-weight: 700; font-size: var(--text-sm); text-transform: uppercase; letter-spacing: .04em;
    color: var(--sp-ink-soft); background: none; border: 0; cursor: pointer; padding: 12px 14px; width: 100%; text-align: inherit;
}
.owner-catalogue thead th button:hover { color: var(--sp-ink); }
.owner-catalogue thead th button::after { content: " \2195"; opacity: .4; }
.owner-catalogue thead th[aria-sort] button { color: var(--sp-ink); }
.owner-catalogue thead th[aria-sort="ascending"] button::after { content: " \2191"; opacity: 1; color: var(--sp-accent-dark); }
.owner-catalogue thead th[aria-sort="descending"] button::after { content: " \2193"; opacity: 1; color: var(--sp-accent-dark); }
.owner-catalogue th.num, .owner-catalogue td.num { text-align: right; white-space: nowrap; }
.owner-catalogue tbody td { padding: 10px 14px; border-bottom: 1px solid var(--sp-line); vertical-align: middle; color: var(--sp-ink-soft); }
.owner-catalogue tbody tr:hover { background: var(--sp-bg); }
.owner-catalogue td.pic { width: 72px; }
.owner-catalogue td.pic img { display: block; width: 56px; height: 56px; object-fit: cover; border-radius: var(--sp-radius-sm); background: var(--sp-surface-alt); }
.owner-catalogue td.name a { font-family: var(--sp-font-display); font-size: 18px; color: var(--sp-ink); text-decoration: none; }
.owner-catalogue td.name a:hover { color: var(--color-link-hover); }
.owner-catalogue td.name small { display: block; font-size: var(--text-sm); color: var(--sp-ink-soft); }
.owner-catalogue td.price { font-family: var(--sp-font-display); font-weight: 600; color: var(--sp-ink); }
.owner-catalogue .out-of-stock-text { display: inline-block; margin-top: 2px; font-size: var(--text-xs); font-weight: 700; color: var(--color-outofstock); text-transform: uppercase; letter-spacing: .04em; }
.owner-catalogue-none { padding: var(--space-5); text-align: center; color: var(--sp-ink-soft); }
.owner-catalogue-purpose {
    margin: var(--space-5) 0; padding: var(--space-4) var(--space-5);
    background: var(--sp-surface); border: 1px solid var(--sp-line); border-left: 4px solid var(--sp-heart);
    border-radius: var(--sp-radius);
}
.owner-catalogue-purpose p:last-child { margin: 0; color: var(--sp-ink); }
@media (max-width: 700px) {
    .owner-catalogue .hide-sm { display: none; }
    .owner-catalogue-tools { padding: var(--space-3); }
    .owner-catalogue-tools label { display: flex; width: 100%; }
    .owner-catalogue-tools select { flex: 1; min-width: 0; width: 100%; }
    .owner-catalogue-tools .catalogue-count { margin-left: 0; }
    .owner-catalogue thead th button { padding: 10px 8px; }
    .owner-catalogue tbody td { padding: 10px 8px; }
    .owner-catalogue td.name a { font-size: 16px; }
    .owner-catalogue-top .catalogue-heading { font-size: 32px; }
}
