/* ============================================================
   Creamy Bite – component classes extracted from inline styles
   Loaded on every public page after style.css.

   Inline style="..." attributes were replaced with these classes so the
   markup stays readable and the styling is cacheable and overridable.

   NOT extracted, deliberately:
     - mailer.php and the email body in admin/order_item_handler.php.
       HTML email clients (Gmail, Outlook) strip <style> blocks, so inline
       CSS is the only styling that survives. Removing it there would send
       unstyled order confirmations.
     - style attributes whose value is computed by PHP at runtime
       (status colours, progress widths). Those keep only their dynamic
       declarations; everything static around them moved here.
   ============================================================ */

/* ── shared small utilities ──────────────────────────────── */
.cb-center      { text-align: center; }
.cb-right       { text-align: right; }
.cb-nowrap      { white-space: nowrap; }
.cb-mono        { font-family: monospace; }
.cb-full-btn    { width: 100%; justify-content: center; display: flex; }
.cb-stack       { display: flex; flex-direction: column; }

/* ── gallery ─────────────────────────────────────────────── */
.cb-gal-cta     { padding: 10px 22px; font-size: 14px; }
.cb-gal-drawer-cta { justify-content: center; display: flex; }
.cb-gal-layer   { position: relative; z-index: 1; }
.cb-gal-lead    { font-size: 16px; margin-bottom: 16px; }
.cb-gal-logo    { height: 32px; }

/* ===== extracted from checkout.php ===== */
/* ── checkout.php ────────────────────────────────────────── */

/* shared colour tokens */
.cbco-text-primary   { color: var(--text-primary); }
.cbco-text-secondary { color: var(--text-secondary); }
.cbco-text-muted     { color: var(--text-muted); }
.cbco-text-success   { color: #10b981; }
.cbco-icon-primary   { color: var(--color-primary); }
.cbco-icon-secondary { color: var(--color-secondary); }

/* shared spacing (visibility utilities live at the end of this file) */
.cbco-mb-20  { margin-bottom: 20px; }
.cbco-mb-24  { margin-bottom: 24px; }

/* nav + drawer */
.cbco-nav-back-btn    { padding: 10px 18px; font-size: 13px; }
.cbco-drawer-back-btn { display: flex; justify-content: center; }

/* page heading */
.cbco-page-head     { text-align: center; margin-bottom: 40px; }
.cbco-page-title    { font-size: 36px; margin-top: 12px; }
.cbco-page-subtitle { color: var(--text-secondary); margin-top: 8px; }

/* B2B trade banner */
.cbco-trade-banner {
    background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dark));
    color: white;
    padding: 18px;
    border-radius: 12px;
    margin-bottom: 24px;
    box-shadow: var(--shadow-md);
}
.cbco-trade-banner-eyebrow { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.12em; color: var(--color-secondary); }
.cbco-trade-banner-title   { font-size: 20px; margin: 4px 0 6px; color: white; }
.cbco-trade-banner-address { font-size: 13px; margin: 0; opacity: 0.9; line-height: 1.4; }

/* form bits */
.cbco-honeypot {
    display: none !important;
    visibility: hidden;
    position: absolute;
    left: -9999px;
    width: 0;
    height: 0;
    overflow: hidden;
}
/* Written at .form-row strength on purpose: responsive.css collapses
   .form-row to a single column, and the inline style this replaced used
   to win over it, so the trade contact row stayed 2-up at every width. */
.form-row.cbco-trade-contact-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.cbco-label-strong { font-weight: 700; }
.cbco-field-hint   { font-size: 12px; color: var(--text-muted); margin-top: 4px; display: block; }

/* delivery / collection selector */
.cbco-order-type-label { font-weight: 600; display: block; margin-bottom: 8px; }
.cbco-order-type-grid  { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.cbco-order-type-option {
    cursor: pointer;
    padding: 14px 10px;
    border-radius: var(--radius-sm);
    text-align: center;
    display: block;
    transition: all 0.2s ease;
}
.cbco-order-type-option-active { border: 2px solid var(--color-primary); background: var(--color-primary-bg); }
.cbco-order-type-option-idle   { border: 1px solid var(--border-light); background: var(--bg-surface); }
.cbco-order-type-icon { font-size: 20px; display: block; margin-bottom: 8px; }
.cbco-order-type-text { font-weight: 700; font-size: 14px; display: block; }

/* postcode + structured address */
.cbco-postcode-status { margin-top: 8px; font-size: 13px; display: none; }
.cbco-structured-address {
    display: none;
    border: 1px solid var(--border-light);
    padding: 16px;
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.02);
    margin-bottom: 20px;
}
.cbco-addr-name-grid  { display: grid; grid-template-columns: 1fr 2fr; gap: 12px; margin-bottom: 12px; }
.cbco-addr-city-row   { margin-bottom: 12px; }
.cbco-addr-label      { font-size: 13px; }
.cbco-manual-link-row { text-align: right; }
.cbco-manual-link     { font-size: 12px; color: var(--color-primary); text-decoration: none; font-weight: 600; }

/* warehouse collection info */
.cbco-collection-info {
    display: none;
    border: 1px solid var(--color-primary-light);
    padding: 18px;
    border-radius: var(--radius-sm);
    background: var(--color-primary-bg);
    margin-bottom: 20px;
}
.cbco-collection-title   { font-size: 16px; margin: 0 0 10px; color: var(--color-primary); display: flex; align-items: center; gap: 8px; }
.cbco-collection-address { font-size: 14px; margin: 0 0 8px; color: var(--text-primary); line-height: 1.5; }
.cbco-collection-hours   { font-size: 13px; margin: 0 0 12px; color: var(--text-secondary); }
.cbco-collection-map-row { margin-top: 10px; }
.cbco-map-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--color-accent);
    color: var(--text-primary);
    font-size: 12px;
    font-weight: 700;
    padding: 6px 14px;
    border-radius: 20px;
    text-decoration: none;
    box-shadow: var(--shadow-xs);
}

