  :root {
    --bg:#FAFAFA;--white:#FFFFFF;--text:#1A1A1A;--text-soft:#3D3D3D;
    --text-muted:#6E6E78;--border:#ECECEC;--cream:#F7F5F0;
    --radius:16px;--radius-sm:12px;

    /* Star / Blueprint / Housing-Style pill colors. These were only ever
       defined as the var(--pp-*, #hex) FALLBACK baked into every usage below
       — never as an actual custom property — so every pill rendered with the
       dark-mode-appropriate fallback in BOTH themes. In light mode that meant
       a moody navy/amber/purple badge sitting on a white card. Defining the
       variables for real here gives light mode its own tinted-chip look;
       body.dark below restores the original dark values unchanged. */
    --pp-star-bg:rgba(254,243,199,.82);--pp-star-border:rgba(245,158,11,.85);--pp-star-icon:#92400E;
    --pp-star-shadow:0 0 0 2px rgba(0,0,0,.04),0 2px 8px rgba(0,0,0,.10);
    --pp-recipe-bg:rgba(219,234,254,.82);--pp-recipe-border:rgba(59,130,246,.85);--pp-recipe-icon:#1D4ED8;
    --pp-recipe-shadow:0 0 0 2px rgba(0,0,0,.04),0 2px 8px rgba(0,0,0,.10);
    --pp-style-bg:rgba(250,232,255,.82);--pp-style-border:rgba(217,70,239,.85);--pp-style-icon:#A21CAF;
    --pp-style-shadow:0 0 0 2px rgba(0,0,0,.04),0 2px 8px rgba(0,0,0,.10);
    /* Unselected ("off") state — a light neutral chip, NOT a dark one. */
    --pp-off-bg:rgba(255,255,255,.82);--pp-off-border:rgba(0,0,0,.18);--pp-off-icon:#8A8A94;
    --pp-off-shadow:0 0 0 2px rgba(0,0,0,.04),0 2px 8px rgba(0,0,0,.10);
  }
  /* --text-muted here (and in :root above) is pinned to the styles.css value on
     purpose — see the note at the top of index.css. This file loads after
     styles.css and used to shadow it with #555560 / #AFAFAF, which is what the
     Pack Builder's sort label and item counts were actually drawn in. */
  html.dark, body.dark{
    --bg:#0E0E10;--white:#18181C;--text:#F2F2F0;--text-soft:#B0B0B8;
    --text-muted:#8A8A94;--border:#26262B;--cream:#141416;

    /* Unchanged from the original fallback values — dark mode already looked
       right, it just wasn't actually reading a real variable. */
    --pp-star-bg:rgba(77,59,5,.82);--pp-star-border:rgba(245,179,1,.85);--pp-star-icon:#F5B301;
    --pp-star-shadow:0 0 0 2px rgba(15,15,17,.62),0 4px 12px rgba(0,0,0,.5);
    --pp-recipe-bg:rgba(16,42,79,.82);--pp-recipe-border:rgba(59,130,246,.85);--pp-recipe-icon:#60A5FA;
    --pp-recipe-shadow:0 0 0 2px rgba(15,15,17,.62),0 4px 12px rgba(0,0,0,.5);
    --pp-style-bg:rgba(59,23,79,.82);--pp-style-border:rgba(217,70,239,.85);--pp-style-icon:#F0ABFC;
    --pp-style-shadow:0 0 0 2px rgba(15,15,17,.62),0 4px 12px rgba(0,0,0,.5);
    --pp-off-bg:rgba(20,20,22,.82);--pp-off-border:rgba(255,255,255,.28);--pp-off-icon:#9A9AA4;
    --pp-off-shadow:0 0 0 2px rgba(15,15,17,.62),0 4px 12px rgba(0,0,0,.5);
  }
  *,*::before,*::after{box-sizing:border-box;}

  /* Skeleton shimmer (.skel / @keyframes sh-shimmer) is injected once,
     globally, by header.js — do not redefine it here. header.js runs
     synchronously before this page's <body> is parsed, so there's no flash;
     a second local copy previously caused the shimmer to render as a static
     frame instead of animating (two stylesheets racing to own the same
     @keyframes name). */

  body{margin:0;background:var(--bg) !important;color:var(--text);font-family:'Inter','Geist',sans-serif !important;min-height:100vh;}

  /* ── Hero page header (matches index.html packs-page-header) ── */
  .bb-page-header{
    width:85%;
    max-width:1400px;
    margin:var(--page-header-margin-top,6px) auto var(--page-header-margin-bottom,12px);
    box-sizing:border-box;
    display:flex;align-items:flex-end;justify-content:space-between;gap:16px;
  }
  @media(max-width:1024px){.bb-page-header{width:100%;padding:0 16px;}}
  .bb-page-left{display:flex;flex-direction:row;align-items:center;gap:12px;}
  .bb-page-h1{
    font-family:'Inter','Geist',sans-serif;font-size:var(--page-title-size,34px);font-weight:var(--page-title-weight,800);
    color:var(--text);margin:0;letter-spacing:var(--page-title-letter-spacing,-0.02em);line-height:var(--page-title-line-height,1.1);
  }
  .bb-page-right{display:flex;align-items:center;gap:8px;margin-bottom:0;}
  /* Site header drops to its shorter mobile height below 1000px (see header.js) —
     the sticky search bar's top offset must follow, or a gap/overlap opens up
     between the fixed header and the sticky toolbar once it docks.
     ──
     These must match the header's SCROLLED height, not its resting one. The
     header shrinks the moment you scroll (.sh-header.sh-scrolled), and the
     toolbar only docks once you have scrolled — so the resting height is never
     the one in play while the toolbar is stuck to it. A single 59px (matched
     against the resting 58/64px) therefore left a permanent strip of page
     showing through between the header and the docked toolbar: 7px at phone
     width, 3px at tablet. Values below are header.js's own scrolled heights:
       ≤999.98px → .sh-header.sh-scrolled .sh-main-inner { height: 56px }
       ≤480px    → .sh-header.sh-scrolled .sh-main-inner { height: 52px } */
  @media (max-width:999.98px){
    /* !important: this precedes the base .bb-search-wrap rule in source
       order, which would otherwise win the cascade at equal specificity */
    .bb-search-wrap{top:56px !important;}
  }
  @media (max-width:480px){
    .bb-search-wrap{top:52px !important;}
  }
  @media(max-width:768px){
    .bb-page-header{margin:var(--page-header-margin-top,6px) auto var(--page-header-margin-bottom,12px);flex-wrap:wrap;gap:12px;}
    .bb-page-right{margin-bottom:0;}
    /* Page header wraps to two lines here (title, then count pill) — the
       desktop -10px pull-up now cuts into that second line, so relax it. */
    .bb-search-wrap{margin-top:6px !important;padding:8px 0 10px !important;}
    /* Keep the selected category visible above the mobile results. The compact
       category button is a control; this heading is the persistent "you are
       here" label users need while scrolling the listings. */
    .packs-content-heading{flex:1 1 100%;width:100%;min-width:0;}
    #bbCategoryTitle{
      display:flex !important;align-items:center;flex:1 1 auto !important;min-width:0;overflow:hidden;
      white-space:nowrap;font-size:18px;
    }
    .packs-content-heading .packs-count-pill{flex-shrink:0;}
    /* Toolbar: search takes its own full-width line, buttons wrap below */
    .bb-search-row{flex-wrap:wrap;}
    /* higher specificity than the base .bb-search-inner rule below, which
       otherwise wins by source order and crushes the input to icon width */
    .bb-search-row .bb-search-inner{flex:1 1 100%;order:-1;}
    .bb-cat-btn{min-width:0;}
    .bb-actions-btn{min-width:0;max-width:150px;}
    .bb-actions-btn span{overflow:hidden;text-overflow:ellipsis;}
  }

  /* ── Layout ── */
  .bb-wrap{
    display:grid;
    grid-template-columns:1fr 520px;
    grid-template-rows:auto 1fr;
    column-gap:20px;
    width:85%;max-width:1400px;margin:0 auto;
  }

  /* ── Left: plushie browser ── */
  .bb-left{grid-column:1;grid-row:2;min-width:0;padding:0 0 60px;}

  /* Hide global nav search on this page */
  body.sh-is-desktop .sh-global-search-wrap{display:none !important;}
  .sh-global-search-wrap{display:none !important;}

  /* ── Inline search toolbar (sticky, full-width across both columns) ── */
  .bb-search-wrap{
    grid-column:1 / -1;grid-row:1;
    position:sticky;top:64px;z-index:20;
    background:var(--bg,#F9F9F7);
    padding:10px 0 12px;margin-top:0;margin-bottom:0;
    display:flex;flex-direction:column;gap:8px;
  }
  body.dark .bb-search-wrap{background:#0e0e10;}
  .bb-search-row{
    display:flex;
    align-items:center;
    gap:14px;
    width:100%;
  }
  .packs-content-title{
    font-size:22px;font-weight:700;color:var(--text);margin:0;
    font-family:'Geist','DM Sans',sans-serif;white-space:nowrap;flex-shrink:0;
    display:inline-flex;align-items:center;gap:8px;
  }
  .packs-content-title-label{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  #bbCategoryTitle .packs-cat-icon{width:23px;height:23px;flex:0 0 23px;}
  #bbCategoryTitle .packs-cat-icon-image{width:25px;height:25px;flex-basis:25px;}
  #bbCategoryTitle .packs-cat-icon-emoji{font-size:20px;}
  .packs-content-heading{
    display:flex;align-items:center;gap:10px;min-width:0;min-height:38px;
    flex-shrink:0;
  }
  .packs-count-pill{
    display:inline-flex;align-items:center;
    background:none;border:0;border-left:1px solid var(--border);
    border-radius:0;padding:1px 0 1px 10px;
    font-family:'Geist','DM Sans',sans-serif;font-size:12px;font-weight:650;
    color:var(--text-muted);width:fit-content;letter-spacing:0;
    transform:translateY(2px);
  }
  /* Legend button, now that it sits in the heading row rather than the
     toolbar. Every dimension is pinned explicitly: this is a flex child of a
     row whose other items grow, so a width without a matching flex basis got
     squeezed into a sliver with the glyph crushed out of sight. The SVG is
     pinned for the same reason — as a flex child it shrinks too.
     No transform here. It briefly carried the count pill's 2px optical nudge,
     copied from a rule written for text sitting on a baseline; on a button it
     just parked it a couple of pixels below the search bar it lines up with. */
  .packs-content-heading .bb-legend-btn{
    flex:0 0 auto;
    /* 38px, the same box every other toolbar control uses (search input,
       Quick Tools, Filter, Sort), and square: width == height, with
       max-width/max-height and padding:0 so no later padding or flex
       stretching can turn it back into a rectangle. */
    width:38px !important;min-width:38px !important;max-width:38px !important;
    height:38px !important;min-height:38px !important;max-height:38px !important;
    padding:0 !important;border-radius:12px;
    align-self:center;
  }
  .packs-content-heading .bb-legend-btn svg{
    flex:0 0 auto;display:block;width:16px;height:16px;
  }
  body.dark .packs-count-pill{background:none;}
  .bb-search-left-col{
    display:flex;
    align-items:center;
    gap:12px;
    flex:1;
    min-width:0;
    width:100%;
  }
  .bb-search-inner{position:relative;display:flex;align-items:center;flex:1;min-width:0;}
  .bb-search-buttons{display:flex;align-items:center;gap:12px;flex-shrink:0;}
  .bb-search-buttons .bb-actions-btn-wrap,
  .bb-search-buttons .bb-anchor-wrap{flex:0 0 auto;}
  /* Height/radius/type match index.html's .packs-view-btn so the two pages'
     toolbars read as one control row (38px, not 42px). */
  .bb-search-buttons .bb-actions-btn,
  .bb-search-buttons .bb-panel-icon-btn{
    width:auto !important;
    height:38px !important;
    border-radius:12px !important;
    padding:0 13px !important;
    font-family:'DM Sans',sans-serif !important;
    font-size:13px !important;
    font-weight:700 !important;
    letter-spacing:-0.01em !important;
    display:inline-flex !important;
    align-items:center !important;
    justify-content:center !important;
    gap:8px !important;
    white-space:nowrap !important;
    border:1.5px solid var(--border) !important;
    background:var(--white) !important;
    color:var(--text) !important;
    box-shadow:0 1px 3px rgba(0,0,0,0.02);
  }
  .bb-search-buttons .bb-actions-btn:hover,
  .bb-search-buttons .bb-panel-icon-btn:hover{
    border-color:var(--text) !important;
    background:var(--chip,#F5F2F0) !important;
  }
  body.dark .bb-search-buttons .bb-actions-btn,
  body.dark .bb-search-buttons .bb-panel-icon-btn{
    background:#141416 !important;
    border-color:#26262B !important;
    color:#F2F2F0 !important;
  }
  .bb-search-buttons .bb-actions-btn svg,
  .bb-search-buttons .bb-panel-icon-btn svg{
    flex-shrink:0;
    margin-right:2px;
  }
  .bb-search-icon{position:absolute;left:12px;color:#AFAFAF;pointer-events:none;display:flex;align-items:center;}
  /* Mirrors index.html's .packs-search-input — same 38px box as the buttons
     beside it, so the whole row lines up on both pages. */
  .bb-search-input{
    width:100%;height:38px;border:1.5px solid var(--border);border-radius:12px;
    padding:0 32px 0 36px;font-family:'DM Sans',sans-serif;font-size:13.5px;
    color:var(--text);background:var(--white);outline:none;
    transition:border-color .15s,box-shadow .15s;
  }
  .bb-search-input:focus{border-color:#16A34A;box-shadow:0 0 0 3px rgba(22,163,74,0.09);}
  .bb-search-input::placeholder{color:var(--text-muted);}
  body.dark .bb-search-input{background:#141416;border-color:#26262B;color:#F2F2F0;}
  body.dark .bb-search-input:focus{border-color:#4ADE80;box-shadow:0 0 0 3px rgba(74,222,128,0.1);}
  /* Visible whenever the field holds text, hidden when it doesn't — expressed as
     a function of the input's own state rather than something JS has to remember
     to keep in sync. The old handler-driven toggle only fired on keystrokes, so
     a value restored by a reload, bfcache, PJAX or autofill left the field full
     and the button missing. :placeholder-shown is true exactly when the input is
     empty, and the button is the input's next sibling. */
  .bb-search-clear{
    position:absolute;right:8px;width:20px;height:20px;border:none;background:none;
    cursor:pointer;padding:0;color:#AFAFAF;display:flex;align-items:center;justify-content:center;
    border-radius:50%;transition:color .12s,background .12s;font-size:16px;line-height:1;
  }
  .bb-search-input:placeholder-shown + .bb-search-clear{display:none;}
  .bb-search-clear:hover{color:#555;background:rgba(0,0,0,0.07);}
  body.dark .bb-search-clear:hover{color:#ddd;background:rgba(255,255,255,0.08);}
  /* Custom category dropdown */
  .bb-cat-btn-wrap{position:relative;flex-shrink:0;}
  .bb-cat-btn{
    height:38px;min-width:130px;padding:0 10px 0 13px;
    border:1.5px solid var(--border);border-radius:12px;
    background:var(--white);font-family:'DM Sans',sans-serif;
    font-size:13px;font-weight:700;color:var(--text);cursor:pointer;
    display:flex;align-items:center;justify-content:space-between;gap:8px;
    transition:border-color .15s;white-space:nowrap;
  }
  .bb-cat-btn:hover,.bb-cat-btn.open{border-color:#16A34A;}
  body.dark .bb-cat-btn{background:#141416;border-color:#26262B;color:#F2F2F0;}
  .bb-cat-dropdown{
    position:absolute;top:calc(100% + 6px);left:0;min-width:190px;
    background:#fff;border-radius:14px;
    box-shadow:0 4px 6px rgba(0,0,0,.07),0 12px 32px rgba(0,0,0,.13);
    z-index:200;padding:6px;display:none;flex-direction:column;
    max-height:min(70vh,560px);overflow-y:auto;overscroll-behavior:contain;
  }
  .bb-cat-dropdown.open{display:flex;}
  body.dark .bb-cat-dropdown{background:#1e1e22;box-shadow:0 4px 6px rgba(0,0,0,.3),0 12px 32px rgba(0,0,0,.4);}
  .bb-cat-opt{
    padding:9px 12px;border:none;background:none;
    font-family:'DM Sans',sans-serif;font-size:13.5px;font-weight:600;
    color:#1A1A1A;cursor:pointer;text-align:left;border-radius:9px;
    transition:background .1s;white-space:nowrap;
    display:flex;align-items:center;gap:8px;
  }
  .bb-cat-opt:hover{background:#F4F4F3;}
  .bb-cat-opt.active{background:rgba(0,0,0,.05);color:var(--text);font-weight:700;}
  .bb-cat-opt.bb-dd-star-item.active{background:rgba(217,119,6,.09);color:#D97706;}
  body.dark .bb-cat-opt{color:#F2F2F0;}
  body.dark .bb-cat-opt:hover{background:rgba(255,255,255,.06);}
  body.dark .bb-cat-opt.active{background:rgba(255,255,255,.07);color:var(--text);}
  body.dark .bb-cat-opt.bb-dd-star-item.active{background:rgba(245,183,0,.1);color:#F5B700;}
  .bb-cat-opt.opt-success{color:#16A34A;}
  .bb-cat-opt.opt-success:hover{background:rgba(22,163,74,.08);}
  body.dark .bb-cat-opt.opt-success{color:#4ADE80;}
  .bb-cat-opt.opt-danger{color:#EF4444;}
  .bb-cat-opt.opt-danger:hover{background:rgba(239,68,68,.08);}
  body.dark .bb-cat-opt.opt-danger{color:#F87171;}
  .bb-cat-opt.opt-amber{color:var(--text,#111);}
  .bb-cat-opt.opt-amber:hover{background:rgba(0,0,0,.06);}
  body.dark .bb-cat-opt.opt-amber{color:#fff;}
  body.dark .bb-cat-opt.opt-amber:hover{background:rgba(255,255,255,.08);}
  .bb-cat-opt:disabled{opacity:1;color:var(--text-muted);cursor:not-allowed;}
  .bb-cat-opt:disabled:hover{background:none;}
  .bb-cat-opt.opt-danger:disabled,body.dark .bb-cat-opt.opt-danger:disabled{color:var(--text-muted);}
  /* Combined "bulk actions" dropdown (select/deselect + remove + hide modes) — sits next to the category dropdown */
  .bb-actions-btn-wrap{position:relative;flex-shrink:0;}
  .bb-actions-btn{
    height:38px;min-width:0;padding:0 10px;
    border:1.5px solid var(--border);border-radius: 12px;
    background:none;font-family:'DM Sans',sans-serif;
    font-size:12px;font-weight:700;color:var(--text-soft);cursor:pointer;
    display:flex;align-items:center;justify-content:center;gap:5px;
    transition:all .15s;white-space:nowrap;
  }
  .bb-actions-btn:hover,.bb-actions-btn.open{border-color:#16A34A;color:#16A34A;}
  body.dark .bb-actions-btn{border-color:#26262B;color:#F2F2F0;}
  .bb-actions-btn.mode-remove{background:#EF4444;border-color:#EF4444;color:#fff;}
  .bb-actions-btn.mode-hide{background:#1A1A1A;border-color:#1A1A1A;color:#fff;}
  .bb-actions-btn.mode-hide:hover{background:#000;border-color:#000;color:#fff;}
  /* "body.dark .bb-actions-btn" above has an extra element in its selector, so it
     out-specifies the two rules just above and silently wins in dark mode — restate
     them scoped to body.dark so the active remove/hide color actually shows. */
  body.dark .bb-actions-btn.mode-remove{background:#EF4444;border-color:#EF4444;color:#fff;}
  body.dark .bb-actions-btn.mode-hide{background:#fff;border-color:#fff;color:#1A1A1A;}
  body.dark .bb-actions-btn.mode-hide:hover{background:#eee;border-color:#eee;color:#1A1A1A;}
  /* Toolbar icon buttons (reuse bb-panel-icon-btn) */
  /* Toolbar-only: the heading row moved inside .bb-search-wrap, so this used to
     catch #bbLegendBtn too and (same specificity, later in the file) beat the
     28px square in .packs-content-heading .bb-legend-btn — it rendered 28x38.
     The legend button is not a toolbar control; exclude it. */
  .bb-search-wrap .bb-panel-icon-btn:not(.bb-legend-btn){height:38px;flex-shrink:0;}
  /* Filter/Sort dropdowns — same anchored style as category dropdown */
  .bb-anchor-wrap{position:relative;flex-shrink:0;}
  .bb-cat-dropdown.bb-anchor-right{left:auto;right:0;min-width:230px;}
  /* ── Filter panel (#bbFilterDropdown) ──
     This was a plain menu: 10px section labels, 13.5px rows and a wrap of 26px
     chips. Legible at a desk, unusable on a phone — and even on desktop the
     selected row was only a slightly different grey. It is a filter surface
     now: a titled header, sections of 42px rows with an explicit check on
     what's on, a search box once the shelf list gets long, and a footer
     stating how many items the current settings leave. The mobile block near
     the bottom of this file grows the same pieces into 52px touch rows inside
     the bottom sheet. */
  #bbFilterDropdown.bb-cat-dropdown{width:388px;max-width:calc(100vw - 40px);padding:0;gap:0;}
  .bb-fd-head{
    position:sticky;top:0;z-index:3;flex-shrink:0;
    display:flex;align-items:center;justify-content:space-between;gap:8px;
    padding:13px 14px 11px;background:inherit;
    border-bottom:1px solid var(--border);border-radius:14px 14px 0 0;
  }
  .bb-fd-title{
    font-family:'Geist','DM Sans',sans-serif;font-size:15px;font-weight:800;
    color:var(--text);letter-spacing:-.01em;
  }
  .bb-fd-head-btns{display:flex;align-items:center;gap:4px;}
  .bb-fd-reset,.bb-fd-clear{
    border:none;background:none;cursor:pointer;padding:6px 8px;border-radius:8px;
    font-family:'DM Sans',sans-serif;font-size:12.5px;font-weight:700;
    color:var(--text-muted);transition:color .12s,background .12s;
  }
  .bb-fd-reset:hover,.bb-fd-clear:hover{color:#EF4444;background:rgba(239,68,68,.08);}
  .bb-fd-clear{margin:-4px -4px 0 0;color:#EF4444;}
  .bb-fd-clear.is-hidden{display:none;}
  .bb-fd-close{
    display:none;align-items:center;justify-content:center;
    width:32px;height:32px;flex-shrink:0;border:none;border-radius:50%;
    background:rgba(0,0,0,.05);color:var(--text-soft);
    font-size:18px;line-height:1;cursor:pointer;
  }
  body.dark .bb-fd-close{background:rgba(255,255,255,.07);}
  .bb-fd-section{padding:12px 10px 10px;}
  .bb-fd-section + .bb-fd-section{border-top:1px solid var(--border);}
  .bb-fd-label{
    padding:0 4px 8px;font-family:'DM Sans',sans-serif;
    font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.07em;
    color:var(--text-muted);
  }
  .bb-fd-label-row{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;}
  .bb-fd-opts{display:flex;flex-direction:column;gap:2px;}
  .bb-fd-opt{
    display:flex;align-items:center;justify-content:space-between;gap:10px;
    width:100%;min-height:42px;padding:0 12px;
    border:none;background:none;border-radius:10px;
    font-family:'DM Sans',sans-serif;font-size:14px;font-weight:600;
    color:var(--text);text-align:left;cursor:pointer;
    transition:background .12s,color .12s;
  }
  .bb-fd-opt:hover{background:#F4F4F3;}
  body.dark .bb-fd-opt:hover{background:rgba(255,255,255,.06);}
  .bb-fd-opt.active{background:rgba(22,163,74,.08);color:#15803D;font-weight:700;}
  body.dark .bb-fd-opt.active{background:rgba(34,197,94,.12);color:#4ADE80;}
  /* The check is drawn on every row and only revealed on the active one, so
     changing the selection never reflows the list. */
  .bb-fd-check{flex-shrink:0;opacity:0;color:currentColor;}
  .bb-fd-opt.active .bb-fd-check{opacity:1;}
  .bb-fd-search{position:relative;display:flex;align-items:center;margin:0 4px 10px;}
  .bb-fd-search svg{position:absolute;left:11px;color:var(--text-muted);pointer-events:none;}
  .bb-fd-search-input{
    width:100%;height:38px;border:1.5px solid var(--border);border-radius:10px;
    padding:0 12px 0 33px;font-family:'DM Sans',sans-serif;font-size:13.5px;
    color:var(--text);background:var(--white);outline:none;
    transition:border-color .15s,box-shadow .15s;
  }
  .bb-fd-search-input:focus{border-color:#16A34A;box-shadow:0 0 0 3px rgba(22,163,74,.09);}
  .bb-fd-search-input::placeholder{color:var(--text-muted);}
  body.dark .bb-fd-search-input{background:#141416;border-color:#26262B;color:#F2F2F0;}
  body.dark .bb-fd-search-input:focus{border-color:#4ADE80;box-shadow:0 0 0 3px rgba(74,222,128,.1);}
  .bb-fd-empty{padding:2px 6px 8px;font-family:'DM Sans',sans-serif;font-size:13px;color:var(--text-muted);}
  /* Sub-category options read as a chip grid rather than a stacked list —
     with categories that carry 20+ sub-categories a vertical list runs the
     panel off the bottom of the screen; wrapping horizontally keeps it a
     bounded, scannable width instead of an ever-taller column. (On a phone
     they go back to full-width rows — see the mobile block.) */
  .bb-dd-subcat-pills{display:flex;flex-direction:row;flex-wrap:wrap;gap:7px;padding:0 4px 4px;}
  .bb-cat-opt.bb-dd-subcat-item{
    flex:none;width:auto;min-height:36px;padding:0 13px;gap:6px;
    border:1.5px solid var(--border);border-radius:999px;
    font-size:13.5px;font-weight:600;
  }
  .bb-cat-opt.bb-dd-subcat-item[hidden]{display:none;}
  .bb-cat-opt.bb-dd-subcat-item .bb-fd-check{width:13px;height:13px;margin-right:-2px;display:none;opacity:1;}
  .bb-cat-opt.bb-dd-subcat-item.active .bb-fd-check{display:block;}
  .bb-cat-opt.bb-dd-subcat-item:hover{border-color:#AFAFAF;background:transparent;}
  .bb-cat-opt.bb-dd-subcat-item.active{border-color:#16A34A;color:#16A34A;font-weight:700;background:rgba(22,163,74,.07);}
  body.dark .bb-cat-opt.bb-dd-subcat-item{border-color:#26262B;}
  body.dark .bb-cat-opt.bb-dd-subcat-item:hover{border-color:#3A3A42;background:transparent;}
  body.dark .bb-cat-opt.bb-dd-subcat-item.active{border-color:#22C55E;color:#22C55E;background:rgba(34,197,94,.1);}
  .bb-fd-foot{
    position:sticky;bottom:0;z-index:3;flex-shrink:0;
    padding:10px 12px 12px;background:inherit;
    border-top:1px solid var(--border);border-radius:0 0 14px 14px;
  }
  .bb-fd-done{
    width:100%;min-height:44px;border:none;border-radius:12px;
    background:#16A34A;color:#fff;cursor:pointer;
    font-family:'Geist','DM Sans',sans-serif;font-size:14.5px;font-weight:700;
    transition:background .15s;
  }
  .bb-fd-done:hover{background:#15803D;}
  .bb-cat-dropdown .bb-dd-label{padding:8px 12px 4px;font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--text-muted);}
  .bb-cat-dropdown .bb-dd-divider{height:1px;background:var(--border);margin:6px 4px;}
  .bb-cat-dropdown .bb-dd-header{display:flex;justify-content:flex-end;padding:2px 4px 0;}
  .bb-panel-icon-btn.open{border-color:#16A34A;color:#16A34A;}

  /* ── Toolbar — now just a shell for subcategory pills rendered by JS ── */
  .product-toolbar{display:none;}
  .product-toolbar-top{display:none;}
  .product-toolbar-subtitle{display:none !important;}
  .product-toolbar-title-text{
    font-family:'Geist','DM Sans',sans-serif;font-size:22px;font-weight:700;
    color:#1A1A1A;letter-spacing:-0.02em;line-height:1;margin:0;
  }
  body.dark .product-toolbar-title-text{color:#F2F2F0;}
  .product-toolbar-count{
    display:inline-flex;align-items:center;margin-left:8px;
    background:rgba(0,0,0,0.04);border:1.5px solid var(--border);
    border-radius:50px;padding:2px 10px;
    font-family:'Geist','DM Sans',sans-serif;font-size:12px;font-weight:700;color:var(--text-muted);
  }
  body.dark .product-toolbar-count{background:rgba(255,255,255,0.05);}

  /* Hide-owned toggle */
  .pp-owned-toggle{
    display:inline-flex;align-items:center;gap:9px;cursor:pointer;
    font-family:'Geist','DM Sans',sans-serif;white-space:nowrap;height:34px;padding:0 2px;
  }
  .pp-owned-toggle .pp-track{
    width:36px;height:20px;border-radius:999px;
    background:rgba(0,0,0,0.14);position:relative;transition:background .22s;flex-shrink:0;
  }
  .pp-owned-toggle .pp-knob{
    position:absolute;top:2px;left:2px;width:16px;height:16px;
    border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,0.3);
    transition:transform .22s cubic-bezier(.4,1.3,.5,1);
  }
  .pp-owned-toggle.is-on .pp-track{background:#2f9d6e;}
  .pp-owned-toggle.is-on .pp-knob{transform:translateX(16px);}
  .pp-owned-toggle .pp-lbl{font-size:13px;font-weight:600;color:#6B6B7B;}
  .pp-owned-toggle.is-on .pp-lbl{color:#1A1A1A;}
  body.dark .pp-owned-toggle .pp-lbl{color:#888890;}
  body.dark .pp-owned-toggle.is-on .pp-lbl{color:#F2F2F0;}
  body.dark .pp-owned-toggle .pp-track{background:rgba(255,255,255,0.15);}


  /* Sort button */
  .pp-sortbtn-wrap{position:relative;}
  .product-sort-wrap{
    display:inline-flex;align-items:center;height:34px;
    padding:0 12px;border-radius:999px;border:1.5px solid var(--border);
    background:var(--white);cursor:pointer;gap:7px;font-family:'Geist','DM Sans',sans-serif;
  }
  body.dark .product-sort-wrap{background:#141416;color:#F2F2F0;}
  .product-sort-label{font-size:12px;font-weight:600;color:var(--text-muted);}
  body.dark .product-sort-label{color:var(--text-muted);}
  #bsSortVal{font-size:13px;font-weight:700;color:#1A1A1A;}
  body.dark #bsSortVal{color:#F2F2F0;}
  .pp-sort-menu{
    display:none;position:absolute;right:0;top:calc(100% + 8px);z-index:200;
    background:#fff;border:1.5px solid var(--border);border-radius:14px;
    box-shadow:0 18px 40px -16px rgba(20,20,30,0.28),0 4px 10px rgba(20,20,30,0.06);
    padding:6px;min-width:200px;
  }
  body.dark .pp-sort-menu{background:#141416;border-color:#26262B;}
  .pp-sort-menu.open{display:block;}
  .pp-sort-item{
    display:flex;align-items:center;justify-content:space-between;
    width:100%;padding:8px 12px;border-radius:9px;border:none;background:none;
    font-family:'Geist','DM Sans',sans-serif;font-size:13px;font-weight:600;
    color:#3D3D3D;cursor:pointer;text-align:left;
  }
  .pp-sort-item:hover{background:rgba(0,0,0,0.04);}
  body.dark .pp-sort-item{color:#B0B0B8;}
  body.dark .pp-sort-item:hover{background:rgba(255,255,255,0.05);}
  .pp-sort-tick{display:none;width:14px;height:14px;color:var(--accent);}
  .pp-sort-item.active .pp-sort-tick{display:block;}

  /* Build Bundle button */
  .bb-build-btn{
    display:inline-flex;align-items:center;gap:6px;
    padding:7px 16px;border-radius: 12px;border:none;
    background:var(--accent);color:#fff;
    font-family:'Nunito',sans-serif;font-size:13px;font-weight:800;
    cursor:pointer;text-decoration:none;transition:opacity .15s;
  }
  .bb-build-btn:hover{opacity:.88;}

  /* Hide old in-page category switcher */
  .bb-type-switcher {
    display: none !important;
  }

  .product-toolbar-subtitle {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-soft);
    margin: 6px 0 0 0;
    font-family: 'Geist', 'DM Sans', sans-serif;
  }

  /* Subcategory pills wrapper */
  .bb-subcats-wrapper {
    position: relative;
    z-index: 10;
    display: flex;
    align-items: center;
    width: 100%;
    margin-bottom: 14px;
  }
  .bb-subcats {
    display: flex;
    flex-wrap: nowrap;
    gap: 7px;
    padding-top: 8px;
    padding-bottom: 8px;
    width: 100%;
    overflow: hidden;
  }
  
  /* Subcategory "More" dropdown styling */
  .subcat-more-wrap {
    position: relative;
    display: inline-block;
    z-index: 500;
  }
  .subcat-more-menu {
    display: none;
    position: fixed;
    z-index: 99999;
    background: #fff;
    border: 1.5px solid var(--border);
    border-radius: 14px;
    box-shadow: 0 18px 40px -16px rgba(20,20,30,0.28), 0 4px 10px rgba(20,20,30,0.06);
    padding: 6px;
    min-width: 190px;
    max-height: 300px;
    overflow-y: auto;
  }
  body.dark .subcat-more-menu {
    background: #141416;
    border-color: #26262B;
    box-shadow: 0 18px 40px -16px rgba(0,0,0,0.6);
  }
  .subcat-more-menu.open {
    display: block;
  }
  .subcat-more-menu::-webkit-scrollbar {
    width: 6px;
  }
  .subcat-more-menu::-webkit-scrollbar-track {
    background: transparent;
  }
  .subcat-more-menu::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.1);
    border-radius: 999px;
  }
  body.dark .subcat-more-menu::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.1);
  }
  .subcat-more-item {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 8px 12px;
    border-radius: 9px;
    border: none;
    background: none;
    font-family: 'Geist', 'DM Sans', sans-serif;
    font-size: 13px;
    font-weight: 600;
    color: #3D3D3D;
    cursor: pointer;
    text-align: left;
    white-space: nowrap;
    transition: all 0.15s ease;
  }
  .subcat-more-item:hover {
    background: rgba(0, 0, 0, 0.04);
    color: #1A1A1A;
  }
  .subcat-more-item.active {
    background: rgba(22,163,74,0.08);
    color: var(--accent);
  }
  body.dark .subcat-more-item {
    color: #B0B0B8;
  }
  body.dark .subcat-more-item:hover {
    background: rgba(255, 255, 255, 0.05);
    color: #F2F2F0;
  }
  body.dark .subcat-more-item.active {
    background: rgba(22,163,74,0.12);
    color: var(--accent);
  }
  
  .subcat-more-chevron {
    transition: transform 0.2s ease;
    margin-left: 2px;
    flex-shrink: 0;
  }
  .subcat-more-wrap:has(.subcat-more-menu.open) .subcat-more-chevron {
    transform: rotate(180deg);
  }
  .subcat-pill{
    display:inline-flex;align-items:center;gap:7px;height:34px;
    padding:0 13px;border-radius:999px;border:1.5px solid var(--border);
    background:var(--white);font-family:'Geist','DM Sans',sans-serif;
    font-size:13px;font-weight:600;color:#6B6B7B;cursor:pointer;
    transition:all .18s ease;white-space:nowrap;user-select:none;
  }
  .subcat-pill:hover{color:#1A1A1A;border-color:#AFAFAF;}
  .subcat-pill.active{background:#1A1A1A;color:#fff;border-color:#1A1A1A;}
  .subcat-pill .sp-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0;}
  .subcat-pill .sp-count{
    font-size:11px;font-weight:700;padding:1px 7px;border-radius:999px;
    background:rgba(26,26,26,0.07);color:#AFAFAF;
  }
  .subcat-pill.active .sp-count{background:rgba(255,255,255,0.22);color:#fff;}
  body.dark .subcat-pill{border-color:#2E2E34;background:#1d1c24;color:#888890;}
  body.dark .subcat-pill:hover{border-color:#888890;color:#F2F2F0;}
  body.dark .subcat-pill.active{background:#F2F2F0;color:#0E0E10;border-color:#F2F2F0;}
  body.dark .subcat-pill .sp-count{background:rgba(255,255,255,0.1);color:#666;}
  body.dark .subcat-pill.active .sp-count{background:rgba(0,0,0,0.18);color:#333;}

  @media (max-width: 900px) {
    .product-toolbar-top {
      flex-wrap: wrap;
    }
    .product-toolbar-right {
      order: 2;
    }
  }

  /* ── Product grid ── */
  .product-grid{
    display:grid;
    grid-template-columns:repeat(auto-fill,minmax(180px,1fr));
    gap:10px;
  }

  .product-card{
    background:#FFFFFF;border:1px solid #ECECEC;border-radius: 16px;
    overflow:visible;padding-top:8px;
    transition:box-shadow .25s ease,border-color .2s;
    cursor:pointer;position:relative;display:flex;flex-direction:column;
    /* Mobile browsers paint a blue tap/selection highlight over the whole
       card on a press-and-hold or drag — these cards aren't text, so kill
       both the highlight and the text-selection it rides on. */
    -webkit-tap-highlight-color:transparent;user-select:none;-webkit-user-select:none;
  }
  .product-card:hover{
    box-shadow:0 10px 28px rgba(0,0,0,.10),0 2px 8px rgba(0,0,0,.06);
    transform:translateY(-5px) scale(1.015);
    border-color:rgba(0,0,0,.16);
    transition:box-shadow .25s ease,transform .25s cubic-bezier(.34,1.56,.64,1),border-color .2s;
    z-index:2;
  }
  body.dark .product-card{background:#141416;border-color:#26262B;}
  body.dark .product-card:hover{
    box-shadow:0 10px 30px rgba(0,0,0,.45),0 2px 8px rgba(0,0,0,.3);
    border-color:rgba(255,255,255,.16);
  }
  .product-card.in-bundle{background:rgba(22,163,74,0.08) !important;border-color:#DCFCE7 !important;}
  body.dark .product-card.in-bundle{background:rgba(22,163,74,0.16) !important;border-color:#15803D !important;}

  /* Held down long enough to trigger the quantity modal instead of a plain add —
     a quick inward scale + accent border so the hold reads as "about to do
     something" before the modal actually appears. */
  .product-card.bb-longpress-active{
    transform:scale(.97);
    border-color:#6366F1;
    box-shadow:0 0 0 3px rgba(99,102,241,.18);
    transition:transform .35s cubic-bezier(.22,1,.36,1),border-color .15s,box-shadow .15s;
  }

  /* ── Admin "add item" card (opens the inline listing creator) ── */
  .bb-add-item-card{
    background:transparent;border:1.5px dashed var(--border);border-radius: 16px;
    display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:8px;min-height:180px;cursor:pointer;color:var(--text-muted);
    transition:all .2s;grid-column:1;
  }
  .bb-add-item-card:hover{border-color:#16A34A;color:#16A34A;background:rgba(22,163,74,.05);transform:translateY(-2px);}
  .bb-add-item-card svg{width:30px;height:30px;}
  .bb-add-item-card span{font-size:13px;font-weight:700;}

  /* ── Per-card edit/delete overlay (shown while in Edit mode) ── */
  .bb-card-edit-controls{position:absolute;top:8px;right:8px;z-index:10;display:flex;gap:4px;}
  .bb-card-edit-btn{
    width:24px;height:24px;border-radius: 12px;border:1px solid rgba(255,255,255,.15);
    background:rgba(0,0,0,.65);backdrop-filter:blur(4px);color:#fff;
    cursor:pointer;display:flex;align-items:center;justify-content:center;
    transition:background .1s,transform .1s;outline:none;
  }
  .bb-card-edit-btn:hover{background:rgba(0,0,0,.8);}
  .bb-card-edit-btn:active{transform:scale(.9);}
  .bb-card-delete-btn{
    width:24px;height:24px;border-radius: 12px;border:1px solid rgba(255,255,255,.15);
    background:rgba(0,0,0,.65);backdrop-filter:blur(4px);color:#fff;
    cursor:pointer;display:flex;align-items:center;justify-content:center;
    transition:background .1s,transform .1s;outline:none;
  }
  .bb-card-delete-btn:hover{background:#EF4444;}
  .bb-card-delete-btn:active{transform:scale(.9);}
  .bb-card-edit-btn.bb-card-unpublished{background:rgba(245,158,11,.85);border-color:rgba(245,158,11,.9);}
  .bb-card-edit-btn.bb-card-unpublished:hover{background:#F59E0B;}
  .product-card:has(.bb-card-unpublished) .product-card-img{opacity:.5;}

  /* ── Inline listing creator (replaces the grid when open) ── */
  /* Inline item editor — full page width, styled like pack.html's product page
     (image left, plain borderless-feeling fields right) instead of a boxed popup. */
  .bb-item-creator{width:85%;max-width:1400px;margin:0 auto;padding:24px 0 60px;}
  .bb-ic-topbar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:22px;}
  .bb-ic-back{
    background:none;border:none;padding:0;cursor:pointer;
    display:flex;align-items:center;gap:5px;font-family:'Geist','DM Sans',sans-serif;
    font-size:13px;font-weight:700;color:var(--text-muted);transition:color .15s;
  }
  .bb-ic-back:hover{color:var(--text);}
  .bb-ic-publish-btn{
    background:rgba(22,163,74,.1);color:#16A34A;border:1px solid rgba(22,163,74,.3);
    border-radius: 12px;padding:6px 14px;font-size:12px;font-weight:800;
    font-family:'Nunito',sans-serif;cursor:pointer;transition:background .15s;
    display:flex;align-items:center;gap:6px;
  }
  .bb-ic-publish-btn:hover{background:rgba(22,163,74,.2);}
  .bb-ic-delete-btn{
    background:rgba(239,68,68,.1);color:#EF4444;border:1px solid rgba(239,68,68,.3);
    border-radius: 12px;padding:6px 14px;font-size:12px;font-weight:800;
    font-family:'Nunito',sans-serif;cursor:pointer;transition:background .15s;
    display:flex;align-items:center;gap:6px;
  }
  .bb-ic-delete-btn:hover{background:rgba(239,68,68,.2);}
  .bb-ic-publish-btn.bb-ic-unpublish{background:rgba(0,0,0,.05);color:var(--text-muted);border-color:var(--border);}
  body.dark .bb-ic-publish-btn.bb-ic-unpublish{background:rgba(255,255,255,.06);}
  .bb-ic-publish-btn.bb-ic-unpublish:hover{border-color:var(--text-muted);color:var(--text);}
  .bb-ic-top{display:grid;grid-template-columns:200px 1fr;gap:32px;align-items:start;}
  @media(max-width:640px){ .bb-ic-top{grid-template-columns:1fr;gap:20px;} .bb-ic-hero{width:200px;} }
  .bb-ic-hero{
    position:relative;overflow:hidden;border-radius:18px;aspect-ratio:1/1;width:100%;
    border:1.5px solid var(--border);background:#f4f3f1;
    display:flex;align-items:center;justify-content:center;
  }
  body.dark .bb-ic-hero{background:#1a1a1c;border-color:#26262B;}
  .bb-ic-hero-img{width:100%;height:100%;object-fit:cover;display:block;}
  .bb-ic-hero-placeholder{
    display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:8px;color:var(--text-muted);opacity:.5;pointer-events:none;
  }
  .bb-ic-hero-placeholder svg{width:48px;height:48px;opacity:.5;}
  .bb-ic-hero-placeholder span{font-size:12px;font-weight:600;}
  .bb-ic-hero-upload-btn{
    position:absolute;bottom:14px;right:14px;
    background:rgba(0,0,0,.55);color:#fff;border:none;border-radius: 12px;
    padding:6px 12px;font-size:11px;font-weight:800;cursor:pointer;
    display:flex;align-items:center;gap:5px;transition:background .15s;
    font-family:'Nunito',sans-serif;
  }
  .bb-ic-hero-upload-btn:hover{background:rgba(0,0,0,.75);}
  .bb-ic-info{display:flex;flex-direction:column;}
  .bb-ic-cat-note{font-size:12px;color:var(--text-muted);font-weight:700;text-transform:uppercase;letter-spacing:.04em;margin-bottom:8px;}
  .bb-ic-cat-note--display-only{color:#7C3AED;}
  .bb-ic-title-input{
    font-family:'DM Sans',sans-serif;font-size:22px;font-weight:900;
    color:var(--text);line-height:1.25;width:100%;
    padding:8px 12px;border-radius:8px;border:1.5px solid var(--border);
    background:var(--bg);outline:none;box-sizing:border-box;
    transition:border-color .15s;margin-bottom:12px;
  }
  .bb-ic-title-input:focus{border-color:#7C3AED;}
  body.dark .bb-ic-title-input{background:#1a1a1c;border-color:#333;}
  .bb-ic-desc-textarea{
    width:100%;padding:8px 12px;border-radius:10px;border:1.5px solid var(--border);
    background:var(--bg);color:var(--text);font-family:'Nunito',sans-serif;
    font-size:13px;font-weight:600;outline:none;resize:vertical;box-sizing:border-box;
    height:70px;transition:border-color .15s;margin-bottom:18px;
  }
  .bb-ic-desc-textarea:focus{border-color:#7C3AED;}
  body.dark .bb-ic-desc-textarea{background:#1a1a1c;border-color:#333;}
  .bb-ic-row{display:flex;gap:12px;margin-bottom:18px;}
  .bb-ic-field{flex:1;min-width:0;}
  .bb-ic-field-label{display:block;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);margin-bottom:6px;}
  .bb-ic-plain-input{
    width:100%;padding:8px 12px;border-radius:8px;border:1.5px solid var(--border);
    background:var(--bg);color:var(--text);font-family:'Nunito',sans-serif;
    font-size:13px;font-weight:700;outline:none;box-sizing:border-box;transition:border-color .15s;
  }
  .bb-ic-plain-input:focus{border-color:#7C3AED;}
  body.dark .bb-ic-plain-input{background-color:#1a1a1c;border-color:#333;}
  .bb-ic-field-hint{font-weight:500;text-transform:none;letter-spacing:0;opacity:.75;}
  .bb-ic-inline-switches{display:flex;gap:22px;margin-bottom:16px;flex-wrap:wrap;}
  .bb-ic-inline-switch{
    display:flex;align-items:center;gap:9px;cursor:pointer;
    font-family:'Geist','DM Sans',sans-serif;font-size:12.5px;font-weight:700;color:var(--text);
  }
  .bb-ic-rows-list{display:flex;flex-direction:column;gap:6px;margin-bottom:8px;}
  .bb-ic-row-item{display:flex;gap:8px;align-items:center;width:100%;}
  .bb-ic-row-item .bb-ic-plain-input{flex:2;min-width:0;}
  .bb-ic-row-item .bb-ic-plain-input.bb-ic-qty-input{flex:0 0 70px;}
  @media(max-width:640px){
    .bb-ic-row-item{flex-wrap:wrap;}
    /* 100px price + 8px gap, plus the 22px drag handle and its own 8px gap. */
    .bb-ic-row-item .bb-ic-amount-val{flex:1 1 calc(100% - 138px) !important;min-width:0;}
    .bb-ic-row-item .bb-ic-amount-price{flex:0 0 100px !important;}
    .bb-ic-row-remove-btn{order:3;}
    #bbicAmountsBlock .bb-ic-field-hint{display:block;margin-top:3px;line-height:1.35;}
  }

  /* Price Table modal — category-wide price/discount/override grid.
     Runs fullscreen: with 10 columns and an inline tier editor per row there's
     no width to spare, and the table itself (not the card) has to be the
     scroll container so the sticky <th> row has something to stick to. */
  #bbPriceTableModal{padding:0;overflow:hidden;align-items:stretch;justify-content:stretch;}
  /* Id-scoped so it outranks the generic .bb-modal-card block further down the
     file (same specificity, later source order = base card wins otherwise). */
  #bbPriceTableModal .bb-pt-modal-card{
    text-align:left;width:100%;max-width:none;border-radius:0;border-width:0;
    height:100vh;height:100dvh;max-height:100vh;max-height:100dvh;
    padding:20px 22px 0;display:flex;flex-direction:column;overflow:hidden;
    box-shadow:none;
  }
  .bb-pt-head{margin-bottom:12px;padding-right:36px;flex:0 0 auto;}
  .bb-pt-filters{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-bottom:10px;flex:0 0 auto;}
  .bb-pt-foot{flex:0 0 auto;padding:12px 0 16px;}

  .bb-pt-bulk-bar{
    display:none;flex-direction:column;gap:10px;margin-bottom:10px;padding:10px 12px;flex:0 0 auto;
    background:rgba(59,130,246,.08);border:1.5px solid rgba(59,130,246,.28);border-radius:10px;
    max-height:38vh;overflow-y:auto;
  }
  .bb-pt-bulk-bar.show{display:flex;}
  .bb-pt-bulk-head{display:flex;align-items:center;flex-wrap:wrap;gap:10px;}
  .bb-pt-bulk-bar-label{font-size:12px;font-weight:800;color:var(--text);white-space:nowrap;}
  .bb-pt-bulk-bar-hint{font-size:11.5px;font-weight:600;color:var(--text-muted);flex:1 1 200px;min-width:160px;}
  .bb-pt-bulk-save-btn{margin-left:auto;background:#16A34A;border-color:#16A34A;color:#fff;}
  .bb-pt-bulk-save-btn:disabled{opacity:.5;cursor:not-allowed;}
  /* Pulses only while rows are actually waiting to be written. */
  .bb-pt-bulk-save-pending{box-shadow:0 0 0 3px rgba(22,163,74,.28);}
  body.dark .bb-pt-bulk-bar{background:rgba(59,130,246,.12);border-color:rgba(96,165,250,.32);}
  /* auto-fill (not auto-fit) so six short control groups stay six columns on a
     wide screen instead of stretching into six very wide ones. */
  .bb-pt-bulk-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(186px,1fr));gap:8px 12px;}
  .bb-pt-bulk-group{min-width:0;}
  /* The tier group carries three controls instead of two, so it gets a double
     slot rather than wrapping its last button onto a line of its own. */
  .bb-pt-bulk-group-wide{grid-column:span 2;}
  .bb-pt-bulk-group-label{
    display:block;margin-bottom:4px;font-size:10px;font-weight:800;text-transform:uppercase;
    letter-spacing:.05em;color:var(--text-muted);white-space:nowrap;
  }
  .bb-pt-bulk-group-row{display:flex;align-items:center;gap:5px;flex-wrap:wrap;}
  .bb-pt-bulk-group-row .bb-pt-input{width:64px;flex:0 0 auto;}
  /* Beats the width:64px above on specificity — selects need to fit their
     longest option ("Replace with"), number inputs don't. */
  .bb-pt-bulk-group-row .bb-pt-bulk-select{width:auto;min-width:76px;cursor:pointer;}
  .bb-pt-bulk-apply{
    padding:6px 10px;border-radius:7px;border:none;background:#3B82F6;color:#fff;
    font-family:'Nunito',sans-serif;font-size:11.5px;font-weight:800;cursor:pointer;white-space:nowrap;
  }
  .bb-pt-bulk-apply:hover{background:#2563EB;}
  .bb-pt-bulk-apply-ghost{background:transparent;color:var(--text-muted);border:1.5px solid var(--border);}
  .bb-pt-bulk-apply-ghost:hover{background:transparent;border-color:#3B82F6;color:#3B82F6;}
  .bb-pt-bulk-subcat{border-top:1.5px solid rgba(59,130,246,.22);padding-top:9px;}
  .bb-pt-bulk-subcat .bb-fp-pill{height:26px;padding:0 10px;font-size:11px;}
  .bb-pt-bulk-subcat-hint{font-size:11.5px;font-weight:600;color:var(--text-muted);}
  .bb-pt-table-wrap{
    width:100%;overflow:auto;border:1.5px solid var(--border);border-radius:10px;
    flex:1 1 auto;min-height:0;
  }
  /* Phone: the fullscreen shell still applies, but the header/filters/bulk
     panel would otherwise eat the whole screen and leave the table a sliver. */
  @media(max-width:640px){
    #bbPriceTableModal .bb-pt-modal-card{padding:14px 12px 0;}
    .bb-pt-head{margin-bottom:8px;}
    .bb-pt-head > div:last-child{display:none;}
    .bb-pt-filters{gap:8px;margin-bottom:8px;}
    .bb-pt-bulk-bar{max-height:30vh;}
    .bb-pt-bulk-grid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));}
    .bb-pt-bulk-group-wide{grid-column:span 1;}
    .bb-pt-foot{padding:10px 0 12px;}
  }
  .bb-pt-table{width:100%;border-collapse:collapse;font-family:'Nunito',sans-serif;font-size:12.5px;}
  .bb-pt-table th{
    text-align:left;padding:9px 10px;font-size:10.5px;font-weight:800;text-transform:uppercase;
    letter-spacing:.04em;color:var(--text-muted);background:var(--bg);border-bottom:1.5px solid var(--border);
    white-space:nowrap;position:sticky;top:0;z-index:2;
  }
  .bb-pt-table td{padding:8px 10px;border-bottom:1px solid var(--border);vertical-align:middle;color:var(--text);}
  .bb-pt-table tbody tr:last-child td{border-bottom:none;}
  .bb-pt-table tbody tr.bb-pt-dirty{background:rgba(124,58,237,.06);}
  .bb-pt-name{font-weight:800;min-width:200px;max-width:270px;}
  /* The thumbnail sits beside the name, so the text half needs min-width:0 to
     stay ellipsable — a flex item defaults to min-width:auto and would push
     the cell wide instead of truncating. */
  .bb-pt-name-inner{display:flex;align-items:center;gap:9px;min-width:0;}
  .bb-pt-name-main{flex:1;min-width:0;}
  .bb-pt-thumb{
    width:38px;height:38px;flex-shrink:0;border-radius:8px;overflow:hidden;
    border:1px solid var(--border);background:rgba(0,0,0,.03);
    display:flex;align-items:center;justify-content:center;color:var(--text-muted);
  }
  body.dark .bb-pt-thumb{background:rgba(255,255,255,.05);}
  .bb-pt-thumb img{width:100%;height:100%;object-fit:contain;padding:3px;}
  .bb-pt-thumb svg{opacity:.35;}
  .bb-pt-name-text{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .bb-pt-subcats{display:flex;flex-wrap:wrap;gap:4px;margin-top:5px;}
  .bb-pt-subcat-tag{
    display:inline-flex;max-width:100%;padding:2px 6px;border-radius:999px;
    background:rgba(124,58,237,.1);color:#7C3AED;font-size:9.5px;font-weight:800;
    line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }
  .bb-pt-subcat-empty{font-size:10px;font-weight:600;color:var(--text-muted);}
  body.dark .bb-pt-subcat-tag{background:rgba(167,139,250,.14);color:#C4B5FD;}
  .bb-pt-filter-disabled{opacity:.55;}
  /* Tiers used to be a static truncated label; now each row carries its own
     editable amount/price list, so the cell needs real width and its own
     internal scroll once an item has more than a handful of tiers. */
  .bb-pt-tiers-cell{min-width:230px;max-width:280px;}
  .bb-pt-tiers-list{max-height:110px;overflow-y:auto;margin-bottom:6px;}
  .bb-pt-tier-row .bb-ic-plain-input{padding:5px 7px;font-size:12px;}
  /* The price table packs its tiers into a table cell, so the shared handle
     is narrowed here rather than stealing width from the amount box. */
  .bb-pt-tier-row .bb-ic-row-drag-handle{flex:0 0 14px;width:14px;height:24px;border-radius:5px;}
  .bb-pt-tier-row .bb-ic-row-drag-handle svg{width:10px;height:10px;}
  .bb-pt-tier-add{
    border:1.5px dashed var(--border);background:transparent;color:var(--text-muted);
    font-size:11px;font-weight:800;border-radius:7px;padding:4px 8px;cursor:pointer;white-space:nowrap;
  }
  .bb-pt-tier-add:hover{border-color:#7C3AED;color:#7C3AED;}
  .bb-pt-check-cell{text-align:center;}
  .bb-pt-row-check,.bb-pt-check-cell input[type="checkbox"]{width:16px;height:16px;cursor:pointer;}
  .bb-pt-select{width:88px;cursor:pointer;}
  .bb-pt-input{
    width:72px;padding:6px 8px;border-radius:7px;border:1.5px solid var(--border);
    background:var(--bg);color:var(--text);font-family:'Nunito',sans-serif;
    font-size:12.5px;font-weight:700;outline:none;box-sizing:border-box;transition:border-color .15s;
  }
  .bb-pt-input:focus{border-color:#7C3AED;}
  body.dark .bb-pt-input{background-color:#1a1a1c;border-color:#333;}
  /* Four booleans in one cell instead of four columns - the table is already
     wide, and these are read far less often than they're set in bulk. */
  .bb-pt-flags-cell{min-width:142px;}
  .bb-pt-flags{display:grid;grid-template-columns:1fr 1fr;gap:2px 8px;}
  .bb-pt-flag{
    display:flex;align-items:center;gap:4px;min-width:0;
    font-size:10px;font-weight:800;color:var(--text-muted);cursor:pointer;
  }
  .bb-pt-flag input[type="checkbox"]{width:13px;height:13px;flex-shrink:0;cursor:pointer;margin:0;}
  .bb-pt-flag span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .bb-pt-type-select{width:104px;}
  .bb-pt-step-input{width:56px;}
  .bb-pt-featured{font-weight:800;white-space:nowrap;font-variant-numeric:tabular-nums;}
  .bb-pt-featured-was{color:var(--text-muted);text-decoration:line-through;}
  .bb-pt-featured-new{color:#3B82F6;margin-left:5px;}
  .bb-pt-effective{font-weight:800;white-space:nowrap;}
  .bb-pt-effective.bb-pt-has-discount{color:#16a34a;}
  .bb-pt-row-save{
    padding:5px 10px;border-radius:7px;border:none;background:#7C3AED;color:#fff;
    font-size:11.5px;font-weight:800;cursor:pointer;white-space:nowrap;
  }
  .bb-pt-row-save:disabled{background:var(--border);color:var(--text-muted);cursor:default;}

  .bb-ic-row-remove-btn{
    flex-shrink:0;width:28px;height:28px;border-radius: 12px;border:1.5px solid var(--border);
    background:none;color:var(--text-muted);cursor:pointer;display:flex;align-items:center;justify-content:center;
    font-size:14px;transition:all .15s;
  }
  .bb-ic-row-remove-btn:hover{border-color:#EF4444;color:#EF4444;}
  .bb-ic-row-drag-handle{
    flex:0 0 22px;width:22px;height:28px;padding:0;border:0;border-radius:7px;
    display:flex;align-items:center;justify-content:center;background:transparent;
    color:var(--text-muted);cursor:grab;touch-action:none;transition:color .15s,background .15s;
  }
  .bb-ic-row-drag-handle:hover{color:#7C3AED;background:rgba(124,58,237,.08);}
  .bb-ic-row-drag-handle:active{cursor:grabbing;}
  .bb-ic-row-drag-handle:focus-visible{outline:2px solid #7C3AED;outline-offset:1px;}
  .bb-ic-row-item.is-amount-dragging{opacity:.42;}
  .bb-ic-add-row-btn{
    background:none;border:1.5px dashed var(--border);color:var(--text-muted);
    border-radius: 12px;padding:7px 14px;font-size:12px;font-weight:800;
    font-family:'Nunito',sans-serif;cursor:pointer;transition:all .15s;
  }
  .bb-ic-add-row-btn:hover{border-color:#7C3AED;color:#7C3AED;}
  /* "Calculate" reads as a recalculation, not another way to add a row, so it
     borrows the green the wheelspin editor's Normalize button uses rather than
     the dashed add-row outline sitting next to it. */
  .bb-ic-calc-btn{
    display:inline-flex;align-items:center;gap:5px;
    background:rgba(22,163,74,.08);border:1.5px solid rgba(22,163,74,.24);
    color:#16a34a;border-radius:12px;padding:7px 12px;font-size:12px;font-weight:800;
    font-family:'Nunito',sans-serif;cursor:pointer;white-space:nowrap;transition:all .15s;
  }
  .bb-ic-calc-btn:hover{background:rgba(22,163,74,.16);border-color:#16a34a;}
  /* Brief green wash on the boxes that were just filled, so it is obvious which
     ones changed when several fill at once. */
  .bb-ic-row-item.bb-ic-row-just-filled .bb-ic-amount-price{
    border-color:#16a34a;
    background:rgba(22,163,74,.10);
    transition:border-color .4s ease,background .4s ease;
  }
  .bb-ic-subcat-pills{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:10px;}
  .bb-ic-subcat-pills:empty{margin-bottom:0;}
  .bb-ic-subcat-add-row{display:flex;gap:8px;align-items:center;}
  .bb-ic-subcat-add-row .bb-ic-plain-input{flex:1;min-width:0;}
  .bb-ic-subcat-add-row .bb-ic-add-row-btn{flex-shrink:0;white-space:nowrap;}
  .bb-ic-req-toggle-btn{
    flex-shrink:0;background:none;border:1.5px solid var(--border);color:var(--text-muted);
    border-radius:8px;padding:0 10px;height:28px;font-size:11px;font-weight:800;
    font-family:'Nunito',sans-serif;cursor:pointer;white-space:nowrap;transition:all .15s;
  }
  .bb-ic-req-toggle-btn:hover{border-color:#7C3AED;color:#7C3AED;}
  .bb-ic-req-picker{position:relative;flex:2;min-width:0;}
  .bb-ic-req-picker-btn{
    width:100%;display:flex;align-items:center;gap:8px;box-sizing:border-box;
    padding:6px 10px;border-radius: 12px;border:1.5px solid var(--border);
    background:var(--bg);color:var(--text);font-family:'Nunito',sans-serif;
    font-size:13px;font-weight:700;cursor:pointer;transition:border-color .15s;
  }
  .bb-ic-req-picker-btn:hover,.bb-ic-req-picker-btn:focus{border-color:#7C3AED;outline:none;}
  body.dark .bb-ic-req-picker-btn{background:#1a1a1c;border-color:#333;}
  .bb-ic-req-picker-icon{width:18px;height:18px;flex-shrink:0;border-radius:5px;overflow:hidden;background:var(--cream);display:flex;}
  body.dark .bb-ic-req-picker-icon{background:#26262B;}
  .bb-ic-req-picker-icon img{width:100%;height:100%;object-fit:contain;}
  .bb-ic-req-picker-label{flex:1;min-width:0;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .bb-ic-req-picker-btn svg{flex-shrink:0;opacity:.6;}
  .bb-ic-req-picker-panel{
    display:none;position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:20;
    background:var(--white);border:1.5px solid var(--border);border-radius: 16px;
    box-shadow:0 8px 24px rgba(0,0,0,.15);overflow:hidden;
  }
  body.dark .bb-ic-req-picker-panel{background:#1e1e22;box-shadow:0 8px 24px rgba(0,0,0,.4);}
  .bb-ic-req-picker-panel.open{display:block;}
  .bb-ic-req-picker-search{
    width:100%;box-sizing:border-box;padding:8px 10px;border:none;border-bottom:1.5px solid var(--border);
    background:none;color:var(--text);font-family:'Nunito',sans-serif;font-size:12.5px;font-weight:600;outline:none;
  }
  .bb-ic-req-picker-list{max-height:220px;overflow-y:auto;padding:4px;}
  .bb-ic-req-picker-opt{
    display:flex;align-items:center;gap:8px;padding:7px 8px;border-radius:7px;cursor:pointer;
    font-size:12.5px;font-weight:600;color:var(--text);
  }
  .bb-ic-req-picker-opt:hover{background:rgba(124,58,237,.1);color:#7C3AED;}
  .bb-ic-req-picker-opt img,.bb-ic-req-picker-opt-noicon{width:18px;height:18px;flex-shrink:0;border-radius:5px;object-fit:contain;background:var(--cream);}
  body.dark .bb-ic-req-picker-opt img,body.dark .bb-ic-req-picker-opt-noicon{background:#26262B;}
  .bb-ic-switches{
    display:flex;flex-direction:column;margin-bottom:22px;
    border-top:1.5px solid var(--border);
  }
  .bb-ic-switch-row{
    display:flex;align-items:center;justify-content:space-between;gap:16px;
    padding:12px 0;border-bottom:1px solid var(--border);
  }
  .bb-ic-switch-row:last-child{border-bottom:none;}
  .bb-ic-switch-text{display:flex;flex-direction:column;gap:1px;}
  .bb-ic-switch-text strong{font-family:'Geist','DM Sans',sans-serif;font-size:13px;font-weight:700;color:var(--text);}
  .bb-ic-switch-text span{font-size:11.5px;font-weight:500;color:var(--text-muted);}
  .bb-ic-switch{position:relative;display:inline-block;width:36px;height:20px;flex-shrink:0;}
  .bb-ic-switch input{opacity:0;width:0;height:0;position:absolute;}
  .bb-ic-switch-slider{
    position:absolute;inset:0;cursor:pointer;border-radius:34px;transition:.2s;
    background:rgba(0,0,0,0.14);border:1px solid rgba(0,0,0,0.1);
  }
  .bb-ic-switch-slider:before{
    position:absolute;content:"";height:14px;width:14px;left:2px;top:2px;
    background:#fff;border-radius:50%;transition:.2s;box-shadow:0 1px 3px rgba(0,0,0,0.15);
  }
  .bb-ic-switch input:checked + .bb-ic-switch-slider{background:#7C3AED;border-color:#7C3AED;}
  .bb-ic-switch input:checked + .bb-ic-switch-slider:before{transform:translateX(16px);}
  body.dark .bb-ic-switch-slider{background:rgba(255,255,255,0.15);border-color:rgba(255,255,255,0.12);}
  .bb-ic-actions{display:flex;gap:8px;}
  .bb-ic-save{
    background:rgba(124,58,237,.1);color:#7C3AED;border:1px solid rgba(124,58,237,.3);
    border-radius:8px;padding:9px 20px;font-size:12px;font-weight:800;
    font-family:'Nunito',sans-serif;cursor:pointer;transition:background .15s;
  }
  .bb-ic-save:hover{background:rgba(124,58,237,.2);}
  .bb-ic-save:disabled{opacity:.6;cursor:default;}
  .bb-ic-cancel{
    background:transparent;color:var(--text-muted);border:1px solid var(--border);
    border-radius:8px;padding:9px 20px;font-size:12px;font-weight:800;
    font-family:'Nunito',sans-serif;cursor:pointer;transition:all .15s;
  }
  .bb-ic-cancel:hover{border-color:var(--text-muted);color:var(--text);}

  /* ── Card entrance animation ── */
  @keyframes ppCardIn {
    from { opacity:0; transform:translateY(14px) scale(.97); }
    to   { opacity:1; transform:translateY(0)    scale(1);   }
  }
  .product-card.card-entering {
    animation: ppCardIn .28s cubic-bezier(.25,.46,.45,.94) both;
  }

  /* ── Card reveal system (staggered wave, scroll-driven) ──
     .pp-reveal-pre hides a freshly-inserted card until the IntersectionObserver
     hands it a slot in the wave; .pp-reveal-in plays the entrance. The `both`
     fill keeps a delayed card at the from-frame until its turn. */
  @keyframes ppCardReveal {
    from { opacity:0; transform:translateY(18px) scale(.96); }
    to   { opacity:1; transform:translateY(0)    scale(1);   }
  }
  .pp-reveal-pre{opacity:0;}
  .pp-reveal-in{animation:ppCardReveal .5s cubic-bezier(.25,.46,.45,.94) both;}
  @media (prefers-reduced-motion: reduce){
    .pp-reveal-pre{opacity:1;}
    .pp-reveal-in{animation:none;}
  }
  /* Old grid fades down-and-out for a beat while a new category renders */
  #bbGrid{transition:opacity .16s ease,transform .16s ease;}
  #bbGrid.pp-grid-leaving{opacity:0;transform:translateY(8px);transition:opacity .12s ease,transform .12s ease;}

  /* Infinite-scroll sentinel + spinner */
  .bb-grid-sentinel{grid-column:1/-1;display:flex;justify-content:center;padding:20px 0;}
  @keyframes bbSpin{to{transform:rotate(360deg)}}
  .bb-load-spinner{
    width:22px;height:22px;border-radius:50%;
    border:2.5px solid rgba(22,163,74,.2);
    border-top-color:#16A34A;
    animation:bbSpin .7s linear infinite;
  }

  .product-card-img{width:100%;aspect-ratio:4/3;flex-shrink:0;position:relative;overflow:hidden;background:transparent;border-radius: 16px;}
  .product-card-img img{
    width:100%;height:100%;object-fit:contain;display:block;position:relative;z-index:2;
    padding:10px;transition:transform .45s cubic-bezier(.2,.7,.3,1);
  }
  .product-card:hover .product-card-img img{transform:scale(1.06);}

  .mcard-name-row {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
  }
  .mcard-name-stack {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1;
  }
  .product-card .pp-starred-pill {
    position: relative !important;
    top: auto !important;
    left: auto !important;
    right: auto !important;
    z-index: 1 !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    height: 40px !important;
    width: 44px !important;
    min-width: 44px !important;
    padding: 0 !important;
    border-radius: 8px !important;
    box-sizing: border-box !important;
    border: 1.5px solid transparent !important;
    cursor: pointer !important;
    pointer-events: auto !important;
    transition: all 0.15s ease !important;
    flex-shrink: 0 !important;
  }
  .product-card .pp-starred-pill svg,
  .product-card .pp-starred-pill .pp-star-ico {
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    width: 22px !important;
    height: 22px !important;
    margin: 0 !important;
  }
  .product-card .pp-starred-pill.is-off {
    background: var(--pp-off-bg) !important;
    color: var(--pp-off-icon) !important;
    border-color: var(--pp-off-border) !important;
  }
  /* An off pill stays grey under the pointer — see button.pp-starred-pill
     in styles.css for why none of these toggles colour on hover. */
  .product-card .pp-starred-pill:not(.is-off) {
    background: var(--pp-star-bg) !important;
    color: var(--pp-star-icon) !important;
    border-color: var(--pp-star-border) !important;
  }

  /* Bottom bar — no filled background, just a reserved-height row (bleeds
     edge-to-edge via negative margins) so every card's footer takes up the
     same space whether or not it has chips in it. Star toggle + synced
     count cluster on the left, in-pack count pinned to the right. */
  .mcard-foot-bar{
    display:flex;align-items:center;gap:8px;min-height:46px;
    margin:auto -11px -11px;padding:8px 11px;
  }
  /* Synced/owned count — same pill style and size as the in-pack chip, just
     coloured blue and pinned to the opposite (left) side of the bar. */
  .mcard-sync-chip{
    display:inline-flex;align-items:center;gap:5px;flex-shrink:0;
    height:29px;box-sizing:border-box;
    background:#DCEAFE;color:#3B82F6;font-family:'DM Sans',sans-serif;font-size:15px;font-weight:900;
    border-radius:20px;padding:0 13px;line-height:26px;
  }
  body.dark .mcard-sync-chip{background:rgba(59,130,246,.2);color:#60A5FA;}
  .mcard-sync-chip svg{flex-shrink:0;width:13px;height:13px;}
  .mcard-qty-chip{
    margin-left:auto;flex-shrink:0;
    height:29px;min-width:29px;box-sizing:border-box;white-space:nowrap;
    background:rgba(22,163,74,.10);color:var(--accent-deep,#15803D);border:1.5px solid rgba(22,163,74,.22);
    font-family:'Inter','Geist','DM Sans',sans-serif;font-size:14px;font-weight:800;
    border-radius:20px;padding:0 10px;line-height:26px;
    display:inline-flex;align-items:center;justify-content:center;
  }
  body.dark .mcard-qty-chip{
    background:rgba(34,197,94,.16);color:#4ADE80;
    border:1.5px solid rgba(74,222,128,.28);
  }
  /* Always shown (even at 0) so the in-pack slot never shifts the star/sync
     chips around — just greyed out when nothing's actually in the pack. */
  .mcard-qty-chip.muted{background:#EFEFEC;color:#ABABA5;border-color:transparent;}
  body.dark .mcard-qty-chip.muted{background:#2A2A2F;color:#5A5A62;border-color:transparent;}

  /* Badge pill (NEW, SALE etc) */
  .mcard-badge{
    position:absolute;top:10px;left:10px;z-index:2;
    background:#DCFCE7;border-radius:50px;
    padding:3px 9px;font-size:10px;font-weight:700;
    letter-spacing:.05em;text-transform:uppercase;color:#166534;
    font-family:'DM Sans',sans-serif;
  }
  body.dark .mcard-badge{background:rgba(16,185,129,.18);color:#86EFAC;}

  /* Discount pill — same slot as .mcard-badge but right-aligned so the two
     can coexist without overlapping. */
  .mcard-discount-badge{
    position:absolute;top:10px;right:10px;z-index:2;
    background:rgba(59,130,246,.14);border-radius:50px;
    padding:3px 9px;font-size:10px;font-weight:800;
    letter-spacing:.05em;color:#3b82f6;
    font-family:'DM Sans',sans-serif;
  }
  body.dark .mcard-discount-badge{background:rgba(59,130,246,.22);color:#60A5FA;}

  /* Hover add-to-bundle overlay */
  .mcard-media-action{
    position:absolute;left:0;right:0;top:0;bottom:0;z-index:5;
    opacity:0;
    /* Bottom-anchored scrim rather than a flat full-tile wash: the button
       sits at the bottom and needs the contrast there, while the item art
       above stays visible — it's what the user is actually choosing. */
    background:linear-gradient(to bottom,
      rgba(255,255,255,0) 30%,
      rgba(255,255,255,.35) 62%,
      rgba(255,255,255,.6) 100%);
    display:flex;align-items:flex-end;justify-content:center;
    padding-bottom:10px;
    transition:opacity .2s ease;pointer-events:none;
  }
  body.dark .mcard-media-action{
    background:linear-gradient(to bottom,
      rgba(20,20,22,0) 30%,
      rgba(20,20,22,.4) 62%,
      rgba(20,20,22,.68) 100%);
  }
  .product-card:hover .mcard-media-action{opacity:1;pointer-events:auto;}
  .mcard-buy-btn{
    width:calc(100% - 20px);height:38px;border:0;border-radius: 12px;cursor:pointer;
    background:#1A1A1A;color:#fff;font-family:'DM Sans',sans-serif;
    font-size:13px;font-weight:700;
    display:inline-flex;align-items:center;justify-content:center;gap:6px;
    box-shadow:0 4px 12px -4px rgba(0,0,0,.35);transition:transform .12s;
  }
  .mcard-buy-btn:hover{background:#1A1A1A;}
  body.dark .mcard-buy-btn{background:#fff;color:#1A1A1A;}

  /* Card body — flex column so the badge row can be pinned to the card's
     bottom edge via margin-top:auto, regardless of how much space the
     name/category text above it takes up. */
  /* min-height (not on .mcard-name) reserves room for a 2-line title without
     depending on grid row-stretch — the footer bar (margin-top:auto) always
     sits the same fixed distance from the card top, so numbers line up
     across every card regardless of how many lines the name wraps to. The
     slack lands as breathing room above the footer, not as a gap directly
     under a short single-line title. */
  /* Fixed height (not min-height, no flex:1) — the card's total height is
     then always image-height + 114px, period, regardless of whether the
     grid/flex context around it happens to stretch rows. That's what
     guarantees the footer chips land at the exact same Y on every card. */
  /* Fixed height — always image-height + 98px, regardless of surrounding
     layout. Name is single-line (truncated, not 2-line clamp) specifically
     so this fixed height never has to over-provision room for a second
     line that usually isn't there — that slack was the "massive gap"
     above the footer chips. */
  /* min-height, not height: the Starred pill adds a row on starred cards, and a
     hard height clipped the foot-bar chips straight off the bottom (the bar is
     pinned with margin-top:auto). Unstarred cards still settle at exactly 106px,
     so nothing shifts for them. */
  .mcard-body{padding:13px 11px 11px;position:relative;display:flex;flex-direction:column;box-sizing:border-box;min-height:106px;}
  /* The row — not the name — reserves the full 2-line height (2 x 1.3 x 16px),
     so the block below it starts at the same Y on every card whether the name
     runs to one line or two. Reserving it on .mcard-name instead would break
     the star: the pill is 40px tall and centers on the name box, so a 1-line
     name inside a fixed 2-line box would leave the star sitting ~10px low.
     Centering both inside a fixed-height row keeps them on the same axis and
     also absorbs the pill's own height, which used to make starred cards
     taller than unstarred ones. */
  .mcard-name-row{display:flex;flex-direction:row;align-items:center;gap:8px;min-height:41.6px;}
  .mcard-name{
    font-family:'DM Sans',sans-serif;font-size:16px;font-weight:800;
    color:#1A1A1A;letter-spacing:-.01em;line-height:1.3;
    /* Wraps onto a 2nd line instead of truncating to "Ashwood Pla…" */
    display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;
    width:100%;min-width:0;
  }
  body.dark .mcard-name{color:#F2F2F0;}

  /* ── Right: bundle panel — sticky, sits just below the site header ── */
  .bb-panel{
    grid-column:2;grid-row:2;align-self:start;
    flex:0 0 520px;
    width:520px;
    position:sticky;
    /* --sh-refban-h is the referral invite banner's own height, set by
       header.js and 0px when it isn't showing. 124px was tuned for the
       no-banner case; without adding this the banner pushed the product grid
       down (normal flow, follows the spacer) but left this sticky panel's
       offset exactly as it was, so the panel's own header visibly sat
       higher than the grid's whenever the banner was up — reported as "the
       pack summary shifted". */
    top:calc(124px + var(--sh-refban-h, 0px));
    height:auto;
    max-height:calc(100vh - 264px - var(--sh-refban-h, 0px));
    display:flex;flex-direction:column;
    background:#ffffff;
    border: 1px solid rgba(0, 0, 0, 0.05);
    border-radius:var(--radius);
    margin:0;
    overflow:hidden;
    box-shadow: 0 20px 40px -15px rgba(0, 0, 0, 0.05), 0 1px 3px rgba(0, 0, 0, 0.01);
  }
  body.dark .bb-panel{
    background:#16161A;
    border: 1px solid rgba(255, 255, 255, 0.05);
    box-shadow: 0 20px 40px -15px rgba(0, 0, 0, 0.3), 0 1px 3px rgba(0, 0, 0, 0.05);
  }

  .bb-panel-head{padding:16px 20px 14px;border-bottom:1px solid rgba(0,0,0,0.05);flex-shrink:0;border-radius:var(--radius) var(--radius) 0 0;}
  body.dark .bb-panel-head{border-bottom-color:rgba(255,255,255,0.05);}
  .bb-panel-title{font-size:17px;font-weight:900;margin:0 0 14px;display:flex;align-items:center;gap:9px;}

  /* Size preset pills */
  .bb-size-row{display:flex;gap:6px;flex-wrap:wrap;}

  @media (max-width: 900px) {
    .product-toolbar-right {
      order: 2;
    }
  }

  /* ── Product grid ── */
  .product-grid{
    display:grid;
    grid-template-columns:repeat(auto-fill,minmax(180px,1fr));
    gap:10px;
  }

  .product-card{
    background:#FFFFFF;border:1px solid #ECECEC;border-radius: 16px;
    overflow:visible;padding-top:8px;
    transition:box-shadow .25s ease,border-color .2s;
    cursor:pointer;position:relative;display:flex;flex-direction:column;
    /* Mobile browsers paint a blue tap/selection highlight over the whole
       card on a press-and-hold or drag — these cards aren't text, so kill
       both the highlight and the text-selection it rides on. */
    -webkit-tap-highlight-color:transparent;user-select:none;-webkit-user-select:none;
  }
  .product-card:hover{
    box-shadow:0 10px 28px rgba(0,0,0,.10),0 2px 8px rgba(0,0,0,.06);
    transform:translateY(-5px) scale(1.015);
    border-color:rgba(0,0,0,.16);
    transition:box-shadow .25s ease,transform .25s cubic-bezier(.34,1.56,.64,1),border-color .2s;
    z-index:2;
  }
  body.dark .product-card{background:#141416;border-color:#26262B;}
  body.dark .product-card:hover{
    box-shadow:0 10px 30px rgba(0,0,0,.45),0 2px 8px rgba(0,0,0,.3);
    border-color:rgba(255,255,255,.16);
  }
  .product-card.in-bundle{background:rgba(22,163,74,0.08) !important;border-color:#DCFCE7 !important;}
  body.dark .product-card.in-bundle{background:rgba(22,163,74,0.16) !important;border-color:#15803D !important;}

  /* ── Admin "add item" card (opens the inline listing creator) ── */
  .bb-add-item-card{
    background:transparent;border:1.5px dashed var(--border);border-radius: 16px;
    display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:8px;min-height:180px;cursor:pointer;color:var(--text-muted);
    transition:all .2s;grid-column:1;
  }
  .bb-add-item-card:hover{border-color:#16A34A;color:#16A34A;background:rgba(22,163,74,.05);transform:translateY(-2px);}
  .bb-add-item-card svg{width:30px;height:30px;}
  .bb-add-item-card span{font-size:13px;font-weight:700;}

  /* ── Per-card edit/delete overlay (shown while in Edit mode) ── */
  .bb-card-edit-controls{position:absolute;top:8px;right:8px;z-index:10;display:flex;gap:4px;}
  .bb-card-edit-btn{
    width:24px;height:24px;border-radius: 12px;border:1px solid rgba(255,255,255,.15);
    background:rgba(0,0,0,.65);backdrop-filter:blur(4px);color:#fff;
    cursor:pointer;display:flex;align-items:center;justify-content:center;
    transition:background .1s,transform .1s;outline:none;
  }
  .bb-card-edit-btn:hover{background:rgba(0,0,0,.8);}
  .bb-card-edit-btn:active{transform:scale(.9);}
  .bb-card-delete-btn{
    width:24px;height:24px;border-radius: 12px;border:1px solid rgba(255,255,255,.15);
    background:rgba(0,0,0,.65);backdrop-filter:blur(4px);color:#fff;
    cursor:pointer;display:flex;align-items:center;justify-content:center;
    transition:background .1s,transform .1s;outline:none;
  }
  .bb-card-delete-btn:hover{background:#EF4444;}
  .bb-card-delete-btn:active{transform:scale(.9);}
  .bb-card-edit-btn.bb-card-unpublished{background:rgba(245,158,11,.85);border-color:rgba(245,158,11,.9);}
  .bb-card-edit-btn.bb-card-unpublished:hover{background:#F59E0B;}
  .product-card:has(.bb-card-unpublished) .product-card-img{opacity:.5;}

  /* ── Inline listing creator (replaces the grid when open) ── */
  /* Inline item editor — full page width, styled like pack.html's product page
     (image left, plain borderless-feeling fields right) instead of a boxed popup. */
  .bb-item-creator{width:85%;max-width:1400px;margin:0 auto;padding:24px 0 60px;}
  .bb-ic-topbar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:22px;}
  .bb-ic-back{
    background:none;border:none;padding:0;cursor:pointer;
    display:flex;align-items:center;gap:5px;font-family:'Geist','DM Sans',sans-serif;
    font-size:13px;font-weight:700;color:var(--text-muted);transition:color .15s;
  }
  .bb-ic-back:hover{color:var(--text);}
  .bb-ic-publish-btn{
    background:rgba(22,163,74,.1);color:#16A34A;border:1px solid rgba(22,163,74,.3);
    border-radius: 12px;padding:6px 14px;font-size:12px;font-weight:800;
    font-family:'Nunito',sans-serif;cursor:pointer;transition:background .15s;
    display:flex;align-items:center;gap:6px;
  }
  .bb-ic-publish-btn:hover{background:rgba(22,163,74,.2);}
  .bb-ic-delete-btn{
    background:rgba(239,68,68,.1);color:#EF4444;border:1px solid rgba(239,68,68,.3);
    border-radius: 12px;padding:6px 14px;font-size:12px;font-weight:800;
    font-family:'Nunito',sans-serif;cursor:pointer;transition:background .15s;
    display:flex;align-items:center;gap:6px;
  }
  .bb-ic-delete-btn:hover{background:rgba(239,68,68,.2);}
  .bb-ic-publish-btn.bb-ic-unpublish{background:rgba(0,0,0,.05);color:var(--text-muted);border-color:var(--border);}
  body.dark .bb-ic-publish-btn.bb-ic-unpublish{background:rgba(255,255,255,.06);}
  .bb-ic-publish-btn.bb-ic-unpublish:hover{border-color:var(--text-muted);color:var(--text);}
  .bb-ic-top{display:grid;grid-template-columns:200px 1fr;gap:32px;align-items:start;}
  @media(max-width:640px){ .bb-ic-top{grid-template-columns:1fr;gap:20px;} .bb-ic-hero{width:200px;} }
  .bb-ic-hero{
    position:relative;overflow:hidden;border-radius:18px;aspect-ratio:1/1;width:100%;
    border:1.5px solid var(--border);background:#f4f3f1;
    display:flex;align-items:center;justify-content:center;
  }
  body.dark .bb-ic-hero{background:#1a1a1c;border-color:#26262B;}
  .bb-ic-hero-img{width:100%;height:100%;object-fit:cover;display:block;}
  .bb-ic-hero-placeholder{
    display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:8px;color:var(--text-muted);opacity:.5;pointer-events:none;
  }
  .bb-ic-hero-placeholder svg{width:48px;height:48px;opacity:.5;}
  .bb-ic-hero-placeholder span{font-size:12px;font-weight:600;}
  .bb-ic-hero-upload-btn{
    position:absolute;bottom:14px;right:14px;
    background:rgba(0,0,0,.55);color:#fff;border:none;border-radius: 12px;
    padding:6px 12px;font-size:11px;font-weight:800;cursor:pointer;
    display:flex;align-items:center;gap:5px;transition:background .15s;
    font-family:'Nunito',sans-serif;
  }
  .bb-ic-hero-upload-btn:hover{background:rgba(0,0,0,.75);}
  .bb-ic-info{display:flex;flex-direction:column;}
  .bb-ic-cat-note{font-size:12px;color:var(--text-muted);font-weight:700;text-transform:uppercase;letter-spacing:.04em;margin-bottom:8px;}
  .bb-ic-cat-note--display-only{color:#7C3AED;}
  .bb-ic-title-input{
    font-family:'DM Sans',sans-serif;font-size:22px;font-weight:900;
    color:var(--text);line-height:1.25;width:100%;
    padding:8px 12px;border-radius:8px;border:1.5px solid var(--border);
    background:var(--bg);outline:none;box-sizing:border-box;
    transition:border-color .15s;margin-bottom:12px;
  }
  .bb-ic-title-input:focus{border-color:#7C3AED;}
  body.dark .bb-ic-title-input{background:#1a1a1c;border-color:#333;}
  .bb-ic-desc-textarea{
    width:100%;padding:8px 12px;border-radius:10px;border:1.5px solid var(--border);
    background:var(--bg);color:var(--text);font-family:'Nunito',sans-serif;
    font-size:13px;font-weight:600;outline:none;resize:vertical;box-sizing:border-box;
    height:70px;transition:border-color .15s;margin-bottom:18px;
  }
  .bb-ic-desc-textarea:focus{border-color:#7C3AED;}
  body.dark .bb-ic-desc-textarea{background:#1a1a1c;border-color:#333;}
  .bb-ic-row{display:flex;gap:12px;margin-bottom:18px;}
  .bb-ic-field{flex:1;min-width:0;}
  .bb-ic-field-label{display:block;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);margin-bottom:6px;}
  .bb-ic-plain-input{
    width:100%;padding:8px 12px;border-radius:8px;border:1.5px solid var(--border);
    background:var(--bg);color:var(--text);font-family:'Nunito',sans-serif;
    font-size:13px;font-weight:700;outline:none;box-sizing:border-box;transition:border-color .15s;
  }
  .bb-ic-plain-input:focus{border-color:#7C3AED;}
  body.dark .bb-ic-plain-input{background-color:#1a1a1c;border-color:#333;}
  .bb-ic-field-hint{font-weight:500;text-transform:none;letter-spacing:0;opacity:.75;}
  .bb-ic-inline-switches{display:flex;gap:22px;margin-bottom:16px;flex-wrap:wrap;}
  .bb-ic-inline-switch{
    display:flex;align-items:center;gap:9px;cursor:pointer;
    font-family:'Geist','DM Sans',sans-serif;font-size:12.5px;font-weight:700;color:var(--text);
  }
  .bb-ic-rows-list{display:flex;flex-direction:column;gap:6px;margin-bottom:8px;}
  .bb-ic-row-item{display:flex;gap:8px;align-items:center;width:100%;}
  .bb-ic-row-item .bb-ic-plain-input{flex:2;min-width:0;}
  .bb-ic-row-item .bb-ic-plain-input.bb-ic-qty-input{flex:0 0 70px;}
  .bb-ic-row-remove-btn{
    flex-shrink:0;width:28px;height:28px;border-radius: 12px;border:1.5px solid var(--border);
    background:none;color:var(--text-muted);cursor:pointer;display:flex;align-items:center;justify-content:center;
    font-size:14px;transition:all .15s;
  }
  .bb-ic-row-remove-btn:hover{border-color:#EF4444;color:#EF4444;}
  .bb-ic-row-drag-handle{
    flex:0 0 22px;width:22px;height:28px;padding:0;border:0;border-radius:7px;
    display:flex;align-items:center;justify-content:center;background:transparent;
    color:var(--text-muted);cursor:grab;touch-action:none;transition:color .15s,background .15s;
  }
  .bb-ic-row-drag-handle:hover{color:#7C3AED;background:rgba(124,58,237,.08);}
  .bb-ic-row-drag-handle:active{cursor:grabbing;}
  .bb-ic-row-drag-handle:focus-visible{outline:2px solid #7C3AED;outline-offset:1px;}
  .bb-ic-row-item.is-amount-dragging{opacity:.42;}
  .bb-ic-add-row-btn{
    background:none;border:1.5px dashed var(--border);color:var(--text-muted);
    border-radius: 12px;padding:7px 14px;font-size:12px;font-weight:800;
    font-family:'Nunito',sans-serif;cursor:pointer;transition:all .15s;
  }
  .bb-ic-add-row-btn:hover{border-color:#7C3AED;color:#7C3AED;}
  /* "Calculate" reads as a recalculation, not another way to add a row, so it
     borrows the green the wheelspin editor's Normalize button uses rather than
     the dashed add-row outline sitting next to it. */
  .bb-ic-calc-btn{
    display:inline-flex;align-items:center;gap:5px;
    background:rgba(22,163,74,.08);border:1.5px solid rgba(22,163,74,.24);
    color:#16a34a;border-radius:12px;padding:7px 12px;font-size:12px;font-weight:800;
    font-family:'Nunito',sans-serif;cursor:pointer;white-space:nowrap;transition:all .15s;
  }
  .bb-ic-calc-btn:hover{background:rgba(22,163,74,.16);border-color:#16a34a;}
  /* Brief green wash on the boxes that were just filled, so it is obvious which
     ones changed when several fill at once. */
  .bb-ic-row-item.bb-ic-row-just-filled .bb-ic-amount-price{
    border-color:#16a34a;
    background:rgba(22,163,74,.10);
    transition:border-color .4s ease,background .4s ease;
  }
  .bb-ic-subcat-pills{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:10px;}
  .bb-ic-subcat-pills:empty{margin-bottom:0;}
  .bb-ic-subcat-add-row{display:flex;gap:8px;align-items:center;}
  .bb-ic-subcat-add-row .bb-ic-plain-input{flex:1;min-width:0;}
  .bb-ic-subcat-add-row .bb-ic-add-row-btn{flex-shrink:0;white-space:nowrap;}
  .bb-ic-req-toggle-btn{
    flex-shrink:0;background:none;border:1.5px solid var(--border);color:var(--text-muted);
    border-radius:8px;padding:0 10px;height:28px;font-size:11px;font-weight:800;
    font-family:'Nunito',sans-serif;cursor:pointer;white-space:nowrap;transition:all .15s;
  }
  .bb-ic-req-toggle-btn:hover{border-color:#7C3AED;color:#7C3AED;}
  .bb-ic-req-picker{position:relative;flex:2;min-width:0;}
  .bb-ic-req-picker-btn{
    width:100%;display:flex;align-items:center;gap:8px;box-sizing:border-box;
    padding:6px 10px;border-radius: 12px;border:1.5px solid var(--border);
    background:var(--bg);color:var(--text);font-family:'Nunito',sans-serif;
    font-size:13px;font-weight:700;cursor:pointer;transition:border-color .15s;
  }
  .bb-ic-req-picker-btn:hover,.bb-ic-req-picker-btn:focus{border-color:#7C3AED;outline:none;}
  body.dark .bb-ic-req-picker-btn{background:#1a1a1c;border-color:#333;}
  .bb-ic-req-picker-icon{width:18px;height:18px;flex-shrink:0;border-radius:5px;overflow:hidden;background:var(--cream);display:flex;}
  body.dark .bb-ic-req-picker-icon{background:#26262B;}
  .bb-ic-req-picker-icon img{width:100%;height:100%;object-fit:contain;}
  .bb-ic-req-picker-label{flex:1;min-width:0;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .bb-ic-req-picker-btn svg{flex-shrink:0;opacity:.6;}
  .bb-ic-req-picker-panel{
    display:none;position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:20;
    background:var(--white);border:1.5px solid var(--border);border-radius: 16px;
    box-shadow:0 8px 24px rgba(0,0,0,.15);overflow:hidden;
  }
  body.dark .bb-ic-req-picker-panel{background:#1e1e22;box-shadow:0 8px 24px rgba(0,0,0,.4);}
  .bb-ic-req-picker-panel.open{display:block;}
  .bb-ic-req-picker-search{
    width:100%;box-sizing:border-box;padding:8px 10px;border:none;border-bottom:1.5px solid var(--border);
    background:none;color:var(--text);font-family:'Nunito',sans-serif;font-size:12.5px;font-weight:600;outline:none;
  }
  .bb-ic-req-picker-list{max-height:220px;overflow-y:auto;padding:4px;}
  .bb-ic-req-picker-opt{
    display:flex;align-items:center;gap:8px;padding:7px 8px;border-radius:7px;cursor:pointer;
    font-size:12.5px;font-weight:600;color:var(--text);
  }
  .bb-ic-req-picker-opt:hover{background:rgba(124,58,237,.1);color:#7C3AED;}
  .bb-ic-req-picker-opt img,.bb-ic-req-picker-opt-noicon{width:18px;height:18px;flex-shrink:0;border-radius:5px;object-fit:contain;background:var(--cream);}
  body.dark .bb-ic-req-picker-opt img,body.dark .bb-ic-req-picker-opt-noicon{background:#26262B;}
  .bb-ic-switches{
    display:flex;flex-direction:column;margin-bottom:22px;
    border-top:1.5px solid var(--border);
  }
  .bb-ic-switch-row{
    display:flex;align-items:center;justify-content:space-between;gap:16px;
    padding:12px 0;border-bottom:1px solid var(--border);
  }
  .bb-ic-switch-row:last-child{border-bottom:none;}
  .bb-ic-switch-text{display:flex;flex-direction:column;gap:1px;}
  .bb-ic-switch-text strong{font-family:'Geist','DM Sans',sans-serif;font-size:13px;font-weight:700;color:var(--text);}
  .bb-ic-switch-text span{font-size:11.5px;font-weight:500;color:var(--text-muted);}
  .bb-ic-switch{position:relative;display:inline-block;width:36px;height:20px;flex-shrink:0;}
  .bb-ic-switch input{opacity:0;width:0;height:0;position:absolute;}
  .bb-ic-switch-slider{
    position:absolute;inset:0;cursor:pointer;border-radius:34px;transition:.2s;
    background:rgba(0,0,0,0.14);border:1px solid rgba(0,0,0,0.1);
  }
  .bb-ic-switch-slider:before{
    position:absolute;content:"";height:14px;width:14px;left:2px;top:2px;
    background:#fff;border-radius:50%;transition:.2s;box-shadow:0 1px 3px rgba(0,0,0,0.15);
  }
  .bb-ic-switch input:checked + .bb-ic-switch-slider{background:#7C3AED;border-color:#7C3AED;}
  .bb-ic-switch input:checked + .bb-ic-switch-slider:before{transform:translateX(16px);}
  body.dark .bb-ic-switch-slider{background:rgba(255,255,255,0.15);border-color:rgba(255,255,255,0.12);}
  .bb-ic-actions{display:flex;gap:8px;}
  .bb-ic-save{
    background:rgba(124,58,237,.1);color:#7C3AED;border:1px solid rgba(124,58,237,.3);
    border-radius:8px;padding:9px 20px;font-size:12px;font-weight:800;
    font-family:'Nunito',sans-serif;cursor:pointer;transition:background .15s;
  }
  .bb-ic-save:hover{background:rgba(124,58,237,.2);}
  .bb-ic-save:disabled{opacity:.6;cursor:default;}
  .bb-ic-cancel{
    background:transparent;color:var(--text-muted);border:1px solid var(--border);
    border-radius:8px;padding:9px 20px;font-size:12px;font-weight:800;
    font-family:'Nunito',sans-serif;cursor:pointer;transition:all .15s;
  }
  .bb-ic-cancel:hover{border-color:var(--text-muted);color:var(--text);}

  /* ── Card entrance animation ── */
  @keyframes ppCardIn {
    from { opacity:0; transform:translateY(14px) scale(.97); }
    to   { opacity:1; transform:translateY(0)    scale(1);   }
  }
  .product-card.card-entering {
    animation: ppCardIn .28s cubic-bezier(.25,.46,.45,.94) both;
  }

  /* ── Card reveal system (staggered wave, scroll-driven) ──
     .pp-reveal-pre hides a freshly-inserted card until the IntersectionObserver
     hands it a slot in the wave; .pp-reveal-in plays the entrance. The `both`
     fill keeps a delayed card at the from-frame until its turn. */
  @keyframes ppCardReveal {
    from { opacity:0; transform:translateY(18px) scale(.96); }
    to   { opacity:1; transform:translateY(0)    scale(1);   }
  }
  .pp-reveal-pre{opacity:0;}
  .pp-reveal-in{animation:ppCardReveal .5s cubic-bezier(.25,.46,.45,.94) both;}
  @media (prefers-reduced-motion: reduce){
    .pp-reveal-pre{opacity:1;}
    .pp-reveal-in{animation:none;}
  }
  /* Old grid fades down-and-out for a beat while a new category renders */
  #bbGrid{transition:opacity .16s ease,transform .16s ease;}
  #bbGrid.pp-grid-leaving{opacity:0;transform:translateY(8px);transition:opacity .12s ease,transform .12s ease;}

  /* Infinite-scroll sentinel + spinner */
  .bb-grid-sentinel{grid-column:1/-1;display:flex;justify-content:center;padding:20px 0;}
  @keyframes bbSpin{to{transform:rotate(360deg)}}
  .bb-load-spinner{
    width:22px;height:22px;border-radius:50%;
    border:2.5px solid rgba(22,163,74,.2);
    border-top-color:#16A34A;
    animation:bbSpin .7s linear infinite;
  }

  .product-card-img{width:100%;aspect-ratio:4/3;flex-shrink:0;position:relative;overflow:hidden;background:transparent;border-radius: 16px;}
  .product-card-img img{
    width:100%;height:100%;object-fit:contain;display:block;position:relative;z-index:2;
    padding:10px;transition:transform .45s cubic-bezier(.2,.7,.3,1);
  }
  .product-card:hover .product-card-img img{transform:scale(1.06);}

  .product-card .pp-starred-pill {
    position: relative !important;
    top: auto !important;
    left: auto !important;
    right: auto !important;
    z-index: 1 !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    height: 40px !important;
    width: 44px !important;
    min-width: 44px !important;
    padding: 0 !important;
    border-radius: 8px !important;
    box-sizing: border-box !important;
    border: 1.5px solid transparent !important;
    cursor: pointer !important;
    pointer-events: auto !important;
    transition: all 0.15s ease !important;
    flex-shrink: 0 !important;
  }

  /* Bottom bar — no filled background, just a reserved-height row (bleeds
     edge-to-edge via negative margins) so every card's footer takes up the
     same space whether or not it has chips in it. Star toggle + synced
     count cluster on the left, in-pack count pinned to the right. */
  .mcard-foot-bar{
    display:flex;align-items:center;gap:8px;min-height:46px;
    margin:auto -11px -11px;padding:8px 11px;
  }
  /* Synced/owned count — same pill style and size as the in-pack chip, just
     coloured blue and pinned to the opposite (left) side of the bar. */
  .mcard-sync-chip{
    display:inline-flex;align-items:center;gap:5px;flex-shrink:0;
    background:#DCEAFE;color:#3B82F6;font-family:'DM Sans',sans-serif;font-size:15px;font-weight:900;
    border-radius:20px;padding:8px 13px;line-height:1.1;
  }
  body.dark .mcard-sync-chip{background:rgba(59,130,246,.2);color:#60A5FA;}
  .mcard-sync-chip svg{flex-shrink:0;width:13px;height:13px;}
  .mcard-qty-chip{
    margin-left:auto;flex-shrink:0;
    background:rgba(22,163,74,.10);color:var(--accent-deep,#15803D);border:1.5px solid rgba(22,163,74,.22);
    font-family:'Inter','Geist','DM Sans',sans-serif;font-size:14px;font-weight:800;
    border-radius:20px;padding:6px 13px;line-height:1.15;
    display:inline-flex;align-items:center;justify-content:center;
  }
  body.dark .mcard-qty-chip{
    background:rgba(34,197,94,.16);color:#4ADE80;
    border:1.5px solid rgba(74,222,128,.28);
  }
  /* Always shown (even at 0) so the in-pack slot never shifts the star/sync
     chips around — just greyed out when nothing's actually in the pack. */
  .mcard-qty-chip.muted{background:#EFEFEC;color:#ABABA5;border-color:transparent;}
  body.dark .mcard-qty-chip.muted{background:#2A2A2F;color:#5A5A62;border-color:transparent;}

  /* Badge pill (NEW, SALE etc) */
  .mcard-badge{
    position:absolute;top:10px;left:10px;z-index:2;
    background:#DCFCE7;border-radius:50px;
    padding:3px 9px;font-size:10px;font-weight:700;
    letter-spacing:.05em;text-transform:uppercase;color:#166534;
    font-family:'DM Sans',sans-serif;
  }
  body.dark .mcard-badge{background:rgba(16,185,129,.18);color:#86EFAC;}

  /* Discount pill — same slot as .mcard-badge but right-aligned so the two
     can coexist without overlapping. */
  .mcard-discount-badge{
    position:absolute;top:10px;right:10px;z-index:2;
    background:rgba(59,130,246,.14);border-radius:50px;
    padding:3px 9px;font-size:10px;font-weight:800;
    letter-spacing:.05em;color:#3b82f6;
    font-family:'DM Sans',sans-serif;
  }
  body.dark .mcard-discount-badge{background:rgba(59,130,246,.22);color:#60A5FA;}

  /* Hover add-to-bundle overlay */
  .mcard-media-action{
    position:absolute;left:0;right:0;top:0;bottom:0;z-index:5;
    opacity:0;
    /* Bottom-anchored scrim rather than a flat full-tile wash: the button
       sits at the bottom and needs the contrast there, while the item art
       above stays visible — it's what the user is actually choosing. */
    background:linear-gradient(to bottom,
      rgba(255,255,255,0) 30%,
      rgba(255,255,255,.35) 62%,
      rgba(255,255,255,.6) 100%);
    display:flex;align-items:flex-end;justify-content:center;
    padding-bottom:10px;
    transition:opacity .2s ease;pointer-events:none;
  }
  body.dark .mcard-media-action{
    background:linear-gradient(to bottom,
      rgba(20,20,22,0) 30%,
      rgba(20,20,22,.4) 62%,
      rgba(20,20,22,.68) 100%);
  }
  .product-card:hover .mcard-media-action{opacity:1;pointer-events:auto;}
  .mcard-buy-btn{
    width:calc(100% - 20px);height:38px;border:0;border-radius: 12px;cursor:pointer;
    background:#1A1A1A;color:#fff;font-family:'DM Sans',sans-serif;
    font-size:13px;font-weight:700;
    display:inline-flex;align-items:center;justify-content:center;gap:6px;
    box-shadow:0 4px 12px -4px rgba(0,0,0,.35);transition:transform .12s;
  }
  .mcard-buy-btn:hover{background:#1A1A1A;}
  body.dark .mcard-buy-btn{background:#fff;color:#1A1A1A;}

  /* Card body — flex column so the badge row can be pinned to the card's
     bottom edge via margin-top:auto, regardless of how much space the
     name/category text above it takes up. */
  /* min-height (not on .mcard-name) reserves room for a 2-line title without
     depending on grid row-stretch — the footer bar (margin-top:auto) always
     sits the same fixed distance from the card top, so numbers line up
     across every card regardless of how many lines the name wraps to. The
     slack lands as breathing room above the footer, not as a gap directly
     under a short single-line title. */
  /* Fixed height (not min-height, no flex:1) — the card's total height is
     then always image-height + 114px, period, regardless of whether the
     grid/flex context around it happens to stretch rows. That's what
     guarantees the footer chips land at the exact same Y on every card. */
  /* Fixed height — always image-height + 98px, regardless of surrounding
     layout. Name is single-line (truncated, not 2-line clamp) specifically
     so this fixed height never has to over-provision room for a second
     line that usually isn't there — that slack was the "massive gap"
     above the footer chips. */
  /* min-height, not height: the Starred pill adds a row on starred cards, and a
     hard height clipped the foot-bar chips straight off the bottom (the bar is
     pinned with margin-top:auto). Unstarred cards still settle at exactly 106px,
     so nothing shifts for them. */
  .mcard-body{padding:13px 11px 11px;position:relative;display:flex;flex-direction:column;box-sizing:border-box;min-height:106px;}
  /* The row — not the name — reserves the full 2-line height (2 x 1.3 x 16px),
     so the block below it starts at the same Y on every card whether the name
     runs to one line or two. Reserving it on .mcard-name instead would break
     the star: the pill is 40px tall and centers on the name box, so a 1-line
     name inside a fixed 2-line box would leave the star sitting ~10px low.
     Centering both inside a fixed-height row keeps them on the same axis and
     also absorbs the pill's own height, which used to make starred cards
     taller than unstarred ones. */
  .mcard-name-row{display:flex;flex-direction:row;align-items:center;gap:8px;min-height:41.6px;}
  .mcard-name{
    font-family:'DM Sans',sans-serif;font-size:16px;font-weight:800;
    color:#1A1A1A;letter-spacing:-.01em;line-height:1.3;
    /* Wraps onto a 2nd line instead of truncating to "Ashwood Pla…" */
    display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;
    width:100%;min-width:0;
  }
  body.dark .mcard-name{color:#F2F2F0;}

  /* ── Panel item animations ── */
  @keyframes bbItemSlideIn {
    from { opacity:0; transform:translateX(18px) scale(0.97); max-height:0; }
    to   { opacity:1; transform:translateX(0)    scale(1);    max-height:350px; }
  }
  @keyframes bbItemSlideOut {
    from { opacity:1; transform:translateX(0)    scale(1);    max-height:350px; }
    to   { opacity:0; transform:translateX(18px) scale(0.97); max-height:0; padding-top:0; padding-bottom:0; }
  }
  .bb-item-row {
    display:flex;align-items:center;gap:12px;padding:10px 16px;border-bottom:1px solid rgba(0,0,0,0.06);
    overflow:hidden;flex-shrink:0;
  }
  body.dark .bb-item-row{border-bottom-color:rgba(255,255,255,0.06);}
  .bb-item-row:last-child{border-bottom:none;}
  .bb-item-row.bb-row-entering {
    animation: bbItemSlideIn 0.22s cubic-bezier(0.34,1.3,0.64,1) both;
  }
  .bb-item-row.bb-row-leaving {
    animation: bbItemSlideOut 0.18s ease-in both;
    pointer-events:none;
  }
  /* Panel height transition */
  .bb-items {
    display:flex;
    flex-direction:column;
    overflow-y:auto;
    overflow-x:hidden;
    min-height:200px;
    max-height:calc(100vh - 380px);
    padding:4px 18px;
    transition: none;
    scrollbar-width:thin;
    scrollbar-color:var(--border) transparent;
  }
  .bb-items::-webkit-scrollbar{width:6px;}
  .bb-items::-webkit-scrollbar-track{background:transparent;}
  .bb-items::-webkit-scrollbar-thumb{background:var(--border);border-radius:999px;}
  .bb-items::-webkit-scrollbar-thumb:hover{background:var(--text-muted);}
  .bb-empty{
    flex:1;display:flex;flex-direction:column;align-items:center;
    justify-content:center;text-align:center;padding:20px 16px;
    color:var(--text-muted);font-size:13px;font-weight:700;line-height:1.6;
    gap:10px;
  }
  .bb-empty-icon-middle {
    display:flex;align-items:center;justify-content:center;
    margin-bottom:0;
  }
  .bb-empty-icon-middle svg { width:44px !important; height:44px !important; }
  .empty-svg-glow {
    animation:emptyFloat 4s ease-in-out infinite;
    filter:drop-shadow(0 8px 16px rgba(156, 163, 175, 0.3));
  }
  @keyframes emptyFloat {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-8px); }
  }
  .bb-empty-arrow {
    display:inline-flex;align-items:center;justify-content:center;
  }
  .bb-empty-arrow svg {
    animation:arrowSlide 1.5s ease-in-out infinite;
  }
  @keyframes arrowSlide {
    0%, 100% { transform: translateX(0); }
    50% { transform: translateX(-4px); }
  }
  .bb-item-row{display:flex;align-items:center;gap:12px;padding:10px 16px;border-bottom:1px solid rgba(0,0,0,0.06);flex-shrink:0;}
  body.dark .bb-item-row{border-bottom-color:rgba(255,255,255,0.06);}
  .bb-item-row:last-child{border-bottom:none;}
  .bb-item-img-wrap{position:relative;width:56px;height:56px;flex:0 0 56px;}
  .bb-item-img{
    width:100%;height:100%;border-radius:10px;object-fit:contain;
    background:#F0EFED;padding:3px;box-sizing:border-box;
  }
  body.dark .bb-item-img{background:#1C1C21;}
  .bb-item-star-badge{
    position:absolute;left:4px;bottom:4px;z-index:2;
    width:24px;height:24px;border-radius:8px;
    display:inline-flex;align-items:center;justify-content:center;
    box-sizing:border-box;line-height:0;
    color:var(--pp-star-icon,#F5B301);background:var(--pp-star-bg,#4D3B05);
    border:2px solid var(--pp-star-border,#F5B301);
    box-shadow:var(--pp-star-shadow,0 0 0 2px rgba(15,15,17,.72),0 4px 12px rgba(0,0,0,.58));
    pointer-events:none;
  }
  .bb-item-star-badge svg,.bb-item-star-badge .pp-star-ico{width:13px;height:13px;display:block;margin:0!important;vertical-align:0!important;}
  .bb-item-recipe-badge{
    position:absolute;left:4px;bottom:4px;z-index:2;
    width:24px;height:24px;border-radius:8px;
    display:inline-flex;align-items:center;justify-content:center;
    box-sizing:border-box;line-height:0;
    color:var(--pp-recipe-icon,#60A5FA);background:var(--pp-recipe-bg,#102A4F);
    border:2px solid var(--pp-recipe-border,#3B82F6);
    box-shadow:var(--pp-recipe-shadow,0 0 0 2px rgba(15,15,17,.72),0 4px 12px rgba(0,0,0,.58));
    pointer-events:none;
  }
  .bb-item-grown-badge{
    position:absolute;left:4px;bottom:4px;z-index:2;
    width:24px;height:24px;border-radius:8px;
    display:inline-flex;align-items:center;justify-content:center;
    box-sizing:border-box;line-height:0;
    color:var(--pp-grown-icon,#4ADE80);background:var(--pp-grown-bg,#052E16);
    border:2px solid var(--pp-grown-border,#22C55E);
    box-shadow:var(--pp-grown-shadow,0 0 0 2px rgba(15,15,17,.72),0 4px 12px rgba(0,0,0,.58));
    pointer-events:none;
  }
  .bb-item-grown-badge.after-star{left:32px;}
  .bb-item-grown-badge svg{width:13px;height:13px;display:block;margin:0!important;vertical-align:0!important;}
  .bb-item-recipe-badge.after-star{left:32px;}
  /* Third slot on the 56px panel thumbnail: 4 / 32 / 60 (24px badge + 4px gap). */
  .bb-item-recipe-badge.after-two,
  .bb-item-style-badge.after-two{left:60px;}
  .bb-item-recipe-badge svg{width:13px;height:13px;display:block;margin:0!important;vertical-align:0!important;}
  .bb-item-style-badge{
    position:absolute;left:4px;bottom:4px;z-index:2;
    width:24px;height:24px;border-radius:8px;
    display:inline-flex;align-items:center;justify-content:center;
    box-sizing:border-box;line-height:0;
    color:var(--pp-style-icon,#F0ABFC);background:var(--pp-style-bg,#3B174F);
    border:2px solid var(--pp-style-border,#D946EF);
    box-shadow:var(--pp-style-shadow,0 0 0 2px rgba(15,15,17,.72),0 4px 12px rgba(0,0,0,.58));
    pointer-events:none;
  }
  .bb-item-style-badge.after-star{left:32px;}
  .bb-item-style-badge svg{width:13px;height:13px;display:block;margin:0!important;vertical-align:0!important;}
  .bb-item-info{flex:1;min-width:0;}
  .bb-item-name{font-size:13px;font-weight:800;white-space:normal;overflow-wrap:anywhere;word-break:break-word;line-height:1.3;}
  /* Line price sits under the name as its own small pill — the quantity
     stepper (.bb-item-stepper) is the primary control and stays the bold/
     high-contrast one; this is secondary info, so lighter weight and no
     border. */
  .bb-item-price-pill{display:inline-flex;align-items:center;width:fit-content;margin-top:4px;padding:2px 9px;border-radius:20px;background:var(--chip,#F5F2F0);color:var(--text-muted);font-size:11px;font-weight:700;}
  body.dark .bb-item-price-pill{background:#1E1E22;color:#9CA3AF;}
  /* Sale chips sit on the same line as the price pill — the discount is a
     property of the price, so it reads as one unit rather than a stray badge.
     `flex-wrap` matters on narrow panels: the struck price drops under the
     pills instead of squeezing the item name. */
  .bb-item-price-row{display:flex;align-items:center;flex-wrap:wrap;gap:5px;}
  .bb-item-price-row .bb-item-price-pill{margin-top:0;}
  .bb-item-price-row{margin-top:4px;}
  .bb-item-discount-pill{display:inline-flex;align-items:center;padding:2px 7px;border-radius:20px;background:rgba(59,130,246,.12);color:#3b82f6;font-size:10.5px;font-weight:800;letter-spacing:.2px;}
  body.dark .bb-item-discount-pill{background:rgba(59,130,246,.2);color:#60A5FA;}
  .bb-item-price-was{font-size:10.5px;font-weight:700;color:var(--text-muted);text-decoration:line-through;opacity:.75;}
  /* Temporary event pricing disclosure — see bbHasPriceOverride. Amber rather
     than the sale-green discount pill, since this is a markup, not a markdown. */
  .bb-item-bulletin-board-pill{display:inline-flex;align-items:center;padding:2px 7px;border-radius:20px;background:rgba(217,119,6,.14);color:#B45309;font-size:10.5px;font-weight:800;letter-spacing:.2px;}
  body.dark .bb-item-bulletin-board-pill{background:rgba(251,191,36,.16);color:#FBBF24;}
  .bb-stepper{display:flex;align-items:center;flex-shrink:0;background:var(--bg);border:1.5px solid var(--border);border-radius:999px;overflow:hidden;}
  body.dark .bb-stepper{background:#0d0d0f;}
  .bb-change-btn{
    display:inline-flex;align-items:center;gap:5px;height:32px;padding:0 12px;
    border-radius: 12px;border:1.5px solid var(--border);background:var(--white);
    font-family:'Geist',sans-serif;font-size:12px;font-weight:700;color:var(--text-soft);
    cursor:pointer;flex-shrink:0;transition:all .15s;
  }
  .bb-change-btn:hover{border-color:#16A34A;color:#16A34A;}
  body.dark .bb-change-btn{background:rgba(255,255,255,0.05);}
  body.dark .bb-change-btn:hover{background:rgba(22,163,74,0.12);}
  .bb-locked-qty-chip{
    display:inline-flex;align-items:center;height:32px;padding:0 10px;gap:4px;
    border-radius:999px;border:1.5px solid var(--border);background:var(--white);
    font-size:12px;font-weight:900;color:var(--text-muted);flex-shrink:0;
  }
  body.dark .bb-locked-qty-chip{background:rgba(255,255,255,0.05);}
  .bb-step-btn{
    width:32px;height:32px;border-radius: 12px;border:none;
    background:transparent;color:var(--text);font-size:16px;font-weight:800;
    cursor:pointer;display:flex;align-items:center;justify-content:center;
    padding:0;transition:background .12s;line-height:1;flex-shrink:0;
  }
  .bb-step-btn:hover{background:rgba(22,163,74,0.1);color:#16A34A;}
  .bb-step-val{font-size:13px;font-weight:900;min-width:24px;text-align:center;}
  .bb-step-input {
    width: 36px;
    height: 32px;
    border-radius: 0;
    border: none;
    border-left: 1px solid var(--border);
    border-right: 1px solid var(--border);
    background: transparent;
    color: var(--text);
    font-family: inherit;
    font-size: 13px;
    font-weight: 900;
    text-align: center;
    outline: none;
    transition: all 0.15s ease;
    -moz-appearance: textfield;
  }
  .bb-step-input::-webkit-outer-spin-button,
  .bb-step-input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }
  .bb-step-input:focus {
    background: rgba(22,163,74,0.05);
  }

  /* Footer */
  .bb-footer{padding:16px 20px;border-top:1px solid rgba(0,0,0,0.05);flex-shrink:0;background:#ffffff;border-radius:0 0 var(--radius) var(--radius);}
  body.dark .bb-footer{background:#16161A;border-top-color:rgba(255,255,255,0.05);}
  /* ── In-pack search (footer, above Total) ──
     Filters the rows in .bb-items. Shown by bbApplyPackSearch only once the
     pack has ≥2 items, so it never sits over an empty or single-item panel. */
  .bb-pack-search-wrap{
    display:none;flex-direction:column;gap:8px;
    margin:0 0 14px;padding:0 0 14px;
    border-bottom:1px solid rgba(0,0,0,0.06);
  }
  body.dark .bb-pack-search-wrap{border-bottom-color:rgba(255,255,255,0.06);}
  .bb-pack-search{position:relative;display:flex;align-items:center;width:100%;}
  .bb-pack-search-icon{
    position:absolute;left:12px;display:flex;align-items:center;
    color:var(--text-muted);pointer-events:none;
  }
  .bb-pack-search-input{
    width:100%;height:38px;box-sizing:border-box;
    border:1.5px solid var(--border);border-radius:10px;
    padding:0 34px 0 36px;
    font-family:'DM Sans',sans-serif;font-size:13.5px;font-weight:600;
    color:var(--text);background:var(--bg);outline:none;
    transition:border-color .15s,box-shadow .15s;
  }
  .bb-pack-search-input::placeholder{color:var(--text-muted);font-weight:500;}
  .bb-pack-search-input:focus{border-color:#16A34A;box-shadow:0 0 0 3px rgba(22,163,74,0.09);}
  body.dark .bb-pack-search-input{background:#0E0E10;border-color:#26262B;}
  body.dark .bb-pack-search-input:focus{border-color:#4ADE80;box-shadow:0 0 0 3px rgba(74,222,128,0.1);}
  .bb-pack-search-clear{
    position:absolute;right:9px;width:20px;height:20px;padding:0;
    border:none;border-radius:50%;background:none;cursor:pointer;
    color:var(--text-muted);font-size:11px;line-height:1;
    display:none;align-items:center;justify-content:center;
    transition:color .12s,background .12s;
  }
  .bb-pack-search-clear:hover{color:var(--text);background:rgba(0,0,0,0.07);}
  body.dark .bb-pack-search-clear:hover{background:rgba(255,255,255,0.08);}
  .bb-pack-search-none{
    font-family:'DM Sans',sans-serif;font-size:12.5px;font-weight:600;
    color:var(--text-muted);text-align:center;padding:2px 0 0;
  }
  /* Rows filtered out by the search. display:none rather than opacity so the
     list actually collapses to the matches. */
  .bb-item-row.bb-item-filtered{display:none !important;}

  .bb-total-row{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:12px;}
  .bb-total-label{font-size:16px;font-weight:800;color:var(--text);}
  .bb-total-price{font-size:26px;font-weight:900;color:var(--text);}
  .bb-min-charge-notice{
    display:flex;align-items:flex-start;gap:8px;margin:0 0 12px;padding:9px 10px;
    border:1px solid rgba(217,119,6,.28);border-radius:9px;
    background:rgba(245,158,11,.08);color:#92400E;
    font-family:'Geist','DM Sans',sans-serif;font-size:12px;font-weight:700;line-height:1.4;
  }
  .bb-min-charge-notice svg{flex:0 0 16px;margin-top:1px;color:#D97706;}
  body.dark .bb-min-charge-notice{
    background:rgba(245,158,11,.10);border-color:rgba(245,158,11,.25);color:#FBBF24;
  }
  /* Shown when the shopper arrived via "Customize Pack" on an official pack and
     the builder's per-item total is above what that pack itself costs. Blue
     rather than the amber of .bb-min-charge-notice above: nothing is wrong and
     nothing is blocked, it just explains a price difference the shopper would
     otherwise see appear unannounced. */
  .bb-origin-notice{
    display:flex;align-items:flex-start;gap:8px;margin:0 0 12px;padding:9px 10px;
    border:1px solid rgba(59,130,246,.28);border-radius:9px;
    background:rgba(59,130,246,.08);color:#1E40AF;
    font-family:'Geist','DM Sans',sans-serif;font-size:12px;font-weight:700;line-height:1.4;
  }
  .bb-origin-notice svg{flex:0 0 16px;margin-top:1px;color:#3B82F6;}
  .bb-origin-notice a{color:inherit;text-decoration:underline;white-space:nowrap;}
  body.dark .bb-origin-notice{
    background:rgba(59,130,246,.12);border-color:rgba(59,130,246,.28);color:#93C5FD;
  }
  body.dark .bb-origin-notice svg{color:#60A5FA;}
  .bb-atc{
    width:100%;padding:13px;border-radius:12px;
    background:transparent;color:#16A34A;border:2px solid #16A34A;
    font-family:'Nunito',sans-serif;font-size:14px;font-weight:900;
    cursor:pointer;transition:background-color .15s,opacity .15s,transform .12s,box-shadow .15s;
  }
  .bb-atc:not(:disabled):hover{
    background:rgba(61,139,106,0.1);
    transform:translateY(-1px);
  }
  .bb-atc:disabled{
    opacity:.45;
    cursor:not-allowed;
    color:#9CA3AF;border-color:#D1D5DB;
  }
  body.dark .bb-atc:disabled{color:#52525B;border-color:#3F3F46;}
  body.dark .bb-atc:not(:disabled){color:#22C55E;border-color:#22C55E;}
  body.dark .bb-atc:not(:disabled):hover{background:rgba(90,175,138,0.12);}
  .bb-buy-now{
    width:100%;padding:13px;border-radius:12px;border:none;
    background:#D1D5DB;color:#fff;
    font-family:'Nunito',sans-serif;font-size:14px;font-weight:900;
    cursor:pointer;transition:background-color .15s,opacity .15s,transform .12s,box-shadow .15s;
  }
  .bb-buy-now:not(:disabled){background:#16A34A;}
  body.dark .bb-buy-now:not(:disabled){background:#16A34A;}
  .bb-buy-now:not(:disabled):hover{
    background:#15803D;
    transform:translateY(-1px);
    box-shadow:0 4px 12px rgba(61,139,106,0.3);
  }
  .bb-buy-now:disabled{
    opacity:.6;
    cursor:not-allowed;
  }
  body.dark .bb-buy-now:disabled{background:#3F3F46;}

  .bb-atc-outlined {
    flex: 1; padding: 11px 8px; border-radius: 12px;
    background: transparent; color: #15803D; border: 1.5px solid #16A34A;
    font-family: 'Nunito', sans-serif; font-size: 13px; font-weight: 900;
    cursor: pointer; transition: background-color .15s, opacity .15s, transform .12s, box-shadow .15s;
    text-align: center;
    box-sizing: border-box;
    position: relative;
    overflow: hidden;
    display: inline-flex; align-items: center; justify-content: center;
  }
  .bb-btn-text {
    position: relative;
    z-index: 2;
  }
  .bb-btn-progress {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    width: 0;
    background: rgba(255, 255, 255, 0.2);
    z-index: 1;
    transition: none;
  }
  .bb-atc-outlined.animating .bb-btn-progress {
    width: 100%;
    transition: width 5s linear;
  }
  .bb-atc-outlined.animating {
    pointer-events: none;
    opacity: 1 !important;
    border-color: #16A34A !important;
    color: #16A34A !important;
  }
  body.dark .bb-atc-outlined.animating {
    border-color: #16A34A !important;
    color: #16A34A !important;
  }
  .bb-atc-outlined:not(:disabled):hover {
    background: rgba(22,163,74,.08);
    transform: translateY(-1px);
    box-shadow: 0 5px 14px rgba(16,185,129,0.12);
  }
  .bb-atc-outlined:disabled {
    opacity: .5;
    cursor: not-allowed;
    background: transparent; color: var(--text); border: 1.5px solid var(--border);
  }
  body.dark .bb-atc-outlined:disabled { border-color: #3F3F46; color: #52525B; }
  body.dark .bb-atc-outlined:not(:disabled) { background: transparent; color: #4ADE80; border-color: rgba(74,222,128,.65); }
  body.dark .bb-atc-outlined:not(:disabled):hover { background: rgba(74,222,128,.09); border-color:#4ADE80; }
  .bb-atc-outlined.is-checkout:not(:disabled){background:#16A34A;color:#fff;border-color:#16A34A;}
  .bb-atc-outlined.is-checkout:not(:disabled):hover{background:#15803D;border-color:#15803D;box-shadow:0 6px 18px rgba(16,185,129,.22);}
  /* In step with the canonical primary in styles.css: white on #15803D in both themes. */
  body.dark .bb-atc-outlined.is-checkout:not(:disabled){background:#15803D;color:#fff;border-color:#15803D;}
  body.dark .bb-atc-outlined.is-checkout:not(:disabled):hover{background:#166534;border-color:#166534;}

  .bb-save-pack {
    flex: 1; padding: 11px 8px; border-radius: 12px;
    background: transparent; color: var(--text); border: 1.5px solid var(--border);
    font-family: 'Nunito', sans-serif; font-size: 13px; font-weight: 900;
    cursor: not-allowed; opacity: 0.5;
    text-align: center;
    box-sizing: border-box;
    transition: all .15s;
    display: inline-flex; align-items: center; justify-content: center;
  }
  .bb-save-pack:not(:disabled) {
    /* 1.5px, not 2px: this sits directly above .bb-atc-outlined in the footer
       stack, which is 1.5px — the heavier edge (in near-white, against two
       thin green outlines) read as a different, chunkier control rather than
       one of the same set. Only the width changed; the colour still carries
       the "secondary but enabled" emphasis. */
    cursor: pointer; opacity: 1; color: var(--text); border: 1.5px solid var(--text);
  }
  .bb-save-pack:not(:disabled):hover {
    background: rgba(0,0,0,0.06);
    border-color: var(--text);
    transform: translateY(-1px);
  }
  body.dark .bb-save-pack {
    border-color: #3F3F46; color: #52525B;
  }
  body.dark .bb-save-pack:not(:disabled) {
    color: var(--text); border-color: var(--text);
  }
  body.dark .bb-save-pack:not(:disabled):hover {
    background: rgba(255,255,255,0.08);
  }

  /* Save + Add to Basket on one line. Both carry flex:1 in their own rules —
     written for when each owned a full-width row — so the widths are set here
     rather than inherited: Add to Basket takes the line, Save takes only what
     it needs. That is the hierarchy the two actions actually have, and it
     hands a whole row back to the item list on a phone. */
  .bb-footer-cta-row{
    display:flex;align-items:stretch;gap:8px;width:100%;
  }
  .bb-footer-cta-row .bb-atc-outlined{flex:1 1 auto;min-width:0;}
  /* Icon only at every width, desktop included. Its title/aria-label still
     name it, and the floppy-disk glyph is the conventional "save" — leaving
     the words on desktop only would have meant the two layouts taught
     different things about the same button. */
  .bb-footer-cta-row .bb-save-pack{
    flex:0 0 auto;
    width:52px;min-width:52px;padding:0;justify-content:center;
  }
  .bb-footer-cta-row .bb-save-pack .bb-save-pack-label{display:none;}
  .bb-footer-cta-row .bb-save-pack svg{flex:0 0 auto;}
  .bb-admin-pack-btn {
    width: 100%; padding: 14px; border-radius: 12px; border: none; margin-top: 8px;
    background: #6366F1; color: #fff;
    font-family: 'Nunito', sans-serif; font-size: 14px; font-weight: 800;
    cursor: pointer; transition: background .15s, transform .12s, box-shadow .15s;
    box-shadow: 0 4px 12px rgba(99,102,241,0.15);
    display: none;
  }
  body.dark .bb-admin-pack-btn { background: #818CF8; color: #0E0E10; }
  .bb-admin-pack-btn:not(:disabled):hover { background: #4f46e5; transform: translateY(-1px); box-shadow: 0 6px 18px rgba(99,102,241,0.25); }
  body.dark .bb-admin-pack-btn:not(:disabled):hover { background: #A5B4FC; }
  .bb-admin-pack-btn:disabled { opacity: 0.45; cursor: not-allowed; }
  .bb-etsy-pack-btn { width:100%;margin-top:8px;padding:13px;border-radius:12px;border:1.5px solid rgba(217,119,6,.48);background:rgba(217,119,6,.10);color:#B45309;font-family:'Nunito',sans-serif;font-size:14px;font-weight:900;align-items:center;justify-content:center;gap:7px;cursor:pointer;transition:background .15s,border-color .15s,transform .12s; }
  .bb-etsy-pack-btn:not(:disabled):hover { background:rgba(217,119,6,.17);border-color:#D97706;transform:translateY(-1px); }
  .bb-etsy-pack-btn:disabled { opacity:.45;cursor:not-allowed; }
  body.dark .bb-etsy-pack-btn { color:#FBBF24;background:rgba(245,158,11,.10);border-color:rgba(245,158,11,.42); }
  .bb-etsy-pack-modal { max-width:520px; }
  .bb-etsy-pack-kicker { color:#D97706;font-size:10px;font-weight:900;letter-spacing:.12em;margin-bottom:7px; }
  .bb-etsy-pack-search-wrap { display:flex;align-items:center;gap:9px;margin-top:18px;padding:0 13px;border:1.5px solid var(--border);border-radius:12px;background:var(--bg);color:var(--text-muted); }
  .bb-etsy-pack-search-wrap:focus-within { border-color:#D97706;box-shadow:0 0 0 3px rgba(217,119,6,.10); }
  .bb-etsy-pack-search-wrap input { min-width:0;flex:1;border:0;outline:0;background:transparent;color:var(--text);padding:11px 0;font:600 13px 'Geist','Nunito',sans-serif; }
  .bb-etsy-pack-list { display:flex;flex-direction:column;gap:7px;margin-top:12px;max-height:360px;overflow:auto; }
  .bb-etsy-pack-option { width:100%;display:grid;grid-template-columns:46px minmax(0,1fr) auto;align-items:center;gap:11px;padding:9px;border:1.5px solid var(--border);border-radius:13px;background:var(--card-bg);text-align:left;color:var(--text);cursor:pointer; }
  .bb-etsy-pack-option:hover,.bb-etsy-pack-option:focus-visible { border-color:#D97706;background:rgba(217,119,6,.06);outline:none; }
  .bb-etsy-pack-option img,.bb-etsy-pack-option-img { width:46px;height:46px;border-radius:10px;object-fit:cover;background:var(--bg);display:flex;align-items:center;justify-content:center; }
  .bb-etsy-pack-option-name { overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:800; }
  .bb-etsy-pack-option-meta { margin-top:3px;color:var(--text-muted);font-size:11px;font-weight:650; }
  .bb-etsy-pack-option-add { color:#B45309;font-size:11px;font-weight:900;white-space:nowrap; }
  body.dark .bb-etsy-pack-option-add { color:#FBBF24; }
  .bb-etsy-pack-state { padding:24px 12px;text-align:center;color:var(--text-muted);font-size:13px; }

  /* Pack name modal */
  .pack-name-modal-overlay {
    position: fixed; inset: 0; background: rgba(5,6,9,0.72);
    backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
    z-index: 1000000; display: none; align-items: center; justify-content: center;
    padding: 20px; overflow-y: auto;
  }
  .pack-name-modal-overlay.show { display: flex; }
  .pack-name-modal-card {
    position: relative; box-sizing: border-box;
    background: var(--card-bg); border-radius: 14px; padding: 28px 24px 24px;
    width: 100%; max-width: 480px; border: 1px solid var(--border);
    box-shadow: 0 28px 70px rgba(0,0,0,.38); font-family: 'Nunito', sans-serif;
  }
  .pack-name-modal-card.is-personal { margin-top: 90px; padding-top: 122px; }
  body.dark .pack-name-modal-card { background: #16161a; border-color: #2c2c31; }
  .pack-name-modal-close {
    position: absolute; top: 16px; right: 16px; z-index: 3;
    width: 34px; height: 34px; padding: 0; border: 0; border-radius: 9px;
    background: transparent; color: var(--text-muted); cursor: pointer;
    display: flex; align-items: center; justify-content: center; transition: color .15s, background .15s;
  }
  .pack-name-modal-close:hover { color: var(--text); background: color-mix(in srgb, var(--text) 7%, transparent); }
  .pack-name-modal-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .pack-personal-hero {
    position: absolute; top: 0; left: 50%; z-index: 2;
    transform: translate(-50%, -50%); width: 200px; height: 200px;
  }
  .pack-personal-hero img {
    display: block; width: 100%; height: 100%; object-fit: cover;
    border-radius: 18px; border: 1px solid rgba(255,255,255,.22);
    box-shadow: 0 16px 36px rgba(0,0,0,.34);
  }
  .pack-name-modal-card.is-admin .pack-personal-hero { display: none; }
  .pack-name-modal-header { text-align: center; margin-bottom: 22px; }
  .pack-name-modal-title { font-size: 20px; font-weight: 900; line-height: 1.2; margin: 0 0 7px; color: var(--text); }
  .pack-name-modal-sub { max-width: 330px; margin: 0 auto; font-size: 13px; font-weight: 600; line-height: 1.45; color: var(--text-muted); }
  .pack-name-modal-label {
    display: block; margin: 0 0 7px; font-size: 11px; font-weight: 800;
    text-transform: uppercase; letter-spacing: .07em; color: var(--text-muted);
  }
  .pack-name-modal-optional { font-weight: 600; opacity: .65; }
  .pack-name-modal-input {
    width: 100%; height: 46px; padding: 11px 14px; border-radius: 10px;
    border: 1.5px solid var(--border); background: var(--bg); color: var(--text);
    font-family: 'Nunito', sans-serif; font-size: 14px; font-weight: 700;
    outline: none; box-sizing: border-box; margin-bottom: 16px;
    transition: border-color .15s, box-shadow .15s;
  }
  .pack-name-modal-input:focus, .pack-name-modal-textarea:focus {
    border-color: var(--accent); box-shadow: 0 0 0 3px rgba(34,197,94,.12);
  }
  body.dark .pack-name-modal-input, body.dark .pack-name-modal-textarea { background: #101012; border-color: #303036; }
  .pack-name-modal-section { margin-bottom: 18px; }
  .pack-name-modal-textarea {
    width: 100%; height: 78px; padding: 11px 14px; resize: vertical;
    border-radius: 10px; border: 1.5px solid var(--border); background: var(--bg);
    color: var(--text); font-family: 'Nunito', sans-serif; font-size: 13px;
    font-weight: 600; line-height: 1.45; outline: none; box-sizing: border-box;
    transition: border-color .15s, box-shadow .15s;
  }
  .pack-name-modal-btns { display: flex; gap: 10px; }
  /* In step with the canonical primary in styles.css: white on #15803D in both
     themes. The literal is deliberate — var(--accent) resolves to #22C55E under
     dark, and white on that is 2.3:1, which is what the old dark-ink inversion
     here was working around. #15803D carries white at 5.0:1 in both themes, so
     the label stays white like every other primary button on the site. */
  .pack-name-modal-confirm {
    flex: 1.25; min-height: 46px; padding: 11px 14px; border-radius: 10px; border: 1px solid #15803D;
    background: #15803D; color: #fff; font-family: 'Nunito', sans-serif;
    font-size: 13px; font-weight: 900; cursor: pointer; transition: background .15s, border-color .15s, transform .15s, box-shadow .15s;
  }
  .pack-name-modal-confirm:hover { background: #126B33; border-color: #126B33; transform: translateY(-1px); box-shadow: 0 6px 18px rgba(34,197,94,.24); }
  body.dark .pack-name-modal-confirm:hover { background: #166534; border-color: #166534; }
  .pack-name-modal-cancel {
    flex: .75; min-height: 46px; padding: 11px 16px; border-radius: 10px;
    border: 1.5px solid var(--border); background: color-mix(in srgb, var(--text) 5%, transparent);
    color: var(--text-soft); font-family: 'Nunito', sans-serif;
    font-size: 13px; font-weight: 900; cursor: pointer; transition: border-color .15s, color .15s, background .15s;
  }
  .pack-name-modal-cancel:hover { border-color: var(--text-muted); color: var(--text); background: color-mix(in srgb, var(--text) 8%, transparent); }
  .pack-name-modal-overwrite {
    width: 100%; min-height: 42px; margin-top: 10px; padding: 10px 14px;
    border-radius: 10px; border: 1.5px solid var(--border); background: transparent;
    color: var(--text-soft); font-family: 'Nunito', sans-serif;
    font-size: 12.5px; font-weight: 800; cursor: pointer; transition: border-color .15s, color .15s, background .15s;
  }
  .pack-name-modal-overwrite:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); background: rgba(34,197,94,.06); }
  .pack-name-modal-overwrite:disabled { opacity: 0.4; cursor: not-allowed; }
  .pack-name-modal-confirm:focus-visible,
  .pack-name-modal-cancel:focus-visible,
  .pack-name-modal-overwrite:focus-visible {
    outline: 2px solid var(--accent); outline-offset: 2px;
  }
  @media (max-width: 520px) {
    .pack-name-modal-overlay { align-items: flex-start; padding: 18px 14px; }
    .pack-name-modal-card { padding: 24px 18px 18px; }
    .pack-name-modal-card.is-personal { margin-top: 72px; padding-top: 94px; }
    .pack-personal-hero { width: 154px; height: 154px; }
    .pack-name-modal-header { margin-bottom: 18px; }
    .pack-name-modal-title { font-size: 19px; }
    .pack-name-modal-btns { flex-direction: column; gap: 8px; }
    .pack-name-modal-confirm { order: -1; }
    .pack-name-modal-confirm, .pack-name-modal-cancel { padding-left: 10px; padding-right: 10px; font-size: 12px; }
  }
  .bb-clear-all{
    font-size:12px;font-weight:700;color:#EF4444;
    background:transparent;border:1.5px solid rgba(239,68,68,0.35);
    border-radius:999px;padding:5px 12px;
    cursor:pointer;transition:background .15s,border-color .15s;
    font-family:'Nunito',sans-serif;white-space:nowrap;
  }
  .bb-clear-all:hover{background:rgba(239,68,68,0.08);border-color:rgba(239,68,68,0.6);}
  body.dark .bb-clear-all{border-color:rgba(239,68,68,0.4);color:#F87171;}
  body.dark .bb-clear-all:hover{background:rgba(239,68,68,0.12);border-color:rgba(239,68,68,0.6);}

  /* Hide-mode grid state (entered/exited via the combined actions dropdown): click cards to hide/unhide them */
  #bbGrid.bb-hide-mode .product-card{cursor:pointer;}
  #bbGrid.bb-hide-mode .product-card:hover{opacity:.6;}
  .mcard-buy-hide,.mcard-buy-unhide{display:none;align-items:center;gap:4px;}
  #bbGrid.bb-hide-mode .mcard-buy-add,#bbGrid.bb-hidden-only-view .mcard-buy-add{display:none;}
  #bbGrid.bb-hide-mode .mcard-buy-remove{display:none;}
  #bbGrid.bb-hide-mode .mcard-buy-hide{display:inline-flex;}
  #bbGrid.bb-hidden-only-view .mcard-buy-hide{display:none;}
  #bbGrid.bb-hidden-only-view .mcard-buy-unhide{display:inline-flex;}
  #bbGrid.bb-hide-mode .mcard-buy-btn,#bbGrid.bb-hidden-only-view .mcard-buy-btn{background:#1A1A1A !important;color:#fff !important;}
  #bbGrid.bb-hide-mode .mcard-buy-btn:hover,#bbGrid.bb-hidden-only-view .mcard-buy-btn:hover{background:#000 !important;}
  body.dark #bbGrid.bb-hide-mode .mcard-buy-btn,body.dark #bbGrid.bb-hidden-only-view .mcard-buy-btn{background:#fff !important;color:#1A1A1A !important;}
  body.dark #bbGrid.bb-hide-mode .mcard-buy-btn:hover,body.dark #bbGrid.bb-hidden-only-view .mcard-buy-btn:hover{background:#eee !important;}
  /* Staged-for-hide selection state (committed in bulk on "Done") */
  #bbGrid.bb-hide-mode .product-card.mcard-staged-hide{border-color:#EF4444 !important;border-width:2px;box-shadow:0 4px 12px rgba(239,68,68,.15);opacity:1 !important;}
  #bbGrid.bb-hide-mode .product-card.mcard-staged-hide .mcard-buy-btn{background:#EF4444 !important;color:#fff !important;}
  #bbGrid.bb-hide-mode .product-card.mcard-staged-hide .mcard-buy-hide::after{content:' \2713';}

  /* Quick-remove mode grid state (entered/exited via the combined actions dropdown) */
  /* In remove mode, the grid reverses: in-bundle cards become "remove", others dim */
  #bbGrid.bb-remove-mode .product-card:not(.in-bundle){opacity:.45;}
  #bbGrid.bb-remove-mode .product-card.in-bundle{background:rgba(239,68,68,0.08) !important;border-color:#EF4444 !important;}
  body.dark #bbGrid.bb-remove-mode .product-card.in-bundle{background:rgba(239,68,68,0.16) !important;}
  #bbGrid.bb-remove-mode .product-card.in-bundle .mcard-buy-btn{background:#EF4444 !important;color:#fff !important;}
  #bbGrid.bb-remove-mode .product-card.in-bundle .mcard-buy-btn:hover{background:#EF4444 !important;}
  #bbGrid.bb-remove-mode .product-card.in-bundle .mcard-qty-chip{background:#EF4444 !important;color:#fff !important;border-color:#EF4444 !important;}
  .mcard-buy-add{display:inline-flex;align-items:center;gap:4px;}
  .mcard-buy-remove{display:none;align-items:center;gap:4px;}
  #bbGrid.bb-remove-mode .product-card.in-bundle .mcard-buy-add{display:none;}
  #bbGrid.bb-remove-mode .product-card.in-bundle .mcard-buy-remove{display:inline-flex;}
  .bb-remove-btn{
    width:32px;height:32px;border-radius: 12px;border:none;
    background:transparent;color:var(--text-muted);font-size:17px;font-weight:800;
    cursor:pointer;display:flex;align-items:center;justify-content:center;
    flex-shrink:0;padding:0;transition:all .15s;line-height:1;
  }
  .bb-remove-btn:hover{color:#EF4444;background:rgba(239,68,68,0.06);}

  /* Edit pack button in pack summary header */
  /* Item count — was plain muted text under the panel title; moved into the
     header's right-side button cluster (left of Edit pack) and given its own
     pill so it reads as a peer of Clear all / Edit pack rather than a caption. */
  .bb-panel-count-pill {
    background: var(--surface, #F3F4F6);
    color: var(--text-soft, #4B5563);
    border: 1.5px solid var(--border, #E5E7EB);
    border-radius: 20px;
    height: 29px;
    padding: 0 15px;
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    font-family: 'Inter', 'Geist', 'DM Sans', sans-serif;
    font-size: 12.5px;
    font-weight: 700;
    white-space: nowrap;
  }
  body.dark .bb-panel-count-pill {
    background: #1E1E22;
    color: #9CA3AF;
    border-color: #374151;
  }
  @media (max-width: 560px) {
    .bb-panel-head > div:first-child { flex-wrap: wrap; }
    .bb-panel-head > div:first-child > div:last-child {
      width: 100%;
      justify-content: space-between;
    }
  }
  .bb-panel-edit-btn {
    background: var(--surface, #F3F4F6);
    color: var(--text-soft, #4B5563);
    border: 1.5px solid var(--border, #E5E7EB);
    border-radius: 12px;
    height: 29px;
    padding: 0 15px;
    box-sizing: border-box;
    font-family: 'Inter', 'Geist', 'DM Sans', sans-serif;
    font-size: 14px;
    font-weight: 800;
    line-height: 26px;
    cursor: pointer;
    transition: all .15s ease;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .bb-panel-edit-btn:hover {
    background: var(--chip, #E5E7EB);
    color: var(--text, #111827);
    border-color: var(--text-muted, #9CA3AF);
  }
  .bb-panel-edit-btn.active {
    background: rgba(16, 185, 129, 0.08);
    color: #15803D;
    border-color: rgba(16, 185, 129, 0.35);
  }
  body.dark .bb-panel-edit-btn {
    background: #1E1E22;
    color: #9CA3AF;
    border-color: #374151;
  }
  body.dark .bb-panel-edit-btn:hover {
    background: #2A2A2F;
    color: #F3F4F6;
    border-color: #4B5563;
  }
  body.dark .bb-panel-edit-btn.active {
    background: rgba(16, 185, 129, 0.16);
    color: #4ADE80;
    border-color: rgba(52, 211, 153, 0.4);
  }

  /* Clear all button (red outline pill on the left when editing) */
  .bb-clear-all {
    background: rgba(239, 68, 68, 0.08);
    color: #EF4444;
    border: 1.5px solid rgba(239, 68, 68, 0.25);
    border-radius: 20px;
    height: 29px;
    padding: 0 15px;
    box-sizing: border-box;
    font-family: 'Inter', 'Geist', 'DM Sans', sans-serif;
    font-size: 14px;
    font-weight: 800;
    line-height: 26px;
    cursor: pointer;
    transition: all .15s ease;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .bb-clear-all:hover {
    background: #EF4444;
    color: #FFFFFF;
    border-color: #EF4444;
  }

  /* Every selected item uses the same +/- stepper, whether it's a plain
     quantity or an amount-based item (Gems, currency packs) stepping by its
     configured qty_step. Tapping the number itself opens the richer preset/
     custom quantity editor — no separate pencil button needed. */
  .bb-item-stepper {
    display: inline-flex;
    align-items: center;
    height: 34px;
    border: 1.5px solid var(--border, #ECECEC);
    border-radius: 20px;
    background: var(--chip, #F5F2F0);
    overflow: hidden;
    user-select: none;
  }
  .bb-step-btn {
    width: 36px;
    height: 34px;
    border: none;
    background: transparent;
    color: var(--text-soft, #4B5563);
    font-size: 16px;
    font-weight: 800;
    line-height: 1;
    font-family: 'Inter', 'Geist', 'DM Sans', sans-serif;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: background 0.15s ease, color 0.15s ease;
  }
  .bb-step-btn:hover {
    background: var(--border, #ECECEC);
    color: var(--text, #111827);
  }
  .bb-step-val {
    min-width: 34px;
    height: 24px;
    margin: 0 2px;
    padding: 0 6px;
    border: none;
    border-radius: 6px;
    background: var(--bg, #fff);
    box-shadow: inset 0 0 0 1px var(--border, #ECECEC);
    color: var(--text, #111827);
    font-family: 'Inter', 'Geist', 'DM Sans', sans-serif;
    font-size: 13px;
    font-weight: 800;
    text-align: center;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: box-shadow 0.15s ease;
  }
  .bb-step-val:hover {
    box-shadow: inset 0 0 0 1.5px var(--text-muted, #9CA3AF);
  }
  body.dark .bb-item-stepper {
    background: #1E1E22;
    border-color: #26262B;
  }
  body.dark .bb-step-btn {
    color: #9CA3AF;
  }
  body.dark .bb-step-btn:hover {
    background: #26262B;
    color: #F2F2F0;
  }
  body.dark .bb-step-val {
    background: #17171A;
    color: #F2F2F0;
    box-shadow: inset 0 0 0 1px #34343B;
  }
  body.dark .bb-step-val:hover {
    box-shadow: inset 0 0 0 1.5px #6B7280;
  }

  /* Matches the site header's own mobile breakpoint (999.98px, see header.js)
     so the panel switches to its stacked/bottom-sheet layout in lockstep with
     the nav switching to its mobile bar — otherwise there's a dead zone
     (was up to 1280px here vs 768px below) where the desktop nav shows but
     the panel is stuck as a permanent bottom bar overlapping the grid: a
     third, unintended layout that's neither the desktop nor mobile design. */
  @media(max-width:999.98px){
    .bb-wrap{display:block;width:100%;max-width:none;}
    .bb-search-wrap{position:sticky;top:64px;}
    /* Search bar + toolbar buttons form a shrink-to-fit left column that is only
       as wide as the buttons row; the search bar (width:100%) matches that width.
       The Pack box is a flex item that fills all remaining width up to the grid's
       right edge and stretches to the full height of both rows. */
    .bb-search-row{display:flex;flex-wrap:nowrap;align-items:stretch;gap:14px;position:relative;}
    /* The Pack box used to sit beside this column, so it was shrink-to-fit
       (flex:0 1 auto). That box is now a fixed bottom bar, leaving the search +
       buttons column as the row's only content — it takes the full width. */
    .bb-search-left-col{display:flex;flex:1 1 100%;flex-direction:column;gap:8px;min-width:0;}
    .bb-search-inner{width:100%;}
    .bb-search-buttons{width:100%;margin-top:0;}
    /* Keep each toolbar pill on one line (no mid-label break like "Category:" /
       "All"). A wrapping flex container otherwise reports a max-content width at
       which the widest pills break, shrinking the whole left column. With the
       labels held on one line the pills sit at their true width and, when space
       finally runs out on narrow phones, the whole pill wraps to the next row. */
    .bb-search-buttons > *{flex-shrink:0;}
    .bb-search-buttons .bb-panel-icon-btn span,
    .bb-search-buttons .bb-actions-btn span{white-space:nowrap;}
    .bb-left{width:100%;padding-bottom:52vh;}
    .bb-panel{
      position:fixed;bottom:0;left:0;right:0;top:auto;
      height:auto;width:100%;max-height:45vh;
      border:none;border-top:1px solid rgba(0,0,0,0.09);border-radius: 16px;
      box-shadow:0 -4px 24px rgba(0,0,0,0.08);
      margin:0;z-index:100;
    }
    /* Items list must shrink & scroll inside the 45vh sheet — its desktop
       min-height otherwise pushes the footer buttons past the clipped edge */
    .bb-panel .bb-items{flex:1 1 auto;min-height:0;max-height:none;}
    body.dark .bb-panel{border-top-color:rgba(255,255,255,0.06);box-shadow:0 -4px 24px rgba(0,0,0,0.4);}
  }

  /* Custom Limit Modal CSS */
  .bb-modal-overlay {
    position:fixed;inset:0;
    background:transparent;
    backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
    z-index:999999;
    display:none;align-items:center;justify-content:center;
    /* Plain `center` clips whichever end overflows once content (the options
       modal's floating gem art + its full form) is taller than the viewport —
       there's no scrollbar to reach the clipped part since a position:fixed
       box isn't a scroll container on its own. overflow-y turns it into one;
       `safe center` (falls back to the plain `center` above in browsers that
       don't know the keyword) keeps it centered when it fits, but stops
       clipping the top and lets the excess scroll off the bottom instead. */
    overflow-y:auto;
    align-items:safe center;
    padding:20px;
    opacity:0;transition:opacity 0.25s ease;
  }
  .bb-modal-overlay.show {
    display:flex;opacity:1;
  }
  .bb-modal-card {
    position:relative;
    background:var(--white);
    border-radius: 16px;
    padding:32px 36px;
    width:100%;max-width:420px;
    text-align:center;
    border:1.5px solid var(--border);
    box-shadow:0 20px 48px rgba(0,0,0,0.12);
    transform:translateY(24px) scale(0.95);
    transition:transform 0.3s cubic-bezier(0.34,1.3,0.64,1);
    font-family:'Nunito',sans-serif;
  }
  body.dark .bb-modal-card {
    box-shadow:0 20px 48px rgba(0,0,0,0.4);
  }
  .bb-modal-overlay.show .bb-modal-card {
    transform:translateY(0) scale(1);
  }

  /* ── Category editor ─────────────────────────────────────────────────────
     A compact admin tool rather than another full settings screen. The icon
     preview stays in the header so every PNG/emoji/SVG change has immediate visual
     feedback, including at phone widths where the editor becomes a sheet-like
     card inside the existing scroll-safe modal overlay. */
  .bb-category-editor-card{
    max-width:520px;padding:26px;text-align:left;
    max-height:calc(100vh - 40px);max-height:calc(100dvh - 40px);
    overflow-y:auto;overscroll-behavior:contain;
  }
  .bb-category-editor-head{display:flex;align-items:flex-start;justify-content:space-between;gap:18px;padding-right:34px;margin-bottom:22px;}
  .bb-category-editor-head h2{margin:0;color:var(--text);font-family:'Inter','Geist',sans-serif;font-size:21px;font-weight:850;letter-spacing:-.025em;line-height:1.15;}
  .bb-category-editor-head p{margin:6px 0 0;max-width:330px;color:var(--text-muted);font-size:12.5px;font-weight:600;line-height:1.45;}
  .bb-category-icon-preview{
    width:58px;height:58px;flex:0 0 58px;border-radius:15px;
    display:flex;align-items:center;justify-content:center;
    border:1.5px solid rgba(22,163,74,.42);
    background:linear-gradient(145deg,rgba(34,197,94,.13),rgba(22,163,74,.035));
    color:var(--green);font-size:28px;box-shadow:inset 0 1px 0 rgba(255,255,255,.28);
  }
  .bb-category-icon-preview svg{width:29px;height:29px;display:block;color:currentColor;}
  /* Same light-mode knock-down as the sidebar (.packs-cat-icon-image img), so
     the editor previews the icon exactly as the light sidebar will draw it. */
  .bb-category-icon-preview img{width:100%;height:100%;display:block;object-fit:contain;padding:7px;box-sizing:border-box;filter:brightness(0);}
  body.dark .bb-category-icon-preview img{filter:none;}
  .bb-category-icon-preview span{font-size:10px;font-weight:800;color:var(--text-muted);text-align:center;line-height:1.15;}
  .bb-category-icon-preview.is-empty{border-color:var(--border);background:var(--bg);box-shadow:none;}
  .bb-category-icon-preview.is-invalid{border-color:rgba(239,68,68,.45);background:rgba(239,68,68,.08);}
  .bb-category-icon-preview.is-invalid span{color:#DC2626;}
  .bb-category-editor-field{display:flex;flex-direction:column;gap:7px;margin-bottom:18px;}
  .bb-category-editor-field > span,
  .bb-category-editor-label-row strong{color:var(--text);font-size:12px;font-weight:850;letter-spacing:.01em;}
  .bb-category-editor-field input,
  .bb-category-emoji-input,
  .bb-category-svg-body textarea{
    width:100%;border:1.5px solid var(--border);border-radius:11px;
    background:var(--bg);color:var(--text);font:700 14px/1.4 'Nunito','Inter',sans-serif;
    outline:none;transition:border-color .15s,box-shadow .15s,background .15s;
  }
  .bb-category-editor-field input{height:43px;padding:0 13px;}
  .bb-category-emoji-input{height:43px;padding:0 13px;font-size:19px;text-align:left;}
  .bb-category-editor-field input:focus,
  .bb-category-emoji-input:focus,
  .bb-category-svg-body textarea:focus{border-color:var(--green);box-shadow:0 0 0 3px rgba(22,163,74,.12);}
  .bb-category-editor-section{padding:15px;border:1px solid var(--border);border-radius:13px;background:color-mix(in srgb,var(--bg) 78%,transparent);}
  .bb-category-editor-label-row{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:11px;}
  .bb-category-editor-label-row > div{display:flex;flex-direction:column;gap:2px;}
  .bb-category-editor-label-row span{color:var(--text-muted);font-size:11.5px;font-weight:600;}
  .bb-category-icon-clear{border:0;background:transparent;color:var(--text-muted);font:800 11px/1 'Nunito',sans-serif;cursor:pointer;padding:5px;border-radius:7px;}
  .bb-category-icon-clear:hover{background:rgba(239,68,68,.09);color:#DC2626;}
  .bb-category-png-drop{border:1.5px dashed color-mix(in srgb,var(--border) 82%,var(--text-muted));border-radius:11px;background:var(--card-bg);transition:border-color .15s,background .15s,box-shadow .15s;overflow:hidden;}
  .bb-category-png-drop.is-dragging{border-color:var(--green);background:rgba(22,163,74,.07);box-shadow:0 0 0 3px rgba(22,163,74,.1);}
  .bb-category-png-choose{width:100%;min-height:68px;padding:12px;border:0;background:transparent;color:var(--text);display:flex;align-items:center;gap:11px;text-align:left;cursor:pointer;font-family:'Nunito','Inter',sans-serif;}
  .bb-category-png-choose:hover{background:rgba(22,163,74,.045);}
  .bb-category-png-upload-icon{width:36px;height:36px;border-radius:10px;display:grid;place-items:center;flex:0 0 36px;color:var(--green);background:rgba(22,163,74,.1);border:1px solid rgba(22,163,74,.18);}
  .bb-category-png-choose > span:last-child{display:flex;flex-direction:column;gap:2px;min-width:0;}
  .bb-category-png-choose strong{font-size:12.5px;font-weight:850;color:var(--text);}
  .bb-category-png-choose small{font-size:10.5px;font-weight:650;color:var(--text-muted);line-height:1.35;}
  .bb-category-png-meta{min-height:31px;padding:7px 11px;border-top:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;gap:10px;color:var(--text-muted);font-size:10.5px;font-weight:700;box-sizing:border-box;}
  .bb-category-png-meta span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .bb-category-png-meta button{border:0;background:transparent;color:#DC2626;font:800 10.5px/1 'Nunito',sans-serif;cursor:pointer;padding:3px 0;}
  .bb-category-png-meta button:hover{color:#EF4444;}
  .bb-category-icon-picks{display:grid;grid-template-columns:repeat(10,minmax(0,1fr));gap:6px;margin-top:9px;}
  .bb-category-icon-picks button{
    aspect-ratio:1;border:1px solid var(--border);border-radius:9px;background:var(--card-bg);
    display:flex;align-items:center;justify-content:center;padding:0;font-size:18px;cursor:pointer;
    transition:transform .12s,border-color .12s,background .12s;
  }
  .bb-category-icon-picks button:hover{transform:translateY(-1px);border-color:rgba(22,163,74,.5);background:rgba(22,163,74,.08);}
  .bb-category-icon-picks button:focus-visible{outline:2px solid var(--green);outline-offset:2px;}
  .bb-category-svg-details{margin-top:12px;border:1px solid var(--border);border-radius:11px;background:var(--card-bg);}
  .bb-category-svg-details summary{padding:12px 14px;color:var(--text-soft);font-size:12px;font-weight:800;cursor:pointer;user-select:none;}
  .bb-category-svg-details[open] summary{border-bottom:1px solid var(--border);color:var(--text);}
  .bb-category-svg-body{padding:12px;}
  .bb-category-emoji-body{display:flex;flex-direction:column;gap:0;}
  .bb-category-svg-body textarea{display:block;min-height:104px;padding:10px 11px;resize:vertical;font:600 11px/1.45 ui-monospace,SFMono-Regular,Consolas,monospace;}
  .bb-category-svg-body p{margin:7px 1px 0;color:var(--text-muted);font-size:10.5px;font-weight:600;line-height:1.4;}
  .bb-category-svg-body code{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;color:var(--text-soft);}
  .bb-category-editor-error{display:none;margin-top:12px;padding:9px 11px;border:1px solid rgba(239,68,68,.28);border-radius:9px;background:rgba(239,68,68,.08);color:#DC2626;font-size:12px;font-weight:750;line-height:1.35;}
  .bb-category-editor-error.show{display:block;}
  .bb-category-editor-actions{margin-top:18px;}
  body.dark .bb-category-editor-section{background:rgba(255,255,255,.018);}
  body.dark .bb-category-icon-preview{box-shadow:inset 0 1px 0 rgba(255,255,255,.07);}
  body.dark .bb-category-icon-picks button{background:#19191D;}
  body.dark .bb-category-icon-picks button:hover{background:rgba(34,197,94,.1);}
  body.dark .bb-category-png-drop{background:#151518;}
  body.dark .bb-category-png-choose:hover{background:rgba(34,197,94,.055);}
  body.dark .bb-category-editor-error{color:#FCA5A5;}
  @media(max-width:560px){
    .bb-category-editor-card{padding:22px 17px 18px;border-radius:15px;}
    .bb-category-editor-head{gap:12px;padding-right:30px;margin-bottom:18px;}
    .bb-category-editor-head h2{font-size:19px;}
    .bb-category-icon-preview{width:52px;height:52px;flex-basis:52px;border-radius:13px;}
    .bb-category-png-choose{min-height:72px;padding:12px 10px;}
    .bb-category-png-choose small{white-space:normal;}
    .bb-category-icon-picks{grid-template-columns:repeat(5,minmax(0,1fr));gap:8px;}
    .bb-category-icon-picks button{min-height:42px;aspect-ratio:auto;font-size:19px;}
  }

  /* Warning banner (options modal / basket warning modal) */
  .bb-warn-box{
    padding:10px 12px;background:rgba(234,179,8,0.07);border:1.5px solid rgba(234,179,8,0.25);
    border-radius:10px;font-size:13px;font-weight:600;color:#92400e;line-height:1.45;white-space:normal;
    text-align:left;
  }
  body.dark .bb-warn-box{background:rgba(234,179,8,0.1);border-color:rgba(234,179,8,0.22);color:#fbbf24;}
  .bb-warn-icon-circle{
    width:22px;height:22px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;
    background:rgba(217,119,6,0.14);
  }
  .bb-warn-icon-circle svg{color:#d97706;}
  body.dark .bb-warn-icon-circle{background:rgba(251,191,36,0.15);}
  body.dark .bb-warn-icon-circle svg{color:#fbbf24;}
  .bb-warn-notice-wrap{margin:0 0 12px;padding-top:12px;border-top:1px solid rgba(0,0,0,0.07);}
  body.dark .bb-warn-notice-wrap{border-top-color:rgba(255,255,255,0.06);}
  .bb-warn-notice{
    width:100%;display:flex;align-items:center;gap:8px;padding:12px 14px;
    background:rgba(234,179,8,0.1);border:1.5px solid rgba(234,179,8,0.35);border-radius:10px;
    font-family:'Geist','Nunito',sans-serif;font-size:14px;font-weight:700;color:#92400e;
  }
  .bb-warn-notice svg{flex-shrink:0;color:#d97706;}
  .bb-warn-notice span{flex:1;text-align:left;}
  body.dark .bb-warn-notice{background:rgba(234,179,8,0.14);border-color:rgba(234,179,8,0.32);color:#fbbf24;}
  body.dark .bb-warn-notice svg{color:#fbbf24;}

  .bb-item-actions{display:contents;}

  .bb-modal-icon {
    font-size:48px;margin-bottom:16px;
  }
  .bb-modal-title {
    font-size:22px;font-weight:900;margin-bottom:8px;
    color:var(--text);
  }
  .bb-modal-desc {
    font-size:14px;font-weight:600;line-height:1.5;
    color:var(--text-soft);margin-bottom:24px;
  }
  .bb-modal-btns {
    display:flex;gap:12px;
  }
  .bb-modal-btn {
    flex:1;padding:12px;border-radius:12px;border:none;
    font-size:15px;font-weight:800;cursor:pointer;
    font-family:inherit;transition:all 0.15s;outline:none;
  }
  .bb-modal-btn-confirm {
    background:#16A34A;color:#fff;
  }
  .bb-modal-btn-confirm:hover {
    background:#15803D;transform:translateY(-1px);
    box-shadow:0 4px 12px rgba(61,139,106,0.25);
  }
  .bb-modal-btn-confirm:disabled {
    background:#9CA3AF;cursor:not-allowed;transform:none;box-shadow:none;
  }
  .bb-modal-btn-cancel {
    background:#E5E7EB;color:#4B5563;
  }
  .bb-modal-btn-cancel:hover {
    background:#D1D5DB;transform:translateY(-1px);
  }
  body.dark .bb-modal-btn-cancel {
    background:#2D2D30;color:#9CA3AF;
  }
  body.dark .bb-modal-btn-cancel:hover {
    background:#3F3F46;
  }

  /* ── Toasts ── */
  /* Card look and container position are shared from styles.css (bottom-right,
     consistent with every other page); this file only keeps its own entrance
     animation. */
  .toast { animation: toastSlideUp 0.35s cubic-bezier(0.34, 1.3, 0.64, 1); }
  @keyframes toastSlideUp {
    from { transform: translateY(20px) scale(0.9); opacity: 0; }
    to { transform: translateY(0) scale(1); opacity: 1; }
  }

  /* Type Switcher */
  .bb-type-switcher {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 20px;
    margin: 16px 0 24px 0;
    flex-wrap: wrap;
  }
  .bb-type-btn {
    position: relative;
    padding: 6px 4px;
    border: none;
    border-radius: 12px;
    background: transparent;
    color: var(--text-soft);
    font-size: 17px;
    font-weight: 800;
    cursor: pointer;
    transition: all 0.2s;
    font-family: 'Geist', 'DM Sans', sans-serif;
  }
  .bb-type-btn:hover {
    color: var(--text);
    background: transparent;
    transform: none;
  }
  .bb-type-btn.active {
    color: var(--accent);
  }
  body.dark .bb-type-btn.active { color:var(--accent); }
  
  .sliding-underline {
    position: absolute;
    left: 0;
    bottom: -15px;
    height: 3px;
    background: var(--accent);
    border-radius: 3px;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    pointer-events: none;
    z-index: 10;
  }
  body.dark .bb-type-btn:hover { background: transparent; color: #fff; }

  /* ── Currency amount picker (used in the "choose amount" modal) ── */
  .curr-desc {
    font-size: 13px;
    color: var(--text-soft);
    font-weight: 500;
    line-height: 1.4;
    text-align: left;
  }
  /* Pills container */
  .curr-pills-wrap {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    margin-top: 4px;
  }
  .curr-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 32px;
    padding: 0 14px;
    border-radius: 99px;
    border: 1.5px solid var(--border);
    background: var(--bg);
    color: var(--text-soft);
    font-family: 'Geist', 'DM Sans', sans-serif;
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
    transition: all 0.15s ease;
    user-select: none;
  }
  .curr-pill:hover {
    border-color: var(--text-muted);
    color: var(--text);
  }
  .curr-pill.active {
    background: var(--text);
    color: var(--white);
    border-color: var(--text);
  }
  body.dark .curr-pill.active {
    background: var(--text);
    color: var(--white);
    border-color: var(--text);
  }
  /* Custom input wrap */
  .curr-custom-wrap {
    display: inline-flex;
    align-items: center;
    gap: 8px;
  }
  .curr-custom-input {
    width: 100px;
    height: 32px;
    border-radius: 99px;
    border: 1.5px solid var(--accent);
    background: var(--white);
    color: var(--text);
    font-family: inherit;
    font-size: 12px;
    font-weight: 700;
    padding: 0 12px;
    outline: none;
    transition: all 0.15s ease;
  }
  body.dark .curr-custom-input {
    background: #0f0f11;
  }
  .curr-custom-input:focus {
    box-shadow: 0 0 0 3px rgba(22,163,74,0.15);
  }
  .curr-owned-label {
    font-family: 'Geist', 'DM Sans', sans-serif;
    font-size: 10px;
    font-weight: 800;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
  }
  .curr-owned-val {
    font-family: 'Geist', 'DM Sans', sans-serif;
    font-size: 16px;
    font-weight: 900;
    color: var(--accent-deep);
  }
  body.dark .curr-owned-val {
    color: #4ade80;
  }
  .curr-price-display {
    font-family: 'DM Sans', sans-serif;
    font-size: 20px;
    font-weight: 900;
    color: var(--text);
  }
  .curr-action-btn {
    height: 36px;
    padding: 0 16px;
    border-radius: var(--radius-sm);
    border: none;
    background: var(--accent);
    color: #fff;
    font-family: 'Nunito', sans-serif;
    font-size: 13px;
    font-weight: 800;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    transition: all 0.15s ease;
  }
  .curr-action-btn:hover {
    opacity: 0.9;
    transform: translateY(-1px);
  }
  .curr-action-btn.in-bundle {
    background: transparent;
    border: 1.5px solid var(--accent);
    color: var(--accent);
  }
  .curr-action-btn.in-bundle:hover {
    background: rgba(22,163,74,0.06);
  }
  .curr-cart-btn {
    height: 32px;
    padding: 0 14px;
    border-radius: var(--radius-sm);
    border: 1.5px solid var(--accent);
    background: transparent;
    color: var(--accent);
    font-family: 'Nunito', sans-serif;
    font-size: 12px;
    font-weight: 800;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    transition: all 0.15s ease;
    white-space: nowrap;
  }
  .curr-cart-btn:hover {
    background: var(--accent);
    color: #fff;
    transform: translateY(-1px);
  }
  .curr-cart-btn.in-cart {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
  }
  .currencies-layout .mcard-media-action {
    display: none !important;
  }
  .currencies-layout .own-badge-pill {
    display: none !important;
  }
  .currencies-layout .bc-qty-badge {
    display: none !important;
  }

  /* ── Options picker modal (amount/currency chooser) ──────────────────── */
  .bb-modal-close {
    position: absolute; top: 16px; right: 16px;
    width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
    border: none; background: transparent; color: var(--text-muted);
    display: flex; align-items: center; justify-content: center;
    cursor: pointer; transition: all 0.15s;
  }
  .bb-modal-close:hover { background: var(--bg); color: var(--text); }

  .bb-amt-label {
    font-size: 11.5px; font-weight: 800; text-transform: uppercase;
    letter-spacing: .07em; color: var(--text-muted); flex-shrink: 0;
  }
  .bb-amt-row { display: flex; flex-direction: column; align-items: center; gap: 10px; }

  /* Centered header — no card intentionally left static here: .bb-opt-modal-img
     positions itself absolute against .bb-opt-modal-card (the nearest
     positioned ancestor — this wrapper stays position:static on purpose so it
     doesn't intercept that), straddling the card's top border half in/half
     out. padding-top below reserves room for the half of the image that
     dips down into the card. */
  .bb-opt-modal-header {
    display: flex; flex-direction: column; align-items: center;
    gap: 10px; margin-bottom: 22px; padding: 130px 8px 0;
  }
  .bb-opt-modal-img {
    position: absolute; top: 0; left: 50%;
    transform: translate(-50%, -50%);
    width: 230px; height: 230px; object-fit: contain;
    display: block; background: none;
    filter: drop-shadow(0 10px 22px rgba(0,0,0,0.28));
  }
  .bb-opt-modal-name {
    display: flex; align-items: center; justify-content: center; gap: 7px;
    font-size: 24px; font-weight: 900; color: var(--text);
    max-width: 100%;
  }
  .bb-opt-modal-name-text {
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .bb-opt-modal-sub { font-size: 15px; font-weight: 600; color: var(--text-muted); }

  /* Phones: the 230px floating gem art (plus its 130px reserved header
     padding) is what was pushing the options modal past the viewport top —
     shrink both so the whole card (art, pills, price, buttons) has a real
     chance of fitting without relying on the overlay's scroll fallback. */
  @media (max-width: 640px) {
    .bb-opt-modal-img { width: 150px; height: 150px; }
    .bb-opt-modal-header { padding: 84px 8px 0; margin-bottom: 14px; }
  }

  /* Amount pills — bigger, centered buttons that fill the popup's width
     rather than a cramped row of bare numbers, so picking "50" doesn't look
     identical to picking "1". Prices are intentionally left off these — the
     Price box below is the one place the actual cost is shown. */
  #bbOptModalPills.curr-pills-wrap {
    margin-top: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(88px, 1fr));
    justify-content: center;
    gap: 10px;
    width: 100%;
  }
  #bbOptModalPills .curr-pill {
    height: 60px;
    padding: 8px 10px;
    border-radius: 14px;
  }
  #bbOptModalPills .curr-pill-amt {
    font-size: 16px;
    font-weight: 800;
  }
  #bbOptModalPills .curr-pill.active {
    background: color-mix(in srgb, var(--accent) 12%, transparent);
    color: var(--accent);
    border-color: var(--accent);
    border-width: 2px;
  }
  body.dark #bbOptModalPills .curr-pill.active { background: rgba(22,163,74,0.15); }

  /* The quantity input sits open beneath the presets at all times — presets are
     shortcuts that fill it, never a mode you have to leave to type a number. */
  .bb-amt-custom-inline { display: flex; align-items: center; gap: 8px; width: 100%; }
  .bb-amt-input-wrap { position: relative; display: flex; align-items: center; flex: 1; min-width: 0; }
  .bb-amt-input {
    width: 100%; height: 34px; border-radius: 10px; box-sizing: border-box;
    border: 1.5px solid var(--border); background: var(--bg); color: var(--text);
    font-family: inherit; font-size: 14px; font-weight: 700;
    padding: 0 26px 0 12px; outline: none; transition: all 0.15s;
    text-align: center;
  }
  .bb-amt-input-big { height: 52px; font-size: 20px; border-radius: 14px; }
  .bb-amt-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(22,163,74,0.12); }
  body.dark .bb-amt-input { background: rgba(255,255,255,0.05); }
  .bb-amt-spinner {
    position: absolute; right: 5px; top: 50%; transform: translateY(-50%);
    display: flex; flex-direction: column; gap: 1px;
  }
  .bb-amt-spinner button {
    width: 16px; height: 14px; border: none; background: transparent; color: var(--text-muted);
    cursor: pointer; display: flex; align-items: center; justify-content: center;
    padding: 0; border-radius: 3px;
  }
  .bb-amt-spinner button:hover { color: var(--text); background: var(--border); }

  .bb-price-box {
    display: flex; align-items: center; justify-content: space-between;
    background: var(--bg); border-radius: 14px; padding: 14px 16px;
  }
  body.dark .bb-price-box { background: rgba(255,255,255,0.05); }

  /* ── Filter panel ─────────────────────────────────────────────────────── */
  .bb-filter-overlay {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 4000;
    background: rgba(10,8,20,0.28);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
  }
  .bb-filter-overlay.open { display: block; }

  .bb-filter-panel {
    display: none;
    position: fixed;
    z-index: 4001;
    background: #FFFFFF;
    border: 1.5px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 20px 60px -12px rgba(20,20,30,0.3), 0 4px 16px rgba(20,20,30,0.08);
    width: 340px;
    max-height: calc(100vh - 100px);
    overflow-y: auto;
    overflow-x: hidden;
    font-family: 'Geist','DM Sans',sans-serif;
    scrollbar-width: thin;
  }
  body.dark .bb-filter-panel {
    background: #141416;
    border-color: #26262B;
    box-shadow: 0 20px 60px -12px rgba(0,0,0,0.6);
  }
  .bb-filter-panel.open { display: block; }

  .bb-fp-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 18px 14px;
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    background: inherit;
    z-index: 1;
    border-radius: 18px 18px 0 0;
  }
  .bb-fp-title {
    font-size: 14px;
    font-weight: 700;
    color: var(--text);
    letter-spacing: -0.01em;
  }
  .bb-fp-close {
    width: 26px; height: 26px; border-radius: 50%;
    border: none; background: rgba(0,0,0,0.06);
    color: var(--text-muted); font-size: 13px; font-weight: 700;
    cursor: pointer; display: flex; align-items: center; justify-content: center;
    transition: background 0.15s;
    flex-shrink: 0;
  }
  .bb-fp-close:hover { background: rgba(0,0,0,0.12); color: var(--text); }
  body.dark .bb-fp-close { background: rgba(255,255,255,0.08); }
  body.dark .bb-fp-close:hover { background: rgba(255,255,255,0.15); }

  .bb-fp-section {
    padding: 14px 18px;
    border-bottom: 1px solid var(--border);
  }
  .bb-fp-section:last-child { border-bottom: none; }
  .bb-fp-label {
    font-size: 10px;
    font-weight: 800;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.07em;
    margin-bottom: 10px;
  }
  .bb-fp-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
  }
  .bb-fp-pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 30px;
    padding: 0 12px;
    border-radius: 999px;
    border: 1.5px solid var(--border);
    background: var(--white);
    font-family: 'Geist','DM Sans',sans-serif;
    font-size: 12px;
    font-weight: 600;
    color: #6B6B7B;
    cursor: pointer;
    transition: all 0.15s ease;
    white-space: nowrap;
    user-select: none;
  }
  .bb-fp-pill:hover {
    border-color: #AFAFAF;
    color: var(--text);
  }
  .bb-fp-pill.active {
    background: var(--text);
    color: #fff;
    border-color: var(--text);
  }
  body.dark .bb-fp-pill {
    background: #1d1c24;
    border-color: #2E2E34;
    color: #888890;
  }
  body.dark .bb-fp-pill:hover {
    border-color: #888890;
    color: #F2F2F0;
  }
  body.dark .bb-fp-pill.active {
    background: #F2F2F0;
    color: #0E0E10;
    border-color: #F2F2F0;
  }
  .bb-subcat-del-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 14px;
    height: 14px;
    padding: 0;
    margin: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: inherit;
    opacity: 0.55;
    font-size: 10px;
    line-height: 1;
    cursor: pointer;
  }
  .bb-subcat-del-btn:hover {
    opacity: 1;
    background: rgba(239,68,68,0.18);
    color: #ef4444;
  }
  .bb-fp-pill-manage {
    cursor: grab;
  }
  .bb-fp-pill-manage:active {
    cursor: grabbing;
  }
  .bb-subcat-drag-handle {
    opacity: 0.45;
    font-size: 12px;
    line-height: 1;
    cursor: grab;
  }
  .bb-subcat-name {
    cursor: text;
  }
  .bb-subcat-name:hover {
    text-decoration: underline;
    text-decoration-style: dotted;
  }
  .bb-subcat-rename-input {
    font: inherit;
    color: inherit;
    background: rgba(0,0,0,0.06);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 1px 6px;
    width: 90px;
  }
  body.dark .bb-subcat-rename-input {
    background: rgba(255,255,255,0.08);
  }
  /* Special colour pills */
  .bb-fp-pill.owned-pill.active {
    background: #f0fdf4;
    color: #16A34A;
    border-color: #16A34A;
  }
  body.dark .bb-fp-pill.owned-pill.active {
    background: rgba(22,163,74,.12);
    color: #22C55E;
    border-color: #22C55E;
  }

  .bb-fp-footer {
    padding: 12px 18px;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    border-top: 1px solid var(--border);
  }
  .bb-fp-reset {
    font-family: 'Geist','DM Sans',sans-serif;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
    background: none;
    border: none;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 6px;
    transition: all 0.15s;
    text-decoration: underline;
    text-underline-offset: 2px;
  }
  .bb-fp-reset:hover { color: #EF4444; text-decoration-color: #EF4444; }
  /* Danger variant — used only where the button's mere presence already means
     something is selected (e.g. the sub-category Clear link, which only
     renders once _activeSubcats is non-empty), so it should read as red by
     default instead of waiting for hover like Reset/Sort A-Z do. */
  .bb-fp-reset.bb-fp-reset-danger { color: #EF4444; text-decoration-color: #EF4444; }
  .bb-fp-reset.bb-fp-reset-danger:hover { color: #DC2626; text-decoration-color: #DC2626; }
  body.dark .bb-fp-reset.bb-fp-reset-danger { color: #F87171; text-decoration-color: #F87171; }
  body.dark .bb-fp-reset.bb-fp-reset-danger:hover { color: #FCA5A5; text-decoration-color: #FCA5A5; }

  /* Filter button badge */
  .bb-filter-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 16px;
    height: 16px;
    border-radius: 999px;
    background: var(--text);
    color: var(--bg);
    font-size: 10px;
    font-weight: 800;
    padding: 0 4px;
    margin-left: 2px;
    line-height: 1;
  }

  @media (max-width: 600px) {
    .bb-filter-panel {
      position: fixed;
      left: 12px !important;
      right: 12px !important;
      top: auto !important;
      bottom: 16px !important;
      width: auto;
    }
  }

  /* ── Phones: let the toolbar wrap ──
     The @media(max-width:768px) block near the top of this file already asks
     .bb-search-row to wrap, but the @media(max-width:999.98px) block above sets
     it back to nowrap and wins on source order at phone widths. Its nowrap is
     right for tablets — the search column and the Pack box sit side by side —
     but on a 375px screen the buttons row needs ~392px and pushed the document
     72px wider than the viewport, scrolling every builder page sideways.
     Re-asserted here, after that block, so tablets keep their layout. */
  @media (max-width: 768px) {
    .bb-search-row{flex-wrap:wrap;}
    .bb-search-left-col{flex:1 1 100%;min-width:0;}
    .bb-search-buttons{flex-wrap:wrap;min-width:0;}
  }

  /* ── Skeleton shimmer cards (shown while products load for the first time) ── */
  .bb-skeleton-card { pointer-events: none; cursor: default !important; }
  /* Sidebar category skeleton rows — sized to match a real .packs-cat-item button
     so swapping in the loaded categories doesn't shift the sidebar's height */
  .bb-cat-skel { display: flex; align-items: center; width: 100%; padding: 9px 10px; box-sizing: border-box; }

  /* ── Phone: top-right Pack button + slide-up sheet (replaces the big bottom panel) ──
     Same 999.98px breakpoint as the .bb-wrap block above — this and that block
     together make up the one "mobile" layout; keeping them in lockstep is the
     whole point (see comment there for why the old 768/1280 split was broken). */
  .bb-pack-fab{display:none !important;}
  .bb-pack-sheet-backdrop{display:none;}
  @media (max-width: 999.98px) {
    /* Card floor is 100px, three-plus to a row on a normal 360-430px phone
       (the previous 132px floor gave just two, each nearly half the screen).
       The foot bar's chips shrink further below to still fit at this width —
       the sync chip's own overflow:ellipsis is what absorbs a long owned
       count ("909,014") now, rather than the card being wide enough to never
       need it. Very narrow (~320-340px) phones fall back to two columns on
       their own since 1fr can't shrink a track below its floor. */
    .product-grid{grid-template-columns:repeat(auto-fill,minmax(100px,1fr)) !important;gap:6px !important;}
    /* A grid item's automatic minimum is its min-content width, which overrides
       the track size — that is HOW the unshrinkable chips above dragged cards
       past the right edge of the page. min-width:0 caps that for good, so a
       future wide chip clips inside its card instead of widening the grid. */
    .product-grid > *{min-width:0 !important;}
    /* Chips scaled down to match the smaller card, and the sync chip may now
       shrink/ellipsis rather than overflow if a number is longer still. */
    .mcard-foot-bar{gap:4px !important;min-height:34px !important;}
    .mcard-sync-chip{
      font-size:11px !important;padding:4px 7px !important;gap:3px !important;
      min-width:0 !important;overflow:hidden !important;
      text-overflow:ellipsis !important;white-space:nowrap !important;
    }
    .mcard-sync-chip svg{width:10px !important;height:10px !important;}
  .mcard-qty-chip{font-size:11px !important;padding:4px 8px !important;}
    /* Shorter than the 1/1 this used to be — that made each card's image
       alone nearly as tall as the whole viewport is wide, so two rows of
       cards barely fit on screen without a lot of scrolling. Card WIDTH
       (the grid's 132px floor, see above) is untouched — this only trims
       vertical footprint. */
    .product-card-img{aspect-ratio:4/3 !important;border-radius: 16px;}
    .product-card-img img{padding:8px !important;}
    /* Flush against the card's left edge otherwise — desktop's gap:8px on
       .mcard-name-row only spaces it from the NAME after it, not from the
       card edge before it. NOTE: no top/right offset here — this pill is
       position:relative (inline in the name row, see the base
       .product-card .pp-starred-pill rule), so a top/right offset shifts it
       out of its own row without pushing the foot-bar row down to match,
       which is what made the star visually overlap the sync chip below it.
       Sized down further than before too — the base 44x40px pill was nearly
       half the width of a ~100px card. */
    .product-card .pp-starred-pill{
      margin-left:4px !important;padding:0 !important;
      width:26px !important;min-width:26px !important;height:26px !important;
    }
    .product-card .pp-starred-pill svg,
    .product-card .pp-starred-pill .pp-star-ico{width:14px !important;height:14px !important;}
    /* The "+ Add" overlay is a desktop hover affordance. On touch devices :hover
       can get stuck "on" after a tap, and its fixed 38px height eats over a
       third of these small square images — tapping the card already adds the
       item via its own onclick, so the overlay is redundant here anyway. */
    .mcard-media-action{display:none !important;}
    /* min-height, not height — same reason as the desktop rule: a hard height
       clipped the foot bar off the bottom of starred cards, which grow by the
       Starred pill's row. Row's own min-height shrinks to match the smaller
       26px star pill above (was sized for the 40px desktop pill). */
    .mcard-name-row{min-height:26px !important;gap:5px !important;}
    .mcard-body{padding:6px 7px 12px !important;height:auto !important;min-height:78px !important;}
    /* .mcard-foot-bar bleeds edge-to-edge via a negative margin sized to match
       .mcard-body's own padding — the desktop padding is 11px/11px (h/bottom),
       but mobile shrinks that to 7px/12px above, so the un-adjusted -11px bleed
       overshoots the card's real edge and gets clipped by mcard-body's
       overflow:hidden, cutting off the right-aligned qty chip ("0"). */
    .mcard-foot-bar{margin:auto -7px -12px !important;padding:6px 7px !important;}
    /* Was 13.5px — read small next to a ~132px card, especially against the
       16px desktop size these cards otherwise inherited everything else from.
       Trimmed again for the narrower 100px floor above. */
    .mcard-name{font-size:12.5px !important;line-height:1.25 !important;}
    /* Pack builder: hidden bottom sheet, toggled by the top-right button */
    .bb-panel{
      transform:translateY(106%);
      opacity:1;
      transition:transform .34s cubic-bezier(.4,0,.2,1), opacity .24s ease, min-height .32s cubic-bezier(.34,1.1,.64,1) !important;
      /* svh, NOT dvh. dvh is the LIVE viewport height, and on a phone it changes
         every time the browser's own chrome moves — the URL bar collapsing on
         scroll, the toolbar sliding back in, the bar that appears when a
         screenshot is taken. Each of those resized this sheet mid-scroll, which
         shortened .bb-items (the flex:1 scroll container inside it) and made the
         browser clamp its scrollTop — the list visibly jumped back to the top,
         over and over, while someone was trying to read down a 75-item pack.
         svh is the height with the chrome SHOWN and is a fixed number: the sheet
         never resizes itself, so nothing ever clamps the scroll. The cost is a
         sheet slightly shorter than the screen while the toolbars are hidden,
         which is the right trade for a list that stays where it is put.
         Both bounds move together so min can never exceed max. */
      height:auto !important;
      min-height:50vh;min-height:50svh;
      max-height:78vh !important;max-height:78svh !important;
      border-top:none !important;border-radius:var(--radius) var(--radius) 0 0 !important;
      box-shadow:0 -10px 44px rgba(0,0,0,.28) !important;
      z-index:1075 !important;overflow:hidden !important;overscroll-behavior:contain;
    }
    /* Compact empty state so it doesn't push sheet above the 52vh floor */
    .bb-empty{padding:10px 16px 6px !important;gap:6px !important;}
    .bb-empty .bb-empty-icon-middle svg{width:38px !important;height:38px !important;}
    .bb-empty .bb-empty-icon-middle{margin-bottom:0 !important;}
    .bb-panel.bb-sheet-open{transform:translateY(0) !important;}
    /* Live finger-follow while dragging the handle — .bb-panel-head listens
       for the touch, see builder.js. Reads a JS-set custom property rather
       than a plain inline transform because the open-state rule above is
       !important and would otherwise always win over an inline style. */
    .bb-panel.bb-sheet-open.bb-sheet-dragging{
      transition:none !important;
      transform:translateY(var(--bb-drag-y,0px)) !important;
      opacity:var(--bb-drag-opacity,1) !important;
      will-change:transform,opacity;
    }
    .bb-panel.bb-sheet-open.bb-sheet-settling{
      transform:translateY(0) !important;
      opacity:1 !important;
      transition:transform .4s cubic-bezier(.2,.82,.2,1), opacity .28s ease !important;
    }
    .bb-panel.bb-sheet-open.bb-sheet-dismissing-down{
      transform:translateY(calc(100% + env(safe-area-inset-bottom, 0px) + 20px)) !important;
      opacity:.82 !important;
      transition:transform .3s cubic-bezier(.4,0,.7,.2), opacity .24s ease !important;
      pointer-events:none;
    }
    /* Listings no longer reserve half the screen — just clear the fixed pack bar */
    .bb-left{padding-bottom:calc(92px + env(safe-area-inset-bottom, 0px)) !important;}

    /* ── Pack summary: fixed full-width bottom action bar ──
       It used to be a flex item wedged into .bb-search-row, where it competed
       with search/filter/sort for toolbar width and scrolled away with the
       toolbar. It's the primary action on this page, so it gets a permanent
       thumb-height slot at the bottom of the viewport instead. Tapping anywhere
       on the bar opens the .bb-panel sheet. */
    .bb-pack-fab {
      display: flex !important;
      position: fixed !important;
      left: 0; right: 0; bottom: 0; top: auto;
      width: 100% !important; z-index: 1060;
      /* One row: title + count on the left, View pill on the right. */
      flex-direction: row !important;
      align-items: center !important;
      justify-content: space-between !important;
      gap: 12px !important;
      /* .bb-panel-icon-btn pins height:38px — this bar sizes to its content. */
      height: auto !important;
      min-width: 0 !important;
      padding: 20px 16px calc(20px + env(safe-area-inset-bottom, 0px)) !important;
      border: none !important;
      border-top: 1px solid rgba(0, 0, 0, 0.07) !important;
      border-radius: 16px;
      background: #ffffff !important;
      color: var(--text) !important;
      /* <button> doesn't inherit the page font — force the site's DM Sans so the
         bar doesn't fall back to the ugly browser-default button font. */
      font-family: 'DM Sans', sans-serif !important;
      font-weight: 700 !important;
      box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.08) !important;
      animation: none !important;
      transform: translateY(0);
      transition: transform .3s cubic-bezier(.4, 0, .2, 1) !important;
    }
    /* Slide the bar away under whichever sheet is up — the pack sheet carries
       its own checkout buttons, and the category sheet shouldn't have a stray
       bar peeking out below it.
       bb-filter-sheet-open (Filter/Sort/Actions — see bbToggleSortDrop et al.
       in builder.js) was missing from this list: the Sort/Filter/Actions
       bottom sheet is ALSO position:fixed;bottom:0, occupying the exact same
       screen region as this fab bar, so without this the fab bar sat there
       un-hidden underneath/behind the sheet's slide-up animation instead of
       getting out of the way first — the two fixed-bottom elements briefly
       fighting for the same space is what read as the sort dropdown
       "glitching". */
    body.bb-sheet-active .bb-pack-fab,
    body.bb-cat-sheet-open .bb-pack-fab,
    body.bb-filter-sheet-open .bb-pack-fab {
      transform: translateY(100%);
    }
    @media (prefers-reduced-motion: reduce){
      .bb-pack-fab{transition:none !important;}
    }
    /* Left side: "Your Pack Summary" with the item count right beside it */
    .bb-pack-fab-info {
      display: flex; flex-direction: column; align-items: flex-start;
      justify-content: center; gap: 2px; flex: 1; min-width: 0; text-align: left;
    }
    .bb-pack-fab-title {
      font-family: 'DM Sans', sans-serif;
      font-size: 14.5px; font-weight: 800; color: var(--text);
      line-height: 1.2; letter-spacing: -0.01em; min-width: 0;
      overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    /* Count sits right beside the title, not off with the price pill. */
    .bb-pack-fab-count {
      flex-shrink: 1;
      font-family: 'DM Sans', sans-serif;
      font-size: 12.5px; font-weight: 700; color: var(--text-soft);
      letter-spacing: -0.01em; line-height: 1.2; white-space: nowrap;
    }
    /* Right side: solid pill (visual only — the whole bar is the tap target) */
    .bb-pack-fab-view {
      flex-shrink: 0; box-sizing: border-box;
      display: inline-flex; align-items: center; justify-content: center;
      height: 38px; padding: 0 22px; border-radius: 10px;
      background: var(--text); color: var(--bg);
      font-family: 'DM Sans', sans-serif;
      font-size: 13px; font-weight: 800; letter-spacing: 0.01em; line-height: 1;
    }
    .bb-pack-fab:hover .bb-pack-fab-view { opacity: 0.88; }
    /* Price pill, sized to match .bb-pack-fab-view exactly so the two read as
       one set — mirrors bbTotalPriceUSD() exactly, same as the sheet's own
       Total line, so this can never drift out of sync with it. */
    .bb-pack-fab-price {
      flex-shrink: 0; box-sizing: border-box;
      display: none; align-items: center; justify-content: center;
      height: 38px; padding: 0 14px; border-radius: 10px;
      background: rgba(0, 0, 0, 0.06);
      font-family: 'DM Sans', sans-serif;
      font-size: 13px; font-weight: 800; color: var(--text); letter-spacing: -0.01em; line-height: 1;
    }
    .bb-pack-fab.bb-fab-visible .bb-pack-fab-price { display: inline-flex; }
    body.dark .bb-pack-fab-price { background: rgba(255, 255, 255, 0.08); }
    body.dark .bb-pack-fab {
      background: #16161A !important;
      border-top: 1px solid rgba(255, 255, 255, 0.07) !important;
      color: var(--text) !important;
      box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.4) !important;
    }

    /* Backdrop behind the sheet */
    .bb-pack-sheet-backdrop.show {
      display: block; position: fixed; inset: 0; z-index: 1070;
      background: rgba(10,8,20,.45); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
      opacity:1;transition:opacity .25s ease;
    }
    .bb-pack-sheet-backdrop.show.bb-sheet-backdrop-dragging {
      opacity:var(--bb-backdrop-opacity,1);
      transition:none;
    }
    .bb-pack-sheet-backdrop.show.bb-sheet-backdrop-dismissing {
      opacity:0;
      transition:opacity .28s ease;
    }

    /* Site header (.sh-header, z-index:100) needs to end up UNDER the sheet
       while it's open. Promoting .page-wrap's own z-index above it (the old
       approach) put page-wrap's whole stacking context — cards and all, not
       just the sheet — above the header too. If the page had been scrolled
       at all before the sheet opened, that let the cards currently sitting
       at the very top of the viewport (normally hidden behind the fixed
       header) paint over it instead of behind it, which is what showed as
       the header "disappearing" into a strip of glitched card content.
       Demoting the header below page-wrap's unchanged z-index:1 gets the
       same "sheet renders above header" result without moving any of
       page-wrap's other content out of its normal place underneath the
       .bb-pack-sheet-backdrop / .packs-cat-sheet-backdrop (z-index 1070). */
    body.bb-sheet-active .sh-header {
      z-index: 0 !important;
    }
    /* Grab handle at the top of the sheet */
    .bb-panel::before{
      content:'';position:absolute;top:8px;left:50%;transform:translateX(-50%);
      width:42px;height:4px;border-radius: 16px;background:var(--border);z-index:2;
    }
    .bb-panel-head{padding-top:22px !important;touch-action:none;}

    @media (prefers-reduced-motion: reduce) {
      .bb-panel,
      .bb-panel.bb-sheet-open.bb-sheet-settling,
      .bb-panel.bb-sheet-open.bb-sheet-dismissing-down,
      .bb-pack-sheet-backdrop.show,
      .bb-pack-sheet-backdrop.show.bb-sheet-backdrop-dismissing {
        transition-duration:.01ms !important;
      }
    }
  }

  /* Phone toolbar: the category, bulk-action, filter and sort controls are
     familiar icon actions here; their full labels remain on tablet/desktop
     and in aria/title text, while the 40px squares keep proper tap targets. */
  @media (max-width: 480px) {
    .bb-search-buttons { gap: 8px; }

    /* Everything except the category control stays an icon square: they open
       sheets, their glyphs are conventional, and Filter carries its own count
       badge. Squares are 44px now rather than 40x38 — 44 is the accepted
       minimum for a reliable touch target, and the row has the width to spare. */
    .bb-search-buttons .bb-actions-btn,
    .bb-search-buttons .bb-panel-icon-btn {
      width:44px !important;min-width:44px !important;height:44px !important;
      padding:0 !important;justify-content:center !important;gap:0 !important;
    }
    .bb-search-buttons .bb-actions-btn .bb-mobile-control-label,
    .bb-search-buttons .bb-panel-icon-btn .bb-mobile-control-label,
    .bb-search-buttons .bb-actions-btn .bb-mobile-control-chev,
    .bb-search-buttons .bb-panel-icon-btn .bb-mobile-control-chev,
    .bb-search-buttons #bbActionsBtnLabel { display:none !important; }
    .bb-search-buttons .bb-panel-icon-btn svg,
    .bb-search-buttons .bb-actions-btn svg { margin:0 !important; }

    /* …but the CATEGORY button keeps its label and takes the leftover width.
       Below 1024px the sidebar is gone, so this button IS the category
       navigation — and as a bare 40px square it showed neither what it did nor
       which category you were in, which is the single most useful thing this
       row can tell you. The old rule hid it on the grounds that there was no
       room for labels; there is, the icon row was only using about two thirds
       of the line. */
    .bb-search-buttons .bb-cat-mobile-btn {
      width:auto !important;min-width:0 !important;height:44px !important;
      flex:1 1 auto;
      justify-content:flex-start !important;
      gap:7px !important;
      padding:0 12px !important;
    }
    .bb-search-buttons .bb-cat-mobile-btn .bb-mobile-control-label,
    .bb-search-buttons .bb-cat-mobile-btn .bb-mobile-control-chev {
      display:inline-block !important;
    }
    /* A long category name shortens rather than pushing the icon squares off
       the end of the row. */
    .bb-search-buttons .bb-cat-mobile-btn .bb-mobile-control-label {
      overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;
    }
    /* The chevron is the affordance that says "this opens something" — it must
       not be the thing that gets truncated away. */
    .bb-search-buttons .bb-cat-mobile-btn .bb-mobile-control-chev,
    .bb-search-buttons .bb-cat-mobile-btn .bb-mobile-control-icon { flex:0 0 auto; }
  }


  /* Panel head icon buttons */
  .bb-panel-icon-btn {
    width: 28px; height: 28px; border-radius: 8px; border: 1.5px solid var(--border);
    background: none; cursor: pointer; display: flex; align-items: center; justify-content: center;
    color: var(--text-soft); flex-shrink: 0; transition: all .15s; position: relative;
  }
  .bb-panel-icon-btn:hover { border-color: var(--text); color: var(--text); }
  body .bb-search-buttons .bb-panel-icon-btn.has-active { border-color: var(--text) !important; color: var(--text) !important; }
  body.dark .bb-search-buttons .bb-panel-icon-btn.has-active { border-color: var(--text) !important; color: var(--text) !important; }
  .bb-panel-icon-badge {
    position: absolute; top: -5px; right: -5px;
    width: 14px; height: 14px; border-radius: 50%;
    background: #16A34A; color: #fff; font-size: 9px; font-weight: 900;
    display: none; align-items: center; justify-content: center;
  }
  .bb-panel-icon-btn.has-active .bb-panel-icon-badge { display: flex; }

  /* Fullscreen Split-Viewport Layout for Desktop (viewport height lock)
     ──
     1000px, not 1025px. Everything that makes up the MOBILE layout — .bb-wrap
     going display:block, .bb-panel becoming a slide-up sheet, the pack summary
     bar appearing — is gated on max-width:999.98px. This block is what puts the
     summary panel on screen as the grid's third column. With the two boundaries
     a full 25px apart, widths from 1000px to 1024.99px got NEITHER: no
     fullscreen grid to hold the panel and no mobile sheet to open it, so the
     pack summary was simply unreachable and the page scrolled it away. The two
     halves have to meet exactly, and 999.98/1000 is the same seam the site
     header switches on (see header.js). */
  @media (min-width: 1000px) {
    body.builder-fullscreen {
      height: 100vh;
      overflow: hidden;
    }
    body.builder-fullscreen .sf-footer {
      display: none !important;
    }
    body.builder-fullscreen .page-wrap {
      height: calc(100vh - 72px);
      min-height: 0 !important;
      overflow: hidden;
      margin-bottom: 0;
    }
    body.builder-fullscreen .page-wrap > .page {
      height: 100%;
      box-sizing: border-box;
      display: flex;
      flex-direction: column;
      padding: 24px 32px 24px;
    }
    body.builder-fullscreen .bb-page-header {
      margin: 0 0 16px;
      width: 100%;
      max-width: none;
      /* Match the 10px inset used by every category row below, so the page
         title and the sidebar's icon column share one clean vertical edge. */
      padding-left: 10px;
      flex-shrink: 0;
    }
    body.builder-fullscreen .bb-wrap {
      flex: 1;
      min-height: 0;
      display: grid;
      /* The panel column's minmax(360,580) has a *finite* max, so Grid's
         track-sizing algorithm grows it toward 580 during the "maximize
         non-flexible tracks" pass, which runs BEFORE the 1fr middle column
         (a flexible track) gets any space at all. At narrow widths that let
         the panel win the full 580 first and left the product grid crushed
         to near-zero. Giving the middle column its own explicit floor via
         minmax(280px,1fr) reserves that space up front so it can't be
         squeezed out. */
      grid-template-columns: 260px minmax(280px, 1fr) minmax(360px, 580px);
      grid-template-rows: auto 1fr;
      column-gap: 24px;
      row-gap: 16px;
      width: 100%;
      max-width: none;
      margin: 0;
    }
    /* The New Item editor + Reward Categories panel are full-page views, not
       part of the fixed-viewport grid/sidebar layout — they should scroll
       with the page like a normal document instead of being trapped in an
       inner scroll region. bb-editor-open (toggled on <body> by
       bbOpenItemCreator/bbOpenRewardCatPanel) lifts the 100vh/overflow:hidden
       lock while either panel is showing. */
    /* While the item editor is open, the "Pack Builder" page title + listings
       count above it are irrelevant — the editor is a full-width form, not
       part of the grid those describe. */
    body.bb-editor-open .bb-page-header {
      display: none;
    }
    body.builder-fullscreen.bb-editor-open {
      height: auto;
      overflow: visible;
    }
    body.builder-fullscreen.bb-editor-open .page-wrap {
      height: auto;
      overflow: visible;
    }
    body.builder-fullscreen.bb-editor-open .page-wrap > .page {
      height: auto;
    }
    body.builder-fullscreen .bb-search-wrap {
      grid-column: 2;
      grid-row: 1;
      position: static;
      padding: 0;
      margin: 0 0 10px 0;
      background: transparent;
      /* Grid items default to min-width:auto, sizing themselves to fit their
         content's min-content — with the search row's fixed-width children
         (340px search box, non-shrinking button group) that min-content is
         wider than the 1fr track actually has room for once the 260px
         sidebar and 360-580px pack summary column are accounted for. Without
         this, the column (and therefore the whole grid) blows out past the
         page's width, and since the fullscreen page wrapper clips overflow,
         the pack summary column gets pushed off the right edge and hidden
         instead of the toolbar wrapping or scrolling. */
      min-width: 0;
    }
    body.builder-fullscreen .bb-search-row {
      display: flex;
      align-items: center;
      /* One line: title at the left, the search box stretching across the
         middle, the button group at the right edge. NOT space-between — with
         the left column flattened by display:contents that would spread the
         three items apart and reopen a gap between the search box and the
         buttons. flex-end matters only in the wrapped fallback, where it
         keeps the buttons right-aligned on their own line; on a single line
         the search box's flex-grow has already claimed the free space, so it
         changes nothing. */
      justify-content: flex-end;
      /* Last-resort wrap so a genuinely too-narrow middle column drops the
         buttons to a second line instead of overflowing into the pack panel
         (the fullscreen page wrapper clips, so overflow = hidden controls).
         With the nested column gone this now only fires when the pieces
         really don't fit. */
      flex-wrap: wrap;
      gap: 12px;
      row-gap: 8px;
      width: 100%;
    }
    body.builder-fullscreen .packs-content-heading {
      align-self: center;
      flex: 0 0 auto;
      margin-top: 0;
      /* The row is justify-content:flex-end, so on the narrowest columns —
         where the title ends up alone on its line — it would otherwise be
         shoved to the right edge. This pins it left. It costs nothing when
         it shares a line with the search box, since the box's flex-grow
         leaves no free space for the auto margin to claim. */
      margin-right: auto;
    }
    /* The search box + button group used to be a nested flex column, and that
       nesting is what stacked the buttons under the search box even on a
       1600px-wide grid: as a flex item the column sized itself from its own
       intrinsic content width, and a text input's max-content contribution is
       just its ~20-character default size — far narrower than the 420px basis
       it actually lays out at. So the column claimed a box too small to hold
       its own two children side by side, wrapped inside itself, and left that
       dead strip to the left of Quick Tools. display:contents dissolves the
       box entirely: the search input and the button group become direct
       children of the row and are sized against the row's real width. */
    body.builder-fullscreen .bb-search-left-col {
      display: contents;
    }
    body.builder-fullscreen .bb-search-inner {
      /* Grows into every pixel between the title and the button group instead
         of sitting at a fixed width with the slack left over as a dead strip.
         That also makes the wrapped fallback tidy: when the buttons drop to
         their own line the search box simply fills the line it kept. The
         300px basis is only the wrap threshold (line breaking uses the basis,
         never the grown width), and there is deliberately no max-width — a
         capped box would put the leftover space back into the row, which is
         the gap this layout exists to remove. */
      flex: 1 1 300px;
      width: auto;
      max-width: none;
      min-width: 150px;
    }
    body.builder-fullscreen .bb-search-buttons {
      display: flex;
      align-items: center;
      /* Content-sized and last on the line, so it always ends flush with the
         grid's right edge. max-width:100% keeps it inside the column at the
         280px floor, and the wrap (plus flex-end) is what that clamp needs to
         stay legible — without it the three buttons just overflow the box. */
      flex: 0 0 auto;
      flex-wrap: wrap;
      justify-content: flex-end;
      gap: 10px;
      row-gap: 8px;
      max-width: 100%;
    }
    body.builder-fullscreen .bb-left {
      grid-column: 2;
      grid-row: 2;
      display: flex;
      flex-direction: column;
      min-height: 0;
      padding: 0 0 24px;
    }
    body.builder-fullscreen .product-grid {
      flex: 1;
      overflow-y: auto;
      padding-right: 8px;
      scrollbar-width: thin;
      align-content: start;
    }
    body.builder-fullscreen .bb-panel {
      grid-column: 3;
      grid-row: 1 / span 2;
      position: static;
      width: 100%;
      height: 100%;
      max-height: none;
      margin: 0;
      display: flex;
      flex-direction: column;
    }
    body.builder-fullscreen .bb-panel .bb-items {
      flex: 1;
      min-height: 0;
      max-height: none;
      overflow-y: auto;
    }

    /* Left category sidebar on builder.html */
    body.builder-fullscreen .packs-sidebar {
      grid-column: 1;
      grid-row: 1 / span 2;
      width: 260px;
      flex-shrink: 0;
      display: flex;
      flex-direction: column;
      gap: 2px;
      border-right: 1.5px solid var(--border);
      border-left: none;
      padding-right: 16px;
      padding-left: 0;
      position: relative;
      /* Matches .bb-panel's own height:100% on this same spanned grid row —
         without a bound here the column just grows with however many
         categories exist and pushes the management controls below the
         viewport (or under the pack panel) instead of scrolling. */
      height: 100%;
      min-height: 0;
    }
    /* The category list is the one part of this column with unbounded
       length — it scrolls on its own so the Favourites/All buttons above
       and the management buttons below stay put and visible. */
    body.builder-fullscreen #bbCatSidebarList {
      flex: 1 1 auto;
      min-height: 40px;
      overflow-y: auto;
      overflow-x: hidden;
      scrollbar-width: thin;
    }
    body.builder-fullscreen .packs-cat-add-btn,
    body.builder-fullscreen .packs-cat-edit-btn {
      flex-shrink: 0;
    }
    body.builder-fullscreen .packs-sidebar-indicator {
      position: absolute;
      top: 0;
      right: -1.5px;
      left: auto;
      width: 2px;
      background: var(--text);
      border-radius: 99px;
      transition: transform .25s cubic-bezier(0.4, 0, 0.2, 1), height .25s cubic-bezier(0.4, 0, 0.2, 1), opacity .15s;
      pointer-events: none;
      z-index: 10;
      opacity: 0;
    }
    body.builder-fullscreen .packs-cat-item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 8px;
      width: 100%;
      padding: 9px 10px;
      border: none;
      background: none;
      border-radius: 8px;
      font-family: 'Geist', 'DM Sans', sans-serif;
      font-size: 14px;
      font-weight: 500;
      color: var(--text-soft);
      cursor: pointer;
      text-align: left;
      transition: background .15s, color .15s;
    }
    body.builder-fullscreen .packs-cat-item:hover {
      background: rgba(0, 0, 0, 0.04);
      color: var(--text);
    }
    body.builder-fullscreen.dark .packs-cat-item:hover {
      background: rgba(255, 255, 255, 0.05);
    }
    body.builder-fullscreen .packs-cat-item.active {
      color: var(--text);
      font-weight: 700;
      background: rgba(0, 0, 0, 0.03);
    }
    body.builder-fullscreen.dark .packs-cat-item.active {
      background: rgba(255, 255, 255, 0.04);
    }
    body.builder-fullscreen .packs-cat-count {
      font-size: 12px;
      font-weight: 600;
      color: var(--text-muted);
    }
    body.builder-fullscreen .packs-cat-item--hidden {
      margin-top: 8px;
      border-top: 1px solid var(--border);
      padding-top: 12px;
      border-radius: 0 0 8px 8px;
      color: var(--text-muted);
    }
    body.builder-fullscreen .packs-cat-item--hidden.active {
      color: var(--text);
    }
  }

  /* ── Mobile category sheet ──
     ≤1024px the sidebar column doesn't exist, and it used to be flatly
     display:none'd with nothing put in its place — there was no way to change
     category on a phone at all. Now the same aside becomes a slide-up sheet
     opened from #bbCatMobileBtn in the toolbar. Mirrors index.css's sheet so
     Browse and Pack Builder behave identically. All the pieces below are inert
     above the breakpoint. */
  .bb-cat-mobile-btn,
  .bb-search-buttons .bb-cat-mobile-btn { display:none !important; }
  .packs-cat-sheet-backdrop{display:none;}
  .packs-sheet-head{display:none;}
  .bb-filter-sheet-backdrop{display:none;}

  /* 999.98px so the sheet takes over on exactly the width where the desktop
     sidebar column stops existing (see the min-width:1000px block above) —
     never both, never neither. */
  @media (max-width: 999.98px) {
    .bb-cat-mobile-btn,
    .bb-search-buttons .bb-cat-mobile-btn { display:inline-flex !important; }
    /* Long category names truncate instead of widening the pill */
    .bb-cat-mobile-btn > span{
      overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;max-width:120px;
    }
    .bb-cat-mobile-btn.open{border-color:#16A34A;color:var(--text);}

    /* Demote the header instead of promoting .page-wrap — see the long
       comment on body.bb-sheet-active .sh-header above for why promoting
       page-wrap itself let scrolled-up card content paint over the header. */
    body.bb-cat-sheet-open .sh-header{z-index:0 !important;}
    .packs-cat-sheet-backdrop{
      display:block;position:fixed;inset:0;z-index:1070;
      background:rgba(10,8,20,.45);
      backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);
      opacity:0;pointer-events:none;transition:opacity .25s ease;
    }
    .packs-cat-sheet-backdrop.show{opacity:1;pointer-events:auto;}

    .packs-sidebar{
      display:flex !important;
      position:fixed;left:0;right:0;bottom:0;top:auto;
      width:100%;max-height:min(76vh,600px);
      z-index:1075;
      flex-direction:column;gap:2px;align-items:stretch;
      background:var(--white);border:none;
      border-radius:20px 20px 0 0;
      padding:0 12px calc(14px + env(safe-area-inset-bottom,0px));
      box-shadow:0 -10px 44px rgba(0,0,0,.28);
      overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
      scrollbar-width:none;-ms-overflow-style:none;
      transform:translateY(101%);
      transition:transform .3s cubic-bezier(.4,0,.2,1),visibility 0s .3s;
      visibility:hidden;
    }
    body.dark .packs-sidebar{background:#16161A;}
    .packs-sidebar::-webkit-scrollbar{display:none;}
    .packs-sidebar.open{
      transform:translateY(0);visibility:visible;
      transition:transform .3s cubic-bezier(.4,0,.2,1),visibility 0s 0s;
    }
    @media (prefers-reduced-motion: reduce){
      .packs-sidebar,.packs-cat-sheet-backdrop{transition:none;}
    }
    .packs-sidebar-indicator{display:none;}

    /* Sheet header — sticks while the category list scrolls under it */
    .packs-sheet-head{
      display:flex;align-items:center;justify-content:space-between;
      position:sticky;top:0;z-index:2;flex-shrink:0;
      margin:0 -12px;padding:20px 16px 10px;
      background:var(--white);
    }
    body.dark .packs-sheet-head{background:#16161A;}
    /* Grab handle, drawn on the head so it stays put while the list scrolls */
    .packs-sheet-head::before{
      content:'';position:absolute;top:8px;left:50%;transform:translateX(-50%);
      width:42px;height:4px;border-radius: 16px;background:var(--border);
    }
    .packs-sheet-title{
      font-family:'Geist','DM Sans',sans-serif;font-size:16px;font-weight:800;
      color:var(--text);letter-spacing:-0.01em;
    }
    .packs-sheet-close{
      display:flex;align-items:center;justify-content:center;
      width:30px;height:30px;flex-shrink:0;margin-right:-4px;
      border:none;border-radius:50%;background:rgba(0,0,0,.05);
      color:var(--text-soft);font-size:14px;line-height:1;cursor:pointer;
    }
    body.dark .packs-sheet-close{background:rgba(255,255,255,.07);}

    /* Full-width rows with a 44px touch target. The desktop .packs-cat-item
       styling on this page lives behind body.builder-fullscreen (min-width:1025px),
       so these are the only rules in play here. */
    .packs-cat-item{
      display:flex;align-items:center;justify-content:space-between;gap:8px;
      width:100%;flex-shrink:0;
      padding:12px 10px;border:none;background:none;border-radius:10px;
      font-family:'Geist','DM Sans',sans-serif;font-size:15px;font-weight:500;
      color:var(--text-soft);cursor:pointer;text-align:left;
    }
    .packs-cat-item.active{color:var(--text);font-weight:800;background:rgba(0,0,0,.05);}
    body.dark .packs-cat-item.active{background:rgba(255,255,255,.07);}
    /* Checkmark removed on active row */
    .packs-cat-item.active::after{display:none !important;}
    .packs-cat-count{
      font-size:13px;font-weight:600;color:var(--text-muted);margin-left:auto;
    }
    .packs-cat-add-btn,.packs-cat-edit-btn{flex-shrink:0;white-space:nowrap;}

    /* ── Filter/Sort/Actions sheets — same bottom-sheet mechanic as
       .packs-sidebar above, just applied to these three dropdowns instead of
       a separate element. The small anchored .bb-cat-dropdown popover they
       use on desktop makes no sense as a fat-finger target on a phone. All
       three share one body-lock class and this rule block — only one is ever
       open at a time (closeAllBbDropdowns runs before any of them opens). ── */
    body.bb-filter-sheet-open .sh-header{z-index:0 !important;}
    .bb-filter-sheet-backdrop{
      display:block;position:fixed;inset:0;z-index:1070;
      background:rgba(10,8,20,.45);
      backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);
      opacity:0;pointer-events:none;transition:opacity .25s ease;
    }
    .bb-filter-sheet-backdrop.show{opacity:1;pointer-events:auto;}
    #bbFilterDropdown.bb-cat-dropdown,
    #bbSortDropdown.bb-cat-dropdown,
    #bbActionsDropdown.bb-cat-dropdown{
      display:flex !important;
      position:fixed !important;left:0;right:0;bottom:0;top:auto !important;
      width:100% !important;max-width:none;min-width:0;
      max-height:min(76vh,600px);
      z-index:1075;
      flex-direction:column;gap:2px;align-items:stretch;
      background:var(--white);border:none;
      border-radius:20px 20px 0 0;
      padding:6px 16px calc(16px + env(safe-area-inset-bottom,0px));
      box-shadow:0 -10px 44px rgba(0,0,0,.28);
      overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
      transform:translateY(101%);
      transition:transform .3s cubic-bezier(.4,0,.2,1),visibility 0s .3s;
      visibility:hidden;
    }
    body.dark #bbFilterDropdown.bb-cat-dropdown,
    body.dark #bbSortDropdown.bb-cat-dropdown,
    body.dark #bbActionsDropdown.bb-cat-dropdown{background:#16161A;}
    #bbFilterDropdown.bb-cat-dropdown::before,
    #bbSortDropdown.bb-cat-dropdown::before,
    #bbActionsDropdown.bb-cat-dropdown::before{
      content:'';position:absolute;top:8px;left:50%;transform:translateX(-50%);
      width:42px;height:4px;border-radius:99px;background:var(--border);
    }
    #bbFilterDropdown.bb-cat-dropdown.open,
    #bbSortDropdown.bb-cat-dropdown.open,
    #bbActionsDropdown.bb-cat-dropdown.open{
      transform:translateY(0);visibility:visible;
      transition:transform .3s cubic-bezier(.4,0,.2,1),visibility 0s 0s;
    }
    /* The filter panel's own pieces grow into touch rows inside the sheet:
       52px options, full-width shelf rows in place of the chip wrap, a sticky
       header carrying the grabber and a close button, and a sticky
       "Show N items" footer clear of the home indicator. */
    #bbFilterDropdown.bb-cat-dropdown{padding:0;max-height:min(86vh,720px);}
    #bbFilterDropdown.bb-cat-dropdown::before{display:none;}
    #bbFilterDropdown .bb-fd-head{padding:22px 16px 12px;border-radius:20px 20px 0 0;}
    #bbFilterDropdown .bb-fd-head::before{
      content:'';position:absolute;top:9px;left:50%;transform:translateX(-50%);
      width:42px;height:4px;border-radius:99px;background:var(--border);
    }
    #bbFilterDropdown .bb-fd-close{display:flex;}
    #bbFilterDropdown .bb-fd-title{font-size:16.5px;}
    #bbFilterDropdown .bb-fd-section{padding:14px 12px 12px;}
    #bbFilterDropdown .bb-fd-label{font-size:11.5px;padding-bottom:9px;}
    #bbFilterDropdown .bb-fd-opt{min-height:52px;padding:0 14px;border-radius:12px;font-size:15px;}
    #bbFilterDropdown .bb-fd-reset,#bbFilterDropdown .bb-fd-clear{font-size:13.5px;padding:8px 10px;}
    #bbFilterDropdown .bb-fd-search{margin:0 2px 10px;}
    #bbFilterDropdown .bb-fd-search svg{left:13px;}
    /* 16px, because anything smaller makes iOS zoom the page on focus. */
    #bbFilterDropdown .bb-fd-search-input{height:46px;font-size:16px;padding-left:36px;border-radius:12px;}
    /* Shelves become the same full-width rows as the options above them: a
       wrap of small pills is the hardest thing on this page to hit. */
    .bb-dd-subcat-pills{display:flex;flex-direction:column;gap:6px;padding:0 2px 2px;}
    #bbFilterDropdown .bb-cat-opt.bb-dd-subcat-item{
      width:100%;justify-content:space-between;min-height:52px;
      padding:0 14px;border-radius:12px;font-size:15px;
      white-space:normal;text-align:left;
    }
    #bbFilterDropdown .bb-cat-opt.bb-dd-subcat-item .bb-fd-check{width:16px;height:16px;}
    #bbFilterDropdown .bb-fd-foot{padding:10px 12px calc(12px + env(safe-area-inset-bottom,0px));}
    #bbFilterDropdown .bb-fd-done{min-height:50px;font-size:16px;border-radius:14px;}
    /* The install prompt floats at z-index 10050 — above every sheet on this
       page. Harmless while the sheets were pure lists, but the filter sheet
       now ends in a "Show N items" button pinned to the bottom edge, and the
       banner landed straight on top of it. Slide it away while any sheet is
       up, exactly as the pack fab bar does further up this file. */
    body.bb-sheet-active .pm-install-banner,
    body.bb-cat-sheet-open .pm-install-banner,
    body.bb-filter-sheet-open .pm-install-banner{
      transform:translateY(calc(100% + 32px)) !important;
      opacity:0 !important;pointer-events:none;
    }
    /* Sort and Actions stay menus, but their rows get the same touch height. */
    #bbSortDropdown .bb-cat-opt,#bbActionsDropdown .bb-cat-opt{
      min-height:48px;padding:0 12px;border-radius:12px;font-size:15px;
    }
    @media (prefers-reduced-motion: reduce){
      #bbFilterDropdown.bb-cat-dropdown,#bbSortDropdown.bb-cat-dropdown,
      #bbActionsDropdown.bb-cat-dropdown,.bb-filter-sheet-backdrop{transition:none;}
    }
  }

  /* "Of choice" reward claim mode — the top type-switcher/subcat pills are
     redundant with the left sidebar so stay hidden, but the sidebar itself
     stays visible with non-claimable categories greyed out (see
     .bb-claim-unlocked, toggled by bbApplyClaimSidebarLock) */
  body.bb-claim-mode #bbTypeSwitcher,
  body.bb-claim-mode .bb-subcats-wrapper { display: none !important; }
  body.bb-claim-mode #bbClaimBanner { display: block !important; }
  body.bb-claim-mode .packs-sidebar .packs-cat-item {
    opacity: 0.35;
    pointer-events: none;
    cursor: not-allowed;
    filter: grayscale(1);
  }
  body.bb-claim-mode .packs-sidebar .packs-cat-item.bb-claim-unlocked {
    opacity: 1;
    pointer-events: auto;
    cursor: pointer;
    filter: none;
  }

  /* Category editor controls (mirrors index.html's pack-category editor) */
  .packs-cat-edit-btn{
    display:none;align-items:center;justify-content:center;
    width:100%;padding:9px 10px;margin-top:8px;border-radius: 12px;
    border:1.5px solid var(--border);background:none;color:var(--text-soft);
    font-family:'Geist','DM Sans',sans-serif;font-size:13px;font-weight:700;cursor:pointer;transition:all .15s;
    box-sizing:border-box;
  }
  .packs-cat-edit-btn:hover{background:rgba(0,0,0,0.04);color:var(--text);border-color:var(--text-muted);}
  body.dark .packs-cat-edit-btn:hover{background:rgba(255,255,255,0.05);}
  .packs-cat-edit-btn.active{color:var(--text);font-weight:800;background:rgba(0,0,0,0.04);border-color:var(--text-muted);}
  body.dark .packs-cat-edit-btn.active{background:rgba(255,255,255,0.06);}
  .packs-cat-add-btn{
    display:none;align-items:center;justify-content:center;gap:6px;
    width:100%;padding:10px;margin-top:10px;border-radius: 12px;
    border:1.5px dashed var(--border);background:none;color:var(--text-soft);
    font-family:'Geist','DM Sans',sans-serif;font-size:13px;font-weight:700;cursor:pointer;transition:all .15s;
    box-sizing:border-box;
  }
  .packs-cat-add-btn:hover{background:rgba(0,0,0,0.04);color:var(--text);border-color:var(--text-muted);}
  body.dark .packs-cat-add-btn:hover{background:rgba(255,255,255,0.05);}
  /* Reward-category item cards: bulk-remove bar is a hardcoded light color
     that doesn't adapt to dark mode on its own. */
  .bb-rc-bulkbar{background:#FFF8F8;border:1.5px solid var(--coral);}

  body.dark .bb-rc-bulkbar{background:rgba(239,68,68,0.12);border-color:#EF4444;}
  .bb-rc-card{cursor:pointer;transition:border-color .12s,background .12s,box-shadow .12s;}
  .bb-rc-card:hover{border-color:var(--coral);}
  .bb-rc-card.selected{border-color:var(--coral);background:rgba(255,107,107,0.1);box-shadow:0 0 0 1.5px var(--coral) inset;}
  .bb-rc-check-badge{width:18px;height:18px;border-radius:5px;display:flex;align-items:center;justify-content:center;border:1.5px solid rgba(0,0,0,0.2);}
  .bb-rc-card.selected .bb-rc-check-badge{background:var(--coral);border-color:var(--coral);}
  /* Native <select> chrome (esp. the dropdown arrow well) ignores custom
     background on Windows/Chrome, leaving a light native box even in dark
     mode — reset appearance and draw our own arrow so it matches the theme. */
  select.bb-ic-plain-input{
    appearance:none;-webkit-appearance:none;-moz-appearance:none;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23AFAFAF' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat:no-repeat;background-position:right 10px center;background-size:12px;
    padding-right:32px;cursor:pointer;
  }
  .packs-cat-delete-x {
    display:flex;align-items:center;justify-content:center;
    width:20px;height:20px;border:none;background:none;
    border-radius:4px;color:#EF4444;font-size:16px;font-weight:700;
    cursor:pointer;transition:all 0.15s;margin-left:2px;
  }
  .packs-cat-delete-x:hover {
    background:rgba(239, 68, 68, 0.1);color:#DC2626;
  }
  .packs-cat-rename-btn {
    display:flex;align-items:center;justify-content:center;
    width:20px;height:20px;border:none;background:none;
    border-radius: 12px;color:var(--text-muted);
    cursor:pointer;transition:all 0.15s;margin-left:2px;flex-shrink:0;
  }
  .packs-cat-rename-btn:hover {
    background:rgba(124,58,237,0.1);color:#7C3AED;
  }
  .packs-cat-item-row{display:flex;align-items:center;gap:2px;}
  .packs-cat-item-row .packs-cat-item{flex:1;min-width:0;}
  .packs-cat-divider{height:1px;background:var(--border);margin:6px 4px;}
  /* Per-category icon — admin-set SVG or emoji, fixed 16px box so both icon
     types (and categories with neither) keep the row's text baseline lined up.
     Shared unscoped rule: applies in both the fullscreen sidebar and the
     mobile category sheet, unlike most of .packs-cat-item's own styling above. */
  .packs-cat-label{display:inline-flex;align-items:center;gap:7px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .packs-cat-icon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;flex-shrink:0;color:currentColor;}
  .packs-cat-icon svg{width:100%;height:100%;display:block;}
  .packs-cat-icon img{width:100%;height:100%;display:block;object-fit:contain;}
  .packs-cat-icon-image{width:18px;height:18px;}
  /* Category artwork is uploaded as white-on-transparent silhouettes (drawn for
     the dark theme), so on the light sidebar they'd be invisible. Knock every
     one of them to black in light mode — the same treatment "All" already got —
     and leave the source artwork untouched in dark. */
  .packs-cat-icon-image img{filter:brightness(0);}
  body.dark .packs-cat-icon-image img{filter:none;}
  .packs-cat-icon-emoji{font-size:14px;line-height:1;}

  /* ── Bulletin Board sidebar entry ──────────────────────────────────────────
     It sits in the category list but is not a category: it's a synthetic,
     cross-category view of everything tagged onto the board, and its items are
     still filed under Bugs/Food/Plants. Reading as "just another category" is
     what made it confusing, so it gets a rule above it to close off the real
     categories, and the same amber the board's own pill uses
     (.bb-item-bulletin-board-pill) so the sidebar entry and the tag on a line
     read as one feature rather than two unrelated things.
     Same divider idiom as .packs-cat-item--hidden below it. */
  /* `body.builder-fullscreen .packs-cat-item` sets `border:none` at (0,2,1) and
     outranks a plain two-class selector here, so the divider silently never
     drew. Anchoring on #bbCatSidebarList wins outright instead of relying on
     source order, and covers the fullscreen and normal sidebars in one rule. */
  #bbCatSidebarList .packs-cat-item.packs-cat-item--bulletin{
    position:relative;
    margin-top:14px;padding-top:16px;border-radius:0;
  }
  /* A short centred rule rather than a full-width border. Absolutely positioned
     on purpose: the button is a flex row, so a ::before in normal flow would
     become a flex child and sit beside the label instead of above it. */
  #bbCatSidebarList .packs-cat-item--bulletin::before{
    content:'';position:absolute;top:0;left:50%;transform:translateX(-50%);
    width:44px;height:1px;background:var(--border);
  }
  body.dark #bbCatSidebarList .packs-cat-item--bulletin::before{
    background:rgba(255,255,255,.18);
  }
  #bbCatSidebarList .packs-cat-item--bulletin.active{color:#B45309;}
  body.dark #bbCatSidebarList .packs-cat-item--bulletin.active{color:#FBBF24;}
  .packs-cat-reorder{display:flex;flex-direction:column;gap:1px;flex-shrink:0;}
  .packs-cat-reorder-btn{
    width:18px;height:14px;border:none;background:none;color:var(--text-muted);
    cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;
    font-size:8px;border-radius: 12px;transition:all .15s;
  }
  .packs-cat-reorder-btn:hover{background:rgba(0,0,0,0.06);color:var(--text);}
  .packs-cat-reorder-btn:disabled{opacity:.3;cursor:default;pointer-events:none;}
  .packs-cat-item.drag-over{border-top:2px solid #16A34A !important;}
  .packs-cat-sortable{position:relative;border-radius:9px;transition:opacity .15s,background .15s;}
  .packs-cat-drag-handle{
    width:25px;height:34px;flex:0 0 25px;padding:0;border:0;border-radius:7px;
    display:flex;align-items:center;justify-content:center;background:transparent;
    color:var(--text-muted);cursor:grab;touch-action:none;
  }
  .packs-cat-drag-handle:hover{color:#16A34A;background:rgba(22,163,74,.08);}
  .packs-cat-drag-handle:active{cursor:grabbing;}
  .packs-cat-drag-handle:focus-visible{outline:2px solid #16A34A;outline-offset:1px;}
  .packs-cat-sortable.is-category-dragging{opacity:.42;}
  .packs-cat-sortable.category-drag-before::before,
  .packs-cat-sortable.category-drag-after::after{
    content:"";position:absolute;z-index:4;left:2px;right:2px;height:3px;
    border-radius:3px;background:#16A34A;box-shadow:0 0 0 2px rgba(22,163,74,.14);
  }
  .packs-cat-sortable.category-drag-before::before{top:-2px;}
  .packs-cat-sortable.category-drag-after::after{bottom:-2px;}
  body.dark .packs-cat-drag-handle:hover{color:#4ADE80;background:rgba(74,222,128,.1);}
   #bbGrid.bb-order-mode .product-card{cursor:grab;}
  #bbGrid.bb-order-mode .product-card:active{cursor:grabbing;}
  #bbGrid.bb-order-mode .product-card:hover{transform:none !important;box-shadow:none !important;}

  #bbGrid.bb-cat-edit-mode .mcard-media-action {
    display: none !important;
  }
  #bbGrid.bb-cat-edit-mode:not(.bb-order-mode) .product-card {
    cursor: default;
  }
  .product-card.bb-dragging {
    opacity: 0.45;
    border: 1.5px dashed #16A34A !important;
    transform: none !important;
    box-shadow: none !important;
  }

  /* Unpublished listings (admins only — bbFiltered() drops them for everyone
     else). They sit at the end of their real category alongside the live
     listings, so they need to read as "not live" at a glance: dimmed artwork
     plus a dashed border and a corner label. The label is a pseudo-element so
     no extra markup is needed on a card that 99% of visitors never see. */
  .product-card.is-unpublished,
  #bbGrid .product-card.is-unpublished {
    border-style: dashed !important;
    border-color: #94A3B8 !important;
  }
  .product-card.is-unpublished .product-card-img,
  .product-card.is-unpublished .mcard-body {
    opacity: 0.5;
  }
  .product-card.is-unpublished::after {
    content: 'Unpublished';
    position: absolute;
    top: 8px;
    left: 8px;
    z-index: 4;
    padding: 3px 7px;
    border-radius: 999px;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    background: #475569;
    color: #fff;
    pointer-events: none;
  }
  body.dark .product-card.is-unpublished,
  body.dark #bbGrid .product-card.is-unpublished {
    border-color: #64748B !important;
  }
  body.dark .product-card.is-unpublished::after {
    background: #94A3B8;
    color: #0F172A;
  }

  /* ── Coming Soon (products.coming_soon) ───────────────────────────────────
     Deliberately NOT styled like .is-unpublished above. An unpublished card is
     an admin-only draft and should read as "not live"; a Coming Soon card is
     shown to everyone on purpose — the whole point is to show off new stock —
     so the artwork stays at full opacity and the card keeps its normal border.
     The only thing that changes is the affordance: a badge saying when you can
     have it, and an inert label where the Add button would be. */
  .mcard-soon-badge {
    position: absolute; top: 10px; right: 10px; z-index: 3;
    background: rgba(245, 158, 11, .16);
    border-radius: 50px;
    padding: 3px 9px;
    font-size: 10px; font-weight: 800;
    letter-spacing: .04em; text-transform: uppercase;
    color: #B45309;
    font-family: 'DM Sans', sans-serif;
    pointer-events: none;
  }
  body.dark .mcard-soon-badge { background: rgba(245, 158, 11, .22); color: #FCD34D; }
  /* Shares the top-right slot with the discount pill — stack rather than
     overlap on the rare item that is both discounted and unreleased. */
  .mcard-discount-badge + .mcard-soon-badge { top: 34px; }

  /* Sits in the same hover overlay slot as .mcard-buy-btn, at the same size, so
     the card doesn't reflow between a buyable and a not-yet-buyable listing. */
  .mcard-soon-btn {
    width: calc(100% - 20px); height: 38px;
    border-radius: 12px;
    background: rgba(120, 120, 130, .28);
    border: 1.5px dashed rgba(255, 255, 255, .55);
    color: #fff;
    font-family: 'DM Sans', sans-serif;
    font-size: 13px; font-weight: 700;
    display: inline-flex; align-items: center; justify-content: center;
    -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
    cursor: default; pointer-events: none;
  }
  /* Light mode's overlay scrim is white, so the label needs dark ink there. */
  body:not(.dark) .mcard-soon-btn {
    background: rgba(26, 26, 26, .10);
    border-color: rgba(26, 26, 26, .35);
    color: #1A1A1A;
  }

  /* Favourite mode grid state (yellow borders, custom buttons) */
  #bbGrid.bb-favourite-mode .product-card.is-favourite {
    background: rgba(245, 158, 11, 0.08) !important;
    border-color: #F59E0B !important;
    border-width: 2px;
    box-shadow: 0 4px 12px rgba(245, 158, 11, 0.1);
  }
  body.dark #bbGrid.bb-favourite-mode .product-card.is-favourite {
    background: rgba(245, 158, 11, 0.16) !important;
  }
  #bbGrid.bb-favourite-mode .product-card.is-favourite .mcard-qty-chip {
    background: #F59E0B !important;
    color: #fff !important;
    border-color: #F59E0B !important;
  }
  .mcard-buy-favourite, .mcard-buy-unfavourite {
    display: none; align-items: center; gap: 4px;
  }
  #bbGrid.bb-favourite-mode .mcard-buy-add {
    display: none !important;
  }
  #bbGrid.bb-favourite-mode .mcard-buy-remove {
    display: none !important;
  }
  #bbGrid.bb-favourite-mode .product-card:not(.is-favourite) .mcard-buy-favourite {
    display: inline-flex;
  }
  #bbGrid.bb-favourite-mode .product-card.is-favourite .mcard-buy-unfavourite {
    display: inline-flex;
  }
  #bbGrid.bb-favourite-mode .mcard-buy-btn {
    background: #F59E0B !important;
    color: #fff !important;
    border-color: #F59E0B !important;
  }
  #bbGrid.bb-favourite-mode .mcard-buy-btn:hover {
    background: #F59E0B !important;
    border-color: #F59E0B !important;
  }
  .bb-actions-btn.mode-favourite {
    background: #F59E0B !important;
    color: #fff !important;
    border-color: #F59E0B !important;
  }

  /* Starred-quality toggle: use the same bottom-left image overlay placement
     as the pack summary and checkout. This final, image-scoped rule supersedes
     the older inline-name positioning without changing the shared on/off
     colours or the toggle's behavior. */
  .product-card .product-card-img {
    isolation: isolate;
  }
  .product-card .product-card-img > img {
    z-index: 1 !important;
  }
  .product-card .product-card-img > .bb-card-star-badge {
    position: absolute !important;
    top: auto !important;
    right: auto !important;
    bottom: 2px !important;
    left: 10px !important;
    z-index: 20 !important;
    width: 40px !important;
    min-width: 40px !important;
    height: 40px !important;
    border-radius: 8px !important;
    margin: 0 !important;
    background: var(--pp-star-bg,#4D3B05) !important;
    border: 2px solid var(--pp-star-border,#F5B301) !important;
    box-shadow: var(--pp-star-shadow,0 0 0 2px rgba(15,15,17,.72),0 4px 12px rgba(0,0,0,.58)) !important;
    color: var(--pp-star-icon,#F5B301) !important;
    line-height: 0 !important;
    transform: translateZ(0);
  }
  body.dark .product-card .product-card-img > .bb-card-star-badge:not(.is-off) {
    background: var(--pp-star-bg,#4D3B05) !important;
    border-color: var(--pp-star-border,#F5B301) !important;
    color: var(--pp-star-icon,#F5B301) !important;
  }
  .product-card .product-card-img > .bb-card-star-badge.is-off {
    background: var(--pp-off-bg) !important;
    border-color: var(--pp-off-border) !important;
    color: var(--pp-off-icon) !important;
    box-shadow: var(--pp-off-shadow) !important;
  }
  .product-card .product-card-img > .bb-card-star-badge svg,
  .product-card .product-card-img > .bb-card-star-badge .pp-star-ico {
    width: 20px !important;
    height: 20px !important;
    display:block !important;
    margin:0 !important;
    vertical-align:0 !important;
  }
  .product-card .product-card-img > .bb-card-recipe-badge {
    position: absolute !important;
    bottom: 2px !important;
    left: 10px !important;
    z-index: 20 !important;
    width: 40px !important;
    min-width: 40px !important;
    height: 40px !important;
    margin: 0 !important;
    background: var(--pp-recipe-bg,#102A4F) !important;
    border: 2px solid var(--pp-recipe-border,#3B82F6) !important;
    box-shadow: var(--pp-recipe-shadow,0 0 0 2px rgba(15,15,17,.72),0 4px 12px rgba(0,0,0,.58)) !important;
    color: var(--pp-recipe-icon,#60A5FA) !important;
    line-height: 0 !important;
    transform: translateZ(0);
  }
  .product-card .product-card-img > .bb-card-recipe-badge.after-star { left: 58px !important; }
  /* Edit mode only: the blueprint pill is a button, and shows dimmed on items
     that aren't blueprints yet so it can be switched on from the grid. Mirrors
     .bb-card-star-badge.is-off next to it. */
  .product-card .product-card-img > button.bb-card-recipe-badge { cursor: pointer !important; }
  .product-card .product-card-img > .bb-card-recipe-badge.is-off {
    background: var(--pp-off-bg) !important;
    border-color: var(--pp-off-border) !important;
    color: var(--pp-off-icon) !important;
    box-shadow: var(--pp-off-shadow) !important;
  }
  /* In-flight PATCH — stops a double click queueing a second write. */
  .product-card.bb-card-busy { opacity: .6 !important; pointer-events: none !important; }
  .product-card .product-card-img > .bb-card-recipe-badge svg { width: 20px !important; height: 20px !important; display:block!important; margin:0!important; vertical-align:0!important; }
  .product-card .product-card-img > .bb-card-style-badge {
    position:absolute!important;bottom:2px!important;left:10px!important;z-index:20!important;
    width:40px!important;min-width:40px!important;height:40px!important;margin:0!important;
    border-radius:8px!important;line-height:0!important;transform:translateZ(0);
    color:var(--pp-style-icon,#F0ABFC)!important;background:var(--pp-style-bg,#3B174F)!important;
    border:2px solid var(--pp-style-border,#D946EF)!important;
    box-shadow:var(--pp-style-shadow,0 0 0 2px rgba(15,15,17,.72),0 4px 12px rgba(0,0,0,.58))!important;
  }
  .product-card .product-card-img > .bb-card-style-badge.after-star { left:58px!important; }
  .product-card .product-card-img > .bb-card-style-badge svg { width:20px!important;height:20px!important;display:block!important;margin:0!important;vertical-align:0!important; }

  /* Third slot. The strip is hand-positioned rather than a flex row (these
     badges are siblings of the <img>, not children of a wrapper), so each one
     needs its own left: the pitch is 48px — 40px badge + 8px gap — giving
     10 / 58 / 106. A card can show star + Fully Grown + Recipe at once. */
  .product-card .product-card-img > .bb-card-recipe-badge.after-two,
  .product-card .product-card-img > .bb-card-style-badge.after-two { left: 106px !important; }

  /* Fully Grown — a control like the star, so it gets the same is-off state. */
  .product-card .product-card-img > .bb-card-grown-badge {
    position: absolute !important;
    top: auto !important;
    right: auto !important;
    bottom: 2px !important;
    left: 10px !important;
    z-index: 20 !important;
    width: 40px !important;
    min-width: 40px !important;
    height: 40px !important;
    border-radius: 8px !important;
    margin: 0 !important;
    background: var(--pp-grown-bg,#052E16) !important;
    border: 2px solid var(--pp-grown-border,#22C55E) !important;
    box-shadow: var(--pp-grown-shadow,0 0 0 2px rgba(15,15,17,.72),0 4px 12px rgba(0,0,0,.58)) !important;
    color: var(--pp-grown-icon,#4ADE80) !important;
    line-height: 0 !important;
    cursor: pointer !important;
    transform: translateZ(0);
  }
  .product-card .product-card-img > .bb-card-grown-badge.after-star { left: 58px !important; }
  .product-card .product-card-img > .bb-card-grown-badge.is-off {
    background: var(--pp-off-bg) !important;
    border-color: var(--pp-off-border) !important;
    color: var(--pp-off-icon) !important;
    box-shadow: var(--pp-off-shadow) !important;
  }
  .product-card .product-card-img > .bb-card-grown-badge svg { width: 20px !important; height: 20px !important; display:block !important; margin:0 !important; vertical-align:0 !important; }

  /* On pointer devices the action temporarily replaces the fixed-height chip
     footer. The image stays untouched, so its bottom-left star remains fully
     visible; moving the pointer away restores synced and in-pack counts. */
  .product-card .mcard-body > .mcard-media-action {
    top: auto;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 5;
    width: auto;
    height: 46px;
    padding: 4px 10px;
    align-items: center;
    background: #FFFFFF;
    border-radius: 0 0 15px 15px;
  }
  body.dark .product-card .mcard-body > .mcard-media-action {
    background: #141416;
  }
  .product-card .mcard-body > .mcard-media-action .mcard-buy-btn {
    width: 100%;
    height: 38px;
    transform: translateY(-2px);
  }
  .product-card .mcard-body > .mcard-media-action:focus-within {
    opacity: 1;
    pointer-events: auto;
  }

  @media (max-width: 999.98px) {
    .product-card .product-card-img > .bb-card-star-badge {
      bottom: 8px !important;
      left: 8px !important;
      width: 30px !important;
      min-width: 30px !important;
      height: 30px !important;
      border-radius: 10px !important;
    }
    .product-card .product-card-img > .bb-card-star-badge svg,
    .product-card .product-card-img > .bb-card-star-badge .pp-star-ico {
      width: 15px !important;
      height: 15px !important;
    }
    .product-card .product-card-img > .bb-card-recipe-badge {
      bottom: 8px !important;
      left: 8px !important;
      width: 30px !important;
      min-width: 30px !important;
      height: 30px !important;
      border-radius: 10px !important;
    }
    .product-card .product-card-img > .bb-card-recipe-badge.after-star { left: 44px !important; }
    .product-card .product-card-img > .bb-card-recipe-badge svg { width: 15px !important; height: 15px !important; }
    .product-card .product-card-img > .bb-card-style-badge {
      bottom:8px!important;left:8px!important;width:30px!important;min-width:30px!important;height:30px!important;border-radius:10px!important;
    }
    .product-card .product-card-img > .bb-card-style-badge.after-star { left:44px!important; }
    .product-card .product-card-img > .bb-card-style-badge svg { width:15px!important;height:15px!important; }
    .product-card .product-card-img > .bb-card-recipe-badge.after-two,
    .product-card .product-card-img > .bb-card-style-badge.after-two { left: 80px !important; }
    .product-card .product-card-img > .bb-card-grown-badge {
      bottom: 8px !important;
      left: 8px !important;
      width: 30px !important;
      min-width: 30px !important;
      height: 30px !important;
      border-radius: 10px !important;
    }
    .product-card .product-card-img > .bb-card-grown-badge.after-star { left: 44px !important; }
    .product-card .product-card-img > .bb-card-grown-badge svg { width: 15px !important; height: 15px !important; }

    /* Three markers at once (star + Fully Grown + Recipe/Housing Style) is the
       only case that doesn't fit: a phone's two-column grid gives the thumbnail
       about 105px, and 3 x 30px on a 36px pitch runs off its right edge. Shrink
       the whole strip rather than letting the last one hang over the artwork —
       :has() is the only way to reach the earlier siblings from the one that
       knows there are three. Browsers without it keep the layout above, which
       is what shipped before this row could exist at all. */
    .product-card .product-card-img:has(> .after-two) > .bb-card-star-badge,
    .product-card .product-card-img:has(> .after-two) > .bb-card-grown-badge,
    .product-card .product-card-img:has(> .after-two) > .bb-card-recipe-badge,
    .product-card .product-card-img:has(> .after-two) > .bb-card-style-badge {
      width: 26px !important;
      min-width: 26px !important;
      height: 26px !important;
      border-radius: 9px !important;
      left: 8px !important;
    }
    .product-card .product-card-img:has(> .after-two) > .after-star { left: 38px !important; }
    .product-card .product-card-img:has(> .after-two) > .after-two { left: 68px !important; }
    .product-card .product-card-img:has(> .after-two) > .bb-card-star-badge svg,
    .product-card .product-card-img:has(> .after-two) > .bb-card-star-badge .pp-star-ico,
    .product-card .product-card-img:has(> .after-two) > .bb-card-grown-badge svg,
    .product-card .product-card-img:has(> .after-two) > .bb-card-recipe-badge svg,
    .product-card .product-card-img:has(> .after-two) > .bb-card-style-badge svg { width: 13px !important; height: 13px !important; }
  }


  /* ── Card badge legend ───────────────────────────────────────────────────
     Opened from #bbLegendBtn, which now sits in the heading row beside the
     listing count (it used to be in the search/filter/sort toolbar).
     Structure mirrors .pack-name-modal-* so the two dialogs on this page read
     as one family; the difference is the phone treatment, where this one docks
     to the bottom as a sheet because it's a read-only reference with nothing
     to type into.

     There was a `.bb-legend-btn { padding:0 11px !important }` here. It made
     sense in the toolbar, where .bb-search-buttons forced these buttons to
     width:auto and they needed horizontal padding to look like pills. In the
     heading the button is a fixed 28px square, and that !important beat the
     padding:0 in its sizing rule — 22px of side padding inside a 28px box left
     about 3px for the glyph, so the button rendered as a squashed rectangle
     with nothing visible in it. Its sizing now lives in exactly one place
     (search .packs-content-heading .bb-legend-btn). */
  .bb-legend-btn svg { margin-right:0 !important; }
  .bb-legend-overlay {
    position:fixed; inset:0; background:rgba(5,6,9,0.72);
    backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
    z-index:1000000; display:none; align-items:center; justify-content:center;
    padding:20px; overflow-y:auto;
  }
  .bb-legend-overlay.show { display:flex; }
  .bb-legend-card {
    position:relative; box-sizing:border-box;
    background:var(--card-bg); border-radius:14px; padding:26px 24px 22px;
    width:100%; max-width:460px; border:1px solid var(--border);
    box-shadow:0 28px 70px rgba(0,0,0,.38); font-family:'Nunito',sans-serif;
  }
  body.dark .bb-legend-card { background:#16161a; border-color:#2c2c31; }
  .bb-legend-close {
    position:absolute; top:14px; right:14px; z-index:3;
    width:34px; height:34px; padding:0; border:0; border-radius:9px;
    background:transparent; color:var(--text-muted); cursor:pointer;
    display:flex; align-items:center; justify-content:center;
    transition:color .15s, background .15s;
  }
  .bb-legend-close:hover { color:var(--text); background:color-mix(in srgb, var(--text) 7%, transparent); }
  .bb-legend-close:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
  .bb-legend-head { margin:0 34px 18px 0; }
  .bb-legend-title { font-size:19px; font-weight:900; line-height:1.2; margin:0 0 6px; color:var(--text); }
  /* --text-soft, not --text-muted: muted is #AFAFAF on white and #555560 on the
     dark card, both of which fall under 3:1 against their own background. Fine
     for a one-word label, not for a paragraph someone has to read. */
  .bb-legend-sub { font-size:13px; font-weight:600; line-height:1.45; color:var(--text-soft); }
  .bb-legend-list {
    list-style:none; margin:0; padding:0; display:grid;
    grid-template-rows:repeat(4, minmax(0, 1fr)); gap:10px;
  }
  /* align-items:flex-start keeps the chip pinned to the first line of copy
     rather than floating to the middle of a three-line description. */
  .bb-legend-row { display:flex; align-items:flex-start; gap:13px; min-height:52px; }
  /* The chips are the real badges: same colour variables, same sizing rules as
     .bb-item-*-badge, so a change to the palette moves both together. */
  .bb-legend-chip {
    flex:0 0 auto; width:34px; height:34px; border-radius:10px;
    display:inline-flex; align-items:center; justify-content:center;
    box-sizing:border-box; line-height:0; border:2px solid transparent;
  }
  .bb-legend-chip svg { display:block; }
  .bb-legend-chip--style  { color:var(--pp-style-icon,#F0ABFC);  background:var(--pp-style-bg,#3B174F);  border-color:var(--pp-style-border,#D946EF); }
  .bb-legend-chip--recipe { color:var(--pp-recipe-icon,#60A5FA); background:var(--pp-recipe-bg,#102A4F); border-color:var(--pp-recipe-border,#3B82F6); }
  .bb-legend-chip--star   { color:var(--pp-star-icon,#F5B301);   background:var(--pp-star-bg,#4D3B05);   border-color:var(--pp-star-border,#F5B301); }
  .bb-legend-chip--grown  { color:var(--pp-grown-icon,#4ADE80);  background:var(--pp-grown-bg,#052E16);  border-color:var(--pp-grown-border,#22C55E); }
  /* No badge variables of its own — the owned-count chip is the flat blue
     .mcard-sync-chip, so this borrows that same blue rather than inventing a
     fourth palette. */
  .bb-legend-chip--sync   { color:#fff; background:#3B82F6; border-color:#3B82F6; }
  .bb-legend-copy { min-width:0; display:flex; flex-direction:column; gap:3px; padding-top:1px; }
  .bb-legend-copy strong { font-size:14px; font-weight:900; color:var(--text); line-height:1.25; }
  .bb-legend-copy span { font-size:12.5px; font-weight:600; line-height:1.45; color:var(--text-soft); }

  /* Phones: dock to the bottom edge as a sheet. Capped at 88vh with the list
     scrolling inside, so a long translation can never push the close button
     off-screen. */
  @media (max-width: 560px) {
    .bb-legend-overlay { align-items:flex-end; padding:0; }
    .bb-legend-card {
      max-width:none; max-height:88vh; overflow-y:auto;
      border-radius:18px 18px 0 0; border-bottom:0;
      padding:22px 18px calc(18px + env(safe-area-inset-bottom));
    }
    .bb-legend-head { margin-right:38px; }
    .bb-legend-title { font-size:18px; }
    .bb-legend-chip { width:32px; height:32px; border-radius:9px; }
  }

/* ── Pack summary rows on phones ──────────────────────────────
   .bb-item-img-wrap was 56px with no breakpoint, so a 375px screen rendered
   the full desktop thumbnail: 56px of art + 12px gap + 32px row padding left
   barely half the row for the item name, and each row stood ~76px tall — only
   about six items fit in the summary sheet at once. Scaling the art and the
   row's own gap/padding down on phones fits roughly three more items per
   screen and leaves the desktop panel (which has the column width to justify
   56px) untouched.

   The marker badges have to scale with it, not just the image: they are 24px
   squares pinned to the thumbnail's bottom-left, and `.after-star` offsets the
   second one to left:32px, so a star + recipe pair spans exactly 56px. Left at
   24px they would overflow a 40px thumbnail, so they step down to 18px with
   the paired offset re-derived (3 + 18 = 21) to span the smaller wrap. */
@media (max-width: 768px) {
  .bb-item-img-wrap { width: 40px; height: 40px; flex: 0 0 40px; }
  .bb-item-row { gap: 10px; padding: 8px 14px; }
  .bb-item-star-badge,
  .bb-item-grown-badge,
  .bb-item-recipe-badge,
  .bb-item-style-badge { width: 18px; height: 18px; border-radius: 6px; border-width: 1.5px; left: 3px; bottom: 3px; }
  .bb-item-grown-badge.after-star,
  .bb-item-recipe-badge.after-star,
  .bb-item-style-badge.after-star { left: 21px; }
  .bb-item-recipe-badge.after-two,
  .bb-item-style-badge.after-two { left: 39px; }
  .bb-item-star-badge svg, .bb-item-star-badge .pp-star-ico,
  .bb-item-grown-badge svg,
  .bb-item-recipe-badge svg,
  .bb-item-style-badge svg { width: 10px; height: 10px; }
}

/* ── Arrival highlight for a card reached from a chat item link ────────────
   builder.html?add=/&item= scrolls this card into view; the ring is how the
   customer knows WHICH card the message meant, since the grid behind it is
   still a grid.

   outline, not border-color: .product-card's border colour is already spoken
   for further up this file and would not take an !important override here, and
   outline draws outside the box so the ring cannot nudge the grid a pixel.
   Purely transient -- builder.js removes the class after ~2.6s, so nothing here
   can leave a card permanently marked. */
@keyframes bbLinkedItemPulse {
  0%   { outline-color: rgba(22,163,74,1);   box-shadow: 0 0 0 0 rgba(22,163,74,.5); }
  70%  { outline-color: rgba(22,163,74,.85); box-shadow: 0 0 0 12px rgba(22,163,74,0); }
  100% { outline-color: rgba(22,163,74,1);   box-shadow: 0 0 0 0 rgba(22,163,74,0); }
}
.product-card.bb-linked-item {
  outline: 3px solid #16A34A !important;
  outline-offset: 2px;
  border-radius: 16px;
  animation: bbLinkedItemPulse 1.3s ease-out 2 !important;
}
/* The ring alone still says "this one" without the pulse. */
@media (prefers-reduced-motion: reduce) {
  .product-card.bb-linked-item { animation: none !important; }
}

/* ── Card foot: price + action row, owned badge on the image ─────────────────
   Replaces the old sync-chip + in-pack-count foot bar. Every card carries the
   same two rows (price, then "+ Add" or the − n + stepper in the same slot), so
   adding an item never changes a card's height. Kept at the end of the file on
   purpose: the foot bar's older rules are declared twice above and again in
   the phone block, several with !important. */
.product-card .mcard-foot-bar{
  display:flex !important;flex-direction:column !important;align-items:stretch !important;
  gap:8px !important;min-height:0 !important;margin:auto 0 0 !important;padding:6px 0 0 !important;
}
.mcard-price{
  display:flex;align-items:baseline;flex-wrap:wrap;column-gap:5px;min-height:19px;
  font-family:'Inter','Geist',sans-serif;font-size:15px;font-weight:900;line-height:1.2;color:var(--text);
}
.mcard-price-from{font-family:'DM Sans',sans-serif;font-size:11.5px;font-weight:700;color:var(--text-muted);}
.mcard-price-was{font-size:11.5px;font-weight:700;color:var(--text-muted);}
/* One-line names sit at the top of the two-line slot rather than centred in
   it, so every name starts on the same line across a row. */
.product-card .mcard-name-row{align-items:flex-start !important;}
/* Five edit-mode buttons (publish, edit, copy link, duplicate, delete) need
   ~136px; a ~100px phone card wraps them rather than letting them overflow. */
.bb-card-edit-controls{flex-wrap:wrap;justify-content:flex-end;max-width:calc(100% - 16px);}
.mcard-act{
  display:flex;align-items:center;justify-content:center;width:100%;height:34px;box-sizing:border-box;
  border-radius:999px;font-family:'DM Sans',sans-serif;touch-action:manipulation;
}
.mcard-add-btn{
  gap:6px;padding:0;cursor:pointer;
  border:1px solid var(--border);background:rgba(0,0,0,.035);color:var(--text-soft);
  font-size:13px;font-weight:800;transition:border-color .15s,color .15s;
}
.mcard-add-btn:hover{border-color:var(--text-muted);color:var(--text);}
body.dark .mcard-add-btn{background:#232327;border-color:transparent;color:#C8C8CF;}
body.dark .mcard-add-btn:hover{color:#F2F2F0;border-color:#3F3F46;}
.mcard-stepper{
  justify-content:space-between;overflow:hidden;
  background:rgba(22,163,74,.10);border:1.5px solid rgba(22,163,74,.28);
}
body.dark .mcard-stepper{background:rgba(34,197,94,.16);border-color:rgba(74,222,128,.3);}
.mcard-step-btn,.mcard-step-val{
  height:100%;border:0;background:transparent;padding:0;cursor:pointer;
  color:var(--accent-deep,#15803D);font-family:'Inter','Geist',sans-serif;
}
body.dark .mcard-step-btn,body.dark .mcard-step-val{color:#4ADE80;}
.mcard-step-btn{flex:0 0 38px;font-size:18px;font-weight:900;line-height:1;}
.mcard-step-btn:hover{background:rgba(22,163,74,.16);}
.mcard-step-val{flex:1 1 auto;min-width:0;padding:0 2px;font-size:13px;font-weight:800;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.mcard-act-soon{border:1px dashed var(--border);color:var(--text-muted);font-size:12px;font-weight:800;}

/* Owned badge — bottom-right of the image; the marker strip owns bottom-left. */
.product-card-img .mcard-owned-slot{position:absolute;right:8px;bottom:8px;z-index:3;display:flex;pointer-events:none;}
.product-card-img .mcard-owned-slot:empty{display:none;}
.product-card-img .mcard-sync-chip{font-size:12px;padding:4px 8px;gap:4px;box-shadow:0 2px 8px rgba(0,0,0,.25);}
.product-card-img .mcard-sync-chip svg{width:11px;height:11px;}
body.dark .product-card-img .mcard-sync-chip{background:rgba(30,58,138,.88);color:#BFDBFE;}

/* The hover "+ Add" overlay duplicated the card's own Add button, so it now
   only appears in the bulk modes, where it names what a click will do. */
#bbGrid:not(.bb-remove-mode):not(.bb-hide-mode):not(.bb-favourite-mode):not(.bb-hidden-only-view) .product-card:hover .mcard-media-action{
  opacity:0 !important;pointer-events:none !important;
}
#bbGrid.bb-remove-mode .mcard-act,
#bbGrid.bb-hide-mode .mcard-act,
#bbGrid.bb-favourite-mode .mcard-act,
#bbGrid.bb-hidden-only-view .mcard-act{visibility:hidden;}

/* ── Phone category chips ── */
.bb-cat-chips{
  display:none;position:relative;gap:6px;overflow-x:auto;overscroll-behavior-x:contain;
  scrollbar-width:none;-webkit-overflow-scrolling:touch;padding:1px 0;
}
.bb-cat-chips::-webkit-scrollbar{display:none;}
.bb-cat-chip{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 12px;
  border-radius:999px;border:1px solid var(--border);background:var(--white,#fff);color:var(--text-soft);
  font-family:'DM Sans',sans-serif;font-size:12.5px;font-weight:800;white-space:nowrap;cursor:pointer;
}
body.dark .bb-cat-chip{background:#141416;color:#B0B0B8;}
.bb-cat-chip.active,body.dark .bb-cat-chip.active{background:var(--text);color:var(--bg);border-color:var(--text);}
.bb-cat-chip-count{font-size:10.5px;font-weight:700;opacity:.6;}
.bb-cat-chip-more{width:32px;padding:0;justify-content:center;}

@media (max-width: 999.98px) {
  .bb-cat-chips{display:flex;}
  .bb-cat-chips[hidden]{display:none;}
  /* The chips replace the "All ▾" toolbar button; its sheet is the chips' first button. */
  .bb-cat-mobile-btn,
  .bb-search-buttons .bb-cat-mobile-btn{display:none !important;}
  /* The nav already says Pack Builder — the 34px page title cost a fifth of the first screen. */
  .bb-page-header{display:none !important;}
  .product-card .mcard-badge-new{display:none !important;}

  /* Phone bottom bar: open-summary button on the left, Add to Basket on the right. */
  .bb-pack-fab{padding:10px 12px calc(10px + env(safe-area-inset-bottom, 0px)) !important;gap:10px !important;}
  .bb-pack-fab-open{
    flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:8px;
    padding:4px 2px;border:0;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer;
  }
  .bb-pack-fab-chev{flex:0 0 auto;color:var(--text-muted);}
  .bb-pack-fab-atc{
    flex:0 0 auto;display:inline-flex;align-items:center;gap:8px;height:46px;padding:0 16px;
    border:0;border-radius:12px;background:#16A34A;color:#fff;cursor:pointer;white-space:nowrap;
    font-family:'Inter','DM Sans',sans-serif;font-size:14px;font-weight:900;
    box-shadow:0 6px 18px rgba(22,163,74,.28);
  }
  body.dark .bb-pack-fab-atc{background:#22C55E;color:#052E16;}
  .bb-pack-fab-atc.is-blocked,
  body.dark .bb-pack-fab-atc.is-blocked{background:#26262B;color:#8A8A94;box-shadow:none;}
  body:not(.dark) .bb-pack-fab-atc.is-blocked{background:#E7E7E4;color:#8A8A94;}
  .bb-pack-fab-atc .bb-pack-fab-price{
    display:inline !important;height:auto !important;padding:0 !important;background:none !important;
    font:inherit !important;color:inherit !important;opacity:.85;
  }

  /* Card foot, scaled to the ~105px phone card. */
  .mcard-price{font-size:12.5px;min-height:16px;column-gap:3px;}
  .mcard-price-from,.mcard-price-was{font-size:9.5px;}
  .mcard-act{height:30px;}
  .mcard-add-btn{font-size:12px;gap:4px;}
  .mcard-add-btn svg{width:11px;height:11px;}
  /* The phone rule higher up shrinks this row to 26px (one line), so a one-
     line name pulled its price and Add button above every two-line card in
     the row. Reserve two lines of the 12.5px/1.25 name at every width. */
  .product-card .mcard-name-row{min-height:31.25px !important;}
  /* ~100px card: 30px buttons left ~30px for the count, which truncated to
     "4…". 24px buttons and no side padding fit a compact count ("999", "1.5k"). */
  .mcard-step-btn{flex-basis:24px;font-size:15px;}
  .mcard-step-val{font-size:11.5px;padding:0;text-overflow:clip;}
  .product-card-img .mcard-owned-slot{right:5px;bottom:5px;}
  .product-card-img .mcard-sync-chip{font-size:10px !important;padding:2px 6px !important;gap:3px !important;}
  .product-card-img .mcard-sync-chip svg{width:9px !important;height:9px !important;}
}

@media (max-width: 768px) {
  /* Search, Quick Tools, Filter and Sort share one line; the chips take the next. */
  .bb-search-row .bb-search-left-col{flex-direction:row !important;flex-wrap:nowrap !important;align-items:center;gap:6px !important;}
  .bb-search-row .bb-search-inner{flex:1 1 0 !important;width:auto !important;min-width:0 !important;order:0 !important;}
  .bb-search-row .bb-search-buttons{flex:0 0 auto !important;width:auto !important;flex-wrap:nowrap !important;gap:6px !important;}
  /* Compact "you are here" heading above the search row. */
  .packs-content-heading{min-height:28px !important;gap:8px !important;}
  #bbCategoryTitle{font-size:15px !important;}
  #bbCategoryTitle .packs-cat-icon,
  #bbCategoryTitle .packs-cat-icon-image{width:18px !important;height:18px !important;flex-basis:18px !important;}
  .packs-content-heading .bb-legend-btn{
    width:28px !important;min-width:28px !important;max-width:28px !important;
    height:28px !important;min-height:28px !important;max-height:28px !important;border-radius:8px;
  }
  .packs-content-heading .bb-legend-btn svg{width:14px;height:14px;}
}
@media (max-width: 480px) {
  .bb-search-buttons .bb-actions-btn,
  .bb-search-buttons .bb-panel-icon-btn{width:40px !important;min-width:40px !important;height:40px !important;}
}

/* ── Shelves row + featured shelf banner (see _bbRenderShelves) ──────────── */
.bb-shelves-wrap[hidden],.bb-shelf-banner-wrap[hidden]{display:none !important;}
.bb-shelves-wrap{position:relative;flex:none;}
.bb-shelves{
  display:flex;gap:8px;overflow-x:auto;overscroll-behavior-x:contain;
  scrollbar-width:none;-webkit-overflow-scrolling:touch;position:relative;padding:2px 0 12px;
}
/* Edge fades only on the side(s) with more to scroll (set by _bbUpdateShelfArrows). */
.bb-shelves-wrap.has-next .bb-shelves{
  -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 56px),transparent);
  mask-image:linear-gradient(90deg,#000 calc(100% - 56px),transparent);
}
.bb-shelves-wrap.has-prev .bb-shelves{
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 56px);
  mask-image:linear-gradient(90deg,transparent,#000 56px);
}
.bb-shelves-wrap.has-prev.has-next .bb-shelves{
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 56px,#000 calc(100% - 56px),transparent);
  mask-image:linear-gradient(90deg,transparent,#000 56px,#000 calc(100% - 56px),transparent);
}
.bb-shelves-arrow{
  position:absolute;top:4px;z-index:3;width:34px;height:34px;border-radius:50%;
  display:none;align-items:center;justify-content:center;padding:0;cursor:pointer;
  border:1px solid var(--border);background:var(--white,#fff);color:var(--text);
  box-shadow:0 4px 14px rgba(0,0,0,.18);
}
body.dark .bb-shelves-arrow{background:#1E1E23;border-color:#34343B;color:#F2F2F0;box-shadow:0 4px 14px rgba(0,0,0,.55);}
.bb-shelves-arrow:hover{border-color:var(--text-muted);}
.bb-shelves-prev{left:0;}
.bb-shelves-next{right:0;}
.bb-shelves-wrap.has-prev .bb-shelves-prev,
.bb-shelves-wrap.has-next .bb-shelves-next{display:flex;}
.bb-shelves::-webkit-scrollbar{display:none;}
.bb-shelf{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:8px;height:38px;padding:0 13px 0 5px;
  border-radius:999px;border:1px solid var(--border);background:var(--white,#fff);color:var(--text-soft);
  font-family:'DM Sans',sans-serif;font-size:13px;font-weight:800;white-space:nowrap;cursor:pointer;
  transition:border-color .15s,color .15s;
}
.bb-shelf.bb-shelf-all{padding:0 14px;}
.bb-shelf:hover{border-color:var(--text-muted);color:var(--text);}
body.dark .bb-shelf{background:#141416;color:#B0B0B8;}
.bb-shelf.active,body.dark .bb-shelf.active{background:var(--text);border-color:var(--text);color:var(--bg);}
.bb-shelf em{font-style:normal;font-size:11px;font-weight:700;opacity:.55;}
.bb-shelf-thumb{flex:none;width:28px;height:28px;border-radius:50%;object-fit:contain;padding:2px;box-sizing:border-box;background:rgba(0,0,0,.06);}
body.dark .bb-shelf-thumb{background:#232327;}
.bb-shelf.active .bb-shelf-thumb{background:rgba(255,255,255,.55);}
body.dark .bb-shelf.active .bb-shelf-thumb{background:#E4E4E0;}

.bb-shelf-banner-wrap{flex:none;margin:0 0 10px;}
.bb-shelf-banner{
  position:relative;display:flex;width:100%;min-height:120px;padding:0;overflow:hidden;cursor:pointer;text-align:left;
  border:1px solid rgba(74,222,128,.28);border-radius:16px;color:#fff;
  background:radial-gradient(120% 150% at 85% 15%,rgba(34,197,94,.34),transparent 60%),linear-gradient(110deg,#0d1a14 0%,#12261c 48%,#18181d 100%);
}
.bb-shelf-banner-copy{position:relative;z-index:2;display:flex;flex-direction:column;justify-content:center;gap:3px;padding:16px 20px;min-width:0;max-width:56%;}
.bb-shelf-banner-kicker{font:800 10px 'DM Sans',sans-serif;letter-spacing:.14em;text-transform:uppercase;color:#86EFAC;}
.bb-shelf-banner strong{font:900 24px/1.1 'Inter','Geist',sans-serif;color:#fff;}
.bb-shelf-banner-sub{font:700 12px 'DM Sans',sans-serif;color:#D1FAE5;opacity:.8;}
.bb-shelf-banner-cta{margin-top:8px;align-self:flex-start;background:#22C55E;color:#052E16;font:900 12px 'Inter',sans-serif;padding:6px 13px;border-radius:999px;}
.bb-shelf-banner-art{position:absolute;right:12px;top:0;bottom:0;width:46%;pointer-events:none;}
.bb-shelf-banner-art img{position:absolute;object-fit:contain;filter:drop-shadow(0 8px 14px rgba(0,0,0,.55));}
.bb-shelf-banner-art .bb-sba0{width:36%;height:90%;right:30%;top:5%;}
.bb-shelf-banner-art .bb-sba1{width:26%;height:64%;right:3%;top:6%;}
.bb-shelf-banner-art .bb-sba2{width:24%;height:58%;right:62%;top:32%;}
.bb-shelf-banner-art .bb-sba3{width:24%;height:56%;right:6%;bottom:0;}

/* A card pulled onto a shelf from another category: its own category name in
   the badge slot, blue so it never reads as NEW/SALE. */
.product-card .mcard-cat-tag{background:rgba(59,130,246,.16) !important;color:#1D4ED8 !important;}
body.dark .product-card .mcard-cat-tag{background:rgba(59,130,246,.24) !important;color:#93C5FD !important;}

.bb-category-editor-field select{
  width:100%;box-sizing:border-box;padding:11px 12px;border-radius:10px;border:1px solid var(--border);
  background:var(--bg);color:var(--text);font:600 14px 'DM Sans',sans-serif;cursor:pointer;
}
.bb-category-banner-hint{display:block;margin-top:6px;font-size:12px;font-weight:600;color:var(--text-muted);}

@media (max-width: 999.98px) {
  .bb-shelves{padding:0 0 8px;gap:6px;}
  /* Phones and tablets swipe the row; arrows would only cover pills. */
  .bb-shelves-wrap .bb-shelves-arrow{display:none !important;}
  .bb-shelf{height:30px;font-size:11.5px;gap:6px;padding-right:10px;}
  .bb-shelf.bb-shelf-all{padding:0 11px;}
  .bb-shelf-thumb{width:22px;height:22px;}
  .bb-shelf em{font-size:10px;}
  .bb-shelf-banner-wrap{margin-bottom:8px;}
  .bb-shelf-banner{min-height:84px;border-radius:12px;}
  .bb-shelf-banner-copy{padding:10px 12px;gap:1px;max-width:60%;}
  .bb-shelf-banner strong{font-size:16px;}
  .bb-shelf-banner-kicker{font-size:8.5px;}
  .bb-shelf-banner-sub{font-size:10.5px;}
  .bb-shelf-banner-cta{display:none;}
  .bb-shelf-banner-art .bb-sba2,.bb-shelf-banner-art .bb-sba3{display:none;}
}
