  :root {
    --white:#FFFFFF;--text:#1A1A1A;--text-soft:#3D3D3D;
    --text-muted:#AFAFAF;--border:#ECECEC;--cream:#F7F5F0;
    --radius:16px;--radius-sm:10px;
    --bg:#FAFAFA;
  }
  body.dark{
    --white:#18181C;--text:#F2F2F0;--text-soft:#B0B0B8;
    --text-muted:#555560;--border:#26262B;--cream:#141416;
    --bg:#0f0f11;
  }
  *,*::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:'Geist','DM Sans',sans-serif;min-height:100vh;}

  /* ── Toolbar — no background, just spacing ── */
  .packs-toolbar{
    display:flex;flex-direction:column;gap:0;
    position:sticky;top:64px;
    z-index:995;
    background:none;
    backdrop-filter:none;-webkit-backdrop-filter:none;
    box-shadow:none;
    transition:none;
    width:85%;max-width:1400px;margin:0 auto;
    padding:0;
  }
  @media(max-width:1024px){
    .packs-toolbar{width:100%;padding:0 16px;top:0;}
  }

  .packs-toolbar-top{
    display:flex;align-items:center;justify-content:space-between;
    min-height:48px;padding:8px 0;position:relative;
  }
  .packs-toolbar-left{display:flex;align-items:center;gap:0;flex-shrink:1;min-width:0;overflow:hidden;}
  /* Inline title tabs — 14px to match index.html left section width */
  .packs-title-tabs{display:flex;align-items:center;gap:6px;white-space:nowrap;}
  .packs-title-tab{
    font-family:'Geist','DM Sans',sans-serif;font-size:22px;font-weight:500;
    color:var(--text-muted);letter-spacing:-0.02em;line-height:1;
    border:none;background:none;cursor:pointer;padding:0 4px 0 0;
    transition:color .15s;white-space:nowrap;
  }
  .packs-title-tab:hover{color:var(--text);}
  .packs-title-tab.active{font-weight:700;color:var(--text);}
  body.dark .packs-title-tab{color:#555560;}
  body.dark .packs-title-tab:hover{color:#F2F2F0;}
  body.dark .packs-title-tab.active{color:#F2F2F0;}
  .packs-title-sep{
    font-size:17px;color:var(--text-muted);opacity:0.35;
    padding:0 4px;line-height:1;pointer-events:none;
  }
  .packs-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 8px;
    font-family:'Geist','DM Sans',sans-serif;font-size:12px;font-weight:700;color:var(--text-muted);
  }
  body.dark .packs-toolbar-count{background:rgba(255,255,255,0.05);}

  /* ── Sticky search bar (matches builder.html) ── */
  .packs-search-wrap{
    position:sticky;top:64px;z-index:990;
    background:var(--bg,#F9F9F7);
    padding:0 0 12px;margin-bottom:0;
    width:100%;
  }
  body.dark .packs-search-wrap{background:#0e0e10;}
  .packs-search-container{
    display:flex;align-items:center;
    width:85%;max-width:1400px;margin-left:auto;margin-right:auto;
  }
  .packs-search-inner{position:relative;display:flex;align-items:center;flex:1;min-width:0;}
  .packs-search-icon{position:absolute;left:12px;color:#AFAFAF;pointer-events:none;display:flex;align-items:center;}
  .packs-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;
  }
  .packs-search-input:focus{border-color:#16A34A;box-shadow:0 0 0 3px rgba(22,163,74,0.09);}
  .packs-search-input::placeholder{color:#AFAFAF;}
  body.dark .packs-search-input{background:#141416;border-color:#26262B;color:#F2F2F0;}
  body.dark .packs-search-input:focus{border-color:#4ADE80;box-shadow:0 0 0 3px rgba(74,222,128,0.1);}
  .packs-search-clear{
    position:absolute;right:8px;width:20px;height:20px;border:none;background:none;
    cursor:pointer;padding:0;color:#AFAFAF;display:none;align-items:center;justify-content:center;
    border-radius:50%;transition:color .12s,background .12s;font-size:16px;line-height:1;
  }
  .packs-search-clear:hover{color:#555;background:rgba(0,0,0,0.07);}
  body.dark .packs-search-clear:hover{color:#ddd;background:rgba(255,255,255,0.08);}
  @media(max-width:1024px){
    .packs-search-wrap{padding:10px 16px 12px;}
    .packs-search-container{width:100%;}
  }
  /* The site header is 64px on desktop but 59px once the mobile nav kicks in
     (≤999.98px). Stick the search bar right under it — top:0 made it hide behind
     the fixed header on phones; the old 64px left a 5px gap on tablets. */
  @media(max-width:999.98px){.packs-search-wrap{top:59px;}}
  @media(max-width:768px){
    .packs-search-container{flex-wrap:wrap;}
    .packs-search-inner{flex:1 1 100%;}
    .packs-view-wrap{flex:1 1 100%;}
    .packs-view-btn{width:100%;}
    .packs-view-dropdown{width:100%;left:0 !important;right:0 !important;}
  }



  /* ── View dropdown (Official / Saved) ── */
  .packs-view-wrap{position:relative;flex-shrink:0;}
  .packs-view-btn{
    height:38px;min-width:140px;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;
  }
  .packs-view-btn:hover,.packs-view-btn.open{border-color:#16A34A;}
  body.dark .packs-view-btn{background:#141416;border-color:#26262B;color:#F2F2F0;}
  .packs-view-dropdown{
    position:absolute;top:calc(100% + 6px);left:0;min-width:170px;
    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;
  }
  .packs-view-dropdown.open{display:flex;}
  body.dark .packs-view-dropdown{background:#1e1e22;box-shadow:0 4px 6px rgba(0,0,0,.3),0 12px 32px rgba(0,0,0,.4);}
  .packs-view-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;
  }
  .packs-view-opt:hover{background:#F4F4F3;}
  .packs-view-opt.active{background:rgba(22,163,74,.09);color:#16A34A;font-weight:700;}
  body.dark .packs-view-opt{color:#F2F2F0;}
  body.dark .packs-view-opt:hover{background:rgba(255,255,255,.06);}
  body.dark .packs-view-opt.active{background:rgba(74,222,128,.1);color:#4ADE80;}

  /* Right controls */
  .packs-toolbar-right{display:flex;align-items:center;gap:12px;flex-shrink:0;}

  /* Sort + Filter buttons — same style as index.html */
  .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:#555560;}
  #packsSortVal{font-size:13px;font-weight:700;color:#1A1A1A;}
  body.dark #packsSortVal{color:#F2F2F0;}
  .pp-sort-menu{
    display:none;position:absolute;right:0;top:calc(100% + 8px);z-index:300;
    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;}
  .product-sort-wrap.has-filters{border-color:var(--accent);color:var(--accent);background:rgba(22,163,74,0.06);}

  /* Filter dropdown */
  .packs-filter-wrap{position:relative;}
  .packs-filter-dd{
    display:none;position:absolute;right:0;top:calc(100% + 8px);z-index:300;
    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:12px;min-width:220px;
  }
  body.dark .packs-filter-dd{background:#141416;border-color:#26262B;}
  .packs-filter-dd.open{display:block;}
  .packs-filter-label{
    font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:.07em;
    color:var(--text-muted);margin-bottom:8px;
  }
  .packs-filter-pills{display:flex;flex-wrap:wrap;gap:5px;}
  .packs-filter-pill{
    display:inline-flex;align-items:center;height:28px;padding:0 11px;
    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 .15s;white-space:nowrap;
  }
  .packs-filter-pill:hover{border-color:#AFAFAF;color:var(--text);}
  .packs-filter-pill.active{background:var(--text);color:#fff;border-color:var(--text);}
  body.dark .packs-filter-pill{background:#1d1c24;border-color:#2E2E34;color:#888890;}
  body.dark .packs-filter-pill:hover{border-color:#888890;color:var(--text);}
  body.dark .packs-filter-pill.active{background:var(--text);color:#0E0E10;border-color:var(--text);}
  .packs-filter-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 0;margin-top:8px;text-decoration:underline;text-underline-offset:2px;
    display:block;transition:color .15s;
  }
  .packs-filter-reset:hover{color:#EF4444;}

  /* ── Page header ── */
  .packs-page-header{
    width:85%;
    max-width:1400px;
    margin:6px auto 12px auto;
    box-sizing:border-box;
    display:flex;align-items:flex-end;justify-content:space-between;gap:16px;
  }
  @media(max-width:1024px){.packs-page-header{width:100%;padding:0 16px;}}
  /* Match builder.html's fullscreen desktop spacing (see .bb-page-header in
     builder.css @media(min-width:1025px)): no extra top margin, larger bottom
     margin, so the two pages' hero header sits at the same height and the
     gap down to the content grid lines up pixel-for-pixel. */
  @media(min-width:1025px){.packs-page-header{margin:0 auto 16px auto;}}
  .packs-page-left{display:flex;flex-direction:row;align-items:center;gap:12px;}
  .packs-title-row{
    display:flex;align-items:center;gap:0;
    margin:0;
  }
  .packs-page-h1{
    font-family:'Inter','Geist',sans-serif;font-size:34px;font-weight:800;
    color:var(--text);margin:0;letter-spacing:-0.02em;line-height:1.1;
    cursor:pointer;
  }
  .packs-title-sep-slash{
    font-family:'Inter','Geist',sans-serif;font-size:34px;font-weight:300;
    color:var(--text-muted);margin:0 8px;opacity:0.4;line-height:1.1;
  }
  .packs-page-h1.dimmed{color:var(--text-muted);font-weight:600;opacity:0.5;font-size:34px;}
  .packs-count-pill{
    display:inline-flex;align-items:center;
    background:rgba(0,0,0,0.04);border:1.5px solid var(--border);
    border-radius:50px;padding:5px 16px;
    font-family:'Geist','DM Sans',sans-serif;font-size:16px;font-weight:700;
    color:var(--text-muted);width:fit-content;
    letter-spacing:0.02em;
  }
  body.dark .packs-count-pill{background:rgba(255,255,255,0.05);}
  .packs-page-right{display:flex;align-items:center;gap:8px;margin-bottom:0;}

  /* ── Main content ── */
  .packs-wrap{
    background:none;
    border:none;
    box-shadow:none;
    width:85%;
    max-width:1400px;
    margin:0 auto 40px auto;
    padding:0 0 40px;
    box-sizing:border-box;
  }
  body.dark .packs-wrap{background:none;}
  @media(max-width:1024px){.packs-wrap{width:100%;padding:16px 0 40px;}}

  /* New pack banner */
  .new-pack-banner{
    display:flex;align-items:center;gap:12px;
    padding:14px 18px;border-radius:12px;margin-bottom:22px;
    width:fit-content;max-width:100%;
    background:rgba(37,99,235,.07);border:1.5px solid rgba(37,99,235,.2);
    font-family:'Geist','DM Sans',sans-serif;font-size:13px;font-weight:600;color:#1D4ED8;
    animation:bannerIn .4s cubic-bezier(.34,1.3,.64,1);
  }
  body.dark .new-pack-banner{background:rgba(96,165,250,.1);border-color:rgba(96,165,250,.25);color:#60A5FA;}
  @keyframes bannerIn{from{opacity:0;transform:translateY(-8px);}to{opacity:1;transform:translateY(0);}}
  .new-pack-banner-ico{font-size:18px;flex-shrink:0;}
  .new-pack-banner-close{
    margin-left:auto;background:none;border:none;cursor:pointer;
    color:currentColor;opacity:.6;font-size:16px;padding:0 4px;line-height:1;
  }
  .new-pack-banner-close:hover{opacity:1;}

  /* Grid */
  .packs-grid{
    display:grid;
    grid-template-columns:repeat(auto-fill,minmax(min(240px,100%),1fr));
    gap:18px;
  }

  /* ── 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;}
  }

  /* ── Category sidebar layout ── */
  .packs-layout{display:flex;align-items:flex-start;gap:28px;}
  .packs-content{flex:1;min-width:0;}
  .packs-sidebar{
    width:260px;flex-shrink:0;
    display:flex;flex-direction:column;gap:2px;
    position:sticky;top:84px;
    border-right:1.5px solid var(--border);
    padding-right:16px;
  }

  .packs-sidebar-indicator{
    position:absolute;
    right:-1.5px;
    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;
  }
  .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;
  }
  .packs-cat-item:hover{background:rgba(0,0,0,0.04);color:var(--text);}
  body.dark .packs-cat-item:hover{background:rgba(255,255,255,0.05);}
  .packs-cat-item.active{color:var(--text);font-weight:700;background:rgba(0,0,0,0.03);}
  body.dark .packs-cat-item.active{background:rgba(255,255,255,0.04);}
  .packs-cat-item:disabled,
  .packs-cat-item.disabled{
    opacity:0.4;
    cursor:not-allowed;
    pointer-events:none;
  }
  .packs-cat-count{font-size:12px;font-weight:600;color:var(--text-muted);}
  .packs-cat-section-label{
    padding:14px 10px 4px;font-size:11px;font-weight:800;letter-spacing:.06em;
    text-transform:uppercase;color:var(--text-muted);
  }
  /* Sale category — tinted with the same accent as .pack-badge-sale so the
     sidebar entry reads as a sale at a glance, not as another plain category */
  .packs-cat-sale{color:#2563eb;font-weight:700;}
  .packs-cat-sale:hover{color:#1d4ed8;background:rgba(37,99,235,.07);}
  .packs-cat-sale.active{color:#2563eb;background:rgba(37,99,235,.09);}
  .packs-cat-sale .packs-cat-count{color:#2563eb;opacity:.75;}
  body.dark .packs-cat-sale{color:#93c5fd;}
  body.dark .packs-cat-sale:hover{color:#bfdbfe;background:rgba(96,165,250,.1);}
  body.dark .packs-cat-sale.active{color:#93c5fd;background:rgba(96,165,250,.12);}
  body.dark .packs-cat-sale .packs-cat-count{color:#93c5fd;}
  .packs-cat-edit-btn{
    display:none;align-items:center;justify-content:center;
    width:100%;padding:9px 10px;margin-top:8px;border-radius:8px;
    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);}

  /* ── Pack Builder promo card — same family as builder.html's sidebar promo,
     pointing the other direction (Browse → Pack Builder). ── */
  .packs-promo-card{
    margin-top:20px;background:#F3EAFD;border:1.5px solid rgba(124,58,237,0.12);
    border-radius:20px;padding:22px 20px;position:relative;overflow:hidden;
    display:flex;align-items:center;justify-content:space-between;
    box-shadow:0 2px 12px rgba(124,58,237,0.04);user-select:none;
  }
  body.dark .packs-promo-card{background:rgba(124,58,237,0.14);border-color:rgba(167,139,250,0.22);}
  .packs-promo-card-content{flex:1;min-width:0;padding-right:6px;z-index:1;}
  .packs-promo-card-title{
    font-family:'Inter','Geist','Fredoka',sans-serif;font-size:16px;font-weight:800;
    color:#4C1D95;margin:0 0 8px;line-height:1.25;letter-spacing:-0.015em;
  }
  body.dark .packs-promo-card-title{color:#DDD6FE;}
  .packs-promo-card-sub{
    font-family:'Inter','Geist',sans-serif;font-size:13.5px;font-weight:600;
    color:#4C1D95;margin:0 0 14px;line-height:1.55;letter-spacing:-0.01em;
  }
  body.dark .packs-promo-card-sub{color:#DDD6FE;}
  .packs-promo-card-sparkles{flex-shrink:0;display:flex;align-items:center;justify-content:center;pointer-events:none;z-index:1;}
  .packs-promo-card-btn{
    display:inline-flex;align-items:center;gap:7px;width:100%;justify-content:center;
    padding:10px 16px;border:none;border-radius:12px;background:#7C3AED;color:#fff;
    font-family:'Geist','DM Sans',sans-serif;font-size:13.5px;font-weight:700;
    cursor:pointer;text-decoration:none;box-sizing:border-box;transition:background .15s;
  }
  .packs-promo-card-btn:hover{background:#6D28D9;}
  .packs-cat-add-btn{
    display:none;align-items:center;justify-content:center;gap:6px;
    width:100%;padding:10px;margin-top:10px;border-radius:8px;
    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);}
  .packs-cat-clear-zone {
    display:none;align-items:center;justify-content:center;gap:8px;
    width:100%;padding:10px;margin-top:10px;border-radius:8px;
    border:1.5px dashed var(--border);background:none;color:var(--text-muted);
    font-family:'Geist','DM Sans',sans-serif;font-size:13px;font-weight:700;
    cursor:pointer;transition:all 0.15s;box-sizing:border-box;
  }
  .packs-cat-clear-zone.active-target {
    border-color:#EF4444;color:#EF4444;
  }
  .packs-cat-clear-zone.drag-over {
    background:rgba(239, 68, 68, 0.1);border-color:#EF4444;transform:scale(1.02);color:#EF4444;
  }
  .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:4px;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-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:3px;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{background:rgba(22,163,74,0.12);color:#16A34A;}

  /* Content header — Sticky top bar with scroll mask */
  .packs-content-header{
    display:flex;align-items:center;justify-content:space-between;
    margin-bottom:20px;position:sticky;top:72px;z-index:25;
    background:var(--bg);padding:14px 0;
    border-bottom:1px solid var(--border);
  }
  /* Small scroll-seam mask, not a full 72px block — a 72px-tall reach here
     ends up painting a solid rectangle over the overwrite-mode banner (and
     anything else sitting just above this header) even before the page has
     scrolled far enough for the header to actually be stuck, since CSS has
     no way to condition this pseudo-element on "currently stuck". Keeping
     the reach small means it can only ever cover the few pixels right at
     this header's own top edge, never content further up the page. */
  .packs-content-header::before{
    content:'';position:absolute;top:-10px;left:-20px;right:-20px;
    height:10px;background:var(--bg);pointer-events:none;
  }
  .packs-content-title{
    font-size:22px;font-weight:700;color:var(--text);margin:0;
    font-family:'Geist','DM Sans',sans-serif;
  }

  /* ── Mobile category sheet ──
     Desktop keeps the vertical sidebar; ≤1024px the *same* aside becomes a
     slide-up sheet driven by these three pieces. All three are inert above the
     breakpoint so the desktop layout is untouched. */
  .packs-cat-mobile-btn{display:none;}
  .packs-cat-sheet-backdrop{display:none;}
  .packs-sheet-head{display:none;}
  .packs-cat-label-sheet{display:none;}

  @media(max-width:1024px){
    /* align-items on .packs-layout is flex-start, which on the desktop ROW axis
       means "don't stretch the columns to equal height". Flipping to a column
       makes that same value apply to WIDTH — so each child shrank to its
       max-content width instead of the container's, and .packs-content ended up
       521px wide inside a 343px phone viewport, scrolling the whole page
       sideways by ~180px. Stretch is what's wanted once the axis flips. */
    .packs-layout{flex-direction:column;gap:16px;align-items:stretch;}
    .packs-content{width:100%;min-width:0;}
    /* The control row (search, view toggle, sort) is ~490px of nowrap content;
       let it wrap rather than set the width floor for the whole column. On a
       phone it also drops onto its own line under the title — min-width:auto is
       the flex default and would otherwise stop it shrinking to fit beside one. */
    .packs-content-header{flex-wrap:wrap;gap:10px;}
    .packs-header-controls{flex-wrap:wrap;min-width:0;flex:1 1 100%;gap:8px !important;}
    /* The <h2> duplicates the category button's label on this breakpoint (both
       say "All" / "Currency" / "Favourites"), and the row it occupies is pure
       cost on a 375px screen — the button is the one that's also a control. */
    /* !important: that wrapper carries an inline display:flex */
    .packs-content-header > div:first-child{display:none !important;}
    /* Search on its own row, then the two filter controls share the next one.
       The 340px inline width on .packs-search-inner is a desktop sizing hint;
       flex-basis:100% overrides it as the main size, but zero it out anyway so
       nothing downstream reads a 340px floor on a 343px viewport. */
    .packs-search-inner{flex:1 1 100% !important;width:auto !important;min-width:0;}
    .packs-cat-mobile-btn,.packs-view-wrap{flex:1 1 0;min-width:0;}
    .packs-view-btn{width:100%;min-width:0;}
    .packs-view-dropdown{width:100%;left:0 !important;right:0 !important;}

    /* Trigger: mirrors .packs-view-btn's shape so the two read as one pair */
    .packs-cat-mobile-btn{
      display:flex;align-items:center;gap:8px;
      height:38px;padding:0 10px 0 12px;
      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;transition:border-color .15s;
    }
    body.dark .packs-cat-mobile-btn{background:#141416;border-color:#26262B;color:#F2F2F0;}
    .packs-cat-mobile-btn.open{border-color:#16A34A;}
    .packs-cat-mobile-ico{display:flex;flex-shrink:0;color:var(--text-soft);}
    /* Long category names truncate rather than widening the button past its
       half of the row and pushing Sort off the edge. */
    .packs-cat-mobile-label{
      flex:1;min-width:0;text-align:left;
      overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
    }
    .packs-cat-mobile-chev{flex-shrink:0;color:var(--text-soft);}

    /* Backdrop. .page-wrap sets z-index:1, which caps everything inside it
       below the fixed site header (z-index:999) — so the body class lifts
       .page-wrap for as long as the sheet is open, same trick builder.css
       uses for its pack sheet. */
    body.pp-cat-sheet-open .page-wrap{z-index:1080;}
    .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;}

    /* The sidebar itself, restyled as the sheet */
    .packs-sidebar{
      position:fixed;left:0;right:0;bottom:0;top:auto;
      width:100%;max-height:min(76vh,600px);
      z-index:1075;
      display:flex;flex-direction:column;gap:2px;align-items:stretch;
      background:var(--white);border-right: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{transition:none;}
      .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:50px;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);}

    /* Grouping labels — the whole point of the sheet over the old chip strip:
       "Your Packs" / "Offers" / "Categories" are three different kinds of
       filter and used to sit shoulder-to-shoulder in one undifferentiated row. */
    .packs-cat-label-sheet{display:block;}
    .packs-cat-section-label{padding:12px 6px 2px;}
    /* Full-width rows with a 44px touch target, not pills */
    .packs-cat-item{
      width:100%;flex-shrink:0;
      padding:12px 10px;border:none;border-radius:10px;
      font-size:15px;
    }
    .packs-cat-item.active{
      background:rgba(0,0,0,.05);font-weight:800;
    }
    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;}
    /* margin-left:auto keeps the count pinned right once the active row grows a
       third child (the ::after checkmark) and space-between stops sufficing. */
    .packs-cat-count{font-size:13px;margin-left:auto;}
    /* Admin-only controls keep their shape in the sheet */
    .packs-cat-add-btn,.packs-cat-edit-btn,.packs-cat-back-btn{flex-shrink:0;white-space:nowrap;}
    /* The scroll-seam mask bleeds 20px past each edge to cover the desktop
       gutter. `.page` only has 16px of padding here, so the extra 4px hung off
       the right of the viewport and gave the whole page a horizontal scroll.
       Match the bleed to the actual mobile gutter. */
    .packs-content-header::before{left:-16px;right:-16px;}
    /* Dynamic categories render into #packsCatList; it must not introduce a
       block of its own between the sheet's flex rows. */
    #packsCatList{display:contents;}
  }

  /* .packs-content-header's top:72px is sized for the 64px desktop bar — its
     10px ::before mask covers the leftover 8px seam. The mobile bar is 58px,
     so that same offset opened a 14px slot the mask can't reach, and a sliver
     of the scrolling card grid showed through between the header and this bar.
     Pin it to the real bar height instead; with the announce banner up the
     fixed stack is 38px taller. 999.98px, not the 1024px the rest of the
     mobile packs layout uses, because the header only drops to 58px below
     1000px — and this block must stay after the 1024px one above so the
     equal-specificity top wins. */
  @media(max-width:999.98px){
    .packs-content-header{top:58px;}
    body.sh-has-announce .packs-content-header{top:96px;}
  }

  /* Pack card — no card chrome, just a floating rounded image + text underneath */
  .pack-card{
    background:none;border:none;border-radius:0;box-shadow:none;
    padding:0;display:flex;flex-direction:column;gap:0;overflow:visible;
    transition:transform .2s ease;position:relative;
  }
  .pack-card:hover{transform:translateY(-2px);}
  .pack-card[draggable="true"]{cursor:grab;}
  .pack-card[draggable="true"]:active{cursor:grabbing;}
  .pack-card-hero{
    width:100%;aspect-ratio:1/1;object-fit:cover;
    border-radius:10px;cursor:pointer;display:block;background:var(--bg);
    transition:opacity .15s, transform .25s ease;
    transform:scale(1.35);
  }
  .pack-card:hover .pack-card-hero{opacity:.92;transform:scale(1.37);}


  /* Corner badge row — draft/new/sale pills sit top-left on the card image,
     side by side so a pack that's e.g. both new and on sale shows both
     at once instead of one overwriting the other. */
  .pack-card-badges{position:absolute;top:10px;left:12px;z-index:10;display:flex;flex-direction:row;flex-wrap:wrap;align-items:flex-start;gap:6px;}
  .pack-badge-draft,.pack-badge-sale{
    padding:6px 9px;border-radius:50px;font-size:10.5px;font-weight:900;letter-spacing:.05em;
    color:#fff;box-shadow:0 2px 6px rgba(0,0,0,.2);white-space:nowrap;
  }
  .pack-badge-draft{background:rgba(217,119,6,0.85);backdrop-filter:blur(4px);}
  .pack-badge-sale{
    background:rgba(37,99,235,0.85);backdrop-filter:blur(4px);
    padding:6px 9px 5px;border-radius:50px;font-size:10.5px;font-weight:900;letter-spacing:.02em;
    color:#fff;box-shadow:0 1px 4px rgba(0,0,0,.15);white-space:nowrap;
    display:inline-flex;align-items:center;justify-content:center;line-height:1;margin-left:2px;
  }

  /* "In basket" badge — bottom-right on the card image, right above the white label line */
  .pack-badge-basket{
    position:absolute;bottom:27%;right:10px;z-index:10;
    display:inline-flex;align-items:center;gap:4px;
    padding:5px 9px;border-radius:6px;font-size:10px;font-weight:800;letter-spacing:.02em;
    background:#16A34A;color:#fff;
    box-shadow:0 2px 6px rgba(0,0,0,.25);
    pointer-events:none;
  }
  .pack-badge-basket svg{flex-shrink:0;}

  /* Image container — clips the zoomed hero image to the rounded corners. */
  .pack-card-img{position:relative;width:100%;flex-shrink:0;border-radius:10px;overflow:hidden;transform:translateZ(0);backface-visibility:hidden;}
  .pack-card-hero-placeholder{
    width:100%;aspect-ratio:1/1;border-radius:14px;
    background:var(--bg);border:1.5px dashed var(--border);
    display:flex;align-items:center;justify-content:center;
    cursor:pointer;transition:border-color .15s;box-sizing:border-box;
  }
  .pack-card-hero-placeholder:hover{border-color:rgba(124,58,237,.4);}
  body.dark .pack-card-hero-placeholder{background:#0f0f11;}

  /* Card body — sits below the image, no background/border of its own */
  .pack-card-body{padding:10px 2px 0;display:flex;flex-direction:column;flex:1;}

  /* Name, then big bold price stacked underneath */
  .pack-name-price-row{display:flex;flex-direction:column;gap:4px;margin-bottom:4px;}
  .pack-card-name{
    font-family:'DM Sans',sans-serif;font-size:15px;font-weight:600;
    color:var(--text);line-height:1.3;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }
  .pack-card-price{
    font-family:'DM Sans',sans-serif;font-size:20px;font-weight:800;
    color:var(--text);white-space:nowrap;
    display:inline-flex;align-items:center;gap:6px;flex-wrap:wrap;
  }

  /* Saved pack — placeholder art with the pack name in its white label area.
     The white band sits at 76.32% of saved-pack-bg.png, but .pack-card-hero
     zooms the art by 1.35 about its centre while this overlay is positioned
     against the UNSCALED container — so the band's on-screen centre is
     0.5 + (0.7632 - 0.5) * 1.35 = 85.53%. Using the raw 76.27% here floated the
     name above the band, onto the artwork. checkout.html and pack.html draw the
     same art unzoomed, so they correctly keep ~76.27%. */
  .saved-pack-name-overlay{position:absolute;top:85.53%;left:50%;transform:translate(-50%,-50%);width:62%;text-align:center;font-weight:900;color:#1a1a1a;text-transform:uppercase;line-height:1.2;pointer-events:none;word-break:break-word;z-index:2;}

  .pack-price-original{text-decoration:line-through;color:var(--text-muted);font-size:14px;font-weight:600;margin-right:4px;}
  .pack-price-sale{color:var(--text);font-weight:800;}
  /* Footer actions (card) */
  .pack-card-footer{display:flex;gap:6px;margin-top:auto;padding-top:10px;}
  .pack-card-edit-controls{position:absolute;top:10px;right:12px;z-index:10;display:flex;gap:5px;}
  .pack-edit-btn{
    width:26px;height:26px;border-radius:8px;border:1px solid rgba(255,255,255,.15);
    background:rgba(0,0,0,.65);backdrop-filter:blur(4px);color:#fff;
    cursor:pointer;transition:background .1s,transform .1s;
    display:flex;align-items:center;justify-content:center;outline:none;
  }
  .pack-edit-btn:hover{background:rgba(0,0,0,.8);}
  .pack-edit-btn:active{transform:scale(.9);}
  .pack-delete-btn{
    width:26px;height:26px;border-radius:8px;border:1px solid rgba(255,255,255,.15);
    background:rgba(0,0,0,.65);backdrop-filter:blur(4px);color:#fff;
    cursor:pointer;transition:background .1s,transform .1s;
    display:flex;align-items:center;justify-content:center;outline:none;
  }
  .pack-delete-btn:hover{background:#DC2626;}
  .pack-delete-btn:active{transform:scale(.9);}
  .pack-popup-footer{display:none;}

  @media(max-width:640px){
    /* Packs list: 2 compact cards per row on phones (was 1 full-width card, so
       only ~2 packs fit on screen). Scales the card internals down — like the
       tighter product cards in builder.html — while keeping hero, name and price
       legible. Tapping a card opens its own pack.html detail page. */
    /* minmax(0,1fr), not 1fr: a bare `1fr` is minmax(auto,1fr), so a card whose
       content has a wide min-content (the hero image row) drags its own column
       past its share and squeezes the other — 166px + 132px against a 288px
       container, overflowing the page. minmax(0,…) lets both tracks shrink to
       an even split and the card contents clip/wrap inside. */
    .packs-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;}
    .packs-grid > *{min-width:0;}
    .pack-card{border-radius:14px;}
    .pack-card-body{padding:9px 10px 10px;}
    .pack-name-price-row{gap:5px;margin-bottom:2px;}
    .pack-card-name{font-size:12.5px;line-height:1.2;}
    .pack-card-price{font-size:12.5px;}
    .pack-card-edit-controls{top:8px;right:8px;}
    .pack-card-footer{gap:6px;padding-top:9px;}
  }

  /* Overwrite mode banner */
  .overwrite-banner{
    display:flex;align-items:center;gap:12px;flex-wrap:wrap;
    padding:14px 18px;border-radius:12px;margin-bottom:22px;
    width:fit-content;max-width:100%;
    background:rgba(124,58,237,.07);border:1.5px solid rgba(124,58,237,.2);
    font-family:'Geist','DM Sans',sans-serif;font-size:13px;font-weight:600;color:#7C3AED;
    animation:bannerIn .4s cubic-bezier(.34,1.3,.64,1);
  }
  body.dark .overwrite-banner{background:rgba(167,139,250,.1);border-color:rgba(167,139,250,.25);color:#A78BFA;}
  .overwrite-banner-ico{font-size:18px;flex-shrink:0;}
  .overwrite-banner > span:not(.overwrite-banner-ico){flex:none;}
  .overwrite-banner-cancel{
    margin-left:auto;background:none;border:1.5px solid rgba(124,58,237,.3);cursor:pointer;
    color:#7C3AED;border-radius:8px;padding:5px 12px;font-size:11px;font-weight:800;
    font-family:'Nunito',sans-serif;transition:background .15s;white-space:nowrap;
  }
  .overwrite-banner-cancel:hover{background:rgba(124,58,237,.1);}
  .pack-overwrite-btn{
    flex:1;padding:11px;border-radius:10px;border:2px solid #7C3AED;
    background:#7C3AED;color:#fff;font-family:'Nunito',sans-serif;
    font-size:13px;font-weight:900;cursor:pointer;transition:all .15s;
    display:flex;align-items:center;justify-content:center;gap:6px;
  }
  .pack-overwrite-btn:hover{background:#6d28d9;border-color:#6d28d9;transform:translateY(-1px);}
  body.dark .pack-overwrite-btn{background:#A78BFA;border-color:#A78BFA;color:#0a0a0c;}
  body.dark .pack-overwrite-btn:hover{background:#9061f9;border-color:#9061f9;}

  /* Empty state */
  .packs-empty{
    display:flex;flex-direction:column;align-items:center;justify-content:center;
    padding:56px 20px;text-align:center;color:var(--text-muted);
    border:1.5px dashed var(--border);border-radius:var(--radius);gap:12px;
    grid-column:1/-1;
  }
  .packs-empty-icon{display:flex;align-items:center;justify-content:center;width:48px;height:48px;color:var(--text-muted);}
  .packs-empty-icon svg{width:44px;height:44px;opacity:0.55;}
  .packs-empty-title{font-size:15px;font-weight:800;color:var(--text-soft);}
  .packs-empty-sub{font-size:13px;font-weight:600;max-width:260px;line-height:1.5;}
  .packs-empty-cta{
    display:inline-flex;align-items:center;gap:6px;padding:10px 20px;
    border-radius:50px;border:1.5px solid #AFAFAF;background:transparent;color:#6B6B7B;
    font-family:'Nunito',sans-serif;font-size:13px;font-weight:800;
    cursor:pointer;text-decoration:none;transition:all .15s;margin-top:4px;
  }
  .packs-empty-cta:hover{border-color:#888;color:#3D3D3D;}

  /* Toast — card look is shared from styles.css; this file only keeps its
     own centered container position and entrance animation. */
  .toast-container{
    position:fixed;bottom:24px;left:50%;transform:translateX(-50%);
    z-index:99999;display:flex;flex-direction:column;gap:12px;
    align-items:center;pointer-events:none;
  }
  .toast{ animation:toastUp .35s cubic-bezier(.34,1.3,.64,1); }
  @keyframes toastUp{from{transform:translateY(20px) scale(.9);opacity:0;}to{transform:translateY(0) scale(1);opacity:1;}}
