/* ------------------------------------------------------------------
   Components — nav, hamburger drawer, hero, product card, footer, forms
   Mobile-first; breakpoints layer on at 768px and 1024px.
   ------------------------------------------------------------------ */

/* ---- Sticky nav -------------------------------------------------- */
.site-nav {
    position: sticky;
    top: 0;
    z-index: 100;
    background: #fff;
    border-bottom: 1px solid var(--color-border);
    box-shadow: var(--shadow-sm);
}

/* 0.75.6 — Pink horizontal menu bar with white pill-button tabs (0.75.7
   pop-pass). Sits directly under .site-nav, sticky just under the nav so
   it stays visible as the page scrolls. Brand-pink background with white
   rounded-pill buttons sitting on top — directly inherits the .hero-jump
   chip aesthetic that previously appeared under the homepage banner
   (0.75.6 removed those; this layer brings the pop back into the bar). */
.site-menu {
    position: sticky;
    top: var(--nav-height-mobile);
    z-index: 99;
    background: var(--color-primary);
    box-shadow: var(--shadow-sm);
}
@media (min-width: 768px) {
    .site-menu { top: var(--nav-height); }
}
.site-menu__inner {
    display: flex;
    justify-content: center;
    gap: var(--space-3);
    padding: var(--space-3) 0;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
.site-menu__link {
    display: inline-flex;
    align-items: center;
    background: #fff;
    color: var(--color-primary-dark);
    border: 2px solid #fff;
    border-radius: 999px;
    padding: 8px 22px;
    font-weight: 600;
    font-size: 14px;
    text-decoration: none;
    white-space: nowrap;
    /* 0.75.8 — inset 1.5px brand-pink ring just inside the white pill,
       independent of the outer border, for extra pop against the bar. */
    box-shadow: inset 0 0 0 1.5px var(--color-primary);
    transition: background 120ms ease, color 120ms ease, transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease;
}
.site-menu__link:hover,
.site-menu__link:focus-visible {
    background: var(--color-primary-dark);
    color: #fff;
    border-color: var(--color-primary-dark);
    transform: translateY(-1px);
    /* Combine inset ring (same colour as bg now so it disappears) + lift shadow. */
    box-shadow: inset 0 0 0 1.5px var(--color-primary-dark), 0 2px 8px rgba(0,0,0,0.18);
    text-decoration: none;
}
@media (max-width: 767px) {
    /* 0.75.15 — centre the three pill destinations on mobile (was
       flex-start). overflow-x: auto on .site-menu__inner is retained
       above so 4+ destinations would still horizontal-scroll cleanly. */
    .site-menu__inner { justify-content: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); }
    .site-menu__link  { padding: 6px 16px; font-size: 13px; }
}
.site-nav__inner {
    height: var(--nav-height-mobile);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
}
@media (min-width: 768px) {
    .site-nav__inner { height: var(--nav-height); }
}
/* 0.75.18 — stacked mobile header. Single-row flex layout was pushing
   the hamburger (and sometimes Cart) off-screen on iPhone Pro Max
   because logo + search input + 3 actions don't fit in 430px. Grid
   restructures to: row 1 = logo (left) + actions justified end
   (Sign in / Cart / hamburger); row 2 = search input spanning full
   width. height: auto + min-height keeps the sticky offset on
   .site-menu (which uses --nav-height-mobile as its top) in sync. */
@media (max-width: 767px) {
    .site-nav__inner {
        display: grid;
        grid-template-columns: auto 1fr;
        grid-template-rows: auto auto;
        height: auto;
        min-height: var(--nav-height-mobile);
        row-gap: var(--space-2);
        align-items: center;
    }
    .site-nav__brand   { grid-row: 1; grid-column: 1; }
    .site-nav__actions { grid-row: 1; grid-column: 2; justify-self: end; }
    .site-nav__search  {
        grid-row: 2;
        grid-column: 1 / -1;
        margin: 0;
        max-width: none;
        min-width: 0;
        flex: 0 1 auto;
    }
}

.site-nav__brand {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-bold);
    color: var(--color-primary);
    text-decoration: none;
    letter-spacing: -0.01em;
    white-space: nowrap;
    flex-shrink: 0;
    line-height: 1.1;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}
.site-nav__brand:hover { text-decoration: none; }
.site-nav__logo {
    height: 88px;
    width: auto;
    display: block;
}
@media (min-width: 768px) {
    .site-nav__logo { height: 128px; }
}
.site-nav__brand small {
    display: block;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-body);
    color: var(--color-text-muted);
    letter-spacing: 0.05em;
    text-transform: uppercase;
}
@media (max-width: 479px) {
    /* At the narrowest widths, drop the "PREORDER" subtitle so the brand
       sits comfortably alongside the action buttons without wrapping. */
    .site-nav__brand { font-size: var(--font-size-base); }
    .site-nav__brand small { display: none; }
    .site-nav__logo { height: 72px; }
}

.site-nav__links {
    display: none;
    align-items: center;
    gap: var(--space-5);
    list-style: none;
    margin: 0;
    padding: 0;
}
.site-nav__links a {
    color: var(--color-text);
    font-weight: var(--font-weight-medium);
    padding: var(--space-2) 0;
}
.site-nav__links a:hover,
.site-nav__links a[aria-current="page"] {
    color: var(--color-primary);
    text-decoration: none;
    border-bottom: 2px solid var(--color-primary);
}
@media (min-width: 1024px) {
    .site-nav__links { display: flex; }
}

.site-nav__actions {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-shrink: 0;
}
@media (max-width: 767px) {
    /* 0.75.15 — swap which auth CTA stays in the top bar on mobile.
       Previously Sign in was hidden + Create account remained pink-
       buttoned in the bar; the drawer carried Sign in. Colin's feedback
       2026-05-15: Sign in is the only obvious mobile CTA users hunt for,
       and Create account belongs in the drawer alongside Sign in's
       partner action. So: Sign in stays visible, Create account moves
       to the drawer. Drawer NAV_HTML already lists both, so the swap
       costs nothing on the drawer side.
       Account + Sign out + VAT toggle remain drawer-only on mobile
       (synced via drawer's own .vat-toggle). */
    .site-nav__actions [data-auth-signup],
    .site-nav__actions [data-auth-account],
    .site-nav__actions [data-auth-signout],
    .site-nav__actions > .vat-toggle {
        display: none !important;
    }
    .site-nav__actions { gap: var(--space-2); }
}

/* VAT toggle inside the drawer — sits below the menu list, label on the
   right of the toggle so it reads as "VAT (toggle) · ex. VAT". */
.nav-drawer__vat-row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-top: var(--space-4);
    padding-top: var(--space-4);
    border-top: 1px solid rgba(255, 255, 255, 0.15);
}

/* ---------- Global search (top nav) ---------- */
.site-nav__search {
    position: relative;
    flex: 1 1 280px;
    max-width: 420px;
    min-width: 180px;
    margin: 0 var(--space-3);
}
.site-nav__search-input {
    width: 100%;
    padding: 8px 12px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--color-primary);
    background: #fff;
    color: var(--color-text);
    font-size: var(--font-size-sm);
}
.site-nav__search-input:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-tint, rgba(233,30,99,0.15));
}
.site-nav__search-dropdown {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    max-height: 420px;
    overflow-y: auto;
    background: #fff;
    border: 1px solid var(--color-primary);
    border-radius: var(--radius-sm);
    box-shadow: 0 8px 24px rgba(0,0,0,0.12);
    z-index: 200;
}
.site-nav__search-dropdown[hidden] { display: none; }
.site-nav__search-empty {
    padding: var(--space-4);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}