/* payment method selector */
.cbco-pay-method-label { margin-bottom: 10px; }
.cbco-pay-method-grid  { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.cbco-pay-option {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 16px;
    border: 2px solid var(--border-light);
    border-radius: var(--radius-sm);
    cursor: pointer;
    background: var(--bg-surface);
    transition: all 0.2s;
}
.cbco-pay-option-active { border-color: var(--color-primary); background: var(--color-primary-bg); }
.cbco-pay-radio { width: 16px; height: 16px; }
.cbco-pay-title { display: block; font-size: 14px; margin-top: 2px; }
.cbco-pay-sub { color: var(--text-muted); }
/* stripe / pay-later panels */
.cbco-stripe-panel   { margin-top: 16px; }
.cbco-stripe-element { padding: 16px; background: var(--bg-main); border: 1px solid var(--border-light); border-radius: var(--radius-sm); min-height: 60px; }
.cbco-stripe-loading { text-align: center; color: var(--text-muted); font-size: 13px; padding: 8px; }
.cbco-stripe-error   { font-size: 12px; color: #ef4444; margin-top: 8px; display: none; }
.cbco-stripe-secure-note { display: flex; align-items: center; gap: 6px; margin-top: 8px; font-size: 11px; color: var(--text-muted); }
.cbco-later-panel { display: none; margin-top: 12px; }
.cbco-later-alert { font-size: 13px; margin: 0; }
.cbco-place-order-btn { width: 100%; justify-content: center; font-size: 16px; padding: 16px; }

/* order summary panel */
/* Deliberately out-specifies responsive.css's
   `.checkout-grid > div:last-child .glass-panel { position: static; }`,
   which the inline style this replaced also beat. */
.checkout-grid > div:last-child .glass-panel.cbco-summary-panel { position: sticky; top: 88px; }
.cbco-summary-hint { font-size: 12px; color: var(--text-muted); margin-bottom: 18px; margin-top: -8px; }
.cbco-osi-variant  { display: block; font-size: 11px; color: var(--text-muted); font-weight: 500; margin-top: 2px; }
.cbco-osi-qty      { margin-top: 4px; }
.cbco-osi-remove   { display: block; margin-top: 4px; }

/* promo code */
.cbco-promo-section { margin-bottom: 14px; }
.cbco-promo-applied {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
    background: rgba(16, 185, 129, 0.08);
    border: 1px solid rgba(16, 185, 129, 0.25);
    border-radius: var(--radius-sm);
}
.cbco-promo-applied-text { font-size: 13px; }
.cbco-promo-code      { letter-spacing: 1px; }
.cbco-promo-remove    { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 14px; }
.cbco-promo-input-row { display: flex; gap: 8px; }
.cbco-promo-input     { flex: 1; text-transform: uppercase; letter-spacing: 1px; }
.cbco-promo-apply-btn { padding: 10px 16px; font-size: 13px; white-space: nowrap; }
.cbco-promo-msg       { font-size: 12px; margin-top: 6px; min-height: 16px; }

/* summary totals */
.cbco-summary-row { display: flex; justify-content: space-between; font-size: 14px; color: var(--text-secondary); margin-bottom: 6px; }
.cbco-summary-row-vat      { font-weight: 600; }
.cbco-summary-row-discount { color: #10b981; font-weight: 600; }
/* The delivery row is now rendered by the SERVER, which adds .cbco-hidden
   itself when there is nothing to say — so this must be display:flex, not
   display:none. It used to start hidden and be re-shown by
   `deliveryRow.style.display = 'flex'` in the browser; while that inline show
   was the only thing that revealed it, the row the server rendered — the one
   that knows about offers and the free-delivery-over figure — never appeared
   at all. .cbco-hidden is the LAST rule in this file, so it still wins when
   the server asks for the row to be hidden. */
.cbco-summary-row-delivery { display: flex; color: #f59e0b; font-weight: 600; }
.cbco-summary-divider-tight { margin: 10px 0; }
.cbco-vat-note { font-size: 12px; color: var(--text-muted); margin-top: 6px; text-align: right; }
.cbco-delivery-banner { margin-top: 20px; padding: 14px; background: rgba(0, 201, 167, 0.06); border: 1px solid rgba(0, 201, 167, 0.15); border-radius: var(--radius-sm); }
.cbco-delivery-banner-text { font-size: 13px; color: var(--color-secondary); display: flex; align-items: center; gap: 8px; }
.cbco-add-more-row  { margin-top: 14px; }
.cbco-add-more-link { font-size: 13px; color: var(--text-muted); display: inline-flex; align-items: center; gap: 6px; }

/* footer */
.cbco-footer-bar  { padding-top: 0; }
.cbco-footer-logo { height: 34px; }

/* ===== extracted from trade_profile.php ===== */
/* ============================================================
   trade_profile.php — extracted inline styles (prefix: cbtp-)
   Every rule is scoped under .trade-page (the <body> class of
   trade_profile.php) so the extracted declarations keep the
   winning position the inline styles had: 2 classes (0,2,0)
   beats .btn-primary / .btn-secondary / .form-control /
   .container / .glass-panel (0,1,0) and .data-table td /
   .data-table th / textarea.form-control (0,1,1) from
   style.css no matter which stylesheet this block lands in.
   Existing !important rules in responsive.css still win, as
   they already did over the inline styles.
   Verified: no .trade-page rule exists in any other stylesheet,
   and no 2-class selector in responsive.css/components.css/
   modal.css/animations.css touches these elements.
   ============================================================ */

/* ── shared tone + ink tokens (deduplicated colours) ───────── */
.trade-page .cbtp-tone-success { background:#ecfdf5; border:1px solid #a7f3d0; }
.trade-page .cbtp-tone-danger  { background:#fef2f2; border:1px solid #fecaca; }
.trade-page .cbtp-tone-plain   { background:var(--bg-main); border:1px solid var(--border-light); }
.trade-page .cbtp-ink-success  { color:#047857; }
.trade-page .cbtp-ink-warn     { color:#b45309; }
.trade-page .cbtp-ink-danger   { color:#b91c1c; }
.trade-page .cbtp-ink-primary  { color:var(--text-primary); }
.trade-page .cbtp-muted        { color:var(--text-muted); }
.trade-page .cbtp-accent       { color:var(--color-primary); }
.trade-page .cbtp-text-right   { text-align:right; }
.trade-page .cbtp-upper        { text-transform:uppercase; }
.trade-page .cbtp-hint         { font-size:11px; color:var(--text-muted); }

/* ── navbar buttons ────────────────────────────────────────── */
.trade-page .cbtp-nav-btn     { padding:8px 16px; font-size:13px; }
.trade-page .cbtp-nav-btn-out { padding:8px 14px; font-size:13px; }

/* ── page shell ────────────────────────────────────────────── */
.trade-page .cbtp-main  { padding:40px 0 80px; background:var(--bg-main); min-height:85vh; }
.trade-page .cbtp-shell { max-width:1050px; }

/* ── account header card ───────────────────────────────────── */
.trade-page .cbtp-account-card {
    background:linear-gradient(135deg, var(--color-primary), var(--color-primary-dark));
    color:white;
    padding:28px;
    border-radius:var(--radius-lg);
    margin-bottom:24px;
    box-shadow:var(--shadow-md);
    display:flex;
    justify-content:space-between;
    align-items:center;
    flex-wrap:wrap;
    gap:20px;
}
.trade-page .cbtp-verified-badge {
    font-size:11px;
    font-weight:800;
    text-transform:uppercase;
    letter-spacing:0.12em;
    color:var(--color-secondary);
    background:rgba(255,255,255,0.1);
    padding:4px 12px;
    border-radius:14px;
}
.trade-page .cbtp-account-name { font-size:26px; margin:10px 0 6px; color:white; }
.trade-page .cbtp-account-meta { font-size:13px; opacity:0.92; }
.trade-page .cbtp-customer-no {
    font-family:monospace;
    font-size:15px;
    letter-spacing:1px;
    background:rgba(255,255,255,0.15);
    padding:3px 10px;
    border-radius:8px;
}
.trade-page .cbtp-stat-label { font-size:12px; opacity:0.85; }
.trade-page .cbtp-stat-value { font-size:28px; font-weight:800; font-family:var(--font-heading); }
.trade-page .cbtp-stat-note  { font-size:12px; opacity:0.9; margin-top:4px; }

/* ── tab bar ───────────────────────────────────────────────── */
.trade-page .cbtp-tabbar  { display:flex; gap:8px; margin-bottom:22px; flex-wrap:wrap; }
.trade-page .cbtp-tab-btn { padding:10px 18px; font-size:13px; font-weight:700; }

/* ── flash messages ────────────────────────────────────────── */
.trade-page .cbtp-alert {
    padding:12px 18px;
    border-radius:var(--radius-sm);
    margin-bottom:18px;
    font-size:14px;
    font-weight:600;
}

/* ── content panel + section headings ──────────────────────── */
.trade-page .cbtp-panel { padding:28px; border-radius:var(--radius-lg); }
.trade-page .cbtp-section-title {
    margin:0 0 4px;
    font-size:20px;
    font-family:var(--font-heading);
    color:var(--text-primary);
}
/* modifiers use the base class in the selector so they win on
   specificity, not on source order */
.trade-page .cbtp-section-title.cbtp-section-title-spaced { margin-bottom:20px; }
.trade-page .cbtp-section-sub { margin:0 0 20px; font-size:13px; color:var(--text-muted); }
.trade-page .cbtp-section-sub.cbtp-section-sub-wide { margin-bottom:24px; }

/* ── profile form ──────────────────────────────────────────── */
.trade-page .cbtp-form-grid {
    display:grid;
    grid-template-columns:repeat(auto-fit, minmax(260px, 1fr));
    gap:18px;
    margin-bottom:18px;
}
.trade-page .cbtp-input-locked  { background:var(--bg-main); cursor:not-allowed; opacity:0.75; }
.trade-page .cbtp-input-mono    { font-family:monospace; letter-spacing:1px; }
.trade-page .cbtp-field-block   { margin-bottom:22px; }
.trade-page .cbtp-label-optional { color:var(--text-muted); font-weight:600; }
.trade-page .cbtp-vat-input     { max-width:320px; }
.trade-page .cbtp-help-block    { display:block; margin-top:6px; font-size:12px; color:var(--text-muted); }
.trade-page .cbtp-btn-save      { padding:12px 26px; font-size:14px; }

/* ── empty states ──────────────────────────────────────────── */
.trade-page .cbtp-empty {
    text-align:center;
    padding:50px 20px;
    color:var(--text-muted);
    background:var(--bg-main);
    border-radius:var(--radius-md);
    border:1px dashed var(--border-color);
}
.trade-page .cbtp-empty.cbtp-empty-tall { padding:60px 20px; }
.trade-page .cbtp-empty-icon  { font-size:54px; margin-bottom:16px; opacity:0.4; }
.trade-page .cbtp-empty-title { font-size:18px; margin:0 0 6px; color:var(--text-primary); }
.trade-page .cbtp-empty-cta   { padding:12px 24px; font-size:14px; margin-top:14px; }

/* ── order / payment tables ────────────────────────────────── */
.trade-page .cbtp-table-full   { width:100%; }
.trade-page .cbtp-row          { border-bottom:1px solid var(--border-light); }
.trade-page .cbtp-cell-code    { font-weight:800; font-family:monospace; color:var(--color-primary); }
.trade-page .cbtp-cell-date    { font-size:13px; color:var(--text-secondary); white-space:nowrap; }
.trade-page .cbtp-cell-sm      { font-size:13px; }
.trade-page .cbtp-cell-amount  { font-weight:800; color:var(--color-primary); font-size:15px; }
.trade-page .cbtp-variant-name { font-weight:600; color:var(--text-secondary); }
.trade-page .cbtp-more-count   { font-size:11px; color:var(--text-muted); font-weight:600; }
.trade-page .cbtp-btn-xs       { padding:6px 12px; font-size:12px; }

/* Order status pill — background / colour / border stay inline
   because statusPill() computes them per row. */
.trade-page .cbtp-status-pill {
    font-size:12px;
    font-weight:700;
    padding:4px 10px;
    border-radius:20px;
    display:inline-flex;
    align-items:center;
    gap:5px;
    white-space:nowrap;
}

/* ── payment summary cards ─────────────────────────────────── */
.trade-page .cbtp-summary-grid {
    display:grid;
    grid-template-columns:repeat(auto-fit, minmax(200px, 1fr));
    gap:14px;
    margin-bottom:24px;
}
.trade-page .cbtp-card       { border-radius:var(--radius-md); padding:16px; }
.trade-page .cbtp-card-label { font-size:12px; font-weight:700; }
.trade-page .cbtp-card-value { font-size:24px; font-weight:800; font-family:var(--font-heading); }
.trade-page .cbtp-pay-state  { font-weight:700; font-size:12px; }

/* ── invoices grid ─────────────────────────────────────────── */
.trade-page .cbtp-invoice-grid {
    display:grid;
    grid-template-columns:repeat(auto-fill, minmax(250px, 1fr));
    gap:14px;
}
/* overrides .cbtp-card padding on specificity, not source order */
.trade-page .cbtp-card.cbtp-invoice-card { padding:18px; }
.trade-page .cbtp-invoice-head {
    display:flex;
    justify-content:space-between;
    align-items:flex-start;
    gap:8px;
}
.trade-page .cbtp-invoice-eyebrow {
    font-size:11px;
    color:var(--text-muted);
    font-weight:700;
    text-transform:uppercase;
    letter-spacing:0.08em;
}
.trade-page .cbtp-invoice-code {
    font-family:monospace;
    font-weight:800;
    color:var(--color-primary);
    font-size:15px;
}
.trade-page .cbtp-invoice-date  { font-size:12px; color:var(--text-muted); margin:8px 0 4px; }
.trade-page .cbtp-invoice-total {
    font-size:20px;
    font-weight:800;
    color:var(--text-primary);
    font-family:var(--font-heading);
    margin-bottom:14px;
}
/* PAID / UNPAID badge — colours stay inline, they depend on $paid. */
.trade-page .cbtp-pay-badge {
    font-size:11px;
    font-weight:700;
    padding:3px 9px;
    border-radius:12px;
    white-space:nowrap;
}
.trade-page .cbtp-btn-block { padding:8px 14px; font-size:12px; width:100%; justify-content:center; }

/* ===== extracted from order.php ===== */
/* ═══════════════════════════════════════════════════════════
   order.php — extracted inline styles (prefix: cbor-)
   ═══════════════════════════════════════════════════════════ */

/* Mobile drawer action buttons (full-width, centred) */
.cbor-drawer-action-btn { width: 100%; display: flex; justify-content: center; }

/* Menu section top spacing */
.products-section.cbor-menu-section { padding-top: 48px; }

/* Cart notice flash message */
.cbor-notice-warn {
    background: #fffbeb;
    border: 1px solid #fde68a;
    color: #b45309;
    padding: 12px 18px;
    border-radius: var(--radius-md);
    margin-bottom: 20px;
    font-size: 14px;
    font-weight: 600;
}

/* Trade wholesale active banner */
.cbor-trade-banner {
    background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dark));
    color: white;
    padding: 14px 20px;
    border-radius: var(--radius-md);
    margin-bottom: 28px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    box-shadow: var(--shadow-md);
}
.cbor-trade-banner-icon { font-size: 18px; margin-right: 8px; color: var(--color-secondary); }
.cbor-trade-banner-note { font-size: 12px; opacity: 0.85; margin-left: 6px; }
.cbor-trade-banner-actions { display: flex; gap: 8px; flex-wrap: wrap; }
/* :hover repeated so the banner buttons keep the flat look the inline style gave them */
.btn-secondary.cbor-trade-banner-btn,
.btn-secondary.cbor-trade-banner-btn:hover {
    padding: 6px 14px;
    font-size: 12px;
    background: rgba(255,255,255,0.15);
    color: white;
    border: 1px solid rgba(255,255,255,0.3);
}

/* "Are you a trade customer?" strip */
.cbor-trade-cta {
    background: var(--color-primary-bg);
    border: 1px solid rgba(199,136,41,0.25);
    padding: 10px 18px;
    border-radius: 12px;
    margin-bottom: 24px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    font-size: 13px;
}
.cbor-trade-cta-icon  { color: var(--color-primary); margin-right: 6px; }
.cbor-trade-cta-links { display: flex; gap: 12px; font-size: 12px; }
.cbor-trade-cta-link  { color: var(--color-primary); font-weight: 700; text-decoration: none; }
.cbor-trade-cta-sep   { opacity: 0.4; }

/* Product card pricing */
.product-price-from.cbor-price-trade-label { color: var(--color-secondary); font-weight: 700; }
.cbor-price-strike { font-size: 12px; color: var(--text-muted); font-weight: 400; }
.cbor-stock-low    { font-size: 11px; color: #f59e0b; font-weight: 700; margin-top: 2px; }

/* Out-of-stock add-to-cart button (:hover repeated to keep the disabled look) */
.btn-add-cart.cbor-btn-oos,
.btn-add-cart.cbor-btn-oos:hover {
    background: var(--bg-surface);
    border: 1.5px solid var(--border-color);
    color: var(--text-muted);
    cursor: not-allowed;
    font-size: 10px;
    width: auto;
    padding: 0 10px;
    font-weight: 700;
    letter-spacing: 0.3px;
}

/* Cart sidebar heading icon */
.cbor-cart-title-icon { color: var(--color-primary); }

/* Footer bottom-bar logo */
.footer-logo-img.cbor-footer-logo-sm { height: 32px; }

/* Delivery radius pop-up */
.cbor-delivery-popup {
    display: none;
    position: fixed;
    bottom: 28px;
    right: 28px;
    max-width: 390px;
    background: linear-gradient(135deg, #5C1D24, #3d1318);
    color: white;
    padding: 20px 22px;
    border-radius: 18px;
    box-shadow: 0 14px 40px rgba(0,0,0,0.35);
    z-index: 99999;
    border: 1px solid rgba(199,136,41,0.4);
}
.cbor-delivery-popup-row   { display: flex; align-items: flex-start; gap: 14px; }
.cbor-delivery-popup-emoji { font-size: 32px; line-height: 1; flex-shrink: 0; }
.cbor-delivery-popup-body  { flex: 1; }
.cbor-delivery-popup-title {
    font-size: 15px;
    display: block;
    margin-bottom: 4px;
    color: #C78829;
    font-weight: 800;
}
.cbor-delivery-popup-text {
    font-size: 13px;
    margin: 0 0 10px;
    line-height: 1.45;
    color: rgba(255,255,255,0.92);
}
.cbor-delivery-popup-highlight { color: #a7f3d0; font-weight: 700; }
.cbor-delivery-popup-foot      { font-size: 12px; opacity: 0.85; }
.cbor-delivery-popup-foot-icon { color: #C78829; }
.cbor-delivery-popup-close {
    background: rgba(255,255,255,0.18);
    border: none;
    color: white;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    font-size: 14px;
    flex-shrink: 0;
}

/* ===== extracted from trade_register.php ===== */
/* ── Trade Register page (trade_register.php) ──────────────────
   Selectors are scoped to body.trade-page purely for specificity:
   these declarations previously lived in inline style attributes,
   which outranked the single-class rules in style.css. The extra
   class keeps them winning regardless of stylesheet order.
   No !important on purpose — see notes. */

.trade-page .cbtr-nav-login-btn { padding: 8px 16px; font-size: 13px; }

.trade-page .cbtr-main      { padding: 60px 0; background: var(--bg-main); min-height: 80vh; }
.trade-page .cbtr-container { max-width: 650px; }
.trade-page .cbtr-panel     { padding: 40px 32px; border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); }

.trade-page .cbtr-panel-head { text-align: center; margin-bottom: 28px; }
.trade-page .cbtr-title      { font-size: 28px; margin: 8px 0 10px; }
.trade-page .cbtr-subtitle   { color: var(--text-secondary); font-size: 14px; margin: 0; }

.trade-page .cbtr-alert-success {
    background: #ecfdf5;
    border: 1px solid #a7f3d0;
    color: #065f46;
    padding: 18px;
    border-radius: 12px;
    font-size: 14px;
    line-height: 1.6;
    margin-bottom: 24px;
}
.trade-page .cbtr-alert-icon { font-size: 18px; vertical-align: -2px; margin-right: 6px; }
.trade-page .cbtr-alert-error {
    background: #fef2f2;
    border: 1px solid #fecaca;
    color: #991b1b;
    padding: 14px;
    border-radius: 10px;
    font-size: 13px;
    margin-bottom: 20px;
}

.trade-page .cbtr-success-actions { text-align: center; margin-top: 20px; }
.trade-page .cbtr-login-btn       { padding: 12px 28px; font-size: 14px; }

.trade-page .cbtr-form            { display: flex; flex-direction: column; gap: 16px; }
.trade-page .cbtr-form-row        { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.trade-page .cbtr-field-label     { font-weight: 700; font-size: 13px; }
.trade-page .cbtr-input-uppercase { text-transform: uppercase; }
.trade-page .cbtr-submit-btn      { margin-top: 10px; width: 100%; justify-content: center; padding: 14px; font-size: 15px; }

.trade-page .cbtr-form-footer  { text-align: center; font-size: 13px; margin-top: 12px; color: var(--text-secondary); }
.trade-page .cbtr-login-link   { color: var(--color-primary); font-weight: 700; }
.trade-page .cbtr-footer-inner { text-align: center; font-size: 13px; color: var(--text-muted); }

/* ===== extracted from about.php ===== */
/* ══════════════════════════════════════════════════════════════
   about.php — extracted inline styles (prefix: cbab-)
   Selectors are scoped with body.about-page so they reliably beat
   the existing single-class and two-class rules in style.css /
   animations.css regardless of stylesheet order, while still
   yielding to the !important responsive overrides exactly as the
   original inline styles did.
   ══════════════════════════════════════════════════════════════ */

/* Navbar "Order Now" button */
body.about-page .cbab-nav-order-btn {
    padding: 10px 22px;
    font-size: 14px;
}

/* Mobile drawer "Order Now" button */
body.about-page .cbab-drawer-order-btn {
    display: flex;
    justify-content: center;
}

/* About hero — lift the container above the ::before overlay */
body.about-page .cbab-hero-inner {
    position: relative;
    z-index: 1;
}

/* Our Story highlight chips */
body.about-page .cbab-story-highlights {
    margin-top: 24px;
}

/* "Get In Touch" section header */
body.about-page .cbab-contact-header {
    margin-bottom: 44px;
}

/* Contact form alerts */
body.about-page .cbab-alert-sent {
    margin-bottom: 28px;
    font-size: 15px;
}
body.about-page .cbab-alert-error {
    margin-bottom: 20px;
}

/* Contact / Find Us panels */
body.about-page .cbab-contact-panel {
    padding: 32px;
}
body.about-page .cbab-find-panel {
    padding: 28px;
    margin-bottom: 20px;
}

/* Panel headings (shared base + two sizes) */
body.about-page .cbab-panel-title,
body.about-page .cbab-panel-title-sm {
    display: flex;
    align-items: center;
    color: var(--color-primary);
}
body.about-page .cbab-panel-title {
    font-size: 19px;
    margin-bottom: 24px;
    gap: 10px;
}
body.about-page .cbab-panel-title-sm {
    font-size: 17px;
    margin-bottom: 16px;
    gap: 8px;
}

/* Spam-trap field: off-screen but still focusable/fillable by bots */
body.about-page .cbab-honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* Full-width "Send Message" submit button */
body.about-page .cbab-submit-btn {
    width: 100%;
    justify-content: center;
    font-size: 15px;
    padding: 15px;
}

/* Shop address block */
body.about-page .cbab-address {
    font-size: 14px;
    color: var(--text-secondary);
    line-height: 1.7;
    margin-bottom: 18px;
}

/* Opening-hours notice inside the Find Us panel */
body.about-page .cbab-hours-alert {
    font-size: 13px;
    margin-bottom: 0;
}

/* Social section */
body.about-page .cbab-social-inner {
    text-align: center;
}
body.about-page .cbab-social-title {
    margin-bottom: 10px;
}
body.about-page .cbab-social-icon {
    font-size: 20px;
}

/* Small logo in the footer bottom bar */
body.about-page .cbab-footer-bottom-logo {
    height: 32px;
}

/* ===== extracted from order_confirmation.php ===== */
/* ============================================================
   order_confirmation.php – extracted inline styles (prefix: cboc-)
   ============================================================ */

/* ── Collection information panel ─────────────────────────── */
/* Compound with .glass-panel so it also beats .glass-panel:hover
   (border-color / box-shadow), exactly as the inline style did. */
.glass-panel.cboc-collect-panel {
    max-width: 540px;
    margin: 0 auto 32px;
    padding: 24px;
    border: 2px solid var(--color-accent);
    background: var(--color-accent-bg);
    border-radius: 16px;
    text-align: center;
    box-shadow: var(--shadow-sm);
}
.cboc-collect-emoji {
    font-size: 36px;
    margin-bottom: 12px;
}
.cboc-collect-title {
    font-size: 20px;
    font-weight: 800;
    font-family: var(--font-heading);
    color: var(--text-primary);
    margin: 0 0 10px;
}
.cboc-collect-address {
    font-size: 15px;
    color: var(--text-secondary);
    line-height: 1.6;
    margin: 0 0 18px;
    font-family: var(--font-body);
}

/* Shared: bold primary-coloured text (collection hours line, Total label). */
.cboc-text-strong,
.conf-label.cboc-text-strong {
    font-weight: 700;
    color: var(--text-primary);
}

/* "Get Directions" button. Qualified with a.btn-primary so the golden
   background, padding, radius, shadow and transition keep winning over
   .btn-primary and .btn-primary:hover in style.css / animations.css —
   the same result the inline style produced. */
a.btn-primary.cboc-directions-btn {
    background: var(--grad-golden);
    border: none;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    text-decoration: none;
    padding: 12px 28px;
    border-radius: 30px;
    font-weight: 700;
    color: #fff;
    box-shadow: var(--shadow-xs);
    transition: all 0.2s ease;
}

/* ── Order detail card ────────────────────────────────────── */
.summary-divider.cboc-divider-tight {
    margin: 20px 0;
}
.cboc-items-heading {
    margin-bottom: 12px;
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
}
.cboc-item-variant {
    color: var(--text-muted);
    font-weight: 600;
}
.cboc-item-price {
    color: var(--color-primary);
    margin-left: 8px;
    font-weight: 700;
}

/* Subtotal / promo / delivery rows */
.cboc-summary-row {
    font-size: 13px;
    color: var(--text-secondary);
    margin-bottom: 6px;
}
.cboc-summary-row-promo {
    color: #10b981;
}
.cboc-summary-row-delivery {
    color: #f59e0b;
}

/* Total row */
.cboc-total-row {
    margin-top: 10px;
}
.conf-value.cboc-total-value {
    font-size: 22px;
    font-weight: 800;
    font-family: var(--font-heading);
    color: var(--color-primary);
}

/* ── CTA buttons row ──────────────────────────────────────── */
.cboc-cta-row {
    display: flex;
    gap: 16px;
    justify-content: center;
    flex-wrap: wrap;
    margin-top: 8px;
}

/* ── Footer ───────────────────────────────────────────────── */
.footer-logo-img.cboc-footer-logo-sm {
    height: 34px;
}

/* ===== extracted from index.php ===== */
/* ── Home page (index.php) – de-inlined styles ─────────────── */

/* Nav / drawer / CTA button size variants */
.btn-primary.cbhm-btn-nav      { padding: 10px 20px; font-size: 14px; }
.btn-primary.cbhm-btn-drawer   { display: flex; justify-content: center; }
.btn-primary.cbhm-btn-wide     { font-size: 15px; padding: 14px 32px; }

/* Stats strip row */
.cbhm-stats-row { display: flex; }

/* Flavours section bottom call-to-action */
.cbhm-flavours-cta { text-align: center; margin-top: 40px; }

/* Story highlight sub-labels */
.cbhm-highlight-sub { color: var(--text-muted); }
/* Landing CTA banner */
.cbhm-cta-inner { text-align: center; }
.section-label.cbhm-label-on-dark { background: rgba(255,255,255,0.2); color: white; }

/* B2B trade callout band */
.cbhm-trade-band {
    background: var(--color-primary-bg);
    border-top: 1px solid rgba(199,136,41,0.15);
    border-bottom: 1px solid rgba(199,136,41,0.15);
    padding: 32px 0;
}
.cbhm-trade-band-inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 20px;
}
.cbhm-trade-pill {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--color-primary);
    background: rgba(92,29,36,0.08);
    padding: 4px 12px;
    border-radius: 14px;
}
.cbhm-trade-heading { font-size: 20px; margin: 8px 0 4px; color: var(--text-primary); }
.cbhm-trade-copy    { font-size: 14px; color: var(--text-secondary); margin: 0; max-width: 520px; }
.cbhm-trade-actions { display: flex; gap: 12px; flex-wrap: wrap; }
.btn-primary.cbhm-btn-trade       { padding: 12px 24px; font-size: 14px; }
.btn-secondary.cbhm-btn-trade-alt { padding: 12px 20px; font-size: 14px; }

/* Footer bottom-bar logo */
.footer-logo-img.cbhm-footer-logo-sm { height: 32px; }

/* ===== extracted from trade_login.php ===== */
/* ============================================================
   trade_login.php — extracted inline styles (prefix: cbtl-)
   ============================================================ */

/* Navbar "Apply for Trade" button — compact variant of .btn-secondary */
.btn-secondary.cbtl-nav-apply-btn {
    padding: 8px 16px;
    font-size: 13px;
}

/* Page shell */
.cbtl-login-main {
    padding: 60px 0;
    background: var(--bg-main);
    min-height: 80vh;
    display: flex;
    align-items: center;
}

.container.cbtl-login-container {
    max-width: 440px;
}

/* Login card. The :hover selector is repeated so the raised shadow survives
   .glass-panel:hover, exactly as the inline style used to. */
.glass-panel.cbtl-login-card,
.glass-panel.cbtl-login-card:hover {
    padding: 40px 32px;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}

/* Card heading block */
.cbtl-login-header {
    text-align: center;
    margin-bottom: 28px;
}

.cbtl-login-title {
    font-size: 26px;
    margin: 8px 0 10px;
}

.cbtl-login-subtitle {
    color: var(--text-secondary);
    font-size: 13px;
    margin: 0;
}

/* Login error banner — softer/tighter than the global .alert-danger */
.alert-danger.cbtl-login-alert {
    background: #fef2f2;
    border: 1px solid #fecaca;
    color: #991b1b;
    padding: 14px;
    border-radius: 10px;
    font-size: 13px;
    margin-bottom: 20px;
    line-height: 1.5;
}

/* Form */
.cbtl-login-form {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.form-label.cbtl-login-label {
    font-weight: 700;
    font-size: 13px;
}

.btn-primary.cbtl-login-submit {
    margin-top: 10px;
    width: 100%;
    justify-content: center;
    padding: 14px;
    font-size: 15px;
}

/* "Apply Here" prompt under the form */
.cbtl-login-signup-note {
    text-align: center;
    font-size: 13px;
    margin-top: 14px;
    color: var(--text-secondary);
}

.cbtl-login-signup-link {
    color: var(--color-primary);
    font-weight: 700;
}

/* Footer copyright line */
.cbtl-footer-note {
    text-align: center;
    font-size: 13px;
    color: var(--text-muted);
}

/* ── Checkout status messages ─────────────────────────────────────
   Built by JS as the postcode and payment checks come back. The colours
   used to be written into each string; keeping them here means a status
   reads the same wherever it is produced, and the JS just names a state. */
.cbco-status        { font-weight: 600; }
.cbco-status-ok     { color: #10b981; }
.cbco-status-warn   { color: #f59e0b; }
.cbco-status-err    { color: #ef4444; }
.cbco-status-muted  { color: var(--text-muted); }

/* Out-of-range and similar blocking messages: a box, not just coloured text,
   because they stop the order going through and must not read as a hint. */
.cbco-status-box {
    background: #fef2f2;
    border: 1px solid #fecaca;
    color: #b91c1c;
    padding: 12px 14px;
    border-radius: 8px;
    margin-top: 8px;
    font-weight: 600;
    font-size: 13px;
    line-height: 1.4;
}
.cbco-inline-error { color: #ef4444; font-size: 13px; padding: 10px; }

/* ── Trade account: status and payment pills ──────────────────────
   One class per state. These used to be three hex values interpolated into
   a style attribute from PHP, which meant restyling a status was a PHP edit
   and the same colours were repeated on every row. */
.cbtp-status-pill.is-delivered  { background:#ecfdf5; color:#047857; border:1px solid #a7f3d0; }
.cbtp-status-pill.is-processing { background:#eff6ff; color:#1d4ed8; border:1px solid #bfdbfe; }
.cbtp-status-pill.is-cancelled  { background:#fef2f2; color:#b91c1c; border:1px solid #fecaca; }
.cbtp-status-pill.is-pending    { background:#fffbeb; color:#b45309; border:1px solid #fde68a; }

.cbtp-pay-badge.is-paid   { background:#ecfdf5; color:#047857; border:1px solid #a7f3d0; }
.cbtp-pay-badge.is-unpaid { background:#fef2f2; color:#b91c1c; border:1px solid #fecaca; }

/* Money still owed is worth noticing, so the card changes as a whole
   rather than only its number. */
.cbtp-card.is-owing                   { background:#fffbeb; border:1px solid #fde68a; }
.cbtp-card.is-owing .cbtp-card-label,
.cbtp-card.is-owing .cbtp-card-value  { color:#b45309; }

/* Variant name under an order line, built by JS on the order page. */
.cbo-variant-label { font-size:11px; color:var(--text-muted); font-weight:500; }

/* Marks a field that stops being mandatory — e.g. delivery instructions once
   the customer has chosen to collect from the warehouse. */
.cbco-optional { font-weight: 600; color: var(--text-muted); font-size: 12px; }

/* Customer-facing invoice page (invoice.php) */
.cbinv-bar-note { font-size: 12px; color: #6b7280; align-self: center; }
.cbinv-missing  { max-width: 560px; margin: 80px auto; padding: 0 20px; text-align: center; }
.cbinv-missing h1 { font-size: 24px; margin-bottom: 12px; }
.cbinv-missing p  { color: var(--text-muted); line-height: 1.7; margin-bottom: 22px; }

/* Trade profile invoice cards */
.cbtp-invoice-balance { display: block; font-size: 12px; font-weight: 600; color: #b45309; margin-top: 2px; }
.cbtp-invoice-pending { display: block; font-size: 12px; color: var(--text-muted); text-align: center; padding: 10px 0; }

/* Basket below the delivery minimum. Amber rather than red: nothing is wrong,
   the customer just needs to add a little more. */
.cbco-min-notice {
    display: flex; align-items: flex-start; gap: 9px;
    background: #fffbeb; border: 1px solid #fde68a; color: #92400e;
    padding: 12px 14px; border-radius: 8px; margin-bottom: 12px;
    font-size: 13px; font-weight: 600; line-height: 1.5;
}

/* Card panel while the basket is still under the minimum. Neutral on purpose:
   nothing has gone wrong, there is simply nothing to pay for yet. */
.cbco-card-waiting {
    display: flex; align-items: center; gap: 9px;
    font-size: 13px; color: var(--text-muted);
    padding: 14px; background: var(--bg-main);
    border: 1px dashed var(--border-light); border-radius: 8px;
}

/* ── Policy pages (shipping, returns, privacy, terms) ─────────── */
.cbpol-page       { padding: 40px 0 80px; }
.cbpol-shell      { max-width: 820px; }
.cbpol-nav-btn    { padding: 9px 18px; font-size: 13px; }
.cbpol-breadcrumb { font-size: 13px; color: var(--text-muted); margin-bottom: 14px; }
.cbpol-breadcrumb a { color: var(--text-muted); }
.cbpol-breadcrumb a:hover { color: var(--color-primary); }
.cbpol-title      { font-size: 34px; margin: 0 0 10px; }
.cbpol-intro      { font-size: 16px; color: var(--text-secondary); margin: 0 0 6px; line-height: 1.6; }
.cbpol-updated    { font-size: 12px; color: var(--text-muted); margin: 0 0 32px; }
.cbpol-body h2    { font-size: 19px; margin: 34px 0 10px; }
.cbpol-body p,
.cbpol-body li    { font-size: 15px; line-height: 1.75; color: var(--text-secondary); }
.cbpol-body ul    { margin: 0 0 16px; padding-left: 22px; }
.cbpol-body li    { margin-bottom: 7px; }
.cbpol-body a     { color: var(--color-primary); text-decoration: underline; }
.cbpol-help       { margin-top: 44px; padding: 22px 24px; background: var(--bg-main);
                    border: 1px solid var(--border-light); border-radius: var(--radius-md); }
.cbpol-help h2    { font-size: 17px; margin: 0 0 8px; }
.cbpol-help p     { font-size: 15px; line-height: 1.7; margin: 0; color: var(--text-secondary); }

/* ── FAQ accordions (pages/faq.php) ──────────────────────────
   <details>/<summary> is a working accordion with no JavaScript, so the
   answers still open on a page where a script failed to load. */
.cbfaq-item          { border: 1px solid var(--border-light); border-radius: var(--radius-md);
                       margin-bottom: 10px; background: var(--bg-surface); overflow: hidden; }
.cbfaq-item summary  { cursor: pointer; padding: 15px 18px; font-weight: 600; font-size: 15.5px;
                       list-style: none; position: relative; padding-right: 44px;
                       transition: background 0.15s ease; }
.cbfaq-item summary::-webkit-details-marker { display: none; }
.cbfaq-item summary:hover   { background: var(--bg-main); }
.cbfaq-item summary::after  { content: '+'; position: absolute; right: 18px; top: 50%;
                              transform: translateY(-50%); font-size: 22px; font-weight: 400;
                              color: var(--color-primary); line-height: 1; }
.cbfaq-item[open] summary::after { content: '−'; }
.cbfaq-item[open] summary   { background: var(--bg-main); border-bottom: 1px solid var(--border-light); }
.cbfaq-item > p,
.cbfaq-item > ul     { padding: 0 18px; margin: 14px 0; font-size: 15px; line-height: 1.7;
                       color: var(--text-secondary); }
.cbfaq-item > ul     { padding-left: 38px; }
.cbfaq-item > *:last-child { margin-bottom: 16px; }

/* Tables inside policy pages (cookie list, allergen grid) */
.cbpol-table         { width: 100%; border-collapse: collapse; margin: 18px 0 26px;
                       font-size: 14.5px; display: block; overflow-x: auto; }
.cbpol-table th      { text-align: left; padding: 11px 13px; background: var(--bg-main);
                       border-bottom: 2px solid var(--border-light); font-size: 13px;
                       text-transform: uppercase; letter-spacing: 0.03em; white-space: nowrap; }
.cbpol-table td      { padding: 11px 13px; border-bottom: 1px solid var(--border-light);
                       vertical-align: top; line-height: 1.6; color: var(--text-secondary); }
.cbpol-table code    { background: var(--bg-main); padding: 2px 6px; border-radius: 4px;
                       font-size: 13px; }

/* ── Admin: product specification panel ──────────────────── */
.cbpf-derived-note   { display: block; font-size: 13.5px; color: var(--text-secondary);
                       line-height: 1.5; padding: 9px 0; }
/* Allergen warning mark. Amber matches .cbpf-check-label-nuts so the two read
   as the same signal; the words "Contains Nuts" stay next to it either way. */
.cbpf-warn-icon      { color: #b45309; margin-right: 2px; }
.cbpf-spec-intro     { font-size: 13.5px; color: var(--text-secondary); line-height: 1.6;
                       margin: 0 0 18px; }
.cbpf-spec-heading   { font-size: 15px; margin: 26px 0 4px; padding-top: 20px;
                       border-top: 1px solid var(--border-light); }
.cbpf-field-hint     { display: block; font-size: 12.5px; color: var(--text-secondary);
                       margin-top: 5px; line-height: 1.5; }

.cbpf-allergen-grid  { display: grid; grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
                       gap: 9px; margin-bottom: 20px; }
.cbpf-allergen-option { display: flex; align-items: center; gap: 9px; padding: 10px 12px;
                       border: 1px solid var(--border-light); border-radius: var(--radius-sm);
                       font-size: 14px; cursor: pointer; transition: all 0.15s ease; }
.cbpf-allergen-option:hover { border-color: var(--color-primary); background: var(--bg-main); }
.cbpf-allergen-option:has(input:checked) { border-color: var(--color-primary);
                       background: rgba(92, 29, 36, 0.06); font-weight: 600; }

.cbpf-review-label   { display: flex; align-items: flex-start; gap: 11px; padding: 14px 16px;
                       border: 1px solid var(--border-light); border-radius: var(--radius-md);
                       background: var(--bg-main); cursor: pointer; font-size: 14.5px; }
.cbpf-review-label:has(input:checked) { border-color: #10b981; background: rgba(16,185,129,0.07); }

.cbpf-nutrition-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(165px, 1fr));
                       gap: 13px; }
.cbpf-nutrition-indent .form-label { padding-left: 14px; font-style: italic; }
.cbpf-basis-input    { max-width: 190px; }
.cbpf-case-input     { max-width: 118px; }

/* Delivery note: the driver's name printed into the signature box. */
.cbdn-sig-filled     { font-weight: 700; font-size: 15px; padding-top: 10px; }

/* Reports */
.rep-muted           { color: #999; font-style: italic; }
.rep-note            { font-size: 12px; color: #666; margin: -14px 0 22px; }

/* Link from a paid card order to its payment in Stripe. */
.cbi-ord-stripe-link { display: inline-flex; align-items: center; gap: 5px; margin-top: 5px;
                       font-size: 11.5px; color: #635bff; text-decoration: none;
                       white-space: nowrap; }
.cbi-ord-stripe-link:hover { text-decoration: underline; }

/* "2 cases · 8 per case" under a trade basket line, so the quantity shown is
   never mistaken for a number of tubs. Same wording in the cart drawer and in
   the checkout summary, because they show the same basket. */
.cbo-case-note,
.cbco-osi-case       { font-size: 11.5px; color: var(--color-secondary); font-weight: 700;
                       margin: 2px 0 3px; letter-spacing: 0.01em; }

/* Prompt on the Products tab pointing at the bulk allergen screen. */
.cbi-allergen-callout { display: flex; align-items: center; justify-content: space-between;
                       gap: 20px; flex-wrap: wrap; padding: 15px 19px; margin-bottom: 18px;
                       background: rgba(245,158,11,0.10);
                       border: 1px solid rgba(245,158,11,0.42);
                       border-radius: var(--radius-sm); }
.cbi-allergen-callout strong { font-size: 14.5px; }
.cbi-allergen-callout p { margin: 5px 0 0; font-size: 13px; color: var(--text-secondary);
                       line-height: 1.6; max-width: 640px; }
.cbi-allergen-cta    { flex: 0 0 auto; }

/* ── Admin: bulk allergen grid ───────────────────────────── */
.cbab-body           { background: var(--bg-main); padding: 0; margin: 0; }
.cbab-wrap           { max-width: 1240px; margin: 0 auto; padding: 26px 22px 70px; }
.cbab-head           { display: flex; justify-content: space-between; align-items: flex-start;
                       gap: 20px; flex-wrap: wrap; margin-bottom: 20px; }
.cbab-title          { font-size: 25px; margin: 0 0 5px; color: var(--color-primary); }
.cbab-sub            { margin: 0; font-size: 14px; color: var(--text-secondary); line-height: 1.6;
                       max-width: 640px; }
.cbab-back           { flex: 0 0 auto; }

.cbab-status         { padding: 13px 17px; border-radius: var(--radius-sm); font-size: 14px;
                       line-height: 1.6; margin-bottom: 18px; }
.cbab-status.is-todo { background: rgba(245,158,11,0.11); border: 1px solid rgba(245,158,11,0.4); }
.cbab-status.is-done { background: rgba(16,185,129,0.10); border: 1px solid rgba(16,185,129,0.38); }

.cbab-tools          { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
                       margin-bottom: 14px; padding: 12px 15px; background: var(--bg-surface);
                       border: 1px solid var(--border-light); border-radius: var(--radius-sm); }
.cbab-tools-label    { font-weight: 700; font-size: 13px; }
.cbab-tools-note     { font-size: 12px; color: var(--text-muted); flex-basis: 100%; }

/* The grid is wide by nature — 14 allergens plus notes. Scroll it inside its
   own box so the page itself never scrolls sideways. */
.cbab-scroll         { overflow-x: auto; background: var(--bg-surface);
                       border: 1px solid var(--border-light); border-radius: var(--radius-sm); }
.cbab-table          { width: 100%; border-collapse: collapse; font-size: 13px; }
.cbab-table th       { background: var(--bg-main); padding: 8px 6px; vertical-align: bottom;
                       border-bottom: 2px solid var(--border-color); }
.cbab-table td       { padding: 7px 6px; border-bottom: 1px solid var(--border-light); }
.cbab-table tbody tr:hover td { background: rgba(92,29,36,0.03); }

/* Product name stays put while the allergen columns scroll under it. */
.cbab-col-product    { position: sticky; left: 0; z-index: 2; background: var(--bg-surface);
                       min-width: 215px; font-weight: 600; }
.cbab-table thead .cbab-col-product { background: var(--bg-main); z-index: 3; }
.cbab-cat-row td     { background: var(--bg-main); font-weight: 700; font-size: 11.5px;
                       text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-primary); }
.cbab-emoji          { margin-right: 6px; }

/* Vertical headers keep 14 columns inside one screen. */
.cbab-col-allergen   { width: 34px; }
.cbab-col-toggle     { writing-mode: vertical-rl; transform: rotate(180deg); background: none;
                       border: 0; cursor: pointer; font-size: 11.5px; font-weight: 600;
                       color: var(--text-secondary); padding: 6px 2px; height: 132px;
                       text-align: left; white-space: nowrap; }
.cbab-col-toggle:hover { color: var(--color-primary); text-decoration: underline; }
.cbab-cell           { text-align: center; }
.cbab-col-notes      { min-width: 205px; }
.cbab-col-notes small{ font-weight: 400; color: var(--text-muted); display: block; font-size: 10.5px; }
.cbab-col-checked    { width: 62px; text-align: center; }
.cbab-notes-input    { font-size: 12.5px; padding: 6px 9px; }

.cbab-box            { display: inline-flex; cursor: pointer; }
.cbab-box input      { width: 17px; height: 17px; cursor: pointer; accent-color: var(--color-primary); }
.cbab-box-check input{ accent-color: var(--color-success); width: 19px; height: 19px; }

tr.is-unconfirmed .cbab-col-product { border-left: 3px solid #f59e0b; }
tr.is-confirmed   .cbab-col-product { border-left: 3px solid var(--color-success); }

.cbab-save-bar       { position: sticky; bottom: 0; margin-top: 18px; padding: 15px 18px;
                       background: var(--bg-surface); border: 1px solid var(--border-light);
                       border-radius: var(--radius-sm); display: flex; align-items: center;
                       gap: 16px; flex-wrap: wrap; box-shadow: 0 -2px 14px rgba(0,0,0,0.06); }
.cbab-save-note      { font-size: 12.5px; color: var(--text-secondary); line-height: 1.55; flex: 1; }

/* ── Reviews strip on the home page ──────────────────────── */
.cbrev-section       { padding: 70px 0; background: var(--bg-main); }
.cbrev-head          { text-align: center; margin-bottom: 38px; }
.cbrev-head .section-title { margin-bottom: 14px; }
.cbrev-summary       { display: inline-flex; align-items: center; gap: 11px; flex-wrap: wrap;
                       justify-content: center; }
.cbrev-summary-text  { font-size: 14.5px; color: var(--text-secondary); }
.cbrev-stars         { color: #f5a623; font-size: 18px; letter-spacing: 1px; white-space: nowrap; }
.cbrev-stars-sm      { font-size: 14px; margin-bottom: 12px; }

/* Slider. The track is a scroll-snapping row, so it works by swipe and
   keyboard on its own; the arrows and dots are an enhancement layered on top
   and stay hidden if the script never runs. */
.cbrev-slider        { position: relative; display: flex; align-items: center; gap: 10px; }
/* Flex with a fixed flex-basis rather than percentage grid columns. Percentage
   track sizes make the children's width depend on the container that is
   supposed to be scrolling them, and min-width:0 is required on the flex item
   or it refuses to shrink below its content and never becomes scrollable. */
.cbrev-track         { display: flex; gap: 22px; overflow-x: auto; overflow-y: hidden;
                       scroll-snap-type: x mandatory; scroll-behavior: smooth;
                       flex: 1 1 0; min-width: 0; padding: 4px;
                       /* Firefox / IE hide the bar; WebKit needs the rule below. */
                       scrollbar-width: none; -ms-overflow-style: none; }
.cbrev-track::-webkit-scrollbar { display: none; }
.cbrev-track:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 3px;
                       border-radius: var(--radius-md); }
.cbrev-track > .cbrev-card { scroll-snap-align: start;
                       flex: 0 0 calc((100% - 44px) / 3); }

.cbrev-nav           { flex: 0 0 auto; width: 42px; height: 42px; border-radius: 50%;
                       border: 1px solid var(--border-color); background: var(--bg-surface);
                       color: var(--color-primary); cursor: pointer; font-size: 15px;
                       display: flex; align-items: center; justify-content: center;
                       transition: all 0.18s ease; }
.cbrev-nav:hover:not(:disabled) { background: var(--color-primary); color: #fff;
                       border-color: var(--color-primary); }
.cbrev-nav:disabled  { opacity: 0.3; cursor: default; }

.cbrev-dots          { display: flex; justify-content: center; gap: 8px; margin-top: 20px; }
.cbrev-dot           { width: 9px; height: 9px; padding: 0; border-radius: 50%; cursor: pointer;
                       border: 0; background: var(--border-strong); transition: all 0.2s ease; }
.cbrev-dot.is-active { background: var(--color-primary); width: 26px; border-radius: 5px; }

@media (max-width: 900px) {
    .cbrev-track > .cbrev-card { flex: 0 0 calc((100% - 22px) / 2); }
}
@media (max-width: 620px) {
    .cbrev-track > .cbrev-card { flex: 0 0 100%; }
    .cbrev-nav       { display: none; }   /* swipe is the natural gesture here */
}

.cbrev-card          { background: var(--bg-surface); border: 1px solid var(--border-light);
                       border-radius: var(--radius-md); padding: 24px 26px;
                       display: flex; flex-direction: column;
                       transition: transform 0.2s ease, box-shadow 0.2s ease; }
.cbrev-card:hover    { transform: translateY(-3px); box-shadow: 0 8px 24px rgba(0,0,0,0.07); }
.cbrev-body          { margin: 0 0 18px; padding: 0; border: 0; font-size: 15px; line-height: 1.7;
                       color: var(--text-primary); font-style: italic; flex: 1; }
.cbrev-body::before  { content: '\201C'; color: var(--color-secondary); font-size: 30px;
                       line-height: 0; vertical-align: -8px; margin-right: 3px; }
.cbrev-meta          { display: flex; flex-direction: column; gap: 2px; font-size: 14px;
                       border-top: 1px solid var(--border-light); padding-top: 13px; }
.cbrev-sub           { font-size: 12.5px; color: var(--text-secondary); }

/* Empty state — shown until the first review is published. */
.cbrev-none          { text-align: center; font-size: 15px; line-height: 1.7;
                       color: var(--text-secondary); max-width: 560px; margin: 0 auto 8px; }

/* ── Leave a review ──────────────────────────────────────── */
.cbrev-write         { max-width: 620px; margin: 30px auto 0; }
.cbrev-write-toggle  { cursor: pointer; list-style: none; display: inline-flex; align-items: center;
                       gap: 9px; margin: 0 auto; padding: 12px 26px; border-radius: 30px;
                       background: var(--bg-surface); border: 1px solid var(--border-color);
                       font-weight: 700; font-size: 14.5px; color: var(--color-primary);
                       transition: all 0.2s ease; }
.cbrev-write-toggle::-webkit-details-marker { display: none; }
.cbrev-write-toggle:hover { background: var(--color-primary); color: #fff;
                       border-color: var(--color-primary); }
.cbrev-write > summary { margin-left: 50%; transform: translateX(-50%); }
.cbrev-write[open] > summary { margin-bottom: 20px; }

.cbrev-form          { background: var(--bg-surface); border: 1px solid var(--border-light);
                       border-radius: var(--radius-md); padding: 24px 26px; text-align: left; }
.cbrev-form-row      { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.cbrev-opt           { font-weight: 400; color: var(--text-muted); font-size: 12px; }
.cbrev-submit        { margin-top: 6px; }
.cbrev-note          { font-size: 12px; color: var(--text-muted); line-height: 1.6;
                       margin: 12px 0 0; }

.cbrev-thanks        { max-width: 620px; margin: 28px auto 0; display: flex; align-items: flex-start;
                       gap: 12px; padding: 16px 20px; border-radius: var(--radius-md);
                       background: rgba(16,185,129,0.10); border: 1px solid rgba(16,185,129,0.35);
                       font-size: 14.5px; line-height: 1.6; text-align: left; }
.cbrev-thanks i      { color: var(--color-success); font-size: 19px; margin-top: 1px; }
.cbrev-error         { max-width: 620px; margin: 22px auto 0; padding: 13px 18px;
                       border-radius: var(--radius-sm); background: rgba(217,56,56,0.09);
                       border: 1px solid rgba(217,56,56,0.32); color: var(--color-danger);
                       font-size: 14px; text-align: left; }

@media (max-width: 560px) {
    .cbrev-form-row  { grid-template-columns: 1fr; }
}


/* Hero float positions — these live here rather than as style="" attributes,
   because inline CSS is banned project-wide. One class per decorative glyph. */
.cb-hero-float--p1 { left: 4%;  top: 16%; }
.cb-hero-float--p2 { right: 7%; top: 20%; }
.cb-hero-float--p3 { right: 16%; bottom: 24%; }
.cb-hero-float--p4 { left: 12%; bottom: 30%; }
.cb-hero-float--p5 { right: 24%; top: 8%; }



/* ============================================================
   Home page banner slider
   ============================================================
   The track is a scroll-snapping row, so it works by swipe and by keyboard
   with no JavaScript at all; the arrows, dots and auto-advance are layered
   on top and hide themselves if the script never runs.

   Slides are sized in vh with a max, not in px: a banner that is 420px tall
   dominates a laptop and looks like a stripe on a large monitor. */
.cbbn            { position: relative; background: var(--color-primary-dark); overflow: hidden; }
.cbbn-track      { display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
                   scroll-behavior: smooth; scrollbar-width: none; -ms-overflow-style: none; }
.cbbn-track::-webkit-scrollbar { display: none; }
.cbbn-track:focus-visible { outline: 3px solid var(--color-secondary); outline-offset: -3px; }

.cbbn-slide      { position: relative; flex: 0 0 100%; scroll-snap-align: start;
                   display: block; text-decoration: none; color: #fff;
                   /* Requested as clamp(650px, 58vh, 110px). Since the minimum
                      (650px) is larger than the maximum (110px), CSS clamp()
                      resolves min(58vh, 110px) — 110px on any real screen —
                      then max(650px, 110px), so this is a fixed 650px on every
                      viewport, not a responsive range. Left exactly as given;
                      flagged in case the min/max were meant the other way round. */
                   height: clamp(650px, 58vh, 110px); }
.cbbn-img        { width: 100%; height: 100%; object-fit: cover; display: block; }

/* A gradient rather than a flat wash: the text end stays readable while the
   far side of the photograph is left alone. */
.cbbn-caption    { position: absolute; inset: 0; display: flex; flex-direction: column;
                   align-items: flex-start; justify-content: center; gap: 12px;
                   padding: 0 clamp(22px, 7vw, 90px);
                   background: linear-gradient(90deg, rgba(44,13,17,0.78) 0%,
                                                      rgba(44,13,17,0.55) 45%,
                                                      rgba(44,13,17,0.08) 100%); }
.cbbn-headline   { font-size: clamp(24px, 4.2vw, 46px); margin: 0; line-height: 1.12;
                   color: #fff; max-width: 17ch; text-shadow: 0 2px 12px rgba(0,0,0,0.35); }
.cbbn-sub        { font-size: clamp(14px, 1.7vw, 19px); margin: 0; max-width: 42ch;
                   line-height: 1.55; color: rgba(255,255,255,0.93); }
.cbbn-cta        { margin-top: 6px; }

/* Text on the right instead — for a banner photo whose product sits on the
   left. Mirrors both the alignment and the gradient direction so the dark
   scrim always sits behind the text, whichever side that is. Chosen per
   slide from Admin → Banners. Desktop-only: the @media block below already
   centres the caption on narrow screens regardless of this, since a phone
   photo rarely has the width for a distinct left/right product zone. */
.cbbn-caption--right { align-items: flex-end; text-align: right;
                   background: linear-gradient(270deg, rgba(44,13,17,0.78) 0%,
                                                       rgba(44,13,17,0.55) 45%,
                                                       rgba(44,13,17,0.08) 100%); }

/* ── Arrows and dots ─────────────────────────────────────── */
.cbbn-nav        { position: absolute; top: 50%; transform: translateY(-50%);
                   width: 46px; height: 46px; border-radius: 50%; border: 0; cursor: pointer;
                   background: rgba(255,255,255,0.9); color: var(--color-primary);
                   font-size: 17px; display: flex; align-items: center; justify-content: center;
                   transition: background 0.18s ease, transform 0.18s ease; z-index: 2; }
.cbbn-nav:hover  { background: #fff; transform: translateY(-50%) scale(1.06); }
.cbbn-prev       { left: 16px; }
.cbbn-next       { right: 16px; }

.cbbn-dots       { position: absolute; left: 0; right: 0; bottom: 16px; z-index: 2;
                   display: flex; justify-content: center; gap: 8px; }
.cbbn-dot        { width: 9px; height: 9px; padding: 0; border: 0; border-radius: 50%;
                   background: rgba(255,255,255,0.5); cursor: pointer; transition: all 0.2s ease; }
.cbbn-dot.is-active { background: #fff; width: 26px; border-radius: 5px; }

@media (max-width: 620px) {
    /* Swipe is the natural gesture on a phone, and the arrows sit on top of
       the picture where a thumb already is. */
    .cbbn-nav     { display: none; }
    .cbbn-caption { background: linear-gradient(180deg, rgba(44,13,17,0.25) 0%, rgba(44,13,17,0.82) 100%);
                    align-items: center; text-align: center; justify-content: flex-end;
                    padding-bottom: 46px; }
    .cbbn-headline { max-width: none; }
}

/* ── Emoji replaced by icons ──────────────────────────────────
   The decorative hero marks, the empty-cart symbol and the confirmation tick
   were emoji. Emoji render in whatever font the visitor's device ships, so
   the same page looked different on Windows, Android and iOS — and none of
   those variants were the brand. Font Awesome is one shape everywhere, takes
   the brand colour, and stays sharp at any size.

   These rules only restore the SIZE the emoji had: the markup around them is
   unchanged, so nothing moved. */
.cb-hero-float > i        { font-size: 0.86em; opacity: 0.92; }
.cb-eyebrow-icon          { margin-right: 6px; }
.flavour-card-img > i { color: var(--color-primary); }
.cart-empty-icon > i { color: var(--text-muted); }
.toast-icon > i { color: var(--color-primary); }
.story-highlight-icon > i { color: var(--color-secondary); }
.gallery-empty-icon > i { color: var(--text-muted); }
.cboc-collect-emoji > i { color: var(--color-primary); }
.cbor-delivery-popup-emoji > i { color: var(--color-primary); }
/* The confirmation tick was 🎉 + 🍦; one green tick says "done" more clearly
   than two competing symbols. */
.confirmation-icon > i { color: var(--color-success); }
/* ── Emoji replaced by icons: order, checkout and trade pages ──
   Same principle as above — the markup around each icon is unchanged, these
   rules only give back the size, colour and spacing the emoji had.

   Three shared classes, because the same three shapes recur: an icon
   trailing a page heading, one leading a small uppercase badge, and one
   leading a sentence in an alert.

   The margins are small because they are not the whole gap. The headings
   keep the literal space the emoji sat after, and .alert is display:flex
   with gap:12px, so .cb-alert-icon only tops that up — 6px, the same total
   as .cbtr-alert-icon on the registration page. */
.cb-title-icon { color: var(--color-primary); font-size: 0.78em; margin-left: 2px; }
.cb-badge-icon { margin-right: 6px; }
.cb-alert-icon { margin-right: 6px; }

/* The product placeholders stand in for a photograph, so they take the brand
   colour rather than the body text colour. Font size is inherited from each
   container, which already sets the size the emoji used. */
.product-image-placeholder > i    { color: var(--color-primary); }
.variant-picker-emoji > i         { color: var(--color-primary); }
.cart-item-img-placeholder > i    { color: var(--color-primary); }
.osi-emoji > i                    { color: var(--color-primary); }
.trade-page .cbtp-empty-icon > i  { color: var(--text-muted); }


/* ── Icon scale inside the old emoji slots ──────────────────────────────
   These boxes were sized for emoji, which sit inside their em box with
   space around them. A Font Awesome glyph fills that box completely, so a
   like-for-like swap made every one of them look oversized — a 72px
   product placeholder became a 72px solid shape.

   0.5em is relative to each box's own font-size, so one rule keeps every
   slot proportional: half of 72px, half of 26px, and so on. Anything that
   sits inline next to text is handled separately at 0.8em, because half
   the text size would be too small to read on paper. */
.cbco-order-type-icon > i,
.cbco-order-type-icon > svg { font-size: 0.5em; width: 1em; height: 1em; }
.trade-page .cbtp-empty-icon > i,
.trade-page .cbtp-empty-icon > svg { font-size: 0.5em; width: 1em; height: 1em; }
.cbor-trade-banner-icon > i,
.cbor-trade-banner-icon > svg { font-size: 0.5em; width: 1em; height: 1em; }
.cbor-delivery-popup-emoji > i,
.cbor-delivery-popup-emoji > svg { font-size: 0.5em; width: 1em; height: 1em; }
.trade-page .cbtr-alert-icon > i,
.trade-page .cbtr-alert-icon > svg { font-size: 0.5em; width: 1em; height: 1em; }
body.about-page .cbab-social-icon > i,
body.about-page .cbab-social-icon > svg { font-size: 0.5em; width: 1em; height: 1em; }
.cboc-collect-emoji > i,
.cboc-collect-emoji > svg { font-size: 0.5em; width: 1em; height: 1em; }
.flavour-card-img > i,
.flavour-card-img > svg { font-size: 0.5em; width: 1em; height: 1em; }

/* ============================================================
   OFFERS, GIFTS AND CART MESSAGES  (cbof-)
   ============================================================
   One set of classes for both places a customer meets an offer: the cart
   drawer on the menu page and the order summary at checkout. The two pages
   render their own markup — they have to, one is a slim drawer and the other
   a full summary — but they share these rules so a buy-one-get-one looks the
   same in both, and so a change of mind about the tone is made once.

   The palette is the brand's own gold and chocolate rather than the usual
   discount red. This is a premium ice cream shop; a saving here should read
   as something the shop is pleased to give, not as a clearance sticker.

   Nothing in here sets `display` on .cbco-summary-row or its variants, so the
   visibility block at the foot of this file keeps the last word.
   ------------------------------------------------------------ */

/* ── Delivery, once something has made it free ──────────────── */
/* Sits on the same row as .cbco-summary-row-delivery and simply recolours it:
   the amber "you are paying for this" becomes the green of a saving. */
.cbof-row-free { color: #10b981; }

/* ── The banner under the total ─────────────────────────────── */
/* Modifiers on .cbco-delivery-banner. Written by the server from the same
   figures as the rows above it, so the two can never disagree. */
.cbof-banner-good {
    background: rgba(16, 185, 129, 0.06);
    border-color: rgba(16, 185, 129, 0.25);
}
.cbof-banner-warn {
    background: rgba(199, 136, 41, 0.07);
    border-color: rgba(199, 136, 41, 0.28);
}
.cbof-banner-text-good { color: #0f9b76; }
.cbof-banner-text-warn { color: #9a6612; }

/* ── "Delivery is £1.99." under the postcode box ────────────── */
/* Its own line rather than sharing #postcodeStatus: that one is written by
   the browser as it measures the distance, and this one only ever repeats
   what the server said the price was. Two writers on one element is how a
   stale figure survives on screen. Hidden by .cbco-hidden, which is the last
   rule in this file, so this display never fights it. */
.cbof-price-note {
    display: block;
    margin-top: 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-secondary);
}

/* ── A gift that has been earned ────────────────────────────── */
/* Below the total on purpose: a free tub is an extra thing in the box, not
   money off, so it must not sit among the rows that add up. */
.cbof-gift-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    margin-top: 10px;
    padding: 9px 12px;
    border: 1px dashed rgba(199, 136, 41, 0.45);
    border-radius: var(--radius-sm);
    background: rgba(253, 244, 229, 0.75);
}
.cbof-gift-label {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
}
.cbof-gift-label > i { font-size: 0.8em; color: var(--color-secondary); }
.cbof-gift-value {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-secondary);
    white-space: nowrap;
}

/* ── The words ──────────────────────────────────────────────── */
/* Quiet by design. These are lines a customer reads once and acts on, not
   shouting — no capitals, no exclamation marks, nothing flashing. */
.cbof-notes {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--border-light);
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.cbof-note {
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--text-secondary);
    display: flex;
    align-items: baseline;
    gap: 8px;
}
/* A small gold dot instead of an icon per line: four icons stacked up read as
   a warning list, and none of this is a warning. */
.cbof-note::before {
    content: '';
    flex: 0 0 auto;
    width: 5px;
    height: 5px;
    margin-top: 1px;
    border-radius: 50%;
    background: var(--color-secondary);
    opacity: 0.65;
}

/* ── The offer badge on a product card ──────────────────────── */
/* Top LEFT, because .product-badge (New / Hot / Best Seller) already owns the
   top right — a card can carry both without either covering the other. */
.cbof-badge {
    position: absolute;
    top: 16px; left: 16px;
    z-index: 10;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: calc(100% - 110px);
    padding: 4px 11px;
    border-radius: 20px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    line-height: 1.5;
    color: #FFF6E6;
    background: linear-gradient(135deg, var(--color-primary) 0%, #7a2b33 100%);
    border: 1px solid rgba(199, 136, 41, 0.55);
    box-shadow: 0 2px 8px rgba(92, 29, 36, 0.22);
    /* A long badge is trimmed rather than allowed to wrap across the photo. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.cbof-badge > i { font-size: 0.8em; color: var(--color-secondary); }

/* Out-of-stock ribbon — same slot/shape as .cbof-badge above (the two never
   show together, $offerBadge is forced empty for an out-of-stock product),
   but in --color-danger rather than the warm offer gradient: this one is a
   blocker, not a promotion, and needs to read as a stop rather than a deal. */
.cbor-oos-ribbon {
    position: absolute;
    top: 16px; left: 16px;
    z-index: 10;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 11px;
    border-radius: 20px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    line-height: 1.5;
    color: #FFF6E6;
    background: var(--color-danger);
    box-shadow: 0 2px 8px rgba(217, 56, 56, 0.35);
}

/* ── The cart drawer's money block ──────────────────────────── */
/* The drawer used to print one line, the basket total, straight from
   cart_handler.php. With an offer running that figure is no longer what the
   customer pays, so the whole block is rendered by the server from
   computeOrderTotals() — the same function that makes the charge. */
.cbof-cart-lines {
    display: flex;
    flex-direction: column;
    gap: 5px;
    margin-bottom: 12px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--border-light);
}
.cbof-cart-line {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    font-size: 13px;
    color: var(--text-secondary);
}
.cbof-cart-line-label {
    display: inline-flex;
    align-items: baseline;
    gap: 7px;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cbof-cart-line-label > i { font-size: 0.8em; }
.cbof-cart-line-value { white-space: nowrap; font-variant-numeric: tabular-nums; }
.cbof-cart-line-offer { color: #0f9b76; font-weight: 600; }
.cbof-cart-line-offer .cbof-cart-line-label > i { color: #0f9b76; }
.cbof-cart-line-vat   { font-weight: 600; }

/* The drawer footer used to hold one figure and two buttons and could not
   grow. It now carries the offer breakdown, an earned gift and up to four
   lines of encouragement — and .cart-items is `flex: 1 1 0` with
   `min-height: 0`, so a tall footer would squeeze the basket itself down to
   nothing and the customer could no longer see what they were buying.
   These two give the basket a floor and let the footer scroll instead.
   components.css loads after style.css, so this wins without !important. */
.cart-sidebar .cart-items  { min-height: 96px; }
.cart-sidebar .cart-footer { max-height: 55vh; overflow-y: auto; }

@media (max-width: 480px) {
    .cbof-badge { top: 12px; left: 12px; max-width: calc(100% - 96px); }
    .cbor-oos-ribbon { top: 12px; left: 12px; }
    .cbof-gift-row { padding: 8px 10px; }
}

/* ============================================================
   "OPEN FOR ORDERS" / "CLOSED NOW"
   ============================================================
   The owner switches delivery and collection on and off by hand from the
   admin panel. These are the customer's side of that: a paused method on the
   checkout chooser, the sentence explaining it, the panel that replaces the
   whole form when both are off, and the notice at the top of the menu.

   The look is deliberately QUIET. Every one of these tells somebody they
   cannot have what they came for, and a red alarm bar reads as "this website
   is broken" rather than "the shop has stopped for the evening". Warm amber
   on cream, the shop's own type, no shouting. Nothing here is an error.

   POSITION MATTERS for the -closed modifier below. toggleOrderType() adds
   .cbco-order-type-option-idle to whichever label is not currently chosen,
   including a closed one — those rules sit near the top of this file, so
   writing these here (same specificity, later in the file) is what keeps a
   paused method looking paused after the customer picks the other one. */

/* ── The paused half of the Delivery / Collection chooser ── */
.cbco-order-type-option-closed {
    /* Dashed, and a shade stronger than --border-light, so "unavailable" reads
       as a decision rather than as a button that failed to paint. */
    border: 1px dashed rgba(92, 29, 36, 0.16);
    background: transparent;
    cursor: not-allowed;
    position: relative;
}
/* No lift, no glow — it is not going anywhere. */
.cbco-order-type-option-closed:hover { transform: none; box-shadow: none; }

.cbco-order-type-pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-top: 8px;
    padding: 3px 10px;
    border-radius: 999px;
    background: var(--color-secondary-bg);
    color: #92610f;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.cbco-order-type-pill > i { font-size: 0.9em; }

/* The sentence under the pair — the owner's own wording when they wrote any. */
.cbco-channel-note {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin-top: 12px;
    padding: 11px 14px;
    border-radius: var(--radius-sm);
    background: var(--color-secondary-bg);
    border: 1px solid rgba(199, 136, 41, 0.22);
    color: #8a5c12;
    font-size: 13px;
    line-height: 1.5;
}
.cbco-channel-note > i { margin-top: 2px; color: var(--color-secondary); }

/* ── Both methods off: this replaces the whole form ── */
.cbco-paused-panel { text-align: center; }
.cbco-paused-mark {
    width: 62px;
    height: 62px;
    margin: 4px auto 18px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-secondary-bg);
    color: var(--color-secondary);
    font-size: 24px;
}
.cbco-paused-title {
    font-size: 22px;
    margin-bottom: 10px;
}
.cbco-paused-note {
    font-size: 15px;
    line-height: 1.6;
    color: var(--text-secondary);
    max-width: 46ch;
    margin: 0 auto 14px;
}
.cbco-paused-sub {
    font-size: 13px;
    color: var(--text-muted);
    margin-bottom: 22px;
}
.cbco-paused-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
}
.cbco-paused-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    text-decoration: none;
}

/* ── The notice at the top of the menu (order.php) ── */
.cbor-paused-notice {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 14px 18px;
    margin-bottom: 20px;
    border-radius: var(--radius-md);
    background: var(--color-secondary-bg);
    border: 1px solid rgba(199, 136, 41, 0.25);
}
.cbor-paused-notice-icon {
    flex: 0 0 auto;
    margin-top: 3px;
    color: var(--color-secondary);
    font-size: 16px;
}
.cbor-paused-notice-body {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}
.cbor-paused-notice-title {
    font-size: 14px;
    font-weight: 700;
    color: #7a4f0c;
}
.cbor-paused-notice-text {
    font-size: 13px;
    line-height: 1.55;
    color: #8a5c12;
}

@media (max-width: 480px) {
    .cbco-paused-actions .cbco-paused-btn { width: 100%; justify-content: center; }
    .cbor-paused-notice { padding: 12px 14px; }
}

/* ============================================================
   VISIBILITY UTILITIES — THESE MUST STAY LAST IN THIS FILE
   ============================================================
   Add nothing below this block.

   These have the same weight as any other single class name, so when two
   rules both set `display`, the one written LAST in the file wins. While
   .cbco-hidden sat near the top, every later rule that set a display beat
   it, and the element it was meant to hide stayed on screen:

     - #minOrderNotice  (.cbco-min-notice, display:flex) showed an empty
       amber bar with a basket icon and no text on every checkout where the
       basket was already over the minimum — the notice "coming blank".
     - #discountRow     (.cbco-summary-row, display:flex) painted
       "Discount −£0.00" on load whenever no promo code was applied.

   Deliberately NOT `!important`. An !important rule outranks an inline
   style, and several places re-show these elements with
   `el.style.display = 'flex'` while leaving the class in place
   (#promoApplied, #discountRow, #cartFooter). Marking these important
   would hide those permanently — trading a visible bug for an invisible
   one. Last position gives the same protection and keeps inline shows
   working. */
.cbco-hidden { display: none; }
.cbor-hidden { display: none; }
