/* Sticks & Stones — shared design system (Ticket 00).
   Canonical source for tokens + shell + catalog components, extracted
   verbatim from the shop pages' previously-duplicated <style> block.
   New homepage/hub components are appended below. */

  :root{
    --bg:#0b0b0c; --bg2:#121214; --card:#161618; --tile:#f3f3f5;
    --red:#e11d2a; --red2:#b3121d; --red-glow:rgba(225,29,42,.45);
    --gold:#e8b34a; --gold2:#caa036; --gold-glow:rgba(232,179,74,.45);
    --text:#f5f5f6; --muted:#9a9aa3; --line:#26262b; --green:#36d17a;
  }
  *{box-sizing:border-box}
  html{scroll-behavior:smooth}
  body{
    margin:0; background:var(--bg); color:var(--text);
    font-family:"Inter",system-ui,-apple-system,Segoe UI,Roboto,sans-serif;
    -webkit-font-smoothing:antialiased; line-height:1.5;
  }
  a{color:inherit; text-decoration:none}
  h1,h2,h3,.dt{font-family:"Oswald",sans-serif; font-weight:600; letter-spacing:.02em; margin:0}
  .wrap{max-width:1200px; margin:0 auto; padding:0 22px}
  .red{color:var(--red)}

  /* ── announcement bar ── */
  .topbar{background:var(--red); color:#fff; text-align:center; font-size:11px;
    font-weight:600; letter-spacing:.13em; text-transform:uppercase; padding:5px 14px}
  /* The in-store suppressor bar — every page since 2026-09-26 (partials/topbar.html; moved here
     from home.html's own <style>). Two classes, so it beats .topbar wherever it sits. */
  .topbar.topbar--feature{background:#cba24a; color:#231a04; font-size:13px; letter-spacing:.08em;
    padding:10px 16px; line-height:1.45; border-bottom:0}
  /* The atelier gives its own .topbar a gradient ::after rule; keep that under ITS bar only. */
  .topbar.topbar--feature::after{content:none}
  .topbar--feature .topbar__lead{font-family:"Oswald",sans-serif; font-weight:700; font-size:15px;
    letter-spacing:.06em; margin-right:.35em}
  .topbar--feature .topbar__cta{color:#231a04; font-weight:800; text-decoration:underline;
    text-underline-offset:3px; white-space:nowrap; margin-left:.35em}
  @media (max-width:600px){
    .topbar.topbar--feature{font-size:11.5px; padding:9px 12px}
    .topbar--feature .topbar__lead{display:block; font-size:14px; margin:0 0 2px}
  }

  /* ── header ── */
  header{position:sticky; top:0; z-index:50; background:rgba(11,11,12,.72);
    backdrop-filter:blur(10px); border-bottom:1px solid var(--line); transition:background .25s}
  header.solid{background:rgba(11,11,12,.97)}
  .nav{display:flex; align-items:center; gap:20px; height:64px}
  .brand{display:flex; align-items:center; gap:11px; font-family:"Oswald",sans-serif;
    font-weight:700; font-size:19px; letter-spacing:.06em; text-transform:uppercase;
    white-space:nowrap; flex:none}
  .brand .mark{width:34px; height:34px; border-radius:8px; display:grid; place-items:center;
    background:linear-gradient(145deg,var(--red),var(--red2)); color:#fff; font-size:15px;
    box-shadow:0 0 18px var(--red-glow)}
  .nav .links{display:flex; gap:18px; margin-left:auto; font-size:13px; font-weight:600;
    letter-spacing:.04em; text-transform:uppercase; color:var(--muted); white-space:nowrap}
  .nav .links a:hover{color:#fff}
  .btn{display:inline-flex; align-items:center; gap:8px; border-radius:50px; font-weight:600;
    font-size:14px; padding:11px 22px; cursor:pointer; border:1px solid transparent;
    transition:transform .12s, box-shadow .2s, background .2s; white-space:nowrap}
  .btn:active{transform:translateY(1px)}
  .btn-red{background:linear-gradient(145deg,var(--red),var(--red2)); color:#fff;
    box-shadow:0 6px 22px -6px var(--red-glow)}
  .btn-red:hover{box-shadow:0 10px 30px -6px var(--red-glow)}
  .btn-ghost{background:transparent; color:#fff; border-color:var(--line)}
  .btn-ghost:hover{border-color:var(--red); color:#fff}
  .nav .btn{margin-left:4px}
  .hide-sm{display:inline-flex}

  /* ── hero ── */
  .hero{position:relative; overflow:hidden; border-bottom:1px solid var(--line);
    background:
      radial-gradient(900px 420px at 78% -8%, rgba(225,29,42,.20), transparent 60%),
      radial-gradient(700px 500px at 0% 110%, rgba(225,29,42,.10), transparent 55%),
      var(--bg)}
  .hero::after{content:""; position:absolute; inset:0; pointer-events:none;
    background-image:linear-gradient(transparent 95%, rgba(255,255,255,.03) 95%),
                     linear-gradient(90deg, transparent 95%, rgba(255,255,255,.03) 95%);
    background-size:46px 46px; opacity:.5}
  .hero .wrap{position:relative; z-index:1; display:grid; grid-template-columns:1.45fr .55fr;   /* was 1.15/.85 — the wordmark plate took ~40% of the fold */
    gap:40px; align-items:center; padding:64px 22px 60px}
  .eyebrow{display:inline-flex; align-items:center; gap:9px; font-size:12px; font-weight:700;
    letter-spacing:.22em; text-transform:uppercase; color:var(--red); margin-bottom:18px}
  .eyebrow::before{content:""; width:26px; height:2px; background:var(--red)}
  .hero h1{font-size:clamp(44px,7vw,84px); line-height:.96; font-weight:700; text-transform:uppercase}
  .hero p.lede{color:var(--muted); font-size:17px; max-width:30em; margin:20px 0 28px}
  .hero .cta{display:flex; gap:13px; flex-wrap:wrap}
  .stats{display:flex; gap:30px; margin-top:34px; flex-wrap:wrap}
  .stat .n{font-family:"Oswald",sans-serif; font-size:30px; font-weight:700; line-height:1}
  .stat .l{font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--muted); margin-top:5px}
  /* featured tile */
  .feature{position:relative; justify-self:center; width:100%; max-width:400px}
  .feature .ring{position:relative; border-radius:20px; padding:26px; background:var(--tile);
    box-shadow:0 30px 70px -20px rgba(0,0,0,.7), 0 0 0 1px rgba(255,255,255,.05),
               0 0 60px -10px var(--red-glow)}
  .feature .ring::before{content:"IN STOCK"; position:absolute; top:16px; left:16px; z-index:2;
    background:var(--red); color:#fff; font-size:10px; font-weight:700; letter-spacing:.12em;
    padding:5px 10px; border-radius:50px}
  .feature img{display:block; width:100%; height:240px; object-fit:contain; mix-blend-mode:multiply}
  .feature .cap{margin-top:14px; text-align:center}
  .feature .cap .nm{font-family:"Oswald",sans-serif; font-weight:600; font-size:18px;
    text-transform:uppercase; color:#111; letter-spacing:.02em}
  .feature .cap .pr{color:#555; font-size:13px; margin-top:2px}
  /* hero brand logo (replaces the featured gun photo) */
  .feature .ring--brand{display:grid; place-items:center; min-height:210px; padding:34px 22px}   /* was 300px/46px */
  .feature .ring--brand::before{display:none}            /* hide the "IN STOCK" pill */
  .gl-mark{text-align:center; line-height:1}
  .gl-word{display:block; font-family:"Archivo Black","Montserrat",sans-serif; font-weight:400;
    font-size:clamp(50px,6.6vw,76px); letter-spacing:-.02em; color:#0c0c0d}
  .gl-word--ss{font-size:clamp(34px,4.9vw,55px); line-height:.9; letter-spacing:-.02em}
  .gl-tag{display:block; margin-top:15px; font-family:"Archivo Black","Inter",sans-serif; font-weight:400;
    font-size:clamp(10px,1.35vw,13px); letter-spacing:.62em; color:var(--red); padding-left:.62em}

  /* ── trust strip ── */
  .trust{border-bottom:1px solid var(--line); background:var(--bg2)}
  .trust .wrap{display:grid; grid-template-columns:repeat(4,1fr); gap:18px; padding:20px 22px}
  .trust .t{display:flex; align-items:center; gap:12px; font-size:13px; color:var(--muted)}
  .trust .t b{color:#fff; font-weight:600}
  .trust .ic{width:30px; height:30px; flex:none; border-radius:8px; display:grid; place-items:center;
    background:rgba(225,29,42,.12); color:var(--red); font-size:15px}

  /* ── sections ── */
  section.cat{padding:58px 0 8px}
  .sec-head{display:flex; align-items:flex-end; justify-content:space-between; gap:20px;
    margin-bottom:26px; flex-wrap:wrap}
  .sec-head h2{font-size:clamp(28px,4vw,42px); text-transform:uppercase}
  .sec-head .sub{color:var(--muted); font-size:14px; margin-top:6px}
  .sec-head .count{font-family:"Oswald",sans-serif; color:var(--red); font-weight:600}
  .accent{width:54px; height:4px; background:var(--red); border-radius:3px; margin-bottom:16px}

  /* ── product grid ── */
  /* --cols (default 4) is set per page from grid_config.py (curate ▦ Grid control). */
  .grid{display:grid; grid-template-columns:repeat(var(--cols,4),minmax(0,1fr)); gap:20px; padding-bottom:30px}
  /* Desktop = exactly --cols across (sidebar present, ≥981px).  Tablet (no sidebar) goes fluid. */
  @media (min-width:521px) and (max-width:980px){
    .grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}
  }
  /* ── "Flatten" view: shop_filter.js adds .flat to .catalog when a NON-brand filter is
        active.  display:contents dissolves the per-brand section + header boxes so every
        matching card flows into ONE continuous grid (no brand grouping).  DOM is untouched
        (curate/filter logic unaffected).  Revert: FLATTEN_ON_FILTER=false in shop_filter.js. */
  .catalog.flat{display:grid; grid-template-columns:repeat(var(--cols,4),minmax(0,1fr)); gap:20px; align-content:start}
  .catalog.flat > .filter-sec, .catalog.flat > .filter-sec > .grid{display:contents}
  .catalog.flat .accent, .catalog.flat .sec-head, .catalog.flat .showall{display:none}
  .catalog.flat #noResults{grid-column:1/-1}
  @media (min-width:521px) and (max-width:980px){
    .catalog.flat{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}
  }
  @media (max-width:520px){
    .catalog.flat{grid-template-columns:repeat(auto-fill,minmax(148px,1fr)); gap:13px}
  }
  .pcard{background:var(--card); border:1px solid var(--line); border-radius:16px; overflow:hidden;
    display:flex; flex-direction:column; transition:transform .14s, border-color .2s, box-shadow .2s}
  .pcard:hover{transform:translateY(-4px); border-color:rgba(225,29,42,.55);
    box-shadow:0 18px 40px -22px rgba(0,0,0,.9), 0 0 0 1px rgba(225,29,42,.25)}
  .pcard__img{position:relative; background:var(--tile); height:188px; display:grid; place-items:center; padding:18px}
  .pcard__img img{max-width:100%; max-height:100%; object-fit:contain; mix-blend-mode:multiply}
  .pcard__img--empty{font-family:"Oswald",sans-serif; color:#6b6b72; font-weight:600; letter-spacing:.1em}
  .badge{position:absolute; top:11px; font-size:10px; font-weight:700; letter-spacing:.1em;
    text-transform:uppercase; padding:5px 9px; border-radius:50px}
  .badge.stock{left:11px; background:var(--green); color:#06210f}
  .badge.low{left:11px; background:var(--red); color:#fff}
  .badge.oos{left:11px; background:#3a3a40; color:#c9c9cf}
  /* "Available" — we can get it. Deliberately NOT the green .badge.stock, which is the
     owner-confirmed "we physically have it" claim (instock_flags.json, 2026-09-18). Two
     different promises must not wear one colour. */
  /* no-photo fallback: fills the tile exactly as a product shot would */
  .pcard__img--ph{width:100%; height:100%; object-fit:cover; display:block}
  .badge.avail{left:11px; background:#1d2b3a; color:#cfe2f5; border:1px solid rgba(207,226,245,.22)}
  .badge.cal{right:11px; background:#101012; color:#fff; border:1px solid rgba(255,255,255,.14)}
  .pcard__body{padding:15px 16px 17px; display:flex; flex-direction:column; gap:9px; flex:1}
  .pcard__title{font-family:"Oswald",sans-serif; font-weight:600; font-size:17px;
    text-transform:uppercase; letter-spacing:.02em; line-height:1.1}
  .pcard__sub{font-size:12px; color:var(--muted); line-height:1.35; min-height:2.5em}
  .pills{display:flex; flex-wrap:wrap; gap:6px}
  .pill{font-size:10px; font-weight:600; letter-spacing:.04em; text-transform:uppercase;
    color:#d6d6db; background:#1d1d20; border:1px solid var(--line); padding:4px 8px; border-radius:50px}
  .price{margin-top:auto; padding-top:11px; border-top:1px solid var(--line)}
  .price .msrp{display:flex; align-items:baseline; gap:8px}
  .price .amt{font-family:"Oswald",sans-serif; font-size:23px; font-weight:700}
  .price .tag{font-size:10px; font-weight:700; letter-spacing:.1em; color:var(--muted);
    border:1px solid var(--line); padding:2px 7px; border-radius:50px}
  .price .hint{font-size:11px; color:var(--red); font-weight:600; margin-top:2px}
  .pcard .btn-red{width:100%; justify-content:center; margin-top:12px; padding:11px}
  /* ⚠ NOT opacity+grayscale. Stacked on the themed blue those gave a 1.48:1 face and a 2.88:1
   LABEL, so a sold-out card's button had dissolved into the card and its words were
   unreadable — it read as broken rather than out of stock. Explicit recessive tokens with a
   visible edge instead; disabled controls are exempt from the 3:1 face rule, and a disabled
   button brighter than the buyable one would be worse. */
.btn-red[disabled]{background:#2b2f3a; color:#b4b9c4; border:1px solid #454b5c; box-shadow:none;
  opacity:1; filter:none; cursor:not-allowed}
  /* ── Featured (owner curate ★) — bold standout colour scheme, shown to everyone.
        Double-class so it beats the per-template inline .pcard regardless of source order. */
  .pcard.pcard--featured{border:1.5px solid var(--gold);
    background:linear-gradient(157deg, rgba(232,179,74,.16), rgba(232,179,74,0) 46%), var(--card);
    box-shadow:0 0 0 1px rgba(232,179,74,.4), 0 18px 44px -20px var(--gold-glow)}
  .pcard.pcard--featured:hover{transform:translateY(-4px); border-color:var(--gold);
    box-shadow:0 0 0 1px rgba(232,179,74,.6), 0 24px 52px -18px var(--gold-glow)}
  .pcard.pcard--featured .pcard__img{background:linear-gradient(180deg,#fbf2dd,#f3f3f5)}
  .pcard.pcard--featured .pcard__title{color:var(--gold)}
  .pcard.pcard--featured .price{border-top-color:rgba(232,179,74,.3)}
  .pcard.pcard--featured .price .amt{color:var(--gold)}
  /* Deleted (owner curate 🗑) — only ever rendered to the owner via ?show_deleted=1.
     Heavily greyed + a "DELETED" ribbon so it's unmistakable from a hidden item. */
  .pcard.pcard--deleted{opacity:.45; filter:grayscale(.9); border-style:dashed; border-color:#5a2a2e}
  .pcard.pcard--deleted:hover{opacity:.7}
  .pcard.pcard--deleted .pcard__img::after{content:"Deleted"; position:absolute; top:11px;
    left:50%; transform:translateX(-50%); z-index:6;
    background:#7a1620; color:#ffd9dc; font:700 10px/1 "Inter",system-ui,sans-serif;
    letter-spacing:.14em; text-transform:uppercase; padding:5px 11px; border-radius:50px;
    box-shadow:0 4px 14px rgba(0,0,0,.55); white-space:nowrap}
  /* "★ Featured" ribbon — CSS-only (no markup change), centred at the BOTTOM of the image
     so it never collides with the top stock / category badges. */
  .pcard.pcard--featured .pcard__img::after{content:"★ Featured"; position:absolute; bottom:10px;
    left:50%; transform:translateX(-50%); z-index:5;
    background:linear-gradient(145deg,var(--gold),var(--gold2)); color:#241a05;
    font:700 10px/1 "Inter",system-ui,sans-serif; letter-spacing:.12em; text-transform:uppercase;
    padding:5px 11px; border-radius:50px; box-shadow:0 4px 14px rgba(0,0,0,.5); white-space:nowrap}

  /* ── CTA band ── */
  .band{margin:64px 0 0; border-top:1px solid var(--line);
    background:radial-gradient(700px 300px at 50% 0%, rgba(225,29,42,.16), transparent 60%), var(--bg2)}
  .band .wrap{text-align:center; padding:60px 22px}
  .band h2{font-size:clamp(28px,4.4vw,46px); text-transform:uppercase}
  .band p{color:var(--muted); max-width:34em; margin:14px auto 26px; font-size:15px}

  /* ── footer ── */
  footer{border-top:1px solid var(--line); background:var(--bg); margin-top:0}
  footer .wrap{display:flex; justify-content:space-between; gap:24px; flex-wrap:wrap; padding:40px 22px}
  footer .fnote{color:var(--muted); font-size:12px; max-width:46em; line-height:1.6}
  footer .brand{font-size:17px}
  footer a.eml{color:var(--red); font-weight:600}
  /* Instagram (partials/social.html). inline-flex so the glyph and the handle share one
     baseline and wrap as a single unit — a floated icon separates from its text at the 860px
     breakpoint below, where the footer columns stack. Sized in em so it tracks whichever
     footer it lands in: the main one is 12.5px, the catalog store's is 12px. */
  footer a.soc, .st-ftr a.soc{display:inline-flex; align-items:center; gap:7px;
    font-weight:600; white-space:nowrap}
  /* Underline follows the LOCAL convention, not one global choice: the main footer's a.eml is
     un-underlined, while .st-ftr underlines every link — so an un-underlined social link would
     look broken sitting between "Terms, Returns & Privacy" and "Contact". Only the main
     footer's copy opts out. */
  /* :not(.st-ftr) because the store's footer IS a <footer>: `footer a.soc` and `.st-ftr a`
     have IDENTICAL specificity (0,2,1), so which underline wins would be decided purely by
     document order — ss.css vs the <style> block inside store_footer.html. That is a
     coin-flip nobody would think to check again. Excluded explicitly instead. */
  footer:not(.st-ftr) a.soc{text-decoration:none}
  /* ⚠ SET THE SIZE EXPLICITLY. In the main footer this link is a SIBLING of p.fnote, not a
     child, so it inherits the body's 16px and rendered noticeably larger than everything
     around it — measured on /policies. 13px sits a half-step above the 12.5px fine print,
     which is where a call to action belongs. The catalog store's copy IS inside a <p> and
     inherits that footer's 12px correctly, so it is deliberately left alone. */
  footer a.soc{color:var(--red); margin-top:10px; font-size:13px}
  footer a.soc:hover, .st-ftr a.soc:hover{text-decoration:underline}
  footer a.soc svg, .st-ftr a.soc svg{width:1.25em; height:1.25em; flex:none}

  .empty{padding:70px 22px; text-align:center; color:var(--muted)}

  @media (max-width:860px){
    .hero .wrap{grid-template-columns:1fr; padding:46px 22px}
    .feature{order:1; max-width:320px}
    .trust .wrap{grid-template-columns:repeat(2,1fr)}
  }
  @media (max-width:520px){
    .trust .wrap{grid-template-columns:1fr}
    .grid{grid-template-columns:repeat(auto-fill,minmax(148px,1fr)); gap:13px}
    .stats{gap:22px}
  }

  /* ── sale pricing + card actions ── */
  .badge.sale{left:11px; background:var(--red); color:#fff; box-shadow:0 0 0 1px rgba(255,255,255,.14)}
  .pricerow{display:flex; align-items:baseline; gap:9px; flex-wrap:wrap}
  .shipnote{margin-top:7px; font-size:.72rem; line-height:1.35; color:var(--muted, #8a8f98)}
  /* SBR/SBS tile tag (2026-09-26): a registered short-barrelled rifle/shotgun transfers on an
     ATF Form 4, not a 4473 — said on the tile, in the body, never on the image (only the stock
     badge belongs there). New selector, declared nowhere inline, so ss.css alone reaches it. */
  .nfatag{display:inline-block; margin:6px 0 2px; padding:3px 8px; border:1px solid var(--gold, #e8b34a);
    border-radius:4px; background:rgba(232,179,74,.12); color:var(--gold, #e8b34a);
    font-size:.7rem; font-weight:700; letter-spacing:.04em; line-height:1.3; text-transform:uppercase}
  .price .amt.sale{color:var(--red)}
  .price .was{font-size:14px; color:var(--muted); text-decoration:line-through;
    text-decoration-color:rgba(225,29,42,.7)}
  .price .save{font-size:11px; font-weight:700; letter-spacing:.05em; text-transform:uppercase;
    color:var(--green); margin-top:4px}
  .actions{display:flex; gap:8px; margin-top:12px}
  .actions .addcart{flex:1; justify-content:center; padding:11px}
  .actions .btn-quote{padding:11px 14px; font-size:13px}

  /* ── header cart button ── */
  .cartbtn{display:inline-flex; align-items:center; gap:8px; background:transparent; color:#fff;
    border:1px solid var(--line); border-radius:50px; padding:9px 15px; font-size:14px; font-weight:600;
    cursor:pointer; transition:border-color .2s}
  .cartbtn:hover{border-color:var(--red)}
  .cartbtn svg{width:18px; height:18px}
  .cartcount{min-width:20px; height:20px; padding:0 6px; border-radius:50px; background:var(--red);
    color:#fff; font-size:12px; font-weight:700; display:inline-grid; place-items:center}
  .cartcount.empty{background:#2a2a2f; color:var(--muted)}

  /* ── cart drawer ── */
  .cart{position:fixed; inset:0; z-index:150; display:none}
  .cart.open{display:block}
  .cart__backdrop{position:absolute; inset:0; background:rgba(0,0,0,.62); backdrop-filter:blur(3px)}
  .cart__panel{position:absolute; top:0; right:0; height:100%; width:min(420px,92vw); background:var(--bg2);
    border-left:1px solid var(--line); display:flex; flex-direction:column;
    box-shadow:-30px 0 80px -20px rgba(0,0,0,.8); animation:cartin .25s ease}
  @keyframes cartin{from{transform:translateX(100%)} to{transform:none}}
  .cart__head{display:flex; align-items:center; justify-content:space-between; padding:20px 22px;
    border-bottom:1px solid var(--line)}
  .cart__head h3{font-family:"Oswald",sans-serif; font-size:22px; text-transform:uppercase}
  .cart__x{background:none; border:none; color:var(--muted); font-size:26px; cursor:pointer; line-height:1}
  .cart__x:hover{color:#fff}
  .cart__items{flex:1; overflow-y:auto; padding:6px 22px}
  .cart__empty{flex:1; display:grid; place-items:center; text-align:center; color:var(--muted);
    font-size:14px; padding:40px; line-height:1.7}
  .citem{display:flex; gap:12px; padding:14px 0; border-bottom:1px solid var(--line)}
  .citem__img{width:60px; height:60px; flex:none; background:var(--tile); border-radius:9px;
    display:grid; place-items:center; padding:6px; font-family:"Oswald",sans-serif; color:#c7c7cc; font-size:10px}
  .citem__img img{max-width:100%; max-height:100%; object-fit:contain; mix-blend-mode:multiply}
  .citem__main{flex:1; min-width:0}
  .citem__name{font-family:"Oswald",sans-serif; font-size:14px; text-transform:uppercase; line-height:1.15}
  .citem__price{color:var(--red); font-weight:600; font-size:13px; margin-top:3px}
  .citem__row{display:flex; align-items:center; justify-content:space-between; margin-top:9px}
  .qty{display:inline-flex; align-items:center; border:1px solid var(--line); border-radius:8px; overflow:hidden}
  .qty button{background:#101012; color:#fff; border:none; width:27px; height:27px; cursor:pointer; font-size:15px; line-height:1}
  .qty button:hover{background:var(--red)}
  .qty span{min-width:30px; text-align:center; font-size:13px; font-weight:600}
  .citem__rm{background:none; border:none; color:var(--muted); font-size:12px; cursor:pointer; text-decoration:underline}
  .citem__rm:hover{color:var(--red)}
  .cart__foot{border-top:1px solid var(--line); padding:18px 22px; background:var(--bg)}
  .cart__sub{display:flex; justify-content:space-between; font-family:"Oswald",sans-serif;
    font-size:20px; font-weight:600; text-transform:uppercase}
  .cart__sub span:last-child{color:var(--red)}
  .cart__note{font-size:11px; color:var(--muted); margin:10px 0 14px; line-height:1.5}
  .cart__checkout{width:100%; justify-content:center; padding:13px}
  .cart__checkout:disabled{opacity:.45; cursor:not-allowed; box-shadow:none}
  .cart__clear{display:block; width:100%; background:none; border:none; color:var(--muted);
    font-size:12px; margin-top:10px; cursor:pointer}
  .cart__clear:hover{color:#fff}

  /* ── toast ── */
  .toast{position:fixed; left:50%; bottom:26px; transform:translateX(-50%) translateY(20px); z-index:300;
    background:var(--card); border:1px solid var(--line); border-left:3px solid var(--red); color:#fff;
    padding:13px 20px; border-radius:10px; font-size:14px; font-weight:500; opacity:0; pointer-events:none;
    transition:opacity .25s, transform .25s; box-shadow:0 20px 50px -16px rgba(0,0,0,.8); max-width:90vw}
  .toast.show{opacity:1; transform:translateX(-50%) translateY(0)}

  /* ── product detail panel (specs) ── */
  .pcard{cursor:pointer}
  .pcard .actions{cursor:default}
  .pd{position:fixed; inset:0; z-index:155; display:none}
  .pd.open{display:block}
  .pd__backdrop{position:absolute; inset:0; background:rgba(0,0,0,.62); backdrop-filter:blur(3px)}
  .pd__panel{position:absolute; top:0; right:0; height:100%; width:min(440px,94vw); background:var(--bg2);
    border-left:1px solid var(--line); display:flex; flex-direction:column;
    box-shadow:-30px 0 80px -20px rgba(0,0,0,.8); animation:cartin .25s ease}
  .pd__head{display:flex; align-items:center; justify-content:space-between; padding:15px 22px;
    border-bottom:1px solid var(--line)}
  .pd__eyebrow{font-size:11px; font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:var(--red)}
  .pd__x{background:none; border:none; color:var(--muted); font-size:26px; cursor:pointer; line-height:1}
  .pd__x:hover{color:#fff}
  .pd__scroll{flex:1; overflow-y:auto; padding:20px 22px}
  .pd__img{background:var(--tile); border-radius:12px; height:210px; display:grid; place-items:center;
    padding:20px; margin-bottom:18px; position:relative}
  .pd__img img{max-width:100%; max-height:100%; object-fit:contain; mix-blend-mode:multiply}
  .pd__img .sale{position:absolute; top:12px; left:12px; background:var(--red); color:#fff; font-size:10px;
    font-weight:700; letter-spacing:.1em; text-transform:uppercase; padding:5px 9px; border-radius:50px}
  .pd__title{font-family:"Oswald",sans-serif; font-size:24px; text-transform:uppercase; line-height:1.05; margin-bottom:6px}
  .pd__sub{color:var(--muted); font-size:13px; margin-bottom:14px; line-height:1.4}
  .pd__desc{color:var(--muted); font-size:13px; line-height:1.55; margin:2px 0 16px}
  .pd__price{display:flex; align-items:baseline; gap:10px; margin-bottom:6px; flex-wrap:wrap}
  .pd__price .amt{font-family:"Oswald",sans-serif; font-size:28px; font-weight:700}
  .pd__price .amt.sale{color:var(--red)}
  .pd__price .was{font-size:15px; color:var(--muted); text-decoration:line-through; text-decoration-color:rgba(225,29,42,.7)}
  .pd__price .save{font-size:11px; font-weight:700; text-transform:uppercase; color:var(--green)}
  .pd__spectitle{font-family:"Oswald",sans-serif; font-size:14px; text-transform:uppercase; letter-spacing:.05em;
    color:var(--red); margin:20px 0 6px; padding-top:16px; border-top:1px solid var(--line)}
  .pd__specs{width:100%; border-collapse:collapse; font-size:13px}
  .pd__specs td{padding:8px 0; border-bottom:1px solid var(--line); vertical-align:top}
  .pd__specs td:first-child{color:var(--muted); width:44%; padding-right:12px}
  .pd__specs td:last-child{color:#fff; font-weight:500}
  .pd__foot{border-top:1px solid var(--line); padding:15px 22px; display:flex; gap:8px}
  .pd__foot .addcart{flex:1; justify-content:center}

  /* ── checkout (age gate + FFL) ── */
  .co{position:fixed; inset:0; z-index:160; display:none; align-items:flex-start; justify-content:center;
    padding:30px 16px; overflow-y:auto}
  .co.open{display:flex}
  .co__backdrop{position:fixed; inset:0; background:rgba(0,0,0,.74); backdrop-filter:blur(4px)}
  .co__panel{position:relative; width:100%; max-width:540px; background:var(--bg2); border:1px solid var(--line);
    border-radius:16px; box-shadow:0 40px 90px -20px rgba(0,0,0,.85); animation:mlpop .22s ease; margin:auto}
  .co__head{display:flex; align-items:center; justify-content:space-between; padding:18px 24px;
    border-bottom:1px solid var(--line); position:sticky; top:0; background:var(--bg2);
    border-radius:16px 16px 0 0; z-index:2}
  .co__head h3{font-family:"Oswald",sans-serif; font-size:23px; text-transform:uppercase}
  .co__x{background:none; border:none; color:var(--muted); font-size:26px; cursor:pointer; line-height:1}
  .co__x:hover{color:#fff}
  .co__body{padding:18px 24px 24px}
  .co__summary{background:#101012; border:1px solid var(--line); border-radius:10px; padding:13px 15px;
    margin-bottom:18px; font-size:13px}
  .co__summary .li{display:flex; justify-content:space-between; gap:12px; padding:3px 0; color:var(--muted)}
  .co__summary .li b{color:#fff; font-weight:600}
  .co__summary .tot{display:flex; justify-content:space-between; border-top:1px solid var(--line);
    margin-top:8px; padding-top:8px; font-family:"Oswald",sans-serif; font-size:17px; text-transform:uppercase; color:#fff}
  .co__summary .tot span:last-child{color:var(--red)}
  .co__sec{border:none; padding:0; margin:0 0 20px; min-inline-size:0}
  .co__sec legend{font-family:"Oswald",sans-serif; font-size:14px; text-transform:uppercase; letter-spacing:.05em;
    color:var(--red); padding:0; margin-bottom:9px}
  .co__hint{font-size:12px; color:var(--muted); margin:0 0 12px; line-height:1.5}
  .co__field{display:block; margin-bottom:11px}
  .co__field span{display:block; font-size:12px; font-weight:600; color:#d6d6db; margin-bottom:5px}
  .co__field em{color:var(--muted); font-style:normal; font-weight:400}
  .co__field input{width:100%; background:#0e0e10; border:1px solid var(--line); border-radius:9px;
    padding:11px 13px; color:#fff; font-size:14px; font-family:inherit}
  .co__field input:focus{outline:none; border-color:var(--red)}
  .co__grid2{display:grid; grid-template-columns:1fr 1fr; gap:11px}
  .co__check{display:flex; align-items:flex-start; gap:9px; font-size:12px; color:#e6e6ea; cursor:pointer;
    margin-top:8px; line-height:1.4}
  .co__check input{margin-top:1px; width:17px; height:17px; accent-color:var(--red); flex:none}
  .co__foot{border-top:1px solid var(--line); padding-top:16px}
  .co__err{color:#ff6b6b; font-size:13px; margin-bottom:10px; font-weight:600}
  .co__submit{width:100%; justify-content:center; padding:13px}
  .co__note{font-size:11px; color:var(--muted); text-align:center; margin:11px 0 0; line-height:1.5}
  .co__done{text-align:center; padding:34px 24px 30px}
  .co__done .ic{width:54px; height:54px; border-radius:50%; background:rgba(54,209,122,.15); color:var(--green);
    display:grid; place-items:center; margin:0 auto 16px; font-size:30px}
  .co__done h4{font-family:"Oswald",sans-serif; font-size:24px; text-transform:uppercase; margin-bottom:8px}
  .co__done p{color:var(--muted); font-size:14px; max-width:34em; margin:0 auto; line-height:1.6}
  .co__done #coDoneEmail{color:var(--red)}
  @media (max-width:520px){ .co__grid2{grid-template-columns:1fr} }

  /* ── checkout: delivery radios + FFL locator ── */
  .co__radio{display:flex; align-items:flex-start; gap:10px; background:#101012; border:1px solid var(--line);
    border-radius:10px; padding:13px 15px; margin-bottom:9px; cursor:pointer; font-size:13px; color:#e6e6ea}
  .co__radio input{margin-top:2px; width:17px; height:17px; accent-color:var(--red); flex:none}
  .co__radio b{color:#fff; font-weight:600}
  .co__radio em{color:var(--muted); font-style:normal; font-size:12px}
  .co__radio:has(input:checked){border-color:var(--red); background:rgba(225,29,42,.07)}
  .ffl-find{display:flex; gap:8px}
  .ffl-find input{flex:1; background:#0e0e10; border:1px solid var(--line); border-radius:9px;
    padding:11px 13px; color:#fff; font-size:14px; font-family:inherit}
  .ffl-find input:focus{outline:none; border-color:var(--red)}
  .ffl-find .btn{padding:11px 18px}
  .ffl-results{margin:12px 0 4px}
  .ffl-map{height:200px; border-radius:10px; overflow:hidden; border:1px solid var(--line);
    margin-bottom:10px; background:#0e0e10}
  .ffl-list{max-height:210px; overflow-y:auto; display:flex; flex-direction:column; gap:7px}
  .ffl-card{text-align:left; background:#101012; border:1px solid var(--line); border-radius:9px;
    padding:10px 12px; cursor:pointer; transition:border-color .15s; display:block; width:100%}
  .ffl-card:hover{border-color:var(--red)}
  .ffl-card.sel{border-color:var(--red); background:rgba(225,29,42,.08)}
  .ffl-card .nm{font-weight:600; font-size:13px; color:#fff}
  .ffl-card .ad{font-size:11px; color:var(--muted); margin-top:2px}
  .ffl-card .mi{float:right; font-size:11px; color:var(--red); font-weight:600; margin-left:8px}
  .ffl-empty{font-size:12px; color:var(--muted); padding:8px 2px}
  .leaflet-popup-content{font-size:12px; margin:9px 12px}
  .leaflet-popup-content b{display:block; margin-bottom:2px}

  /* ── mailing-list consent gate (shown before any email/quote action) ── */
  .ml-modal{position:fixed; inset:0; z-index:200; display:none; align-items:center;
    justify-content:center; padding:20px}
  .ml-modal.open{display:flex}
  .ml-modal__backdrop{position:absolute; inset:0; background:rgba(0,0,0,.74); backdrop-filter:blur(5px)}
  .ml-modal__card{position:relative; width:100%; max-width:444px; background:var(--card);
    border:1px solid var(--line); border-radius:18px; padding:32px 28px 22px; text-align:center;
    box-shadow:0 40px 90px -20px rgba(0,0,0,.85), 0 0 70px -16px var(--red-glow);
    animation:mlpop .22s ease}
  @keyframes mlpop{from{opacity:0; transform:translateY(14px) scale(.97)} to{opacity:1; transform:none}}
  .ml-modal__x{position:absolute; top:12px; right:14px; background:none; border:none;
    color:var(--muted); font-size:26px; line-height:1; cursor:pointer}
  .ml-modal__x:hover{color:#fff}
  .ml-modal__badge{display:inline-block; font-size:11px; font-weight:700; letter-spacing:.16em;
    text-transform:uppercase; color:var(--red); background:rgba(225,29,42,.12);
    border:1px solid rgba(225,29,42,.32); padding:5px 12px; border-radius:50px; margin-bottom:15px}
  .ml-modal__card h3{font-family:"Oswald",sans-serif; font-size:27px; text-transform:uppercase;
    margin-bottom:10px; line-height:1.05}
  .ml-modal__card p{color:var(--muted); font-size:14px; margin:0 auto 18px; max-width:33em}
  .ml-check{display:flex; align-items:flex-start; gap:11px; text-align:left; background:#101012;
    border:1px solid var(--line); border-radius:11px; padding:13px 15px; margin-bottom:16px; cursor:pointer}
  .ml-check input{margin-top:1px; width:18px; height:18px; accent-color:var(--red); flex:none; cursor:pointer}
  .ml-check span{font-size:13px; color:#e6e6ea; line-height:1.4}
  .ml-modal__go{width:100%; justify-content:center; padding:13px}
  .ml-modal__go:disabled{opacity:.45; cursor:not-allowed; box-shadow:none}
  .ml-modal__later{display:block; width:100%; background:none; border:none; color:var(--muted);
    font-size:13px; margin-top:11px; cursor:pointer; padding:6px}
  .ml-modal__later:hover{color:#fff}

  /* ============================================================
     Shared site components — added in Ticket 00 (homepage + /shop)
     ============================================================ */

  /* mobile nav toggle + active link state */
  .navtoggle{display:none; background:transparent; border:1px solid var(--line); border-radius:10px;
    padding:7px 8px; color:#fff; cursor:pointer; margin-left:auto}
  .navtoggle svg{width:22px; height:22px; display:block}
  .nav .links a.active{color:#fff; position:relative}
  .nav .links a.active::after{content:""; position:absolute; left:0; right:0; bottom:-7px; height:2px;
    background:var(--red); border-radius:2px}
  .only-sm{display:none}

  @media (max-width:1024px){
    header .wrap.nav{position:relative}
    .navtoggle{display:inline-flex; align-items:center; justify-content:center}
    .nav .links{position:absolute; top:64px; left:0; right:0; margin:0;
      flex-direction:column; gap:0; align-items:stretch;
      background:rgba(11,11,12,.985); border-bottom:1px solid var(--line);
      padding:6px 22px 14px; display:none; box-shadow:0 24px 40px -22px rgba(0,0,0,.9)}
    .nav .links.open{display:flex}
    .nav .links a{padding:14px 0; border-bottom:1px solid var(--line); font-size:15px; color:var(--text)}
    .nav .links a:last-child{border-bottom:0}
    .nav .links a.active::after{display:none}
    .only-sm{display:block}
    .hide-sm{display:none}
  }
  /* ⚠ MOBILE NAV FIT (M8). On phones the in-flow row is brand + hamburger + cart (the links
     collapse to an absolute dropdown), and the wide uppercase brand plus the 26px gaps
     overflowed the viewport — clipping the rightmost item, the Cart button, off-screen and
     forcing a horizontal scroll. Higher specificity (`header .wrap.nav …`) on purpose: five
     shop templates set an inline `.nav{gap:26px}` that loads after ss.css and would otherwise
     win. Shrink the brand, tighten the gap, and pin the toggle + cart to the right edge so the
     brand takes the slack instead of the cart. */
  @media (max-width:560px){
    header .wrap.nav{gap:10px}
    header .wrap.nav .brand{font-size:15px; letter-spacing:.02em; gap:7px; min-width:0}
    header .wrap.nav .brand .mark{width:27px; height:27px; font-size:11px}
    header .wrap.nav .navtoggle{margin-left:auto}
    header .wrap.nav .cartbtn{padding:8px 11px; gap:6px}
  }
  @media (max-width:380px){
    /* Smallest phones (SE 375 down to 320): show just the S&S mark. The 15px wordmark fits to
       ~381px (measured), so it stays on iPhone 12–14 (390) etc.; below that the wordmark is a
       bare text node, and font-size:0 collapses it while the mark keeps its own size — freeing
       ~130px so the Cart button always fits, without shrinking the cart itself. */
    header .wrap.nav .brand{font-size:0; gap:0}
    header .wrap.nav .brand .mark{font-size:11px}
  }

  /* category tiles (homepage + /shop hub) */
  .cat-tiles{display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:18px; padding-bottom:8px}
  .cat-tile{position:relative; display:flex; flex-direction:column; justify-content:space-between;
    min-height:182px; padding:24px; border-radius:18px; background:var(--card); border:1px solid var(--line);
    overflow:hidden; transition:transform .14s, border-color .2s, box-shadow .2s}
  .cat-tile::before{content:""; position:absolute; inset:0; pointer-events:none; opacity:0;
    background:radial-gradient(420px 220px at 110% -20%, var(--red-glow), transparent 60%); transition:opacity .25s}
  .cat-tile:hover{transform:translateY(-4px); border-color:rgba(225,29,42,.55);
    box-shadow:0 22px 46px -26px rgba(0,0,0,.9)}
  .cat-tile:hover::before{opacity:1}
  .cat-tile h3{font-size:25px; text-transform:uppercase; letter-spacing:.02em; position:relative}
  .cat-tile p{color:var(--muted); font-size:13px; line-height:1.45; margin-top:8px; max-width:30em; position:relative}
  .cat-tile .go{display:inline-flex; align-items:center; gap:8px; margin-top:18px; color:var(--red);
    font-family:"Oswald",sans-serif; font-weight:600; font-size:13px; letter-spacing:.06em;
    text-transform:uppercase; position:relative}
  .cat-tile .soon{position:absolute; top:18px; right:18px; font-size:10px; font-weight:700; letter-spacing:.1em;
    text-transform:uppercase; color:var(--muted); border:1px solid var(--line); border-radius:50px; padding:4px 9px}
  .cat-tile.is-soon{opacity:.85}
  .cat-tile.is-soon:hover{transform:none}

  /* trusted-manufacturers brand strip */
  .brand-strip{display:flex; flex-wrap:wrap; gap:14px 30px; align-items:center; justify-content:center; padding:6px 0 2px}
  .brand-strip .b{font-family:"Oswald",sans-serif; font-weight:600; font-size:18px; letter-spacing:.06em;
    text-transform:uppercase; color:#cfcfd6; opacity:.78; transition:opacity .2s, color .2s}
  .brand-strip .b:hover{opacity:1; color:#fff}

  /* featured pcard helpers */
  .pcard .pc-from{font-size:11px; color:var(--muted); letter-spacing:.06em; text-transform:uppercase; margin-right:6px}

  /* contact / location + site-wide FFL finder */
  .contact{display:grid; grid-template-columns:1fr 1fr; gap:30px; align-items:start}
  .contact .info p{color:var(--muted); font-size:14px; line-height:1.7; margin:0 0 8px}
  .contact .info b{color:#fff; font-weight:600}
  .fflbox{background:var(--card); border:1px solid var(--line); border-radius:16px; padding:22px}
  .fflbox h3{font-size:20px; text-transform:uppercase}
  .fflbox .lbl{font-size:12px; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); margin-top:6px; display:block}
  .fflrow{display:flex; gap:10px; margin-top:10px; flex-wrap:wrap}
  .fflrow input{flex:1; min-width:150px; background:var(--bg2); border:1px solid var(--line); border-radius:50px;
    color:var(--text); padding:11px 18px; font-size:14px; font-family:inherit}
  .fflrow input:focus{outline:none; border-color:var(--red)}
  .ffllist{margin-top:16px; display:flex; flex-direction:column; gap:10px}
  .ffllist .f{background:var(--bg2); border:1px solid var(--line); border-radius:12px; padding:12px 14px; font-size:13px}
  .ffllist .f b{color:#fff}
  .ffllist .f .d{color:var(--muted); margin-top:3px}
  .ffllist .muted{color:var(--muted); font-size:13px}
  @media (max-width:760px){ .contact{grid-template-columns:1fr} }


/* ════════════════════════════════════════════════════════════════════════
   Shop filter sidebar + per-brand "top 5 / show all" (shared by /shop/* pages)
   Paired with /static/shop_filter.js.  Class names match the optics page.
   ════════════════════════════════════════════════════════════════════════ */
.layout{max-width:1200px; margin:0 auto; padding:10px 22px 0;
  display:grid; grid-template-columns:250px 1fr; gap:34px; align-items:start}
.sidebar{position:sticky; top:80px; max-height:calc(100vh - 96px); overflow-y:auto;
  background:var(--bg2); border:1px solid var(--line); border-radius:14px; padding:18px;
  scrollbar-width:thin; scrollbar-color:var(--line) transparent}
.sidebar::-webkit-scrollbar{width:8px}
.sidebar::-webkit-scrollbar-thumb{background:var(--line); border-radius:8px}
.sidebar::-webkit-scrollbar-thumb:hover{background:#3a3a42}
/* keep the Filters header + count pinned while the filter groups scroll under them */
.sidebar__head{position:sticky; top:-18px; z-index:2; background:var(--bg2); margin:-18px -18px 0; padding:18px 18px 8px}
.sidebar__count{position:sticky; top:34px; z-index:2; background:var(--bg2); margin:0 -18px; padding:0 18px 10px}
.sidebar__head{display:flex; align-items:center; justify-content:space-between}
.sidebar__head h3{font-family:"Oswald",sans-serif; font-size:18px; text-transform:uppercase; letter-spacing:.04em}
.sidebar__clear{background:none; border:none; color:var(--muted); font-size:12px; cursor:pointer; text-decoration:underline}
.sidebar__clear:hover{color:var(--red)}
.sidebar__count{font-size:12px; color:var(--muted); margin-top:4px}
.sidebar__count b{color:#fff; font-family:"Oswald",sans-serif; font-size:14px}
.sidebar__search{position:relative; margin-top:12px}
.sidebar__search svg{position:absolute; left:11px; top:50%; transform:translateY(-50%); width:15px; height:15px; fill:var(--muted); pointer-events:none}
.sidebar__search input{width:100%; box-sizing:border-box; background:var(--bg); border:1px solid var(--line); border-radius:9px; color:#fff; font-size:13px; padding:9px 12px 9px 34px}
.sidebar__search input::placeholder{color:var(--muted)}
.sidebar__search input:focus{outline:none; border-color:#e1b463}
.sidebar__search input::-webkit-search-cancel-button{-webkit-appearance:none; height:14px; width:14px; background:var(--muted); cursor:pointer;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M15 5L5 15M5 5l10 10' stroke='black' stroke-width='2'/%3E%3C/svg%3E") center/contain no-repeat}
.fgroup{border-top:1px solid var(--line); margin-top:14px; padding-top:14px}
.fgroup h4{font-size:11px; font-weight:700; letter-spacing:.13em; text-transform:uppercase;
  color:var(--muted); margin:0 0 9px}
.fopt{display:flex; align-items:center; gap:10px; padding:5px 0; font-size:13px; color:#d6d6db; cursor:pointer}
.fopt:hover{color:#fff}
.fopt input{appearance:none; -webkit-appearance:none; width:17px; height:17px; flex:none;
  border:1px solid var(--line); border-radius:5px; background:#0e0e10; cursor:pointer; position:relative}
.fopt input:checked{background:var(--red); border-color:var(--red)}
.fopt input:checked::after{content:"\2713"; position:absolute; inset:0; display:grid; place-items:center;
  font-size:11px; color:#fff; font-weight:700}
.fopt span{flex:1}
.fopt em{color:var(--muted); font-style:normal; font-size:11px}
/* Scoped under .layout so it beats a page's inline `.btn{display:inline-flex}`
   (equal specificity + later in cascade) — otherwise the toggle shows on desktop
   and becomes a stray grid cell, breaking the sidebar layout. */
.layout .filter-toggle{display:none; width:100%; justify-content:center; margin-bottom:14px}

.showall{display:flex; flex-direction:column; align-items:center; justify-content:center; gap:5px;
  background:var(--card); border:1.5px dashed var(--line); border-radius:16px; cursor:pointer;
  color:#d6d6db; font-family:"Oswald",sans-serif; text-transform:uppercase; letter-spacing:.04em;
  min-height:160px; transition:border-color .2s, color .2s, transform .14s}
.showall:hover{border-color:var(--red); color:#fff; transform:translateY(-4px)}
.showall .n{font-size:30px; font-weight:700; line-height:1; color:var(--red)}
.showall .t{font-size:12px; font-weight:600}
.showall .arr{font-size:17px; margin-top:2px}
.showall[hidden]{display:none}

@media (max-width:980px){
  .layout{grid-template-columns:1fr; gap:0}
  .sidebar{position:static; display:none; margin-bottom:22px}
  .sidebar.open{display:block}
  .layout .filter-toggle{display:inline-flex}
}

/* Wide product-detail panel (opt-in via .pd--wide, used on /shop/silencers):
   the panel fills the page to the RIGHT of the 250px filter sidebar, which stays
   visible + clickable.  Sidebar's right edge = centred-layout left + 22px pad +
   250px sidebar = layout-left + 272px.  Content is centred + width-capped so the
   roomy panel still reads well.  Mobile (≤980px, sidebar is a drawer) keeps the
   default right-side panel. */
@media (min-width:981px){
  .pd--wide{pointer-events:none}                       /* let clicks fall through to the sidebar */
  .pd--wide .pd__backdrop, .pd--wide .pd__panel{pointer-events:auto}
  .pd--wide .pd__backdrop{left:calc(max((100vw - 1200px) / 2, 0px) + 272px)}
  .pd--wide .pd__panel{left:calc(max((100vw - 1200px) / 2, 0px) + 272px);
    right:0; width:auto; max-width:none}
  .pd--wide .pd__scroll{padding:30px max(40px, 5%)}
  .pd--wide .pd__img{height:340px}
  .pd--wide .pd__scroll > *{max-width:860px; margin-left:auto; margin-right:auto}
}

/* ════════════════════════════════════════════════════════════════════════
   GOLD / BLUE / CHARCOAL theme — OPT-IN per page via <body class="theme-gbc">.
   Applied to all storefront pages EXCEPT The Vault (shop_reserve) and Premium
   (shop_atelier), which keep their own looks by simply NOT adding the class.
   To REVERT a page: remove class="theme-gbc" from its <body>.  To revert
   everywhere: delete this block (and the class from each body).
   ════════════════════════════════════════════════════════════════════════ */
body.theme-gbc{
  --bg:#16171b; --bg2:#1d1f25; --card:#23262f; --tile:#f3f3f5;
  --red:#3a5fd9; --red2:#2a47b0; --red-glow:rgba(58,95,217,.45);   /* royal blue = actions/buttons */
  --green:#cba24a;                                                  /* In-Stock badge → gold */
  --text:#f5f5f6; --muted:#9b9ba6; --line:#353944;
  --gold:#cba24a;
}
/* gold for the premium text/line highlights (white-text-safe on charcoal) */
.theme-gbc .red,
.theme-gbc .sec-head .count,
.theme-gbc .eyebrow,
.theme-gbc .gl-tag,
.theme-gbc .price .hint,
.theme-gbc .price .amt.sale,
.theme-gbc .pd__eyebrow,
.theme-gbc .pd__spectitle,
/* ⚠ THIS RETINT LIST IS HAND-MAINTAINED AND KEPT MISSING RULES. theme-gbc aliases --red to
   royal blue, so any `color:var(--red)` TEXT rule absent from this list renders blue on
   charcoal — measured 2.75-3.46:1, all below AA. These were the wayfinding/confirmation
   ones: the only CTA text on the homepage department tiles, each cart line's price, the
   Show-all "+N", the distance to the FFL you are shipping a firearm to, /contact section
   labels and the FAQ +/- affordance. ADD ANY NEW color:var(--red) TEXT RULE HERE TOO. */
.theme-gbc .cat-tile .go,
.theme-gbc .citem__price,
.theme-gbc .showall .n,
.theme-gbc .ffl-card .mi,
.theme-gbc .infocard h3,
.theme-gbc .faq summary::after,
.theme-gbc .g11-svc .num,
.theme-gbc .co__summary .tot span:last-child,
.theme-gbc footer a.eml{ color:var(--gold) }
.theme-gbc footer a.soc{ color:var(--gold) }
.theme-gbc .accent,
.theme-gbc .eyebrow::before{ background:var(--gold) }
.theme-gbc .badge.stock{ background:var(--gold); color:#231a04 }   /* gold pill, dark text */
/* re-tint the hardcoded reds (not driven by --red) */
.theme-gbc .hero{
  background:
    radial-gradient(900px 420px at 78% -8%, rgba(203,162,74,.18), transparent 60%),
    radial-gradient(700px 500px at 0% 110%, rgba(58,95,217,.15), transparent 55%),
    var(--bg); }
.theme-gbc .band{
  background:radial-gradient(700px 300px at 50% 0%, rgba(203,162,74,.14), transparent 60%), var(--bg2); }
.theme-gbc .pcard:hover{ border-color:rgba(58,95,217,.6);
  box-shadow:0 18px 40px -22px rgba(0,0,0,.9), 0 0 0 1px rgba(203,162,74,.30) }
.theme-gbc .cat-tile:hover{ border-color:rgba(58,95,217,.55) }
.theme-gbc .trust .ic{ background:rgba(203,162,74,.14); color:var(--gold) }
.theme-gbc .price .was,
.theme-gbc .pd__price .was{ text-decoration-color:rgba(203,162,74,.7) }
.theme-gbc .co__radio:has(input:checked),
.theme-gbc .ffl-card.sel{ background:rgba(58,95,217,.08) }

  /* ⚠ CARD GEOMETRY (audit 2026-09-15). Three defects, all in one place:
     (1) `.pcard__img` was a FIXED height:188px at every viewport, never touched by a media
         query, so the tile never adapted; aspect-ratio makes it proportional instead.
     (2) `.pcard__title`/`.pcard__sub` had no clamp, so raw distributor titles and long
         subtitles made row heights wildly ragged across the grid.
     Appended as its own rule rather than edited in place because four templates re-declare
     these same selectors inline AFTER ss.css — a surgical edit would not reach them. */
  .pcard .pcard__img{height:auto; aspect-ratio:4/3}
  .pcard .pcard__title{display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
    overflow:hidden}
  .pcard .pcard__sub{display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical;
    overflow:hidden; min-height:0}
  /* Card titles link to the product's own page (/shop/item/…, 2026-09-26). The link must not
     restyle the title: `.pcard.pcard--featured .pcard__title` (gold) and every inline
     `.pcard__title` rule still decide colour and type; `inherit` passes them through. Written at
     (0,3,1) so no inline `a{…}` in a template can outrank it wherever it sits. */
  .pcard .pcard__title a.pcard__link{color:inherit; text-decoration:none}
  .pcard .pcard__title a.pcard__link:hover{text-decoration:underline}

/* ⚠ 981-1150px: cards got SMALLER as the window got BIGGER. Below 981px the sidebar hides and
   the grid runs fluid; at 981px the sidebar returns but the grid snaps back to a fixed column
   count, so a 1000px laptop showed narrower cards than a 900px tablet. Stay fluid until there
   is room for the fixed count. */
@media (min-width:981px) and (max-width:1150px){
  .grid, .catalog.flat{grid-template-columns:repeat(auto-fill,minmax(190px,1fr))}
}

  /* ⚠ GOLD ON A WHITE PLATE. `.gl-tag` (WEAPONS / GEAR UP / GLASS UP / PERFECTION /
     SUPPRESSED) is the tagline inside the white wordmark tile, and the theme retints it
     gold — which measured 1.74-2.15:1 on `--tile` #f3f3f5, effectively unreadable. The
     tile is a fixed light surface on every tier, so scope a dark brass to it. (0,4,0)
     beats the (0,2,0) `.theme-gbc .gl-tag` retint. */
  .theme-gbc .feature .ring--brand .gl-tag,
  .feature .ring--brand .gl-tag{ color:#6b5410 }

  /* ⚠ SPARSE BRAND SECTIONS. /shop/firearms renders 157 per-brand sections and 79 hold 3 cards
     or fewer, each previously wearing a full 42px header + sub + accent bar — so the store read
     as empty purely from the scroll cost of the chrome. Brand grouping, the per-brand header and
     the A-Z order are the owner's calls (2026-06-28) and are UNCHANGED; FLATTEN_ON_FILTER stays
     false. A thin brand has a thin header, nothing more. Structure shop_filter.js keys on
     (.filter-sec, data-vendor, data-top, .vcount, .showall) is untouched. */
  .cat.cat--sparse{padding-top:14px; padding-bottom:6px}
  .cat--sparse .accent{display:none}
  .cat--sparse .sec-head{align-items:center; margin-bottom:12px; padding-bottom:0; border-bottom:0}
  .cat--sparse .sec-head h2{font-size:20px; letter-spacing:.01em}
  .cat--sparse .sec-head .sub{display:none}
  .cat--sparse .sec-head .count{font-size:12px}

/* ── Firearms dropdown in the header (2026-09-17). NEW selectors — no copy in any template,
   so this is the one place they live (CLAUDE.md "storefront cascade"). The trigger is an <a>
   inside .nav .links and inherits that link style; only the menu is styled here. ── */
.navdd{position:relative; display:inline-flex}
.navdd__btn{display:inline-flex; align-items:center; gap:5px; cursor:pointer}
.navdd__car{width:12px; height:12px; transition:transform .15s}
.navdd__btn[aria-expanded="true"] .navdd__car{transform:rotate(180deg)}
/* HORIZONTAL, in line with the top banner (owner, 2026-09-18: "make the firearms sub menu run
   horizontal with the top banner"). It was a vertical stack. Still a DROPDOWN — the 2026-09-17
   ruling that it "should open right under it and you have to pick one. it shouldnt stay open on
   a page" is untouched; only the direction the items lay out in has changed.
   ⚠ A ROW IS WIDE, AND THE OLD RULE CENTRED IT ON THE TRIGGER WITH translateX(-50%). Firearms
   sits left of centre in the nav, so a centred row runs off the left edge on a narrow window —
   a vertical menu never could. `max-width` plus the clamp below keep it on screen. */
/* ⚠ `width:max-content` IS LOAD-BEARING, NOT TIDYING. An absolutely positioned box shrink-to-fits
   against its CONTAINING BLOCK, which here is `.navdd` — a `position:relative` wrapper only as
   wide as the word "Firearms" (measured: 122px). So `flex-direction:row` computed as `row` and
   still rendered FOUR STACKED ROWS, because the items had 122px to share and wrapped. The
   stylesheet said horizontal and the page was vertical; only reading the rendered box found it. */
.navdd__menu{position:absolute; top:calc(100% + 16px); left:50%; transform:translateX(-50%);
  display:flex; flex-direction:row; align-items:center; gap:4px; padding:6px;
  width:max-content; max-width:calc(100vw - 24px); flex-wrap:wrap; justify-content:center;
  background:rgba(11,11,12,.985); border:1px solid var(--line); border-radius:999px;
  box-shadow:0 24px 40px -22px rgba(0,0,0,.9); z-index:60}
.navdd__menu[hidden]{display:none}
/* One declaration, not two: `white-space` folded in here rather than added as a second
   `.nav .links .navdd__menu a` rule. Duplicate selectors are what the storefront-cascade note
   warns about, and adding one in the same file would be starting that problem myself.
   nowrap because "Shotguns" breaking over two lines would read as two sections. */
.nav .links .navdd__menu a{padding:9px 15px; border-radius:999px; color:var(--muted);
  font-size:13px; white-space:nowrap}
.nav .links .navdd__menu a:hover{color:#fff; background:rgba(255,255,255,.06)}
.nav .links .navdd__menu a.active{color:#fff; background:rgba(255,255,255,.08)}
.nav .links .navdd__menu a.active::after{display:none}
@media (max-width:1024px){
  /* the phone menu is a column: the dropdown becomes an inline accordion under its tab */
  .navdd{display:block}
  .nav .links .navdd__btn{width:100%; justify-content:space-between}
  /* ⚠ flex-direction MUST be reset here. The desktop rule above is now `row`, and this block
     only ever overrode position/transform/padding — so without this line the phone accordion
     would inherit the row and lay four sections across a 375px screen. A media block that
     silently inherits a changed base is the quietest way to break the phone. */
  .navdd__menu{position:static; transform:none; min-width:0; max-width:none; padding:0 0 6px 16px;
    flex-direction:column; flex-wrap:nowrap; justify-content:flex-start;
    border:0; border-radius:0; background:transparent; box-shadow:none}
  .nav .links .navdd__menu a{padding:12px 0; border-bottom:1px solid var(--line); border-radius:0;
    font-size:14px; white-space:normal}
  .nav .links .navdd__menu a:last-child{border-bottom:0}
}

/* ── SORT BAR (owner, 2026-09-19: "add a sort by filters across the top") ──────────────────
   NEW selectors, so they live here only — nothing re-declares .sortbar in a template's inline
   <style>, unlike .grid / .pcard / .sec-head which this file's own storefront-cascade note
   warns about. If a shop template ever does re-declare them, edit BOTH copies. */
.sortbar{display:flex; align-items:center; gap:10px; margin:0 0 14px; flex-wrap:wrap}
.sortbar__l{font-family:"Oswald",sans-serif; font-size:12px; font-weight:600;
  letter-spacing:.12em; text-transform:uppercase; color:var(--muted)}
.sortbar__s{font:inherit; font-size:13px; color:var(--text); background:var(--card,#16161a);
  border:1px solid var(--line); border-radius:999px; padding:7px 32px 7px 13px; cursor:pointer;
  appearance:none; -webkit-appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),
                   linear-gradient(135deg,currentColor 50%,transparent 50%);
  background-position:calc(100% - 16px) 52%, calc(100% - 11px) 52%;
  background-size:5px 5px, 5px 5px; background-repeat:no-repeat}
.sortbar__s:hover{border-color:var(--gold,#cba24a)}
.sortbar__s:focus-visible{outline:2px solid var(--gold,#cba24a); outline-offset:2px}
/* ── SEARCH, BEFORE SORT (Cyle Reynolds, 2026-09-24: "add a search bar before sort on all
   product pages") ──────────────────────────────────────────────────────────────────────
   ⚠ ON /shop/accessories THIS IS A MOVE, NOT AN ADDITION. The box lived in .sidebar__search,
   and that sidebar is display:none on a phone until "Filters" is tapped — so the one control
   that narrows 590 cards was invisible to every phone shopper. One #searchBox per page: a
   second element with the same id is invalid and shop_filter.js binds only the first. */
.sortbar__q{position:relative; flex:1 1 220px; max-width:340px; min-width:0}
.sortbar__q svg{position:absolute; left:12px; top:50%; transform:translateY(-50%); width:15px;
  height:15px; fill:var(--muted); pointer-events:none}
.sortbar__q input{width:100%; box-sizing:border-box; font:inherit; font-size:13px;
  color:var(--text); background:var(--card,#16161a); border:1px solid var(--line);
  border-radius:999px; padding:7px 13px 7px 35px; -webkit-appearance:none; appearance:none}
.sortbar__q input::placeholder{color:var(--muted)}
.sortbar__q input:hover{border-color:var(--gold,#cba24a)}
.sortbar__q input:focus{outline:none; border-color:var(--gold,#cba24a)}
.sortbar__q input:focus-visible{outline:2px solid var(--gold,#cba24a); outline-offset:2px}
.sortbar__q input::-webkit-search-cancel-button{-webkit-appearance:none; height:14px; width:14px;
  background:var(--muted); cursor:pointer;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M15 5L5 15M5 5l10 10' stroke='black' stroke-width='2'/%3E%3C/svg%3E") center/contain no-repeat}
@media (max-width:520px){ .sortbar{margin-bottom:10px} .sortbar__s{flex:1 1 auto}
  .sortbar__q{flex:1 1 100%; max-width:none} }

/* ── IN-TILE FITMENT DROPDOWN (optics: adapter plates · silencers: threaded barrels) ──
   Moved here from shop_optics.html's inline <style> on 2026-09-19 so both lanes share
   one declaration. Nothing re-declares these selectors in a template today. */
.gfplate{position:relative; margin-top:8px; border-top:1px solid var(--line); padding-top:7px}
/* The trigger. Styled as the old <summary> was, so the tile reads identically when closed. */
.gfplate__btn{display:flex; align-items:center; gap:5px; width:100%; cursor:pointer;
  background:none; border:0; padding:2px 0; text-align:left; font:inherit; font-size:12px;
  font-weight:700; color:#e1b463; letter-spacing:.02em}
.gfplate__car{margin-left:auto; opacity:.8; transition:transform .15s}
.gfplate__btn[aria-expanded="true"] .gfplate__car{transform:rotate(180deg)}
/* ⚠ FIXED, AND POSITIONED FROM JS. `.pcard` is `overflow:hidden`, so a menu laid out inside
   the card is clipped — the body below the trigger is ~120px and a four-plate menu is ~250px.
   Fixed escapes ancestor overflow; the JS sets top/left from the trigger's rect and flips the
   menu above when the viewport has no room below. */
.gfplate__list{position:fixed; z-index:200; list-style:none; margin:0; padding:7px;
  display:grid; gap:5px; width:max-content; max-width:min(340px, 92vw);
  background:var(--card,#16161a); border:1px solid var(--line);
  border-radius:12px; box-shadow:0 18px 40px rgba(0,0,0,.55)}
.gfplate__list[hidden]{display:none}
/* ⚠ THE OPEN CARD MUST NOT BE TRANSFORMED. `.pcard:hover` translates the card, and a
   transformed ancestor becomes the containing block for a fixed descendant — which would put
   the menu back inside the card's clipped box at exactly the moment it is being used. */
.pcard--ddopen{transform:none !important; z-index:5}
.gfplate__list li{display:flex; align-items:baseline; gap:8px; justify-content:space-between;
  font-size:11.5px; line-height:1.35; color:var(--muted)}
/* ⚠ THE NAME GETS ITS OWN LINE. A card is ~184px wide and a plate is named
   'C&H PLT FOR GLK 43X/48 MOS TO RMR' — name, price and two buttons on ONE line squeezed the
   name to a one-word-per-line column that was technically present and unreadable. Wrapping puts
   the name across the full width and price + buttons beneath it. Measured in the browser, not
   inferred from the rule. */
.gfplate__n{flex:1 1 100%; min-width:0; color:var(--text)}
.gfplate__p{flex:0 0 auto; font-weight:700; color:var(--text); font-variant-numeric:tabular-nums}
.gfplate__none{font-size:11.5px; line-height:1.4; color:var(--muted); margin-top:6px}
/* The fit reason, moved off the card badge and into the menu it describes. */
.gfplate__why{font-size:11px; line-height:1.4; color:var(--muted); padding-bottom:6px;
  border-bottom:1px solid var(--line)}
.gfplate__note{font-size:11px; line-height:1.4; color:var(--muted); padding-top:5px;
  border-top:1px solid var(--line)}
.gfplate__note:first-child{border-top:0; padding-top:0}
.gfplate__note a{color:var(--gold,#cba24a)}
.gfplate__row{display:flex; align-items:center; gap:6px; flex-wrap:wrap}
.gfplate__row + .gfplate__row{border-top:1px solid var(--line); padding-top:5px}
/* The Add button is the whole point of moving plates into the tile: the rail's plates were
   buyable and the tile's must stay buyable. Small, but a real button, not a link. */
.gfplate__b{flex:0 0 auto; font:inherit; font-size:10.5px; font-weight:700; cursor:pointer;
  padding:3px 8px; border-radius:7px; text-decoration:none; line-height:1.5;
  background:var(--gold,#cba24a); color:#231a04; border:1px solid var(--gold,#cba24a)}
.gfplate__b:hover{filter:brightness(1.07)}
.gfplate__b.is-on{background:transparent; color:var(--gold,#cba24a)}
/* 'Use' is the quieter of the two — trying a plate is not buying one. */
.gfplate__b--try{background:transparent; color:var(--muted); border-color:var(--line)}
.gfplate__b--try:hover{color:var(--text); border-color:var(--gold,#cba24a)}