.site-nav__search-row {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-3);
    border-bottom: 1px solid var(--color-border);
}
.site-nav__search-row:last-child { border-bottom: none; }
.site-nav__search-variant {
    flex: 1;
    display: block;
    color: var(--color-text);
    text-decoration: none;
    padding: 4px 6px;
    border-radius: 4px;
    min-width: 0;
}
.site-nav__search-variant:hover,
.site-nav__search-result--active {
    background: var(--color-primary-tint, rgba(233,30,99,0.08));
    text-decoration: none;
}
.site-nav__search-variant-head { display: flex; gap: 4px; align-items: baseline; flex-wrap: wrap; }
.site-nav__search-pos {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex-shrink: 0;
    min-width: 110px;
    align-items: flex-end;
}
.site-nav__search-po {
    display: inline-flex;
    gap: 6px;
    align-items: baseline;
    padding: 3px 8px;
    border-radius: 999px;
    background: var(--color-primary-tint, rgba(233,30,99,0.12));
    color: var(--color-primary);
    font-size: 11px;
    text-decoration: none;
    white-space: nowrap;
}
.site-nav__search-po:hover,
.site-nav__search-po.site-nav__search-result--active {
    background: var(--color-primary);
    color: #fff;
    text-decoration: none;
}
@media (max-width: 767px) {
    /* Tight enough to share the 375px container with logo + cart + hamburger
       without pushing the actions block off-screen. min-width: 90 leaves a
       readable input on iPhone SE (320 px) too. */
    .site-nav__search { margin: 0 var(--space-2); min-width: 90px; flex: 1; }
    .site-nav__search-input { padding: 6px 10px; font-size: 13px; }
    .site-nav__search-pos { min-width: 90px; }
}

/* ---------- Product page: "Due in on these shipments" list ---------- */
.product-detail__po-list {
    border: 1px solid var(--color-primary);
    border-radius: var(--radius-sm);
    padding: var(--space-4);
    background: #fff;
}
.product-detail__po-list-heading {
    margin: 0 0 var(--space-3);
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-bold);
    color: var(--color-text);
}
.product-detail__po-list-items {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}
.product-detail__po-row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    border: 1px solid var(--color-primary);
    border-radius: var(--radius-sm);
    background: var(--color-primary-tint, rgba(233,30,99,0.04));
}
.product-detail__po-chip {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    border: 1px solid var(--color-primary);
    border-radius: 999px;
    background: #fff;
    color: var(--color-primary);
    font-weight: var(--font-weight-bold);
    font-size: var(--font-size-sm);
    text-decoration: none;
    white-space: nowrap;
}
.product-detail__po-chip:hover {
    background: var(--color-primary);
    color: #fff;
    text-decoration: none;
}
.product-detail__po-meta {
    flex: 1;
    min-width: 0;
}
.product-detail__po-link {
    color: var(--color-primary);
    font-weight: var(--font-weight-bold);
    font-size: var(--font-size-sm);
    text-decoration: none;
    white-space: nowrap;
}
.product-detail__po-link:hover { text-decoration: underline; }
@media (max-width: 520px) {
    .product-detail__po-row { flex-wrap: wrap; }
    .product-detail__po-link { width: 100%; text-align: right; }
}

/* 0.80.0 — Due In / Pre Alloc / Allocated to you / Ordered / Available
   grid inside each PO row on the product page. Compact horizontal layout
   that flow-wraps on narrow viewports. */
.product-detail__po-breakdown {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: var(--space-2) var(--space-3);
    margin-top: var(--space-2);
    font-size: var(--font-size-sm);
}
.product-detail__po-breakdown .text-xs { line-height: 1.2; margin-bottom: 2px; }
.product-detail__po-row--fully-allocated {
    background: rgba(0, 0, 0, 0.02);
    border-color: rgba(0, 0, 0, 0.08);
}
.product-detail__po-row--fully-allocated .product-detail__po-chip {
    background: var(--color-text-muted);
}

.vat-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-size-sm);
    user-select: none;
    padding: var(--space-3) var(--space-5);
    border: 1px solid var(--color-primary);
    border-radius: var(--radius-sm);
    background: #fff;
    color: var(--color-primary);
    font-weight: var(--font-weight-bold);
    cursor: pointer;
}
.vat-toggle:hover {
    background: var(--color-primary-tint, rgba(233,30,99,0.08));
}
.vat-toggle__switch {
    width: 36px;
    height: 20px;
    border-radius: 10px;
    background: #ddd;
    position: relative;
    cursor: pointer;
    transition: background 0.15s ease;
}
.vat-toggle__switch::after {
    content: '';
    position: absolute;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #fff;
    top: 2px;
    left: 2px;
    transition: left 0.15s ease;
}
.vat-toggle[data-state="inc"] .vat-toggle__switch {
    background: var(--color-primary);
}
.vat-toggle[data-state="inc"] .vat-toggle__switch::after {
    left: 18px;
}

/* Hamburger */
.hamburger {
    width: 32px; height: 32px;
    border: none; background: transparent; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
}
.hamburger span {
    width: 20px; height: 2px; background: var(--color-text);
    position: relative;
}
.hamburger span::before, .hamburger span::after {
    content: ''; position: absolute; left: 0; width: 20px; height: 2px; background: var(--color-text);
}
.hamburger span::before { top: -6px; }
.hamburger span::after  { top: 6px; }
@media (min-width: 1024px) { .hamburger { display: none; } }

/* Mobile drawer */
.nav-drawer {
    position: fixed;
    top: 0; right: 0; bottom: 0;
    width: 80%; max-width: 360px;
    background: #fff;
    box-shadow: var(--shadow-lg);
    transform: translateX(100%);
    transition: transform 0.25s ease;
    z-index: 200;
    padding: var(--space-5);
    overflow-y: auto;
}
.nav-drawer[aria-hidden="false"] { transform: translateX(0); }
.nav-drawer__backdrop {
    position: fixed; inset: 0; background: rgba(0,0,0,0.4);
    opacity: 0; pointer-events: none; transition: opacity 0.2s ease;
    z-index: 150;
}
.nav-drawer[aria-hidden="false"] + .nav-drawer__backdrop,
.nav-drawer__backdrop[data-open="true"] {
    opacity: 1; pointer-events: auto;
}
.nav-drawer ul { list-style: none; padding: 0; }
.nav-drawer li { margin: 0 0 var(--space-3); }
.nav-drawer a {
    color: var(--color-text);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-medium);
}
.nav-drawer__close {
    position: absolute; top: var(--space-3); right: var(--space-3);
    background: transparent; border: none; font-size: 24px; cursor: pointer;
}

/* ---- Hero -------------------------------------------------------- */
.hero {
    padding: var(--space-6) 0 var(--space-7);
    text-align: center;
}
.hero__title {
    font-size: var(--font-size-h1);
    color: var(--color-primary);
    margin-bottom: var(--space-3);
}
@media (min-width: 768px) {
    .hero { padding: var(--space-8) 0; }
    .hero__title { font-size: var(--font-size-hero); }
}
.hero__subtitle { color: var(--color-text-muted); margin-bottom: var(--space-5); }
.hero__preorder-band {
    display: inline-block;
    padding: var(--space-2) var(--space-4);
    background: var(--color-primary-tint);
    color: var(--color-primary-dark);
    border-radius: var(--radius-md);
    font-weight: var(--font-weight-medium);
    font-size: var(--font-size-sm);
    margin-bottom: var(--space-4);
}

/* ---- Product grid + card ---------------------------------------- */
.product-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: var(--space-4);
}
@media (min-width: 768px) {
    .product-grid { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--space-5); }
}

.product-card {
    background: #fff;
    border: 1px solid var(--color-primary);
    border-radius: var(--radius-sm);
    padding: var(--space-3);
    transition: box-shadow 0.15s ease, border-color 0.15s ease;
    display: flex; flex-direction: column;
    position: relative;
}
.product-card:hover { box-shadow: var(--shadow-md); }
.product-card__image {
    aspect-ratio: 1 / 1;
    background: var(--color-bg-alt);
    border-radius: var(--radius-sm);
    object-fit: contain;
    margin-bottom: var(--space-3);
}
.product-card__name {
    font-weight: var(--font-weight-medium);
    font-size: var(--font-size-sm);
    margin-bottom: var(--space-2);
    line-height: 1.3;
    color: var(--color-text);
    min-height: 2.6em;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.product-card__sku { font-size: var(--font-size-xs); color: var(--color-text-muted); }
.product-card__pack { font-size: var(--font-size-xs); color: var(--color-text-muted); margin-bottom: var(--space-2); }
.product-card__eta {
    font-size: var(--font-size-xs);
    background: var(--color-primary-tint);
    color: var(--color-primary-dark);
    padding: 2px var(--space-2);
    border-radius: 10px;
    display: inline-block;
    margin-bottom: var(--space-2);
    font-weight: var(--font-weight-medium);
}
.product-card__price {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-bold);
    color: var(--color-text);
    margin-top: auto;
    margin-bottom: var(--space-2);
}
.product-card__price small { font-size: var(--font-size-xs); color: var(--color-text-muted); font-weight: var(--font-weight-body); }
.product-card__add {
    margin-top: var(--space-2);
    font-size: var(--font-size-sm);
    padding: var(--space-2) var(--space-3);
}

/* ---- Product detail --------------------------------------------- */
.product-detail {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-5);
    margin: var(--space-5) 0;
}
@media (min-width: 768px) {
    .product-detail { grid-template-columns: 5fr 6fr; gap: var(--space-7); }
}
.product-detail__image {
    aspect-ratio: 1 / 1;
    background: var(--color-bg-alt);
    border-radius: var(--radius-md);
    object-fit: contain;
    width: 100%;
}
.product-detail__price { font-size: 28px; font-weight: var(--font-weight-bold); margin: var(--space-3) 0; }
.qty-input {
    display: inline-flex;
    align-items: center;
    border: 1px solid var(--color-primary);
    border-radius: var(--radius-sm);
    overflow: hidden;
    width: 120px;
}
.qty-input button { background: #fff; border: none; width: 36px; height: 42px; cursor: pointer; font-size: 18px; touch-action: manipulation; }
.qty-input button:hover { background: var(--color-bg-alt); }
.qty-input input {
    border: none;
    text-align: center;
    flex: 1;
    height: 42px;
    padding: 0;
    min-width: 0;
    appearance: textfield;
    -moz-appearance: textfield;
}
.qty-input input::-webkit-outer-spin-button,
.qty-input input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.qty-input input:focus { outline: none; }

/* 0.75.22 — global mobile bump for qty steppers (brand-listing cards,
   brand-product page, cart). 36x42 default fails Apple HIG 44x44 tap
   target minimum; below that, two missed taps in a row trigger iOS
   double-tap-zoom. touch-action: manipulation on .qty-input button
   above kills the zoom; this rule prevents the missed taps that
   were causing the zoom in the first place. /po page has its own
   48x48 override inside the @media block further down. */
@media (max-width: 767px) {
    .qty-input { height: 48px; width: 100%; }
    .qty-input button { width: 48px; height: 48px; font-size: 20px; }
    .qty-input input { height: 48px; }
}

/* ---- Cart + checkout tables -------------------------------------- */
.cart-table { width: 100%; border-collapse: collapse; }
.cart-table th, .cart-table td { padding: var(--space-3); border-bottom: 1px solid var(--color-border); text-align: left; }
.cart-table th { font-weight: var(--font-weight-medium); color: var(--color-text-muted); font-size: var(--font-size-sm); text-transform: uppercase; letter-spacing: 0.03em; }
/* 0.26.3: Unit price + VAT columns are detail-only — desktop trade users
   want the per-line breakdown (invoice-style verification), but on phones
   they push Qty and Remove off-screen. Hide both under 768 px; the totals
   box at the foot of the cart still shows aggregate VAT for mobile users. */
@media (max-width: 767px) {
    .cart-table .cart-table__col--detail { display: none; }
    /* 0.75.23 — cart-table → stacked card per row on mobile. Even with
       the .cart-table__col--detail columns hidden, the remaining 4
       columns (Item, Qty, Line total, Remove) compete for ~398px of
       viewport — and after 0.75.22 the qty stepper grew to 144px wide,
       which crushed the Item column to ~80px so product names wrapped
       character-by-character. Convert each <tr> into a stacked card
       (image+name row 1, qty stepper row 2, line total + Remove row 3).
       Markup stays as a <table> — pure CSS. */
    .cart-table thead { display: none; }
    .cart-table, .cart-table tbody, .cart-table tbody tr { display: block; }
    .cart-table tbody tr {
        padding: var(--space-3) 0;
        border-bottom: 1px solid var(--color-border);
    }
    .cart-table tbody td {
        display: block;
        padding: 0;
        border: none;
        min-width: 0;
        width: auto;
    }
    /* The Item cell (1st td) keeps its existing .cart-item flex layout
       so image + name stay side-by-side. */
    .cart-table tbody td + td { margin-top: var(--space-3); }
    /* Qty cell — qty-input is already 100% wide on mobile from 0.75.22 */
    .cart-table tbody tr > td:nth-child(2) .qty-input { width: 100%; }
    /* Line total cell — synthesise a 'Total:' label since thead is hidden. */
    .cart-table tbody tr > td:nth-last-child(2) {
        font-weight: var(--font-weight-bold);
        font-size: var(--font-size-lg);
    }
    .cart-table tbody tr > td:nth-last-child(2)::before {
        content: 'Total: ';
        color: var(--color-text-muted);
        font-weight: var(--font-weight-body);
        font-size: var(--font-size-base);
        margin-right: var(--space-2);
    }
    /* Remove button — full width on its own row. */
    .cart-table tbody tr > td:last-child .btn {
        display: block;
        width: 100%;
        text-align: center;
    }
}
/* 0.26.4: variant thumbnail in the Item cell so customers visually
   recognise their basket lines. 56 px desktop, 40 px mobile so the row
   doesn't bloat. object-fit: cover keeps non-square images centred
   without distortion; placeholder.svg renders at the same dims. */
.cart-item { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.cart-item__thumb {
    /* 0.31.1 — bumped from 56 → 80 desktop (40 → 56 mobile) so the basket
       image is properly visible. Cart row has width to accommodate. */
    width: 80px;
    height: 80px;
    border-radius: 6px;
    object-fit: cover;
    flex: 0 0 auto;
    background: var(--color-surface-2, #f5f5f5);
}
.cart-item__text { min-width: 0; flex: 1 1 auto; }
@media (max-width: 767px) {
    .cart-item__thumb { width: 56px; height: 56px; }
}
/* 0.26.5: bumped 360 → 420. The 0.26.4-era totals box squeezed both
   "Shipping (ex. VAT)" (label wrapped to 2 lines) and the new ETA copy
   ("Ships Tue 5 May, delivers Wed 6 May" wrapped mid-sentence). 420 fits
   both at base font; the cart card is wider than this so no overflow. */
.cart-totals { max-width: 420px; margin-left: auto; margin-top: var(--space-5); }
.cart-totals__row { display: flex; justify-content: space-between; padding: var(--space-2) 0; }
.cart-totals__row--grand { border-top: 2px solid var(--color-text); padding-top: var(--space-3); font-weight: var(--font-weight-bold); font-size: var(--font-size-lg); }

/* ---- Footer ------------------------------------------------------ */
/* 0.74.47: full spec mirror of sweetandglory.com main-site footer —
   color #666, 14px body / 18px headings, Source Sans Pro (global),
   line-height 1.25 (tighter than the global 1.5), headings 600 weight
   with 8px bottom padding. White bg + light-grey separator preserved
   from 0.74.46. Hover darkens to #333 for click affordance. */
.site-footer {
    margin-top: var(--space-8);
    padding: var(--space-6) 0;
    background: var(--color-bg);
    color: #666;
    font-size: var(--font-size-sm);
    line-height: 1.25;
    border-top: 1px solid var(--color-border);
}
.site-footer a { color: #666; }
.site-footer a:hover { color: #333; }
.site-footer__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-5);
}
@media (min-width: 768px) {
    .site-footer__grid { grid-template-columns: repeat(4, 1fr); }
}
.site-footer__col h3 {
    color: #666;
    font-size: 18px;
    font-weight: 600;
    line-height: 1.25;
    margin: 0;
    padding-bottom: var(--space-2);
}
.site-footer__col ul { list-style: none; padding: 0; margin: 0; }
.site-footer__col li { margin-bottom: var(--space-2); }
/* 0.74.48: social icons row — mirrors sweetandglory.com main-site
   Facebook/Instagram/LinkedIn/X anchors. Right-aligned on desktop,
   centered on mobile. Inline SVG (no Font Awesome dependency). */
.site-footer__social {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-4);
    margin-top: var(--space-5);
}
.site-footer__social a {
    color: #666;
    display: inline-flex;
    align-items: center;
    line-height: 1;
    transition: color 0.15s ease;
}
.site-footer__social a:hover { color: #333; }
.site-footer__social svg { width: 24px; height: 24px; display: block; }
@media (max-width: 767px) {
    .site-footer__social { justify-content: center; }
}
.site-footer__legal { border-top: 1px solid var(--color-border); margin-top: var(--space-4); padding-top: var(--space-4); color: #666; }

/* ---- Incoming shipments panel (homepage) ------------------------- */
.incoming-countries {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}
.country-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 4px 10px;
    background: var(--color-primary-tint);
    color: var(--color-primary-dark);
    border-radius: 14px;
    font-size: var(--font-size-sm);
    white-space: nowrap;
}
.country-chip__flag {
    font-size: var(--font-size-base);
    line-height: 1;
    display: inline-flex;
    align-items: center;
}
.country-chip__flag .flag-img {
    width: 18px;
    height: 13px;
    border-radius: 2px;
    box-shadow: 0 0 0 1px rgba(0,0,0,0.08);
    object-fit: cover;
}

/* Generic flag image + placeholder (shared across homepage + PO page). */
.flag-img {
    display: inline-block;
    border-radius: 3px;
    box-shadow: 0 0 0 1px rgba(0,0,0,0.1);
    object-fit: cover;
    vertical-align: middle;
}
.flag-placeholder {
    display: inline-block;
    font-size: 22px;
    line-height: 1;
    vertical-align: middle;
}

/* Month headers between shipment groups */
.shipments-group-heading {
    color: var(--color-primary);
    font-size: var(--font-size-h3);
    letter-spacing: 0.04em;
    margin: var(--space-5) 0 var(--space-3);
}
.shipments-group-heading:first-child { margin-top: 0; }

.shipments-card {
    padding: 0;
    overflow: hidden;
}
.shipments-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-sm);
}
.shipments-table thead th {
    background: var(--color-primary);
    color: #fff;
    padding: var(--space-3) var(--space-4);
    font-weight: var(--font-weight-medium);
    font-size: var(--font-size-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    text-align: left;
}
.shipments-table tbody td {
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--color-border);
    vertical-align: middle;
}
.shipments-table tbody tr:last-child td { border-bottom: none; }
.shipments-table tbody tr:hover { background: var(--color-bg-alt); }

.shipments-table__flag { width: 64px; }
.shipments-flag {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 30px;
}
.shipments-flag .flag-img {
    width: 40px;
    height: 30px;
}
.shipments-table__id { width: 120px; white-space: nowrap; }
.shipments-id-link {
    color: var(--color-primary-dark);
    font-weight: var(--font-weight-bold);
    text-decoration: none;
    font-size: var(--font-size-base);
}
.shipments-id-link:hover { text-decoration: underline; }
.shipments-table__details { min-width: 280px; }
.shipments-table__action { width: 120px; text-align: right; }

.btn-order {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    /* 0.74.29: align with .btn — use accessible button bg tokens so
       white-on-button hits ~6.5:1. */
    background: var(--color-primary-button);
    color: #fff;
    padding: 6px 16px;
    border-radius: 999px;
    font-weight: var(--font-weight-bold);
    font-size: var(--font-size-sm);
    text-decoration: none;
    letter-spacing: 0.02em;
    white-space: nowrap;
}
.btn-order:hover { background: var(--color-primary-button-hover); color: #fff; text-decoration: none; }

@media (max-width: 767px) {
    /* Stack the shipment row on mobile */
    .shipments-table thead { display: none; }
    /* 0.75.21 — back off the 0.75.20 24/24 gap+padding combo: button
       was still being clipped at the viewport edge (Colin's screenshot
       2026-05-15 b). Reverted to 16/16 which is still symmetric
       (button sits halfway between PO text and card border) but
       leaves ~10-12px of measured slack to absorb font / letter-
       spacing variance in the rendered "ORDER ›" content.
       0.75.20 history: 24/24 was mathematically inside the card box
       but a few px of computed button width or container rounding
       pushed it past the viewport edge.
       tbody set to display: block so it doesn't carry table-row-group
       width quirks; tr widths now constrained by the parent
       .shipments-card box (overflow: hidden + position: relative).
       All td get min-width: 0 so any column can shrink. */
    .shipments-table tbody { display: block; }
    .shipments-table tbody tr { display: grid; grid-template-columns: 40px 1fr auto; grid-template-rows: auto auto; gap: 2px var(--space-4); padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--color-border); }
    .shipments-table tbody td { padding: 0; border: none; min-width: 0; }
    .shipments-table__flag { grid-row: 1 / span 2; }
    .shipments-table__id { grid-column: 2; grid-row: 1; }
    .shipments-table__details { grid-column: 2; grid-row: 2; min-width: 0; }
    .shipments-table__action { grid-column: 3; grid-row: 1 / span 2; align-self: center; }
    .btn-order { padding: 6px 12px; }
}

/* 0.75.21 — kill any residual horizontal page scroll on mobile. Safety
   backstop in case any other element overflows the viewport — without
   this users can finger-swipe the whole page left/right (Colin reported
   this in 0.75.15 → fixed there, but multiple later CSS changes could
   regress it). overflow-x: clip is preferred over: hidden because it
   doesn't establish a scrolling context, so the .site-nav and
   .site-menu (both position: sticky) continue to stick to the
   viewport instead of to body. Browser support: Chrome 90+, Firefox 81+,
   Safari 16+ — all customers' phones. */
@media (max-width: 767px) {
    html, body { overflow-x: clip; }
}

/* ---- Single-PO detail page (/po.html) ---------------------------- */
.po-page-layout {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-5);
    margin: var(--space-5) 0;
}
/* Grid items default to min-width: auto, which lets the inner products
   table (8 cols, no min-width) push each grid cell wider than the
   container. Forcing min-width: 0 lets the .card[overflow-x:auto]
   wrapper scroll the table horizontally instead of overflowing the page. */
.po-sidebar,
.po-main { min-width: 0; }
@media (min-width: 1024px) {
    .po-page-layout { grid-template-columns: 240px 1fr; gap: var(--space-6); }
}

/* Breadcrumbs (above PO hero) */
.po-breadcrumbs {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-size-xs);
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
    text-transform: uppercase;
    margin-bottom: var(--space-3);
    font-weight: var(--font-weight-medium);
}
.po-breadcrumbs a {
    color: var(--color-text-muted);
    text-decoration: none;
}
.po-breadcrumbs a:hover { color: var(--color-primary); }
.po-breadcrumbs__arrow { color: var(--color-border-strong); }
.po-breadcrumbs__current { color: var(--color-primary); font-weight: var(--font-weight-bold); }

/* PO hero: big "SHIPMENT …" + status + due */
.po-hero {
    display: flex;
    align-items: flex-start;
    gap: var(--space-5);
    margin-bottom: var(--space-4);
    flex-wrap: wrap;
}
.po-hero__flag {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 80px;
    height: 60px;
}
.po-hero__flag .flag-img {
    width: 80px;
    height: 60px;
    border-radius: var(--radius-sm);
}
.po-hero__body { flex: 1; min-width: 260px; }
.po-hero__title {
    color: var(--color-primary);
    font-size: 36px;
    letter-spacing: 0.03em;
    margin: 0 0 var(--space-2);
    line-height: 1.1;
    word-break: break-word;
}
@media (max-width: 640px) {
    .po-hero__title { font-size: 26px; }
}
.po-hero__meta {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: var(--font-size-base);
}
.po-hero__meta strong { font-weight: var(--font-weight-bold); }
.po-status-pill {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 10px;
    background: var(--color-primary-tint);
    color: var(--color-primary-dark);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
}

.po-intro { max-width: 760px; }
.po-intro p { margin: 0 0 var(--space-2); }

/* --- Legacy header card (kept for backwards-compat, not currently used) --- */
.po-header-card {
    display: flex;
    align-items: center;
    gap: var(--space-5);
    padding: var(--space-5);
    margin-bottom: var(--space-4);
}
.po-header-card__flag {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 72px;
    height: 54px;
}
.po-header-card__flag .flag-img {
    width: 72px;
    height: 54px;
    border-radius: var(--radius-sm);
}
.po-header-card__flag .flag-placeholder {
    font-size: 48px;
}
.po-header-card__body h1 { font-size: var(--font-size-h2); margin: 0; }

.po-sidebar {
    background: #fff;
    border: 1px solid var(--color-primary);
    border-radius: var(--radius-sm);
    padding: var(--space-4);
    align-self: start;
}
/* 0.74.15 — sticky only on the >=1024px sidebar layout. Below that the
   page is single-column so the filter renders inline above the products;
   sticky there glues the filter to the middle of the viewport while
   product rows scroll past behind it. */
@media (min-width: 1024px) {
    .po-sidebar {
        position: sticky;
        top: calc(var(--nav-height) + var(--space-3));
    }
}
.po-filter-group { margin-bottom: var(--space-5); }
.po-filter-group:last-child { margin-bottom: 0; }
.po-filter-heading {
    font-size: var(--font-size-base);
    margin: 0;
    display: inline-block;
}
.po-filter-subheading {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-bold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
    margin: 0 0 var(--space-3);
}
.po-filter-list {
    max-height: 260px;
    overflow-y: auto;
    padding-right: var(--space-2);
}
.po-filter-item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: 4px 0;
    font-size: var(--font-size-sm);
    cursor: pointer;
    user-select: none;
}
.po-filter-item input { width: auto; margin: 0; }
.po-filter-item:hover { color: var(--color-primary); }

.breadcrumbs a { color: var(--color-text-muted); text-decoration: none; }
.breadcrumbs a:hover { color: var(--color-primary); }

/* ---- PO quick-order table (/po.html) ---------------------------- */
.po-products-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-sm);
}
.po-products-table thead th {
    background: var(--color-primary);
    color: #fff;
    padding: var(--space-3) var(--space-3);
    font-weight: var(--font-weight-medium);
    font-size: var(--font-size-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    text-align: left;
    /* 0.80.5 — headers may wrap onto two lines so multi-word labels like
       "ALREADY ALLOCATED" and "ALLOCATED TO YOU" don't force their columns
       wider than their content needs. Short labels (SKU, PRICE, DUE IN…)
       still fit on one line. line-height tightened so the header row stays
       compact when something does wrap. */
    white-space: normal;
    line-height: 1.2;
    vertical-align: middle;
}
.po-products-table tbody td {
    /* 0.80.4 — vertical padding kept generous; horizontal trimmed to
       var(--space-2) so 9 columns + the merged Order cell fit comfortably
       inside the card on a typical 1280-1440px viewport without horizontal
       overflow clipping the Add-to-basket button. */
    padding: var(--space-3) var(--space-2);
    border-bottom: 1px solid var(--color-border);
    vertical-align: middle;
}
.po-products-table thead th { padding: var(--space-3) var(--space-2); }
.po-products-table tbody tr:last-child td { border-bottom: none; }
.po-products-table tbody tr:hover { background: var(--color-bg-alt); }

/* 0.80.4 — column widths shrunk across the board so the 9-column table fits
   in the available card width without overflow-x clipping the rightmost
   cell. Previously the table needed ~1140px min and clipped on viewports
   under ~1300px; now ~950px min comfortably fits a 1100px card. */
.po-products-table__img { width: 72px; min-width: 72px; }
.po-products-table__img img {
    width: 64px;
    height: 64px;
    object-fit: contain;
    background: var(--color-bg-alt);
    border-radius: var(--radius-sm);
}
.po-products-table__sku {
    width: 76px;
    min-width: 76px;
    white-space: nowrap;
    color: var(--color-primary);
    font-weight: var(--font-weight-medium);
    font-size: var(--font-size-xs);
}
.po-products-table__name { min-width: 220px; }
.po-products-table__name a { color: var(--color-primary); font-weight: var(--font-weight-medium); text-decoration: none; }
.po-products-table__name a:hover { text-decoration: underline; }
.po-products-table__price { text-align: right; white-space: nowrap; }
.po-products-table__qty { text-align: right; white-space: nowrap; width: 72px; min-width: 72px; }
/* 0.80.6 — center-align modifier for the Already Allocated column. The bar
   underneath the number is also center-anchored visually (flex-end on the
   bar puts the slate segment at the right edge of the cell). */
.po-products-table__qty--center { text-align: center; }
/* 0.80.3 — Order column hosts both the qty stepper AND the Add-to-basket
   button (vertical stack). 0.80.4 — shrunk to 124px to fit the row.
   padding-right ensures the button doesn't touch the table border. */
.po-products-table__order { width: 124px; min-width: 124px; padding-right: var(--space-2); }
.po-products-table__order-cell {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    align-items: stretch;
}
.po-products-table__order-cell .btn-update { width: 100%; padding-left: 4px; padding-right: 4px; font-size: var(--font-size-xs); }
.po-products-table__order .qty-input {
    width: 100%;
    height: 32px;
}
.po-products-table__order .qty-input button {
    width: 28px;
    height: 32px;
    font-size: 16px;
    color: var(--color-text);
}
.po-products-table__order .qty-input input {
    height: 32px;
    width: 100%;
    min-width: 0;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    /* Hide the browser's native spinner — the −/+ buttons are the stepper. */
    appearance: textfield;
    -moz-appearance: textfield;
}
.po-products-table__order .qty-input input::-webkit-outer-spin-button,
.po-products-table__order .qty-input input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.po-products-table__order .qty-input input:focus {
    outline: 2px solid var(--color-primary);
    outline-offset: -2px;
}

/* 0.80.0 — stacked progress bar under the Available qty on the PO table +
   product page. Visualises Pre Allocated / Allocated to you / Ordered by
   others / Available as four left-to-right segments coloured to match the
   columns so the eye spots fully-reserved lines instantly. */
.po-bar {
    /* 0.80.6 — flex-end anchors the single allocated-progress segment to
       the right of the container. The bar "fills leftward" as more stock
       is locked: 0% = no visible bar against a faint slate track, 100% =
       fully filled. Matches the "gauge that empties as stock is taken"
       mental model. */
    display: flex;
    justify-content: flex-end;
    width: 100%;
    height: 6px;
    background: var(--color-bg-alt);
    border-radius: 3px;
    overflow: hidden;
    margin-top: 4px;
}
.po-bar__seg                  { display: block; height: 100%; }
/* 0.80.1 — bar simplified to three segments: Already Allocated (everything
   spoken for outside you) / Allocated to you / Available. The previous
   four-segment split (OW vs other customers) was merged — customers don't
   need that distinction; what matters is "how much is gone vs left". */
.po-bar__seg--prealloc        { background: #94a3b8; }   /* slate — already allocated to existing pre-orders */
.po-bar__seg--yours           { background: #f472b6; }   /* pink — your contribution */
.po-bar__seg--avail           { background: #34d399; }   /* green — buyable */

/* 0.80.0 — "Fully reserved" badge on PO rows where effective_qty=0. Sits
   under the product description. Pink-tinted so it doesn't compete with the
   Add-to-basket CTA but is unmissable on every fully-allocated row. */
.po-pill {
    display: inline-block;
    margin-top: 4px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    line-height: 1.4;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.po-pill--reserved {
    background: rgba(236, 72, 153, 0.12);
    color: var(--color-primary);
    border: 1px solid rgba(236, 72, 153, 0.30);
}

/* Visually de-emphasise rows that are fully allocated — readable, but
   subordinate to rows that can still be ordered. */
.po-products-table tbody tr[data-fully-allocated="true"] {
    background: rgba(0, 0, 0, 0.015);
}
.po-products-table tbody tr[data-fully-allocated="true"]:hover {
    background: rgba(0, 0, 0, 0.03);
}
.po-products-table tbody tr[data-fully-allocated="true"] .po-products-table__name a {
    color: var(--color-text-muted);
}

.btn-update {
    display: inline-block;
    padding: 6px 16px;
    border-radius: 999px;
    background: var(--color-primary);
    color: #fff;
    border: none;
    font-weight: var(--font-weight-bold);
    font-size: var(--font-size-xs);
    letter-spacing: 0.06em;
    cursor: pointer;
    white-space: nowrap;
}
.btn-update:hover:not(:disabled) { background: var(--color-primary-hover); }
.btn-update:disabled { background: #ccc; cursor: not-allowed; }

/* 0.75.19 — /po quick-order layout on mobile.
   The 8-column desktop table (img, sku, name, price, due-in, ordered,
   stepper, button) requires ~860px to render and was clipping the
   right ~half of the row on iPhone Pro Max — the qty stepper and Add
   to basket button (the two interactive cells customers actually need)
   sat off-screen. Convert each <tr> into a card and the <tbody> into
   a 2-column grid; the header row is hidden and per-cell labels are
   synthesised via ::before pseudo-elements (markup unchanged, so po.js
   doesn't need to know about the responsive shape). Desktop layout
   above (>=768px) is untouched. */
@media (max-width: 767px) {
    .po-products-table { display: block; border: 0; }
    .po-products-table thead { display: none; }
    .po-products-table tbody {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: var(--space-4);
    }
    .po-products-table tbody tr {
        display: flex;
        flex-direction: column;
        gap: var(--space-2);
        padding: var(--space-3);
        border: 1px solid var(--color-primary);
        border-radius: var(--radius-sm);
        background: #fff;
    }
    .po-products-table tbody tr:hover    { background: #fff; }
    .po-products-table tbody tr:last-child td,
    .po-products-table tbody td {
        display: block;
        padding: 0;
        border: none;
        width: auto;
        min-width: 0;
        text-align: left;
        white-space: normal;
    }
    .po-products-table__img    { width: 100%; }
    .po-products-table__img img {
        width: 100%;
        height: auto;
        aspect-ratio: 4 / 3;
        background: var(--color-bg-alt);
        padding: var(--space-2);
        border-radius: var(--radius-sm);
    }
    .po-products-table__sku    { font-size: var(--font-size-xs); }
    .po-products-table__name a { font-size: var(--font-size-base); }
    .po-products-table__price  { font-weight: var(--font-weight-bold); font-size: var(--font-size-base); }
    /* Synthesise per-row labels on mobile so the bare numbers in the
       availability + ordered cells have context (no thead to lean on).
       Available cell has no [data-ordered-qty]; ordered cell does. */
    .po-products-table__qty {
        font-size: var(--font-size-xs);
        color: var(--color-text-muted);
        font-weight: var(--font-weight-body);
    }
    .po-products-table__qty:not([data-ordered-qty])::before {
        content: 'Due in: ';
    }
    .po-products-table__qty[data-ordered-qty]:not(:empty)::before {
        content: 'In basket: ';
    }
    .po-products-table__qty[data-ordered-qty]:empty { display: none; }
    .po-products-table__qty strong { color: var(--color-text); font-weight: var(--font-weight-bold); }
    /* Push the order controls to the bottom of the card so the Add-to-
       basket buttons line up across tiles even when descriptions wrap
       to different heights. */
    .po-products-table__order { margin-top: auto; }
    /* 0.75.22 — bump qty stepper to 48x48 on mobile (was 32x36 from the
       desktop-scoped rule above). Below Apple HIG 44x44 minimum the
       buttons were fat-finger missing and triggering iOS double-tap
       zoom on /po. touch-action: manipulation on .btn already kills
       the zoom; the size bump is what stops the missed taps. */
    .po-products-table__order .qty-input { width: 100%; height: 48px; }
    .po-products-table__order .qty-input button { width: 48px; height: 48px; font-size: 20px; }
    .po-products-table__order .qty-input input { width: 100%; height: 48px; font-size: 16px; }
    .po-products-table__order .btn-update {
        padding: 10px 12px;
        font-size: var(--font-size-sm);
        white-space: nowrap;
    }
}

/* ---- My account page --------------------------------------------- */
.account-tabs {
    display: flex;
    gap: var(--space-1);
    border-bottom: 2px solid var(--color-border);
    margin-bottom: var(--space-5);
    overflow-x: auto;
}
.account-tab {
    background: transparent;
    border: none;
    padding: var(--space-3) var(--space-4);
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-medium);
    color: var(--color-text-muted);
    cursor: pointer;
    border-bottom: 3px solid transparent;
    margin-bottom: -2px;
    white-space: nowrap;
}
.account-tab:hover { color: var(--color-primary); }
.account-tab--active {
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
}

.account-filter-tabs {
    display: flex;
    gap: var(--space-1);
    background: var(--color-bg-alt);
    padding: 4px;
    border-radius: var(--radius-md);
}
.account-filter {
    background: transparent;
    border: none;
    padding: 6px 14px;
    font-size: var(--font-size-sm);
    cursor: pointer;
    border-radius: var(--radius-sm);
    color: var(--color-text-muted);
}
.account-filter[aria-selected="true"] {
    background: #fff;
    color: var(--color-primary);
    font-weight: var(--font-weight-bold);
    box-shadow: var(--shadow-sm);
}

.address-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--space-4);
}
.address-card {
    position: relative;
    padding: var(--space-4);
}
.address-card--default {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 1px var(--color-primary);
}
.address-card__lines { color: var(--color-text); line-height: 1.6; }
.address-default-badge {
    display: inline-block;
    background: var(--color-primary);
    color: #fff;
    font-size: 10px;
    padding: 2px 6px;
    border-radius: 4px;
    letter-spacing: 0.08em;
    vertical-align: middle;
    margin-left: 4px;
}

/* Checkout address picker (radio cards) */
/* Container-border convention (0.20.7): match top-nav pill style. */
.address-pick {
    display: flex;
    gap: var(--space-3);
    align-items: flex-start;
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--color-primary);
    border-radius: var(--radius-sm);
    margin-bottom: var(--space-2);
    cursor: pointer;
    background: #fff;
}
.address-pick:hover { box-shadow: 0 0 0 1px var(--color-primary); }
.address-pick input[type=radio] { margin-top: 4px; width: auto; }
.address-pick--selected {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 1px var(--color-primary);
    background: var(--color-primary-tint);
}

.orders-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-sm);
}
.orders-table thead th {
    background: var(--color-primary);
    color: #fff;
    padding: var(--space-3) var(--space-4);
    font-weight: var(--font-weight-medium);
    font-size: var(--font-size-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    text-align: left;
}
.orders-table tbody td {
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--color-border);
}
.orders-table tbody tr:last-child td { border-bottom: none; }
.orders-table tbody tr:hover { background: var(--color-bg-alt); }

.status-pill {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 10px;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    background: #e2e3e5;
    color: #383d41;
}
.status-pill--pending_payment { background: #fff3cd; color: #856404; }
.status-pill--paid            { background: #fde5ee; color: var(--color-primary-dark); }
.status-pill--ow_so_created   { background: #d4edda; color: #155724; }
.status-pill--ow_so_failed    { background: #f8d7da; color: #721c24; }
.status-pill--fulfilled       { background: #d4edda; color: #155724; }
.status-pill--cancelled       { background: #e2e3e5; color: #383d41; }
.status-pill--refunded        { background: #f8d7da; color: #721c24; }
/* 0.75.4 — display_status (5-state badge): ON HOLD / BALANCE REQUIRED /
   PAID / PROCESSING / SHIPPED. Class names are display_status lowercased
   with spaces → hyphens (deriveDisplayStatus output passed straight
   through to .status-pill--{lower-kebab}). */
.status-pill--on-hold          { background: #fff3cd; color: #856404; }
.status-pill--balance-required { background: #ffe0b2; color: #8a4b00; }
.status-pill--paid             { background: #fde5ee; color: var(--color-primary-dark); }
.status-pill--processing       { background: #cce5ff; color: #004085; }
.status-pill--shipped          { background: #d4edda; color: #155724; }

/* Expandable order rows on /account.html Orders tab */
.orders-table--expandable .order-row { cursor: pointer; }
.order-row__chevron {
    color: var(--color-text-muted, #777);
    transition: transform 0.15s ease;
    text-align: center;
    user-select: none;
}
.order-row[aria-expanded="true"] .order-row__chevron {
    transform: rotate(90deg);
    color: var(--color-primary);
}
.order-detail-row > .order-detail-cell {
    background: var(--color-bg-alt, #fafafa);
    padding: var(--space-4);
}
.order-detail__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-4);
}
@media (min-width: 900px) {
    .order-detail__grid { grid-template-columns: 2fr 1fr; }
}
.order-detail__heading {
    margin: 0 0 var(--space-2);
    font-size: var(--font-size-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted, #777);
}
.order-lines-table { width: 100%; border-collapse: collapse; font-size: var(--font-size-sm); }
.order-lines-table thead th {
    padding: var(--space-2) var(--space-3);
    border-bottom: 1px solid var(--color-border);
    font-size: var(--font-size-xs);
    text-align: left;
    color: var(--color-text-muted, #777);
    font-weight: var(--font-weight-medium);
}
.order-lines-table tbody td {
    padding: var(--space-2) var(--space-3);
    border-bottom: 1px solid var(--color-border);
    vertical-align: top;
}
.order-lines-table tbody tr:last-child td { border-bottom: none; }

.order-detail__side { display: flex; flex-direction: column; gap: var(--space-4); }
.order-detail__totals dl {
    margin: 0;
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 4px 16px;
    font-size: var(--font-size-sm);
}
.order-detail__totals dt { color: var(--color-text-muted, #777); }
.order-detail__totals dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.order-detail__totals .order-detail__grand { font-weight: var(--font-weight-medium); color: var(--color-primary-dark); padding-top: 4px; border-top: 1px solid var(--color-border); }
.order-detail__addresses { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
@media (max-width: 640px) {
    .order-detail__addresses { grid-template-columns: 1fr; }
}
.order-detail__address { background: #fff; border: 1px solid var(--color-primary); border-radius: var(--radius-sm); padding: var(--space-3); }

/* ---- Form layouts ------------------------------------------------ */
.form-row { display: grid; grid-template-columns: 1fr; gap: var(--space-3); margin-bottom: var(--space-3); }
@media (min-width: 640px) { .form-row.two { grid-template-columns: 1fr 1fr; } }
.card {
    background: #fff;
    /* Container-border convention (0.20.7): match top-nav pill style. */
    border: 1px solid var(--color-primary);
    border-radius: var(--radius-sm);
    padding: var(--space-5);
    box-shadow: var(--shadow-sm);
}

/* ---- Product detail: availability + transform card --------------- */
.product-detail__pack {
    margin: 0 0 var(--space-2) 0;
    color: var(--color-text);
    font-size: var(--font-size-md);
}
.product-detail__availability {
    margin-top: var(--space-4);
    padding: var(--space-3) var(--space-4);
    background: var(--color-bg-alt);
    border-left: 3px solid var(--color-primary);
    border-radius: var(--radius-sm);
}
.product-detail__availability-num {
    display: inline-block;
    font-size: 1.75rem;
    font-weight: var(--font-weight-bold);
    color: var(--color-primary-dark);
    margin-right: var(--space-2);
    line-height: 1;
}
.product-detail__availability-word {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}
.product-detail__availability--empty {
    border-left-color: #aaa;
    color: var(--color-text-muted);
}
.product-detail__transform {
    padding: var(--space-4);
    background: #fde5ee;
    border-radius: var(--radius-md);
}
.product-detail__transform-link {
    display: inline-block;
    margin-top: var(--space-1);
    color: var(--color-primary-dark);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
}
.product-detail__transform-link:hover { text-decoration: underline; }

/* ---- Cart page: reservation banner ------------------------------ */
.cart-reservation {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    margin: var(--space-4) 0;
    background: #fde5ee;
    border: 1px solid #f7c6d7;
    border-radius: var(--radius-md);
    color: var(--color-primary-dark);
    font-size: var(--font-size-sm);
}
.cart-reservation__icon {
    font-size: 1.25rem;
    line-height: 1;
}
.cart-reservation--expired {
    background: #fff3cd;
    border-color: #ffe49a;
    color: #856404;
}

/* 0.84.3 — dispatch-from notice. Renders at the top of every preorder
   basket's totals stack to make the dispatch-after-stock-lands semantics
   un-missable. Sits in the same column as the totals (max-width: 420px)
   so it occupies the full width of the totals strip. Amber palette
   distinguishes it from the pink reservation banner — pink = active
   countdown timer, amber = scheduled future date. */
.cart-dispatch-notice {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    margin-bottom: var(--space-3);
    background: #fff8e1;
    border: 1px solid #ffe082;
    border-radius: var(--radius-md);
    color: #6b5a17;
    font-size: var(--font-size-sm);
    line-height: 1.4;
}
.cart-dispatch-notice__icon {
    font-size: 1.25rem;
    line-height: 1;
    flex-shrink: 0;
    margin-top: 1px;
}
.cart-dispatch-notice__body {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.cart-dispatch-notice__body strong {
    font-size: var(--font-size-base);
}

/* ---- Cart page: min-order shortfall banner (0.21.0) ---------------- */
/* Renders under the cart totals block when this cart's subtotal is below
   the configurable min-order floor (Settings → Shipping rules). The
   Proceed-to-checkout button is disabled alongside; defensive 400 at
   POST /api/checkout/session catches any crafted request that slips by. */
.cart-min-order-banner {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    margin: var(--space-4) 0 0 auto;
    max-width: 360px;
    background: #fff3cd;
    border: 1px solid #ffe49a;
    border-radius: var(--radius-md);
    color: #856404;
    font-size: var(--font-size-sm);
    line-height: 1.4;
}
.cart-min-order-banner__icon {
    font-size: 1.25rem;
    line-height: 1;
}
.btn[disabled], .btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ---- Cart page: delivery-postcode banner (0.22.0) ------------------ */
/* Sits between the <h1> heading and the first cart section. Drives the
   per-cart shipping row via POST /api/shipping/quote. Content varies
   between "postcode known" (compact label + Change) and "postcode
   missing" (inline input). */
.postcode-banner {
    margin: var(--space-3) 0 var(--space-4);
    padding: var(--space-3) var(--space-4);
    background: #fff;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}
.postcode-banner__row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}
.postcode-banner__form {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-top: var(--space-3);
    flex-wrap: wrap;
}
.postcode-banner__form[hidden] { display: none; }

/* ---- Cart page: shipping row + dims row in the totals block (0.22.0) ---------- */
.cart-totals__row--shipping { color: var(--color-text); gap: var(--space-4); }
.cart-totals__row--shipping .text-error {
    color: #721c24;
    font-weight: var(--font-weight-medium);
}
/* Stacked value cell: amount on top, VAT + carrier meta right-aligned beneath. (0.22.2) */
.cart-shipping-value {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    text-align: right;
    gap: 2px;
    min-width: 0;
}
.cart-shipping-value__amount { font-weight: var(--font-weight-medium); white-space: nowrap; }
.cart-shipping-value__vat,
.cart-shipping-value__meta {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    line-height: 1.3;
}
/* 0.26.2: ETA copy ("Ships Tue 5 May, delivers Wed 6 May") was rendering
   at .meta size (xs / muted) which made it easy to miss. Bump up: bigger,
   regular text colour, slightly more weight. Still right-aligned with the
   shipping row.
   0.26.5: nowrap so the dispatch promise reads as one phrase instead of
   wrapping mid-sentence ("Ships Tue 5 May, delivers Wed 6" + "May" on
   line 2 was Colin's repro). The 360 px totals box can accommodate ~35
   chars at base size; if a future longer ETA copy bursts, the totals box
   widens with it (no width clamp on the eta line itself). */
.cart-shipping-value__eta {
    font-size: var(--font-size-base);
    color: var(--color-text);
    font-weight: var(--font-weight-medium);
    line-height: 1.35;
    margin-top: 4px;
    white-space: nowrap;
}
.cart-totals__row--dims {
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}
.cart-totals__row--postcode { font-size: var(--font-size-sm); }
.cart-postcode-cell {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}
.cart-postcode-cell input[data-cart-postcode-input] {
    width: 110px;
    padding: 4px 8px;
    text-transform: uppercase;
    font-size: var(--font-size-sm);
}

/* ------------------------------------------------------------------
   Generic breadcrumbs — used on /brand/, /brand-product/, /product/.
   /po/ has its own .po-breadcrumbs style (kept for backwards-compat).
   Mirrors po-breadcrumbs visually so the site feels consistent.
   ------------------------------------------------------------------ */
.breadcrumbs {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-size-xs);
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
    text-transform: uppercase;
    margin-bottom: var(--space-3);
    flex-wrap: wrap;
}
.breadcrumbs a {
    color: var(--color-text-muted);
    text-decoration: none;
}
.breadcrumbs a:hover { color: var(--color-primary); }
.breadcrumbs__sep { color: var(--color-border-strong); }
.breadcrumbs__current {
    color: var(--color-primary);
    font-weight: var(--font-weight-bold);
}

/* ------------------------------------------------------------------
   Cookie consent banner (UK PECR/GDPR — Google Consent Mode v2)
   Injected by layout.js on first visit; sits at bottom of viewport
   above the fold so it can't be missed.
   ------------------------------------------------------------------ */
.consent-banner {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 9999;
    background: #fff;
    border-top: 2px solid var(--color-primary);
    box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.08);
    padding: var(--space-3) var(--space-4);
}
.consent-banner__inner {
    max-width: 1200px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}
.consent-banner__text {
    margin: 0;
    flex: 1;
    min-width: 220px;
    color: var(--color-text);
    font-size: var(--font-size-sm);
    line-height: 1.5;
}
.consent-banner__text a {
    color: var(--color-primary);
    text-decoration: underline;
}
.consent-banner__buttons {
    display: flex;
    gap: var(--space-2);
    flex-shrink: 0;
}
.consent-banner__btn {
    padding: 8px 18px;
    border: 1px solid var(--color-border);
    background: #fff;
    color: var(--color-text);
    border-radius: var(--radius-sm, 4px);
    font-size: var(--font-size-sm);
    font-weight: 600;
    cursor: pointer;
    transition: opacity 0.15s ease;
}
.consent-banner__btn:hover { opacity: 0.85; }
.consent-banner__btn--accept {
    /* 0.74.29: accessible button bg variant for 4.5:1+ on white text. */
    background: var(--color-primary-button);
    color: #fff;
    border-color: var(--color-primary-button);
}
@media (max-width: 600px) {
    .consent-banner__inner { flex-direction: column; align-items: stretch; }
    .consent-banner__buttons { width: 100%; }
    .consent-banner__btn { flex: 1; padding: 12px 16px; }
}

/* ---------- /search page (0.43.0) ----------
   Site-wide search across both pipelines (preorder + brand catalogue).
   Reuses .brand-variant-grid + .brand-variant-card from brand-catalogue.css
   so cards match the look of the brand pages. .search-card adds the PO
   chip strip used on preorder results. */
.search-page__form {
    display: flex;
    gap: var(--space-2);
    margin-bottom: var(--space-4);
    flex-wrap: wrap;
}
.search-page__input {
    flex: 1 1 280px;
    padding: 10px 14px;
    font-size: var(--font-size-base);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
}
.search-page__input:focus {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}
.search-page__status { margin-bottom: var(--space-4); }
.search-page__section { margin-top: var(--space-5); }
.search-page__section-title { margin-bottom: var(--space-1); }

.search-card__pos {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: var(--space-2);
}
.search-card__po-chip {
    display: inline-flex;
    gap: 6px;
    align-items: baseline;
    padding: 3px 8px;
    border-radius: 999px;
    background: var(--color-primary-tint, rgba(233,30,99,0.12));
    color: var(--color-primary);
    font-size: 11px;
    text-decoration: none;
    white-space: nowrap;
}
.search-card__po-chip:hover {
    background: var(--color-primary);
    color: #fff;
}

/* ---------- Accessibility (0.45.0) ----------
   Skip-to-main-content link injected by layout.js as the first child of
   <header data-site-nav>. Off-screen by default; slides into view on
   keyboard focus. Mouse users never see it. Sighted keyboard users
   get a one-Tab path past 8+ nav links to the page's main content. */
.skip-to-main {
    position: absolute;
    top: -100px;
    left: var(--space-3);
    z-index: 1100;
    padding: 12px 20px;
    background: var(--color-primary);
    color: #fff;
    font-weight: var(--font-weight-bold);
    text-decoration: none;
    border-radius: var(--radius-sm);
    box-shadow: 0 2px 8px rgba(0,0,0,0.2);
    transition: top 0.15s ease-out;
}
.skip-to-main:focus,
.skip-to-main:focus-visible {
    top: var(--space-3);
    outline: 2px solid #fff;
    outline-offset: 2px;
    color: #fff;
    text-decoration: none;
}

/* Buttons get a visible keyboard focus ring. :focus-visible (rather than
   :focus) so mouse users don't see a ring after click — only keyboard
   users get the indicator, which is the WCAG 2.4.7 requirement. Outline
   sits OUTSIDE the button via offset so it doesn't crowd the existing
   border-radius. */
.btn:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}
.btn-secondary:focus-visible,
.btn-ghost:focus-visible {
    outline-color: var(--color-primary);
}

/* <main id="main"> gets focused programmatically by the skip-link. We
   don't want a default browser focus ring on the page body — the user
   has just navigated TO main, the visible cue is the page already
   scrolled there. Suppress only when focused programmatically. */
main:focus { outline: none; }

/* qty-input had `outline: none` on the inner <input> with no replacement
   indicator — keyboard users couldn't tell when the qty field was
   focused. Move the focus ring to the OUTER container via :focus-within
   so the wrapping pill grows a visible ring without changing layout. */
.qty-input:focus-within {
    box-shadow: 0 0 0 2px var(--color-primary);
    outline-offset: 2px;
}

/* "See all results for X →" footer link added to the top-nav search
   dropdown. Always visible (whether there are results or not) so the user
   can fall through to the full-page search. */
.site-nav__search-see-all {
    display: block;
    padding: 10px 14px;
    border-top: 1px solid var(--color-border);
    background: var(--color-bg-alt);
    color: var(--color-primary);
    text-decoration: none;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-bold);
    text-align: center;
}
.site-nav__search-see-all:hover { background: var(--color-primary); color: #fff; }


/* 0.75.36 — Newsletter signup banner, sits above the 4-column footer grid.
   Soft pink to match the site palette, with a single-row form on desktop +
   stacked layout on mobile. Hidden by default via JS while the Mailchimp
   action URL is unset, so the empty banner never ships. */
.site-footer__newsletter {
    background: linear-gradient(135deg, #fff3f7 0%, #ffe8f0 100%);
    border-top: 1px solid rgba(239, 81, 144, 0.15);
    border-bottom: 1px solid rgba(239, 81, 144, 0.15);
    padding: var(--space-5) 0;
}
.site-footer__newsletter-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-5);
    flex-wrap: wrap;
}
.site-footer__newsletter-copy {
    flex: 1 1 320px;
    min-width: 0;
}
.site-footer__newsletter-title {
    margin: 0 0 4px 0;
    font-size: 1.25rem;
    color: #2a2a2a;
}
.site-footer__newsletter-subtitle {
    margin: 0;
    color: var(--color-text-muted, #555);
    font-size: 0.95rem;
}
.site-footer__newsletter-form {
    display: flex;
    gap: var(--space-2);
    flex: 0 1 auto;
    align-items: stretch;
    flex-wrap: wrap;
    position: relative;
}
.site-footer__newsletter-input {
    flex: 1 1 240px;
    min-width: 0;
    padding: 10px 14px;
    border: 1px solid rgba(0,0,0,0.15);
    border-radius: var(--radius-sm, 6px);
    background: #fff;
    font-size: 0.95rem;
    box-sizing: border-box;
}
.site-footer__newsletter-input:focus {
    outline: 2px solid #EF5190;
    outline-offset: 1px;
    border-color: #EF5190;
}
.site-footer__newsletter-btn {
    padding: 10px 22px;
    font-weight: 600;
    flex: 0 0 auto;
}
.site-footer__newsletter-status {
    flex: 1 0 100%;
    margin: 6px 0 0 0;
    font-size: 0.9rem;
    min-height: 1.2em;
}
.site-footer__newsletter-status--ok    { color: #2d7a36; }
.site-footer__newsletter-status--error { color: #b3261e; }
.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;
}
@media (max-width: 720px) {
    .site-footer__newsletter-inner { flex-direction: column; align-items: stretch; gap: var(--space-3); }
    .site-footer__newsletter-copy  { flex: 0 0 auto; }  /* override the 320px flex-basis used at desktop — otherwise leaves a 320px-tall blank gap below copy on mobile */
    .site-footer__newsletter-form  { flex-wrap: wrap; }
    .site-footer__newsletter-input { flex: 1 1 100%; }
    .site-footer__newsletter-btn   { flex: 1 1 100%; }
}

/* 0.75.39 — Homepage section title links. The h2 wraps an <a> for the
   destination page (e.g. Incoming shipments → /due-in). Color: inherit
   so the heading still reads as a heading; subtle hover affordance via
   pink underline. */
.section-title-link {
    color: inherit;
    text-decoration: none;
}
.section-title-link:hover,
.section-title-link:focus {
    color: #EF5190;
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 4px;
}

/* 0.85.0 — Generic SSR description body, used by /product, /po, /seasonal
   (the brand pages use the matching .brand-hero__description block in
   brand-catalogue.css). Server-side ssr-pages.js fills the
   [data-seo-description] placeholder when ops has typed a body under the
   Page descriptions admin tab. The block remains `hidden` (HTML attribute)
   until SSR populates it, so the visual layout is unchanged for pages
   without copy. */
.seo-description {
    margin: var(--space-5) 0 var(--space-4);
    padding-top: var(--space-4);
    border-top: 1px solid var(--color-border);
    color: var(--color-text, #1a1a1a);
    font-size: var(--font-size-base, 1rem);
    line-height: 1.6;
    max-width: 70ch;
}
.seo-description p {
    margin: 0 0 var(--space-3);
}
.seo-description p:last-child {
    margin-bottom: 0;
}
