/* ============================================================= STICKER BOMB
   AtlantaTCG — Direction "Sticker Bomb" · Jet Set Radio / skate culture.
   Spray paint on light concrete, die-cut stickers on the wall — MATURED for
   usability: cards & tiles sit DEAD STRAIGHT (0deg) in a clean grid,
   non-overlapping clickable areas, solid high-contrast sticker faces, generous
   spacing. Loud identity, legible & easy to shop by everyone.

   Ported verbatim from approved home mockup 09-v2.html, then extended with the
   shared chrome (cart drawer), store, product & about pages in the same skin.
   ============================================================================ */
:root{
  /* ============================================================
     BRAND RE-SKIN — AtlantaTCG emblem palette (was a rainbow).
     Legacy token NAMES are kept (so existing rules recolor without
     a rewrite) but every VALUE now maps to the real brand system:
       amethyst purple · coin gold · card blue · warm brown · black
       on cream / parchment surfaces. Green is SEMANTIC ONLY.
     Canonical source: ../brand/tokens.css
     ============================================================ */
  /* "orange" slot  →  COIN GOLD (primary CTA / highlight) */
  --orange:#E0A526;        /* coin gold — dark text rides on it */
  --orange-bright:#F2B940; /* gold highlight */
  /* "blue" slot    →  CARD BLUE (secondary brand accent — recurring) */
  --blue:#3A6BB0;          /* card blue — AA behind white text */
  --blue-deep:#27518C;     /* deep card blue — blue text on light surfaces */
  --blue-bright:#5A8AD0;   /* lighter card blue */
  --blue-lively:#3D7FD0;   /* lively card blue — bright accents */
  /* "yellow" slot  →  COIN GOLD (always dark text) */
  --yellow:#E0A526;
  /* "magenta" slot →  AMETHYST PURPLE (primary brand accent) */
  --magenta:#6E3FA3;       /* amethyst — AA behind white text */
  --magenta-bright:#8A57C8;
  /* "purple" slot  →  amethyst (kept consistent) */
  --purple:#6E3FA3;
  --ink:#14110C;           /* warm near-black — text + keylines */
  --white:#FFFFFF;
  --paper:#FBF5E9;         /* cream — solid light sticker face */
  --photo-bg:#FCFBF6;      /* near-white product-photo panel — white shots blend in under multiply */
  /* "green" slots — GREEN IS SEMANTIC (in-stock) ONLY.
     Decorative uses are remapped off-green individually below. */
  --green:#2E7D52;         /* muted leaf green — the ONLY green */
  --green-bright:#2E7D52;  /* keep stock tags one cohesive green */
  /* warm brand support tones */
  --brown:#5A3E22;
  --brown-deep:#3A2817;
  --brown-tint:#8A6A3E;
  --silver:#C9CDD2;
  --silver-deep:#8C9298;
  --gold-deep:#B9831A;
  --gold-tint:#F2D38A;
  --sold-out:#9B3A2E;
  /* ---- Vibrant logo-fan accent POPS (decor / badges / stock / hovers) ---- */
  --vib-red:#CE3B2B;        /* card red — HOT / ★ / energy */
  --vib-red-deep:#9B3A2E;
  --vib-green:#57A347;      /* creature green — NEW / fresh / in-stock pop */
  --vib-green-deep:#2E7D52;
  --vib-amethyst:#9B6FC8;   /* bright gem purple */
  --parchment:#F4EAD6;     /* warm panel surface (was cold --concrete) */
  --concrete:#F4EAD6;      /* warm parchment — NO cold grey anywhere */
  --shadow:0 9px 0 rgba(20,17,12,.16), 0 16px 30px rgba(20,17,12,.28);
  --die:7px;               /* white die-cut border thickness */
  --keyline:3px;           /* black cel-shaded keyline */
  --r-card:16px;

  /* ---- BLUE COIN role system: card-blue is the primary; gold is the accent.
     Every functional element (price, selectors, active states, section-title
     shadows, primary CTAs, links) pulls from these so the whole site is one
     system. Change a role here and it moves everywhere. Gold stays for pops. */
  --primary:var(--blue);            /* #3A6BB0 — primary action + brand lead */
  --primary-deep:var(--blue-deep);  /* #27518C — on light surfaces */
  --primary-hover:var(--blue-lively);
  --on-primary:#fff;
  --accent:var(--orange);           /* coin gold — accent pops only */
  --on-accent:var(--ink);
  --price-bg:var(--blue);           /* price ribbon */
  --on-price:#fff;
  --sel:var(--blue);                /* selected filter / active tab */
  --on-sel:#fff;
  --link:var(--blue-deep);          /* text links + breadcrumbs */
  --title-shadow:var(--blue);       /* section/page-title hard shadow */
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;
  font-family:'Rubik','Rubik Fallback',system-ui,sans-serif;
  font-size:16px;
  line-height:1.5;
  color:var(--ink);
  background-color:#F4EAD6;
  /* warm parchment so text laid on it passes contrast — brand-tinted glow */
  background-image:
    radial-gradient(circle at 10% 14%, rgba(110,63,163,.13), rgba(110,63,163,0) 16%),
    radial-gradient(circle at 88% 6%, rgba(58,107,176,.13), rgba(58,107,176,0) 18%),
    radial-gradient(circle at 94% 70%, rgba(224,165,38,.16), rgba(224,165,38,0) 16%),
    radial-gradient(circle at 4% 78%, rgba(90,62,34,.12), rgba(90,62,34,0) 18%),
    repeating-conic-gradient(from 0deg at 50% 50%, rgba(58,40,23,.012) 0deg 1deg, rgba(255,255,255,.012) 1deg 2deg),
    linear-gradient(180deg,#FBF5E9,#F1E4CB);
  background-attachment:fixed;
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
}
/* fine asphalt noise — decorative, subtle so it never hurts legibility */
body::before{
  content:"";position:fixed;inset:0;z-index:0;pointer-events:none;opacity:.38;mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/></svg>");
}
/* On phones, a fixed background + a fixed multiply noise overlay each force a
   full-viewport repaint every scroll frame (low-end scroll jank). Pin both to the
   page so they translate with content and the compositor can cache the blend —
   mirrors the gallery's existing fixed->scroll mobile fallback. Desktop look intact. */
@media(max-width:700px){
  body{background-attachment:scroll;position:relative}
  body::before{position:absolute}
}
a{color:inherit;text-decoration:none}
img{display:block;max-width:100%}
button{font-family:inherit;cursor:pointer;border:none;background:none}
input,select,textarea{font-family:inherit}
.wrap{max-width:1240px;margin:0 auto;padding:0 22px;position:relative;z-index:1}

/* ===================== MOBILE / iOS FOUNDATION =====================
   Keeps the loud sticker look but makes it behave on iPhones: no text auto-inflation
   in landscape, no grey tap-flash, no 300ms tap delay or double-tap zoom on controls,
   and chrome that clears the notch + home indicator (paired with viewport-fit=cover in
   each page's <meta viewport>). env() resolves to 0 on non-notch devices, so these are
   inert everywhere else. */
html{-webkit-text-size-adjust:100%;text-size-adjust:100%;overflow-x:clip}
/* belt-and-suspenders: clip stray horizontal bleed (decorative hero blobs that sit a
   little off-screen) so phones never get an accidental sideways scroll. overflow:clip
   (not hidden) doesn't create a scroll container, so the sticky header still works. */
body{overflow-x:clip}
*{-webkit-tap-highlight-color:transparent}
a,button,input,select,textarea,label,summary,.card,.cat-chip,.ev-day{touch-action:manipulation}
@supports(padding:max(0px)){
  header.bar .bar-inner{
    padding-top:calc(10px + env(safe-area-inset-top));
    padding-left:max(18px,env(safe-area-inset-left));
    padding-right:max(18px,env(safe-area-inset-right));
  }
  body .wrap{
    padding-left:max(22px,env(safe-area-inset-left));
    padding-right:max(22px,env(safe-area-inset-right));
  }
}

/* visible, in-aesthetic focus ring used everywhere */
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible{
  outline:3px solid var(--blue);outline-offset:3px;border-radius:6px;
}

/* skip link — part of the look */
.skip{position:absolute;left:-9999px;top:auto}
.skip:focus{left:16px;top:12px;z-index:200;background:var(--yellow);color:var(--ink);
  padding:12px 18px;border:var(--keyline) solid var(--ink);font-family:'Bungee','Bungee Fallback',sans-serif;font-size:14px;border-radius:8px;
  box-shadow:3px 3px 0 var(--ink)}
.visually-hidden{position:absolute;left:-9999px}
/* peeling folded corner — decorative only */
.peel::after{
  content:"";position:absolute;top:-2px;right:-2px;width:26px;height:26px;z-index:6;
  background:linear-gradient(135deg, rgba(0,0,0,.28), rgba(255,255,255,.95) 46%, #EBE3D2 60%);
  clip-path:polygon(100% 0, 0 0, 100% 100%);
  border-top-right-radius:12px;
  box-shadow:-3px 4px 7px rgba(0,0,0,.32);
  transition:transform .25s ease;
  pointer-events:none;
}
.peel:hover::after{transform:translate(2px,2px) scale(1.1)}

/* ================================================================= HEADER */
/* min-height reserves the bar's rendered height (72px at every breakpoint,
   measured) so the JS-filled chrome can't push the page down after first
   paint — the shell <header class="bar" data-bar> ships empty in the HTML. */
header.bar{position:sticky;top:0;z-index:80;min-height:72px}
.bar-inner{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding:10px 18px;
  background:var(--ink);
}
/* underline = the logo's card fan: purple · gold · blue · green · red */
.bar::after{content:"";display:block;height:6px;
  background:linear-gradient(90deg,
    var(--magenta),var(--orange),var(--blue),var(--vib-green),var(--vib-red));
  box-shadow:0 3px 7px rgba(0,0,0,.32)}
.brand{display:flex;align-items:center;gap:12px;order:1;margin-right:auto}
.brand .logo{
  width:46px;height:46px;border-radius:10px;object-fit:cover;
  border:3px solid #fff;outline:3px solid var(--ink);
  background:#fff;
}
/* silver-chrome wordmark — nods to the emblem's metal lettering */
.wordmark{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:22px;line-height:1;letter-spacing:.5px;
  color:var(--silver);
  background:linear-gradient(180deg,#F2F4F6 0%,var(--silver) 40%,var(--silver-deep) 70%,#6F757B 100%);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
  text-shadow:0 2px 0 rgba(0,0,0,.45);
  filter:drop-shadow(2px 2px 0 rgba(20,17,12,.55));}
/* "TCG" = SOLID vivid yellow flat fill (no gradient/chrome); ATLANTA keeps chrome */
.wordmark b{
  background:none;
  -webkit-background-clip:border-box;background-clip:border-box;
  -webkit-text-fill-color:var(--brand-yellow,#FFC400);color:var(--brand-yellow,#FFC400);}

/* header search */
.search{display:flex;align-items:center;gap:0;order:3;flex:1 1 100%;max-width:none;min-width:200px}
.search input{
  flex:1;font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:600;font-size:16px;color:var(--ink);  /* 16px: stops iOS zoom-on-focus */
  background:var(--paper);padding:11px 14px;min-height:44px;
  border:3px solid var(--ink);border-right:none;border-radius:10px 0 0 10px;
}
.search input::placeholder{color:#6A5A48}
/* header search submit = card blue (secondary control) */
.search button{
  font-family:'Bungee','Bungee Fallback',sans-serif;font-size:12px;color:#fff;background:var(--blue);
  padding:0 14px;min-height:44px;min-width:48px;
  border:3px solid var(--ink);border-radius:0 10px 10px 0;
  display:flex;align-items:center;justify-content:center;transition:background .18s;
}
.search button:hover{background:var(--blue-lively)}
.search button svg{width:20px;height:20px}
/* The header search is ONE joined input+button pill. Ring the whole pill on
   focus (input or submit) rather than the input alone — the input-only ring
   wrapped the input's square right edge, so it ran through / behind the
   magnifying-glass button and read as clipped. */
.search:focus-within{outline:3px solid var(--blue);outline-offset:3px;border-radius:13px}
.search input:focus-visible,.search button:focus-visible{outline:none}

/* ---- search suggestions dropdown (combobox panel under either search) ---- */
.search{position:relative}                          /* anchor for the abs panel (mobile-search anchors via its own overlay positioning) */
.sugg{position:absolute;left:0;right:0;top:calc(100% + 7px);z-index:90;
  background:var(--paper);border:3px solid var(--ink);border-radius:14px;
  box-shadow:6px 8px 0 rgba(20,17,12,.28);padding:6px;
  max-height:min(64vh,440px);overflow-y:auto;overscroll-behavior:contain}
.sugg[hidden]{display:none}
.sugg-group{padding:4px 2px 2px}
.sugg-head{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:10px;letter-spacing:.6px;color:#8A7A63;padding:4px 8px 6px}
.sugg-opt{display:flex;align-items:center;gap:11px;padding:9px 10px;border-radius:9px;
  text-decoration:none;color:var(--ink);font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:600;font-size:14px;line-height:1.2}
.sugg-opt .s-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sugg-opt .s-count,.sugg-opt .s-price{flex:0 0 auto;font-size:12px;font-weight:700;color:#6A5A48}
.sugg-opt .s-thumb{flex:0 0 auto;width:34px;height:34px;border-radius:7px;object-fit:cover;
  border:2px solid var(--ink);background:#fff}
/* hover + keyboard-active share one highlight so mouse and keyboard agree */
.sugg-opt.active,.sugg-opt:hover{background:var(--yellow)}
.sugg-game{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:13px}
.sugg-game .s-count{font-family:'Rubik','Rubik Fallback',sans-serif}
.sugg-all{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:11px;color:var(--blue);margin-top:2px}
.sugg-all.active,.sugg-all:hover{background:var(--blue);color:#fff}
.sugg-empty{padding:10px 12px;font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:600;font-size:13px;color:#6A5A48;margin:0}

/* "pop" keyframe: a quick scale/rotate bounce reused for small tap-feedback effects */
@keyframes pop{0%{transform:scale(1)}40%{transform:scale(1.5) rotate(-8deg)}100%{transform:scale(1)}}

/* =============================================== DISPLAY-ONLY (no cart) */
/* (Phase 4.5: the header in-store-only chip was removed; the message lives
   in the homepage info strip, on product cards, and on the PDP) */
/* product page: "get it at the shop" panel — the PDP's action block.
   Parchment sticker card; fills the info column that used to run empty
   under the price and turns the buy decision into a visit. */
.visit-panel{background:var(--paper);border:2.5px solid var(--ink);border-radius:14px;
  box-shadow:4px 4px 0 rgba(20,17,12,.18);padding:18px 20px;margin:6px 0 10px;
  display:flex;flex-direction:column;gap:10px}
.visit-head{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:15px;letter-spacing:.4px;color:var(--ink);margin:0}
.visit-facts{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:3px;
  font-weight:600;font-size:14px;color:#5A4A36}
.visit-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:2px}
.visit-actions .btn-slap{font-size:13px;padding:12px 18px}
.visit-note{margin:0;font-size:13px;font-weight:500;color:#5A4A36}
.visit-note a{color:var(--blue-deep,#27518C);font-weight:700;text-decoration:underline}
@media(max-width:560px){
  .visit-actions{flex-direction:column}
  .visit-actions .btn-slap{width:100%;justify-content:center}
}
/* product-page format selector (variant pills) */
.variant-pills{display:flex;flex-wrap:wrap;gap:10px;margin:0 0 16px}
.variant-pill{display:inline-flex;flex-direction:column;align-items:flex-start;gap:2px;
  font-family:'Rubik','Rubik Fallback',sans-serif;text-align:left;color:var(--ink);background:var(--paper);
  padding:9px 14px;border-radius:11px;border:2.5px solid var(--ink);box-shadow:2px 2px 0 rgba(0,0,0,.5);
  transition:transform .12s,box-shadow .12s,background .15s}
.variant-pill:hover{background:var(--yellow);transform:translate(-1px,-1px);box-shadow:3px 3px 0 rgba(0,0,0,.6)}
.variant-pill.active{background:var(--blue);border-color:var(--ink)}
.variant-pill.active .vp-name,.variant-pill.active .vp-price{color:#fff}
.vp-name{font-weight:800;font-size:12px;letter-spacing:.2px;text-transform:uppercase}
.vp-price{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:13px;color:var(--blue-deep)}
.variant-pill.soldout{opacity:.55}

/* price RANGE on cards ("$5.50 – $98.00"): a compact dash so the tab stays tidy */
.price-tab{white-space:nowrap}
.price-tab .to{font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:700;font-size:.62em;color:rgba(20,17,12,.5);margin:0 3px;vertical-align:2px}
.pdp-price .to{font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:600;font-size:.5em;color:var(--brown-tint);margin:0 6px;vertical-align:6px}

/* PDP format breakdown — Pack / Box / Case, each with its live price + stock */
.pdp-formats{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:0 0 18px}
.pdp-formats:empty{display:none}
.pdp-formats .fmt-head{font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:800;font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--brown-tint);margin-right:2px}
.fmt{display:inline-flex;align-items:baseline;gap:6px;background:#fff;border:3px solid var(--ink);border-radius:9px;padding:6px 11px;box-shadow:2px 2px 0 rgba(0,0,0,.5)}
.fmt-name{font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:800;font-size:12px;text-transform:uppercase;letter-spacing:.3px;color:var(--ink)}
.fmt-price{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:14px;color:var(--blue-deep)}
.fmt-x{font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:700;font-size:10px;text-transform:uppercase;color:#B23A2E;letter-spacing:.3px}
.fmt.soldout{opacity:.62}
.fmt.soldout .fmt-price{text-decoration:line-through}

/* ---------------------------------- MAIN NAV: SHOP ▾ dropdown + nav links */
nav.cats{display:flex;gap:8px;flex-wrap:wrap;align-items:center;width:100%;order:4;
  padding-top:4px}
@media(min-width:980px){
  /* Single-row header in NORMAL flex flow: logo LEFT, a big search beside it, then
     SHOP ▾ / EVENTS / ABOUT US + the in-store pill pushed to the RIGHT via
     margin-left:auto. Search is a primary task (Nielsen) so it stays large (basis
     560px) but it remains IN FLOW with flex-shrink, so the wider nav can NEVER
     overlap it — at tighter widths the search shrinks (floored ~260px) and then the
     bar wraps gracefully, but the zones never collide (the old absolute-centred
     search overlapped the nav once the right zone widened). */
  .brand{margin-right:0}
  .search{order:2;flex:0 1 480px;min-width:240px;max-width:520px;margin:0}
  nav.cats{order:3;width:auto;flex:0 0 auto;justify-content:flex-end;margin-left:auto;padding-top:0}
}
/* shared nav pill look: SHOP ▾ toggle + the plain SHOP ALL / ABOUT US links */
.nav-link,.shop-toggle{
  font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:800;font-size:12.5px;letter-spacing:.3px;text-transform:uppercase;
  color:var(--ink);background:var(--paper);
  padding:8px 12px;min-height:38px;display:inline-flex;align-items:center;gap:6px;
  border-radius:8px;border:2px solid var(--ink);box-shadow:2px 2px 0 rgba(0,0,0,.5);
  transition:transform .15s, box-shadow .15s, background .15s;white-space:nowrap;
}
.nav-link:hover,.nav-link:focus-visible,
.shop-toggle:hover,.shop-toggle:focus-visible{
  background:var(--yellow);transform:translateY(-2px);box-shadow:3px 5px 0 rgba(0,0,0,.6)}
.shop-toggle .caret{font-size:11px;line-height:1;transition:transform .18s}

/* the dropdown shell */
.shop-dd{position:relative}
.shop-dd.open .shop-toggle,
.shop-dd:focus-within .shop-toggle{background:var(--yellow)}
.shop-dd.open .shop-toggle .caret,
.shop-dd:focus-within .shop-toggle .caret{transform:rotate(180deg)}

/* Panel opens on the JS-managed .open class (hover-intent delay + click-to-pin,
   wireChrome) AND on keyboard focus (:focus-within, no JS needed). The old
   bare :hover opened on the first pixel — a cursor passing through flung it
   open; the intent delay fixes that without losing the CSS focus path. */
.shop-menu{
  position:absolute;top:calc(100% + 8px);left:0;z-index:90;min-width:248px;
  display:flex;flex-direction:column;gap:4px;padding:10px;
  background:var(--parchment);border:var(--keyline) solid var(--ink);border-radius:14px;
  box-shadow:var(--shadow);
  opacity:0;visibility:hidden;transform:translateY(-6px);pointer-events:none;
  transition:opacity .16s ease, transform .16s ease, visibility .16s;
}
/* a tiny hover bridge so the gap below the toggle doesn't drop the menu */
.shop-menu::before{content:"";position:absolute;top:-10px;left:0;right:0;height:12px}
@media(min-width:980px){.shop-menu{left:50%;transform:translate(-50%,-6px)}}
.shop-dd.open .shop-menu,
.shop-dd:focus-within .shop-menu{
  opacity:1;visibility:visible;transform:translateY(0);pointer-events:auto}
@media(min-width:980px){
  .shop-dd.open .shop-menu,
  .shop-dd:focus-within .shop-menu{transform:translate(-50%,0)}
}
/* EVENTS nav dropdown — same shell + reveal model as SHOP (wired by the shared
   wireDd() in app.js), but right-anchored so a terminal nav item stays on-screen.
   Reuses .shop-toggle (button) + .shop-item (rows) for identical styling. */
.ev-dd{position:relative}
.ev-dd.open .shop-toggle,
.ev-dd:focus-within .shop-toggle{background:var(--yellow)}
.ev-dd.open .shop-toggle .caret,
.ev-dd:focus-within .shop-toggle .caret{transform:rotate(180deg)}
.ev-menu{
  position:absolute;top:calc(100% + 8px);right:0;z-index:90;min-width:216px;
  display:flex;flex-direction:column;gap:4px;padding:10px;
  background:var(--parchment);border:var(--keyline) solid var(--ink);border-radius:14px;
  box-shadow:var(--shadow);
  opacity:0;visibility:hidden;transform:translateY(-6px);pointer-events:none;
  transition:opacity .16s ease, transform .16s ease, visibility .16s;
}
.ev-menu::before{content:"";position:absolute;top:-10px;left:0;right:0;height:12px}
.ev-dd.open .ev-menu,
.ev-dd:focus-within .ev-menu{
  opacity:1;visibility:visible;transform:translateY(0);pointer-events:auto}

.shop-item{
  display:flex;align-items:center;justify-content:space-between;gap:9px;
  font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:700;font-size:14px;color:var(--ink);
  background:#fff;padding:10px 15px 10px 13px;min-height:42px;border-radius:9px;border:2px solid var(--ink);
  box-shadow:2px 2px 0 rgba(0,0,0,.3);transition:transform .12s, box-shadow .12s, background .14s;
  white-space:nowrap;
}
.shop-item:hover,.shop-item:focus-visible{background:var(--yellow);transform:translate(-1px,-1px);box-shadow:3px 3px 0 rgba(0,0,0,.4)}
.shop-item.active{background:var(--sel);color:var(--on-sel);border-color:var(--ink)}
.shop-item.active .mi-count{background:rgba(255,255,255,.25)}
.shop-item-all{background:var(--primary);color:var(--on-primary);font-family:'Bungee','Bungee Fallback',sans-serif;font-size:12px;text-transform:uppercase;letter-spacing:.4px}
.shop-item-all:hover,.shop-item-all:focus-visible{background:var(--primary-hover);color:#fff}
.shop-item-all .ar{font-family:'Rubik','Rubik Fallback',sans-serif}
.mi-count{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:11px;background:var(--ink);color:#fff;
  padding:2px 8px;border-radius:20px;min-width:26px;text-align:center}

/* ---- second-level flyout: a category → its live product types ---- */
.mi-label{margin-right:auto}
/* fixed-width slot so every row reserves the same column — the › on flyout
   rows and the empty slot on plain rows keep all the count pills aligned.
   Bolder, ink-toned and given edge room so it reads as a clear "more inside"
   affordance instead of a thin mark crowding the corner. */
.mi-chev{flex:0 0 13px;width:13px;text-align:center;
  font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:900;font-size:18px;line-height:1;color:var(--ink);opacity:.4;
  transition:transform .16s, opacity .16s}
.shop-cat{position:relative}
.shop-cat:hover .mi-chev,.shop-cat.sub-open .mi-chev{opacity:.85}
.shop-cat.sub-open .shop-item.has-sub{background:var(--yellow)}
.shop-cat.sub-open .mi-chev{transform:translateX(1px);opacity:1}
.shop-sub{position:absolute;top:-2px;left:calc(100% + 10px);z-index:95;width:238px;
  display:flex;flex-direction:column;gap:5px;padding:9px;
  background:var(--parchment);border:var(--keyline) solid var(--ink);border-radius:14px;box-shadow:var(--shadow);
  opacity:0;visibility:hidden;transform:translateX(-6px);pointer-events:none;
  transition:opacity .15s ease, transform .15s ease, visibility .15s}
/* bridge across the gap so the diagonal reach never drops the panel */
.shop-sub::before{content:"";position:absolute;left:-12px;top:0;bottom:0;width:14px}
.shop-cat.sub-open .shop-sub{opacity:1;visibility:visible;transform:none;pointer-events:auto}
/* flip to the left edge of the menu when a right-side panel would clip */
.shop-cat.flip-left .shop-sub{left:auto;right:calc(100% + 10px);transform:translateX(6px)}
.shop-cat.flip-left .shop-sub::before{left:auto;right:-12px}
.shop-cat.flip-left.sub-open .shop-sub{transform:none}
.sub-head{font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:800;font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;
  color:#5A4A36;padding:2px 6px 4px}
.sub-item{display:flex;align-items:center;justify-content:space-between;gap:10px;
  font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:700;font-size:13px;color:var(--ink);background:#fff;
  padding:8px 10px;min-height:38px;border-radius:8px;border:2px solid var(--ink);box-shadow:2px 2px 0 rgba(0,0,0,.28);
  white-space:nowrap}
.sub-item:hover,.sub-item:focus-visible{background:var(--yellow);transform:translate(-1px,-1px);box-shadow:3px 3px 0 rgba(0,0,0,.4)}
.sub-item .mi-count{font-size:10px;min-width:22px}
.sub-all{background:var(--primary);color:#fff;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:11px;text-transform:uppercase;letter-spacing:.3px}
.sub-all:hover,.sub-all:focus-visible{background:var(--primary-hover);color:#fff}
@media(prefers-reduced-motion:reduce){.shop-sub,.mi-chev{transition:none}}

/* =============================================== MOBILE HEADER (<980px) */
/* mobile-only tool buttons: magnifier + hamburger. Hidden on desktop. */
.header-tool{order:5;display:inline-flex;align-items:center;justify-content:center;
  width:44px;height:44px;flex:0 0 auto;color:var(--ink);background:var(--yellow);
  border:3px solid var(--ink);border-radius:10px;box-shadow:3px 3px 0 rgba(0,0,0,.6);
  transition:transform .15s,box-shadow .15s,background .15s}
.header-tool:hover,.header-tool:focus-visible{background:var(--orange-bright);transform:translateY(-2px)}
.header-tool:active{transform:translate(1px,1px);box-shadow:1px 1px 0 rgba(0,0,0,.6)}
.header-tool svg{width:22px;height:22px}
.header-tool#searchToggle{order:4;background:var(--blue);color:#fff}
.header-tool#searchToggle:hover,.header-tool#searchToggle:focus-visible{background:var(--blue-lively)}
/* hamburger glyph -> animates to an X when its panel is open */
.ham-box{position:relative;width:20px;height:15px;display:block}
.ham-line{position:absolute;left:0;right:0;height:2.8px;border-radius:2px;background:currentColor;
  transition:transform .22s ease,opacity .18s ease}
.ham-line:nth-child(1){top:0}
.ham-line:nth-child(2){top:6px}
.ham-line:nth-child(3){top:12px}
.mmenu-open .hamburger .ham-line:nth-child(1){transform:translateY(6px) rotate(45deg)}
.mmenu-open .hamburger .ham-line:nth-child(2){opacity:0}
.mmenu-open .hamburger .ham-line:nth-child(3){transform:translateY(-6px) rotate(-45deg)}

/* mobile search EXPANDS IN the header bar — an ink overlay across the top
   toolbar row (logo + tools tuck under it) instead of dropping a second row,
   so the sticky header stays one row tall. Tap 🔍 to expand; back-arrow / Esc
   / outside-tap collapse it. The suggestions panel still drops below the bar. */
/* animate via TRANSFORM only (no opacity/visibility fade): the field must be
   genuinely visible the instant it's focused or iOS won't raise the keyboard.
   Closed state is display:none via [hidden], so there's nothing to fade. */
.mobile-search{position:absolute;top:0;left:0;right:0;z-index:3;
  display:flex;align-items:center;gap:9px;padding:10px 14px;background:var(--ink);
  pointer-events:none;transform:translateY(-8px);
  transition:transform .2s ease}
.mobile-search[hidden]{display:none}
.msearch-open .mobile-search{pointer-events:auto;transform:none}
/* back-arrow: the shared right-arrow icon flipped into a ← */
.msearch-back{flex:0 0 auto;width:46px;height:46px;border-radius:11px;cursor:pointer;
  border:3px solid #fff;background:transparent;color:#fff;
  display:flex;align-items:center;justify-content:center}
.msearch-back svg{width:20px;height:20px;transform:scaleX(-1)}
.msearch-back:active{transform:scale(.93)}
/* input+submit stay a joined pill; ring just the pill on focus (not the whole bar) */
.msearch-pill{position:relative;display:flex;flex:1;min-width:0}
.msearch-pill:focus-within{outline:3px solid var(--blue);outline-offset:3px;border-radius:13px}
.mobile-search input{flex:1;min-width:0;font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:600;font-size:16px;color:var(--ink);
  background:var(--paper);padding:11px 14px;min-height:46px;
  border:3px solid var(--ink);border-right:none;border-radius:10px 0 0 10px}
.mobile-search input::placeholder{color:#6A5A48}
.mobile-search button[type="submit"]{font-family:'Bungee','Bungee Fallback',sans-serif;color:#fff;background:var(--blue);
  min-height:46px;min-width:52px;padding:0 14px;display:flex;align-items:center;justify-content:center;
  border:3px solid var(--ink);border-radius:0 10px 10px 0}
.mobile-search button[type="submit"]:hover{background:var(--blue-lively)}
.mobile-search button svg{width:20px;height:20px}
.mobile-search input:focus-visible,.mobile-search button:focus-visible{outline:none}

/* die-cut menu panel (slides down under the bar) */
.mobile-menu{order:7;flex:0 0 100%;display:flex;flex-direction:column;gap:8px;
  margin:0;padding:0 4px;max-height:0;opacity:0;overflow:hidden;
  transition:max-height .3s ease,opacity .22s ease,margin .3s ease,padding .3s ease}
.mobile-menu[hidden]{display:none}
.mmenu-open .mobile-menu{max-height:78vh;opacity:1;margin-top:12px;padding:14px;overflow-y:auto;
  overscroll-behavior:contain;
  background:var(--parchment);border:var(--keyline) solid var(--ink);border-radius:16px;
  box-shadow:6px 6px 0 rgba(20,17,12,.55)}
.m-link,.m-cat{display:flex;align-items:center;justify-content:space-between;gap:12px;
  font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:800;font-size:15px;letter-spacing:.2px;color:var(--ink);
  background:#fff;padding:13px 15px;min-height:50px;border-radius:11px;
  border:2.5px solid var(--ink);box-shadow:3px 3px 0 rgba(0,0,0,.4);
  transition:transform .12s,box-shadow .12s,background .14s}
.m-link:active,.m-cat:active{background:var(--yellow);transform:translate(1px,1px);box-shadow:1px 1px 0 rgba(0,0,0,.4)}
.m-link:focus-visible,.m-cat:focus-visible{background:var(--yellow)}
.m-link.m-shop-all{background:var(--primary);color:var(--on-primary);font-family:'Bungee','Bungee Fallback',sans-serif;font-size:14px;text-transform:uppercase;letter-spacing:.4px}
.m-link.m-shop-all .ar{font-family:'Rubik','Rubik Fallback',sans-serif}
.m-cats{display:flex;flex-direction:column;gap:8px}
.m-cat .mi-count{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:11px;background:var(--ink);color:#fff;
  padding:2px 8px;border-radius:20px;min-width:26px;text-align:center}
/* category-with-types → tap-to-expand accordion (mirrors the desktop flyout) */
.m-cat-group{display:flex;flex-direction:column}
.m-cat-exp{width:100%;cursor:pointer;justify-content:space-between}
.m-cat-r{display:inline-flex;align-items:center;gap:9px}
.m-cat-r .m-caret{flex:0 0 13px;width:13px;text-align:center;font-size:13px;line-height:1;transition:transform .2s}
.m-cat-group.open .m-cat-exp{background:var(--yellow)}
.m-cat-group.open .m-cat-exp .m-caret{transform:rotate(180deg)}
.m-cat-sub{display:none;flex-direction:column;gap:6px;padding:8px 0 2px 12px}
.m-cat-group.open .m-cat-sub{display:flex}
.m-sub-link{display:flex;align-items:center;justify-content:space-between;gap:10px;
  font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:600;font-size:13.5px;color:var(--ink);background:var(--paper);
  padding:10px 12px;min-height:44px;border-radius:9px;border:2px solid var(--ink);box-shadow:2px 2px 0 rgba(0,0,0,.28)}
.m-sub-link:active{background:var(--yellow);transform:translate(1px,1px);box-shadow:1px 1px 0 rgba(0,0,0,.4)}
.m-sub-link .mi-count{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:10px;background:var(--ink);color:#fff;
  padding:2px 7px;border-radius:20px;min-width:22px;text-align:center}
.m-sub-all{background:var(--primary);color:#fff;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:11px;
  text-transform:uppercase;letter-spacing:.3px;justify-content:center;gap:6px}
@media(prefers-reduced-motion:reduce){.m-cat-exp .m-caret{transition:none}}
/* Shared collapsible-group pattern for the mobile menu — used by BOTH the
   "Shop" row (its categories) and the "Events" row (its pages), mirroring the
   desktop SHOP ▾ / EVENTS ▾ dropdowns. Despite the name, .m-shop-* is not
   Shop-specific; anything that needs a tap-to-expand nav row reuses it. */
.m-shop-toggle{width:100%;cursor:pointer;justify-content:space-between}
.m-caret{font-size:14px;line-height:1;transition:transform .2s}
.m-shop-group.open .m-caret{transform:rotate(180deg)}
.m-shop-sub{display:flex;flex-direction:column;gap:8px;max-height:0;overflow:hidden;
  transition:max-height .28s ease}
.m-shop-group.open .m-shop-sub{max-height:1400px;margin-top:8px;padding-left:12px;
  border-left:3px solid rgba(20,17,12,.22)}

/* lock background scroll while the menu is open. overflow on the ROOT (not position:fixed
   on body — that drags the sticky bar + menu off-screen by the scroll offset) freezes the
   page in place and keeps the sticky header pinned regardless of how far you'd scrolled. */
html.mnav-lock{overflow:hidden}

/* HIDE the desktop inline search + nav on mobile; SHOW the tool buttons */
@media(max-width:979.98px){
  .search{display:none}
  nav.cats{display:none}
  .header-tool{display:inline-flex}
}
/* On desktop the mobile system is fully inert */
@media(min-width:980px){
  .header-tool,.mobile-search,.mobile-menu{display:none !important}
}
/* reduced-motion: instant show/hide, no slide, no hamburger morph */
@media(prefers-reduced-motion:reduce){
  .mobile-search,.mobile-menu,.ham-line,.header-tool,.m-link,.m-cat{transition:none}
}

/* ================================================================== HERO */
.hero{position:relative;padding:50px 0 24px;overflow:visible}
.blob{position:absolute;border-radius:50%;filter:blur(3px);opacity:.6;z-index:0;mix-blend-mode:multiply;pointer-events:none}
/* hero blobs spread the logo fan: purple · blue · gold · green · red */
.b1{width:220px;height:190px;left:-50px;top:28px;background:radial-gradient(circle,var(--magenta),transparent 68%)}
.b2{width:280px;height:230px;right:-70px;top:0;background:radial-gradient(circle,var(--blue),transparent 66%)}
.b3{width:170px;height:150px;right:26%;bottom:-30px;background:radial-gradient(circle,var(--orange),transparent 66%)}
.b4{width:160px;height:150px;left:30%;top:-14px;background:radial-gradient(circle,var(--vib-green),transparent 66%);opacity:.5}
.b5{width:150px;height:140px;left:6%;bottom:8px;background:radial-gradient(circle,var(--vib-red),transparent 66%);opacity:.5}

/* pages with no hero banner (Store, Product) still get the same blob glow —
   a zero-height marker positioned right above the page content; the .blob
   children bleed down into it via their own absolute offsets. z-index:0 (vs.
   .wrap's z-index:1) keeps real content painted on top with no clipping needed. */
.page-blobs{position:relative;height:0;overflow:visible;z-index:0;pointer-events:none}

.hero-grid{position:relative;z-index:2;display:grid;grid-template-columns:0.9fr 1.12fr;gap:36px;align-items:center}
@media(max-width:900px){.hero-grid{grid-template-columns:1fr;gap:24px}}
/* big sprayed wordmark — decorative styling, but it IS the h1 text.
   "SLAP" rides silver-chrome (emblem metal), "SOME" gold, "PACKS" purple. */
.spray-title{
  font-family:'Bungee','Bungee Fallback',sans-serif;line-height:.95;margin:0 0 6px;
  font-size:clamp(44px,8.5vw,100px);
  color:var(--silver);
  -webkit-text-stroke:3px var(--ink);
  text-shadow:4px 4px 0 var(--silver-deep), 8px 8px 0 var(--ink);
  letter-spacing:-1px;
}
.spray-title .l2{color:var(--orange);text-shadow:4px 4px 0 var(--gold-deep),8px 8px 0 var(--ink)}
.spray-title .l3{color:var(--magenta-bright);text-shadow:4px 4px 0 var(--magenta),8px 8px 0 var(--ink)}
.lede{font-size:1.0625rem;font-weight:500;line-height:1.55;max-width:42ch;margin:14px 0 24px;color:#231C12}
.lede b{background:var(--yellow);padding:1px 6px;border-radius:4px;font-weight:800;box-shadow:1px 1px 0 rgba(0,0,0,.4)}
.hero-cta{display:flex;gap:14px;flex-wrap:wrap;align-items:center}
/* on phones the two CTAs stack; size them to a single full-width column and
   center their labels so the pair reads as a tidy block, not a ragged edge. */
@media(max-width:560px){
  .hero-cta{gap:12px}
  .hero-cta .btn-slap{width:100%;justify-content:center}
}
/* PRIMARY CTA = card blue + white (Blue Coin lead) */
.btn-slap{
  font-family:'Bungee','Bungee Fallback',sans-serif;font-size:15px;color:var(--on-primary);background:var(--primary);
  padding:15px 24px;min-height:48px;display:inline-flex;align-items:center;border-radius:12px;border:var(--keyline) solid var(--ink);
  box-shadow:4px 4px 0 var(--ink);
  transition:transform .14s, box-shadow .14s;
}
/* secondary = coin gold accent + black ink */
.btn-slap.alt{background:var(--accent);color:var(--on-accent)}
.btn-slap:hover,.btn-slap:focus-visible{transform:translate(-2px,-2px);box-shadow:7px 7px 0 var(--ink)}
.btn-slap:active{transform:translate(2px,2px);box-shadow:1px 1px 0 var(--ink)}

/* hero stat stickers — tamed angles, non-overlapping, solid faces */
.stat-cluster{position:relative;display:grid;grid-template-columns:1fr 1fr;gap:16px;align-content:center}
.s1{background:var(--yellow)}
/* second hero stat picks up the blue number + a card-blue keyline pop */
.s2{outline-color:var(--blue)}
.s2 .n{color:var(--blue-deep)}

/* tape ticker — homepage: translucent gold masking tape, full viewport bleed.
   Legacy .ticker below stays for about/events/graded until those pages migrate. */
.tape-ticker{position:relative;overflow:hidden;
  margin:80px calc(50% - 50vw) 0;
  background:rgba(224,165,38,.18);
  border-top:2px dashed rgba(20,17,12,.28);border-bottom:2px dashed rgba(20,17,12,.28);
  box-shadow:0 2px 7px rgba(20,17,12,.13), inset 0 0 18px rgba(224,165,38,.10)}
.tape-ticker .tt-track{display:flex;white-space:nowrap;width:max-content;padding:11px 0;
  font-family:'Ranchers','Ranchers Fallback',cursive;font-size:clamp(17px,2.2vw,22px);letter-spacing:1.5px;color:var(--ink);
  /* 78s = the old 26s scaled 3x with the tripled halves — same px/sec speed */
  animation:scroll 78s linear infinite;will-change:transform}
/* no span padding: the trailing middot's own 12px gap spaces every junction,
   so the -50% wrap seam is pixel-identical to the in-phrase seams */
.tape-ticker .tt-track span{display:inline-block}
.tape-ticker .tt-track b{font-weight:400;color:var(--vib-red);padding-right:12px}
.tape-ticker:hover .tt-track{animation-play-state:paused}
/* the 80px top gap is tuned for desktop; as a fixed px value it eats a large
   share of a phone viewport and reads as "page ended". Taper it on mobile. */
@media(max-width:700px){.tape-ticker{margin-top:40px}}
@media(prefers-reduced-motion:reduce){.tape-ticker .tt-track{animation:none}}

/* marquee ticker — decorative */
.ticker{margin-top:34px;background:var(--ink);
  border-radius:12px;overflow:hidden;box-shadow:var(--shadow);transform:rotate(-.5deg)}
.ticker-track{display:flex;gap:40px;white-space:nowrap;padding:11px 0;
  font-family:'Bungee','Bungee Fallback',sans-serif;font-size:15px;color:var(--yellow);
  animation:scroll 30s linear infinite;will-change:transform}
.ticker-track span{display:inline-flex;gap:40px}
/* ticker stars spread the logo fan, weighted toward BLUE — every other ★ is blue */
.ticker-track i,.ticker-track em{font-style:normal}
.ticker-track i{color:var(--blue-bright)}
.ticker-track em{color:var(--blue-bright)}
.ticker-track i:nth-of-type(2n){color:var(--vib-green)}
.ticker-track em:nth-of-type(2n){color:var(--magenta-bright)}
.ticker-track em:nth-of-type(4n){color:var(--vib-red)}
@keyframes scroll{from{transform:translateX(0)}to{transform:translateX(-50%)}}
/* reduced-motion: stop the marquee (was the only infinite animation with no RM gate) */
@media(prefers-reduced-motion:reduce){.ticker-track{animation:none}}

/* ============================================ REAL-SHOP PHOTO STICKERS
   Photos framed like die-cut stickers: thick white die-cut border + black
   keyline + hard drop shadow. TIDIED for UX: captions are a LABEL BAR pinned
   to the frame's inner bottom (never floating over photo content), tape/badge
   decorations are kept INSIDE the frame's footprint so nothing clips the
   headline or neighbours. Tilt is contained (<=2deg). */
.photo-sticker{
  position:relative;display:block;background:#fff;
  /* thin double border: slim white die-cut band + a fine ink outer line,
     matching the product cards' hairline feel */
  border:3px solid #fff;outline:1px solid var(--ink);
  border-radius:14px;box-shadow:0 8px 18px rgba(20,17,12,.16);overflow:hidden;
  width:100%;height:100%;
}
.photo-sticker img{width:100%;height:100%;object-fit:cover;display:block}
/* a small brand tab dot leads the label{content:"";flex:0 0 auto;width:11px;height:11px;border-radius:50%;
  background:var(--orange);border:2px solid #fff;box-shadow:0 1px 2px rgba(0,0,0,.5)}

/* masking-tape strip — kept WITHIN the frame top so it never overhangs into
   the headline or a neighbouring tile. Brand-tinted translucent tape. */
.tape{
  position:absolute;z-index:5;width:84px;height:22px;top:8px;
  background:rgba(224,165,38,.78);border:1px dashed rgba(20,17,12,.4);
  box-shadow:0 2px 5px rgba(0,0,0,.22);pointer-events:none;border-radius:2px;
}
.tape.tl{left:14px;transform:rotate(-5deg)}
.tape.tr{right:14px;transform:rotate(5deg);background:rgba(58,107,176,.7)}
.tape.bl{top:auto;bottom:8px;left:18px;transform:rotate(4deg);background:rgba(87,163,71,.62)}
.tape.green{background:rgba(87,163,71,.62)}
.tape.red{background:rgba(206,59,43,.58)}

/* ---- HERO greeter photo (the waving Pikachu, framed beside the headline) ---- */
.hero-photo{
  position:relative;align-self:center;justify-self:center;
  width:100%;max-width:none;
  padding-top:18px; /* room for the SAY HEY! badge above the frame */
  transform:rotate(-1.6deg);
}
/* native ratio = the whole landscape shot, no cropping (it's a wide 16:9-ish frame) */
.hero-photo .photo-sticker{aspect-ratio:3762/2512}
.hero-photo .photo-sticker img{object-position:center}
/* NOTE: an old desktop-only rule enlarged .hero-photo 1.25x here. The anime
   entrance always overrode it back to scale(1) — the approved look — so its
   only visible effect was a split-second giant flash on first paint before
   the animation kicked in. Removed 2026-07-11 (PR #95). */
/* Google reviews as a little TRADING-CARD, sitting in the open LEFT space of the
   wide greeter photo (the Pikachu stands on the right). On-theme for a TCG shop.
   Lives on .hero-photo so it layers over the photo. */
/* Google reviews as a HOLO TRADING-CARD, clickable, sitting in the open LEFT
   space of the wide greeter photo (the Pikachu stands on the right). The whole
   card is an <a> to the Google reviews page. Foil sheen via gradients + a
   sweeping .rc-shine highlight. */
.hero-photo .rev-card{
  position:absolute;left:34px;top:50%;transform:translateY(-50%) rotate(-5deg);z-index:8;
  display:block;width:clamp(150px,15vw,210px);text-decoration:none;
  color:var(--ink,#14110C);text-align:center;line-height:1;cursor:pointer;
  background:
    linear-gradient(135deg,rgba(255,255,255,.55),rgba(255,255,255,0) 38%),
    linear-gradient(150deg,rgba(110,63,163,.16),rgba(58,107,176,.16) 30%,rgba(224,165,38,.18) 58%,rgba(206,59,43,.14) 80%,rgba(87,163,71,.16)),
    var(--cream,#FBF5E9);
  border:6px solid #fff;outline:3px solid var(--ink,#14110C);border-radius:16px;
  box-shadow:var(--shadow);overflow:hidden;
  transition:transform .16s, box-shadow .16s, filter .16s;
}
.hero-photo .rev-card:hover,
.hero-photo .rev-card:focus-visible{
  transform:translateY(-50%) rotate(-5deg) scale(1.05);
  box-shadow:7px 9px 0 var(--ink,#14110C);filter:saturate(1.08);outline-offset:0;
}
.hero-photo .rev-card:focus-visible{outline:3px solid var(--brand-blue,#3A6BB0)}
.hero-photo .rev-card:active{transform:translateY(-50%) rotate(-5deg) scale(.99)}
/* the sweeping foil highlight */
.hero-photo .rev-card .rc-shine{
  position:absolute;top:-60%;left:-40%;width:55%;height:220%;z-index:1;pointer-events:none;
  background:linear-gradient(115deg,rgba(255,255,255,0),rgba(255,255,255,.7) 50%,rgba(255,255,255,0));
  transform:rotate(8deg);animation:revFoil 5.5s ease-in-out infinite;will-change:transform;
}
/* sweep with transform (compositor) instead of animating `left` (layout+paint every
   frame, forever, above the fold). translateX 290% of the 55%-wide element ≈ the old
   -40%→120% `left` travel; rotate(8deg) is folded in so the keyframe doesn't drop it. */
@keyframes revFoil{0%,100%{transform:translateX(0) rotate(8deg)}50%{transform:translateX(290%) rotate(8deg)}}
.hero-photo .rev-card > *{position:relative;z-index:2}
.hero-photo .rev-card .rc-top{display:block;background:var(--brand-purple,#6E3FA3);color:#fff;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:13px;letter-spacing:1.5px;padding:7px 0;text-shadow:1px 1px 0 rgba(0,0,0,.35)}
.hero-photo .rev-card .rc-score{display:block;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:clamp(46px,5.5vw,58px);line-height:1;margin-top:11px;color:var(--ink,#14110C);text-shadow:2px 2px 0 rgba(224,165,38,.55)}
.hero-photo .rev-card .rev-stars{display:block;color:var(--brand-gold,#E0A526);font-size:20px;letter-spacing:3px;margin-top:6px;text-shadow:0 1px 1px rgba(0,0,0,.25)}
.hero-photo .rev-card .rc-sub{display:block;font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:800;font-size:11.5px;color:var(--brand-blue,#3A6BB0);padding:8px 0 0;text-transform:uppercase;letter-spacing:.6px}
.hero-photo .rev-card .rc-cta{display:block;margin:11px 10px 12px;background:var(--brand-blue,#3A6BB0);color:#fff;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:10.5px;letter-spacing:.4px;padding:8px 6px;border-radius:9px;border:2px solid var(--ink,#14110C);box-shadow:2px 2px 0 var(--ink,#14110C)}
.hero-photo .rev-card:hover .rc-cta,
.hero-photo .rev-card:focus-visible .rc-cta{background:var(--brand-gold,#E0A526);color:var(--ink,#14110C)}
@media(prefers-reduced-motion:reduce){.hero-photo .rev-card .rc-shine{animation:none;opacity:.25}}
/* review-card mobile sizing — MUST come after the base .rev-card rules above:
   same specificity, so source order is what lets these win on small screens.
   (They used to sit before the base block, which left them dead and let the
   base top:50% pair with bottom:10px into an over-constrained box that
   clipped the stars.) */
@media(max-width:700px){
  .hero-photo .rev-card{left:12px;width:clamp(136px,38vw,170px)}
  .hero-photo .rev-card .rc-score{font-size:46px}
  .hero-photo .rev-card .rev-stars{font-size:17px;letter-spacing:2px}
}
@media(max-width:480px){
  /* tuck the card to the BOTTOM-LEFT so it never covers Pikachu (who stands right) */
  .hero-photo .rev-card{
    top:auto;bottom:10px;left:8px;transform:rotate(-5deg);width:132px;border-width:5px;
  }
  .hero-photo .rev-card:hover,
  .hero-photo .rev-card:focus-visible{transform:rotate(-5deg) scale(1.04)}
  .hero-photo .rev-card:active{transform:rotate(-5deg) scale(.99)}
  .hero-photo .rev-card .rc-score{font-size:40px;margin-top:9px}
  .hero-photo .rev-card .rc-top{font-size:12px;padding:6px 0}
  .hero-photo .rev-card .rev-stars{font-size:15px}
  .hero-photo .rev-card .rc-sub{font-size:10.5px;padding-top:6px}
  .hero-photo .rev-card .rc-cta{font-size:9.5px;margin:9px 8px 10px;padding:7px 5px}
}
/* suppress the folded-corner on the hero so it never collides with the badge */
.hero-photo .photo-sticker.peel::after{display:none}
/* badge pinned to the frame's TOP CENTER, poking just above and overlapping the
   top edge of the Pikachu photo (the .hero-photo padding-top reserves the room). */
.hero-photo .greeter-badge{
  position:absolute;top:-10px;left:50%;z-index:9;
  font-family:'Bungee','Bungee Fallback',sans-serif;font-size:12px;color:var(--ink);background:var(--orange);
  width:70px;height:70px;border-radius:50%;display:grid;place-items:center;text-align:center;line-height:1;
  border:3px solid var(--ink);box-shadow:3px 3px 0 rgba(0,0,0,.5);transform:translateX(-50%) rotate(-4deg);padding:6px;
}
/* hero now holds copy + photo + a small stat strip */
.hero-side{display:flex;flex-direction:column;gap:20px;align-items:center}

/* ---- STEP INSIDE: a CLEAN, ALIGNED grid of real shop photos.
   6-column track. One full-width "banner" anchor tile (16:6) on top, then two
   tidy rows of three uniform 4:3 tiles. Everything aligns to the same columns
   and baselines — no overlap, no dense auto-flow, no clipping. Tiny alternating
   tilt keeps the hand-slapped sticker personality without breaking the grid. */
#shop{padding-bottom:30px}
/* the banner anchor: full width{grid-column:1 / -1}
/* barely-there alternating tilt — contained{transform:rotate(-1deg)}
@media(max-width:900px){
  /* 2 across; banner stays full width{gap:16px}
}

/* ============================================================== SECTIONS */
section{position:relative;padding:38px 0;z-index:1}
.sec-head{display:flex;align-items:flex-end;gap:16px;flex-wrap:wrap;margin-bottom:26px}
/* the heading's default h2 margins made flex-end alignment lie: the SEE ALL
   button hugged the line's true bottom while the title floated 38px above it
   (walkthrough finding 7 — the button read as orphaned on its own row) */
.sec-head .sec-title{margin:0}
.sec-title{
  font-family:'Bungee','Bungee Fallback',sans-serif;font-size:clamp(26px,4.6vw,42px);line-height:1;color:var(--ink);
  background:var(--paper);padding:11px 17px;border-radius:12px;
  border:var(--keyline) solid var(--ink);box-shadow:5px 5px 0 var(--title-shadow);
}
/* section-title hard shadow pops cycle the logo fan to match each scrawl */
.sec-title.t-blue{box-shadow:5px 5px 0 var(--blue)}
.sec-title.t-green{box-shadow:5px 5px 0 var(--vib-green)}
.sec-title.t-red{box-shadow:5px 5px 0 var(--vib-red)}
.sec-title.t-gold{box-shadow:5px 5px 0 var(--orange)}
/* scrawl pops cycle the logo fan across sections (on light parchment, so use
   the deeper{color:var(--purple)}
/* secondary "SHOP ALL →" — plain card-blue text link (deliberately quieter than
   the hero's two button CTAs so it doesn't compete with them) */
.see-all{margin-left:auto;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:13px;color:var(--blue);
  min-height:44px;display:inline-flex;align-items:center;gap:8px;transition:color .18s}
.see-all .ar{font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:800;font-size:16px;line-height:1;
  transition:transform .18s}
.see-all:hover,.see-all:focus-visible{color:var(--blue-lively)}
.see-all:hover .ar,.see-all:focus-visible .ar{transform:translateX(3px)}
@media (prefers-reduced-motion:reduce){.see-all .ar{transition:none}.see-all:hover .ar{transform:none}}

/* ---------------------------------------------------- CATEGORY STICKERS */
.cat-wall{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:18px}
/* mobile: 2-up category grid — matches the product wall's density. minmax(190px)
   auto-fill collapses to a SINGLE full-width column below ~470px (10 tiles = a
   ~4,500px scroll before the shop), so force two columns to halve the scroll and
   read as a proper category grid rather than a tall stack of banners. */
@media(max-width:560px){
  .cat-wall{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
  .cat-chip .cat-foot{padding:11px 14px;min-height:46px}
  .cat-chip .cn{font-size:13px}
}
/* "COMIC POP, CLEAN" tile — ink footer + ben-day halftone mark, name only.
   The card body reads black behind the footer; the mark carries all the color. */
.cat-chip{
  display:flex;flex-direction:column;overflow:hidden;position:relative;color:#fff;
  border-radius:14px;background:var(--ink);
  border:1px solid var(--ink);
  box-shadow:0 8px 18px rgba(20,17,12,.16);transition:transform .18s, box-shadow .18s;
}
/* mark = a light panel holding the brand logo (images/logos/<key>.png) or a
   fallback symbol icon — present on EVERY tile so all tiles are the same size.
   Halftone dots sit at the edges and fade out of the center (first radial gradient
   punches a clean hole) so the logo always lands on a clear surface. */
.cat-chip .cat-mark{display:flex;align-items:center;justify-content:center;position:relative;aspect-ratio:16/9;padding:16px;
  color:var(--ink);border-bottom:0.5px solid var(--ink);
  background:
    radial-gradient(circle at 50% 46%, var(--photo-bg) 24%, rgba(252,251,246,0) 66%),
    radial-gradient(circle, rgba(224,165,38,.5) 1.5px, transparent 1.7px) 0 0/12px 12px,
    var(--photo-bg)}
.cat-chip .cat-logo{position:absolute;top:16px;left:16px;width:calc(100% - 32px);height:calc(100% - 32px);object-fit:contain;object-position:center;display:block}
.cat-chip .cat-mark-icon svg{width:42px;height:42px}
/* footer: category name only. an arrow reserves its slot but stays invisible
   until hover/focus, so at rest every tile is dead clean with zero layout shift. */
.cat-chip .cat-foot{display:flex;align-items:center;justify-content:center;gap:8px;position:relative;flex:1;
  background:var(--primary);padding:13px 30px;min-height:52px}
.cat-chip .cn{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:15px;line-height:1.12;text-align:center;
  display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.cat-chip .cat-foot::after{content:'→';font-family:'Bungee','Bungee Fallback',sans-serif;font-size:15px;position:absolute;right:14px;top:50%;
  opacity:0;transform:translateY(-50%) translateX(-6px);transition:opacity .18s, transform .18s}
.cat-chip:hover,.cat-chip:focus-visible{transform:translateY(-4px) scale(1.03);box-shadow:0 18px 32px rgba(20,17,12,.26)}
.cat-chip:hover .cat-foot::after,.cat-chip:focus-visible .cat-foot::after{opacity:1;transform:translateY(-50%)}

/* ----------------------------------------------------- PRODUCT STICKERS */
/* readable grid that just happens to look like slapped stickers:
   generous gap so the (straight, 0deg) cards never overlap clickable areas */
.wall{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));
  gap:26px 22px;padding:10px 6px 6px;
}
/* mobile: a denser 2-up product grid — one giant card per row wastes the screen */
@media(max-width:560px){
  .wall{grid-template-columns:repeat(2,minmax(0,1fr));gap:14px 12px;padding:8px 0 4px}
}

/* ============ related-products carousel (product page) ============ */
.rel-wrap{position:relative}
/* generous inner padding so card hover (translateY(-5px) scale(1.02) + big
   shadow) never clips against the scrollport; negative margins keep the strip
   visually aligned with the rest of the page */
.rel-scroll{
  display:flex;overflow-x:auto;scroll-snap-type:x mandatory;
  gap:22px;padding:16px 14px 34px;margin:-6px -8px -20px;
  scroll-padding-inline:14px;-webkit-overflow-scrolling:touch;
  scrollbar-width:thin;
}
.rel-scroll .card{flex:0 0 240px;scroll-snap-align:start}
.rel-arrow{
  position:absolute;top:50%;transform:translateY(-50%);z-index:2;
  width:42px;height:42px;border-radius:50%;border:3px solid var(--ink);
  background:var(--paper);color:var(--ink);font-size:22px;line-height:1;
  cursor:pointer;box-shadow:3px 3px 0 var(--ink);
}
.rel-arrow:hover:not(:disabled){background:var(--orange)}
.rel-arrow:disabled{opacity:.35;cursor:default;box-shadow:none}
.rel-prev{left:-10px}.rel-next{right:-10px}
@media(max-width:560px){
  .rel-scroll .card{flex-basis:170px}
  .rel-prev{left:-4px}.rel-next{right:-4px}
}
/* THIN frame, uniform across every card: a fine ink hairline + soft lift on a
   parchment face. No white die-cut edge, no per-card hover accent. */
.card{
  position:relative;background:var(--parchment);
  border:0.5px solid var(--ink);
  border-radius:14px;box-shadow:0 8px 18px rgba(20,17,12,.16);
  transform:none;
  transition:transform .22s cubic-bezier(.2,1.3,.4,1), box-shadow .22s;
  display:flex;flex-direction:column;
}
.card:hover{transform:translateY(-5px) scale(1.02);box-shadow:0 18px 32px rgba(20,17,12,.26);z-index:5}
.card:focus-within{z-index:6}

/* near-white photo panel + multiply blend = the white product-shot backdrop
   dissolves seamlessly (and off-white/soft-shadow photos integrate too). */
/* comic-pop backdrop: ben-day halftone dots fading out of a clean center hole,
   same language as the homepage category tiles. Multiply-blended product shots
   land on the clear center; the dots frame every image identically. */
.thumb{position:relative;display:block;border-radius:10px 10px 0 0;overflow:hidden;
  background:
    radial-gradient(circle at 50% 46%, var(--photo-bg) 24%, rgba(252,251,246,0) 66%),
    radial-gradient(circle, rgba(224,165,38,.5) 1.5px, transparent 1.7px) 0 0/12px 12px,
    var(--photo-bg);
  aspect-ratio:1/1;border-bottom:0.5px solid var(--ink)}
.thumb img{width:100%;height:100%;object-fit:contain;padding:16px;
  mix-blend-mode:multiply;transition:transform .3s}
.card:hover .thumb img{transform:scale(1.04)}

.body{padding:14px 15px 15px;display:flex;flex-direction:column;flex:1}
.pname{font-weight:800;font-size:0.95rem;line-height:1.3;min-height:2.6em;
  display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  color:var(--ink);margin:0 0 12px}
/* narrow 2-up walls clip most names at 2 lines ("…ex sv4a Pokem…") — give
   phones a third line so the wall scans without guessing */
@media(max-width:560px){.pname{-webkit-line-clamp:3;line-clamp:3;min-height:3.9em}}
.pname a{color:var(--ink)}
.pname a:hover{color:var(--blue)}
.meta-row{display:flex;align-items:center;gap:8px;margin-top:auto;margin-bottom:12px}
/* plain price: black Bungee numbers, no box or banner. */
.price-tab{
  font-family:'Bungee','Bungee Fallback',sans-serif;font-size:18px;line-height:1;color:var(--ink);
  max-width:100%;
}
/* 2-up cards are ~170px wide, so shrink the price pill (esp. "$x – $y" ranges) to fit */
@media(max-width:560px){
  /* 2-up cards are ~123px wide. Let a RANGE wrap to two short lines and size the
     pill to its content so the high end ($249.00) can never clip off the gold edge.
     Single prices stay on one line; clamp() down-scales numerals first. */
  .price-tab{
    display:inline-block;max-width:100%;
    font-size:clamp(13px,4.1vw,15px);line-height:1.05;
    white-space:normal;word-break:keep-all;
  }
  .price-tab .to{white-space:nowrap;margin:0 2px}
  .card .body{min-width:0}
  .meta-row{min-width:0;flex-wrap:wrap}
}
/* "SLAP IN CART" = PRIMARY card blue + white */
.add{
  width:100%;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:13px;color:var(--on-primary);background:var(--primary);
  padding:13px;min-height:48px;border-radius:10px;border:3px solid var(--ink);
  box-shadow:3px 3px 0 var(--ink);
  transition:transform .12s, box-shadow .12s, background .2s;
  display:flex;align-items:center;justify-content:center;gap:8px;
}
.add:hover:not(:disabled){background:var(--primary-hover);transform:translate(-1px,-1px);box-shadow:5px 5px 0 var(--ink)}
.add:active:not(:disabled){transform:translate(2px,2px);box-shadow:1px 1px 0 var(--ink)}
.add:disabled{background:#9AA0A8;color:#F4F2EE;cursor:not-allowed;transform:none;box-shadow:3px 3px 0 rgba(0,0,0,.4);border-color:#3a3a3a}
.add.added{background:var(--vib-green);color:var(--ink)}
.add svg{width:16px;height:16px}

/* --------------------------- VISIT IN PERSON → ABOUT (photo-background band)
   Full-bleed shop photo with a blue→ink scrim on the left so the white copy
   always reads. The whole band is one link to the About (location) page. */
/* ink background + 1px footer overlap: the band's height lands on a fractional
   pixel, and at some zoom/DPR levels the compositor rounds it to a cream hairline
   between band and footer — paint the slack ink-dark so no seam can ever show.
   Scoped to .visit-band (homepage only): contact.html also has a section#visit,
   which this rule must NOT touch. */
.visit-band{margin-top:10px;margin-bottom:0;padding:0;line-height:0;background:var(--ink)}
.visit-hero{display:flex;align-items:center;position:relative;overflow:hidden;
  min-height:clamp(300px,40vw,440px);
  background-image:
    linear-gradient(90deg, rgba(39,81,140,.92) 0%, rgba(39,81,140,.55) 38%, rgba(20,17,12,.22) 62%, rgba(20,17,12,.08) 100%),
    url(../images/shop/visit-store.jpg);
  background-size:cover;background-position:center 42%;
  transition:background-position .3s}
.visit-inner{display:flex;flex-direction:column;align-items:flex-start;gap:38px;width:100%;
  color:#fff;padding-top:56px;padding-bottom:56px}
.visit-h{font-family:'Ranchers','Ranchers Fallback',cursive;font-weight:400;color:#fff;margin:0;
  font-size:clamp(38px,6.2vw,72px);line-height:.94;letter-spacing:.5px;text-shadow:0 3px 22px rgba(0,0,0,.45)}
.visit-sub{font-family:'Ranchers','Ranchers Fallback',cursive;font-size:clamp(22px,3vw,34px);color:#fff;margin:0;
  text-shadow:0 2px 16px rgba(0,0,0,.4)}
.visit-cta{margin-top:6px;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:14px;line-height:1;color:#fff;background:var(--ink);
  text-decoration:none;padding:16px 26px;border-radius:10px;box-shadow:4px 4px 0 rgba(0,0,0,.35);
  display:inline-flex;align-items:center;gap:8px;transition:transform .15s, box-shadow .15s}
.visit-cta:hover,.visit-cta:focus-visible{transform:translate(-1px,-2px);box-shadow:6px 6px 0 rgba(0,0,0,.4)}
@media(max-width:560px){.visit-cta{width:100%;justify-content:center}}

/* ================================================================ FOOTER
   Dark multi-column: brand + contact (icon list) + blurb · SHOP · INFO ·
   FOLLOW US, then a payment-badge row and a copyright/links bar. */
footer{position:relative;z-index:1;margin-top:-1px;background:var(--ink);color:#CFC7B4}
.foot-grid{display:grid;grid-template-columns:1.4fr 1fr .8fr .8fr .6fr;gap:36px;padding:56px 0 30px}
@media(max-width:1000px){.foot-grid{grid-template-columns:1fr 1fr;gap:36px 26px}.foot-brand{grid-column:1/-1}}
@media(max-width:640px){.foot-grid{grid-template-columns:1fr}}
.foot-brand .wordmark{font-size:26px;color:#fff;display:inline-block;margin-bottom:14px}
.foot-about{font-size:13px;line-height:1.6;color:#A99C82;max-width:44ch;margin:0}
.foot-col h3,.foot-hours-col h3{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:12px;color:#fff;margin:0 0 14px;letter-spacing:.5px}
/* plain contact rows — only the value (address/phone/email) is a link; popover adds secondary acts */
.foot-boxes{display:flex;flex-direction:column;gap:16px;margin-top:16px}
.foot-box-wrap{position:relative}
.foot-box{display:block}
.foot-box-head{display:flex;align-items:center;gap:8px;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:11.5px;letter-spacing:.5px;color:var(--orange)}
.foot-box-head svg{width:15px;height:15px;fill:var(--blue-bright)} /* card-blue glyphs, matching the pre-redesign footer (Jin) */
.foot-box-val{display:inline-block;margin-top:6px;font-size:14px;line-height:1.45;color:#D8CEB8;text-decoration:none;transition:color .15s}
.foot-box-val:hover,.foot-box-val:focus-visible{color:#fff;text-decoration:underline}
.foot-pop{position:absolute;left:0;bottom:calc(100% + 6px);display:flex;gap:6px;padding:6px;background:#FBF5E9;border:2px solid var(--ink);border-radius:10px;box-shadow:0 6px 0 rgba(20,17,12,.25);opacity:0;transform:translateY(4px);pointer-events:none;transition:opacity .16s,transform .16s;z-index:5}
.foot-box-wrap:hover .foot-pop,.foot-box-wrap:focus-within .foot-pop{opacity:1;transform:none;pointer-events:auto}
@media(hover:none){.foot-pop{display:none}} /* touch: tap the link directly, no hover UI */
.foot-pop-btn{font:600 12.5px/1 'Rubik',sans-serif;color:var(--ink);background:none;border:0;border-radius:7px;padding:7px 9px;cursor:pointer;white-space:nowrap;text-decoration:none;display:inline-flex;align-items:center}
.foot-pop-btn:hover{background:var(--gold-tint)}
@media(prefers-reduced-motion:reduce){.foot-pop{transition:none}}
/* hours table */
.foot-hours{border:1px solid #3A342A;border-radius:12px;padding:6px 16px}
.foot-hr{display:flex;justify-content:space-between;gap:18px;padding:9px 0;font-size:13.5px;color:#D8CEB8;font-variant-numeric:tabular-nums}
.foot-hr + .foot-hr{border-top:1px solid #2C2820}
.foot-col a{display:flex;align-items:center;min-height:32px;font-size:14px;line-height:1.5;color:#C9BFA8;transition:color .15s}
.foot-col a:hover{color:var(--blue-bright)}
.foot-col nav a{padding:0}
/* footer socials — bare glyphs, centered, gold on hover (no circles) */
.foot-follow{text-align:center}
.foot-social{display:flex;gap:20px;justify-content:center}
.soc{display:grid;place-items:center;color:#E6DECB;transition:color .15s,transform .15s}
.soc:hover,.soc:focus-visible{color:var(--yellow);transform:translateY(-2px)}
/* channel not live yet: dimmed placeholder, no hover lift, tooltip says so */
.soc.soc-soon{opacity:.38;cursor:default}
.soc.soc-soon:hover{color:#E6DECB;transform:none}
.soc svg{width:28px;height:28px}
.soc-i rect,.soc-i circle{fill:none;stroke:currentColor;stroke-width:2}
.soc-i .dot{fill:currentColor;stroke:none}
.soc-d path{fill:currentColor}
/* payment methods row — badges on their own transparent cards, no divider line */
.foot-pay{display:flex;align-items:center;gap:18px;flex-wrap:wrap;padding:6px 0 24px}
.foot-pay-label{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:14px;letter-spacing:.4px;color:#B4A88C;text-transform:uppercase}
.foot-pay img{height:clamp(46px,7vw,60px);width:auto;max-width:100%}
/* copyright / links bar */
.foot-legal{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
  padding:16px 0 30px;border-top:1px solid rgba(255,255,255,.1);font-size:12.5px;color:#8C8069}
.foot-legal-links a{color:#8C8069;margin-left:18px;transition:color .15s}
.foot-legal-links a:hover{color:#fff}
@media(max-width:520px){.foot-legal-links a{margin:0 18px 0 0}}
/* bottom line = the same logo-fan gradient strip as the header top */
footer::after{content:"";display:block;height:6px;
  background:linear-gradient(90deg,var(--magenta),var(--orange),var(--blue),var(--vib-green),var(--vib-red))}
/* ---- toast notification animations (the "added to cart" popup) ---- */
@keyframes toastIn{from{opacity:0;transform:translateY(24px) scale(.85)}to{opacity:1;transform:none}}
@keyframes toastOut{to{opacity:0;transform:translateY(16px) scale(.92)}}

/* =========================================== CART DRAWER (slide-in sticker) */
.scrim{position:fixed;inset:0;z-index:90;background:rgba(17,16,22,.55);
  opacity:0;visibility:hidden;transition:opacity .25s ease, visibility .25s ease}
.scrim.open{opacity:1;visibility:visible}

/* ============================================ BREADCRUMB (shared sub-pages) */
.crumb{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-weight:700;font-size:13px;
  padding:20px 0 0;color:#5A4A36}
.crumb a{color:var(--link);text-decoration:none;padding:4px 2px;min-height:32px;display:inline-flex;align-items:center}
.crumb a:hover{color:var(--accent);text-decoration:underline}
.crumb .sep{color:#7A6A52}
.crumb span[aria-current]{color:var(--ink)}

/* page title shared across sub-pages */
.page-title{
  font-family:'Bungee','Bungee Fallback',sans-serif;font-size:clamp(22px,5.2vw,52px);line-height:1.04;color:var(--ink);margin:14px 0 0;
  display:inline-block;max-width:100%;background:var(--paper);padding:12px 20px;border-radius:14px;
  border:var(--keyline) solid var(--ink);box-shadow:6px 6px 0 var(--title-shadow);
  overflow-wrap:break-word;
}
@media(max-width:560px){.page-title{padding:10px 14px;box-shadow:4px 4px 0 var(--title-shadow)}}
/* store page-title rides a card-blue hard shadow */
.page-title.t-blue{box-shadow:6px 6px 0 var(--blue)}

/* =================================================================== STORE */
.store-wrap{padding:0 0 30px}
/* pre-render space reservation: the wall is JS-built into the empty #grid, so
   without this the footer paints high and jumps a full screen when the cards
   land (Lighthouse flagged CLS 0.13). :empty stops matching once JS fills it. */
.wall:empty{min-height:100vh}
.store-head-row{margin:0 0 22px}
.store-layout{display:grid;grid-template-columns:268px 1fr;gap:30px;align-items:start}
@media(max-width:860px){.store-layout{grid-template-columns:1fr}}

/* -------------------------------------------------------------- FILTER RAIL */
/* filter rail = a stack of sticker panels. Owner's call: it scrolls WITH the
   page — no sticky pin, no internal scroll box — so the whole store is one
   scroll surface and every filter (incl. Availability at the bottom) is reached
   by simply scrolling the page. */
.filters{align-self:start;
  display:flex;flex-direction:column;gap:18px}
/* mobile: collapse the filter rail behind a "Filters" button so products are the first
   thing you see, not 20+ filter rows. The toggle lives in the head row; the open state
   is tracked on .store-wrap so both it and the rail (in .store-layout) can react. */
.filters-toggle{display:none}
@media(max-width:860px){
  .filters-toggle{
    display:inline-flex;align-items:center;gap:9px;margin-top:14px;
    font-family:'Bungee','Bungee Fallback',sans-serif;font-size:13px;letter-spacing:.3px;color:var(--ink);
    background:var(--yellow);border:var(--keyline) solid var(--ink);border-radius:11px;
    padding:0 16px;min-height:48px;box-shadow:4px 4px 0 var(--ink);cursor:pointer;
  }
  .filters-toggle .ft-count{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:11px;background:var(--primary);color:#fff;
    padding:2px 9px;border-radius:20px;min-width:24px;text-align:center}
  .filters-toggle .caret{margin-left:2px;transition:transform .2s}
  .store-wrap.filters-open .filters-toggle .caret{transform:rotate(180deg)}
  .store-wrap .filters{display:none}
  .store-wrap.filters-open .filters{display:flex;margin-bottom:10px}
}
.filter-block{
  background:var(--paper);border:var(--die) solid #fff;outline:var(--keyline) solid var(--ink);
  border-radius:14px;box-shadow:var(--shadow);padding:16px;
}
/* sidebar headers = deep card blue, underlined in blue — a recurring blue cue */
.filter-block h2{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:13px;color:var(--blue-deep);margin:0 0 12px;letter-spacing:.4px;
  padding-bottom:8px;border-bottom:3px solid var(--blue)}
.filter-list{display:flex;flex-direction:column;gap:7px}
.filter-list button{
  display:flex;align-items:center;gap:8px;width:100%;text-align:left;
  font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:700;font-size:13.5px;color:var(--ink);
  background:#fff;padding:9px 11px;min-height:42px;border:2px solid var(--ink);border-radius:9px;
  box-shadow:2px 2px 0 rgba(0,0,0,.35);transition:transform .12s,box-shadow .12s,background .15s;
}
.filter-list button:hover{background:var(--yellow);transform:translate(-1px,-1px);box-shadow:3px 3px 0 rgba(0,0,0,.4)}
.filter-list button.active{background:var(--sel);color:var(--on-sel);border-color:var(--ink)}
.filter-list button.active .fcount{background:rgba(255,255,255,.25);color:#fff}
.fcount{margin-left:auto;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:11px;background:var(--ink);color:#fff;
  padding:2px 8px;border-radius:20px;min-width:26px;text-align:center}

/* store main column head: result count + sort */
.store-main-head{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-bottom:14px}
.result-count{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:15px;color:var(--ink);
  background:var(--paper);padding:8px 14px;border-radius:10px;border:2px solid var(--ink);
  box-shadow:2px 2px 0 rgba(0,0,0,.4)}
/* product count number reads in deep card blue */
.result-count b{color:var(--blue-deep)}
.sort-wrap{margin-left:auto;display:flex;align-items:center;gap:8px}
.sort-wrap label{font-weight:800;font-size:12px;text-transform:uppercase;letter-spacing:.4px;color:#5A4A36}
.sort-select{
  font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:700;font-size:14px;color:var(--ink);
  background:var(--yellow);padding:10px 14px;min-height:44px;border:3px solid var(--ink);border-radius:10px;
  box-shadow:2px 2px 0 rgba(0,0,0,.5);cursor:pointer;
}

/* active filter chips */
.chips{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:18px}
.chips:empty{margin:0}
.chip{display:inline-flex;align-items:center;gap:6px;font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:800;font-size:12.5px;
  color:var(--ink);background:var(--orange);padding:6px 8px 6px 12px;border-radius:20px;
  border:2.5px solid var(--ink);box-shadow:2px 2px 0 rgba(0,0,0,.4)}
.chip button{width:24px;height:24px;border-radius:50%;background:var(--ink);color:#fff;display:grid;place-items:center}
.chip button svg{width:13px;height:13px}
.chip button:hover{background:var(--primary)}
/* pinned to the far right of the active-filter row — standard storefront
   pattern (filters left, one clear action right), and keeps it from
   drifting around as the number of active chips changes */
.chip.clear{background:var(--ink);color:#fff;padding:8px 14px;cursor:pointer;min-height:40px;margin-left:auto}
.chip.clear svg{width:13px;height:13px}
.chip.clear:hover{background:var(--primary)}

/* friendly empty state */
.empty{grid-column:1/-1;text-align:center;padding:60px 20px;
  background:var(--paper);border:var(--die) solid #fff;outline:var(--keyline) solid var(--ink);
  border-radius:16px;box-shadow:var(--shadow)}
.empty .big{font-size:54px;margin-bottom:6px}
.empty h2{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:24px;color:var(--ink);margin:0 0 8px}
.empty p{font-weight:600;color:#5A4A36;margin:0 0 22px}
.empty .btn-clear{display:inline-flex;align-items:center;gap:8px;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:14px;color:var(--on-primary);
  background:var(--primary);padding:14px 22px;min-height:48px;border-radius:12px;border:var(--keyline) solid var(--ink);
  box-shadow:4px 4px 0 var(--ink);transition:transform .14s,box-shadow .14s}
.empty .btn-clear:hover{transform:translate(-2px,-2px);box-shadow:6px 6px 0 var(--ink)}
/* out-of-stock empty state: directions + browse actions, centered and wrapping */
.empty-actions{display:flex;flex-wrap:wrap;gap:12px;justify-content:center}

/* ================================================================= PRODUCT */
.pdp-wrap{padding:0 0 30px}
.pdp{display:grid;grid-template-columns:1fr 1fr;gap:38px;align-items:start;margin-top:24px}
@media(max-width:860px){.pdp{grid-template-columns:1fr;gap:26px}}
/* product photo: ONE frame (walkthrough finding 5 — the old stage-card +
   inner mat double-framed the art down to ~55% of its container). The stage
   is now a plain positioning wrapper; .img-frame alone carries the hero
   photo-sticker recipe, and tighter padding lets the product fill it. */
.pdp-stage{position:relative}
.pdp-stage .img-frame{position:relative;background:var(--photo-bg);
  /* same thin frame recipe as the hero greeter photo (.photo-sticker):
     slim 3px white die-cut band + 1px ink hairline, no thick keyline */
  border-radius:14px;border:3px solid #fff;outline:1px solid var(--ink);overflow:hidden;aspect-ratio:1/1;
  box-shadow:0 8px 18px rgba(20,17,12,.16);
  display:grid;place-items:center;cursor:zoom-in}
/* multiply melts the white photo backdrop into the panel; the product's own
   contact shadow survives the blend and grounds it (no fake rectangle shadow). */
.pdp-stage .img-frame img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;padding:18px;
  mix-blend-mode:multiply}
/* phones: cap the photo so name + price make the first screen (finding 9).
   Cap by WIDTH, not height: max-height clamped only the height and broke
   the 1:1 square into a wide rectangle (photo read as off-centre), and 40vh
   tracked the viewport height — which on mobile grows/shrinks as the URL bar
   collapses on scroll, so the frame visibly resized ("glitchy enlarge").
   A horizontal cap keeps the frame square, centred, and rock-steady while
   scrolling. */
@media(max-width:560px){.pdp-stage .img-frame{max-width:min(74vw,320px);margin-inline:auto}}
/* click-to-zoom lightbox: same image, full viewport, any click/Esc closes */
.pdp-zoom{position:fixed;inset:0;z-index:80;background:rgba(20,17,12,.88);
  border:0;padding:4vmin;margin:0;width:100%;height:100%;display:grid;place-items:center;cursor:zoom-out}
.pdp-zoom img{max-width:100%;max-height:100%;object-fit:contain;border-radius:10px;background:#fff}

.pdp-info{display:flex;flex-direction:column}
.pdp-title{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:clamp(26px,4vw,40px);line-height:1.04;color:var(--ink);margin:0 0 16px}
.pdp-price-row{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-bottom:16px}
.pdp-price{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:34px;color:var(--ink)}
/* names the format the big price belongs to (Pack · $7.00) so it never
   reads as a second, competing price under the picker */
.pdp-price-fmt{font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:800;font-size:14px;letter-spacing:.14em;
  text-transform:uppercase;color:#5A4A36;margin-right:10px;vertical-align:6px}
/* availability: quiet colored text, standard ecommerce treatment (no pill) */
.pdp-stock{font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:600;font-size:14px;letter-spacing:.1px}
.pdp-stock.in{color:#1E7A3C}
.pdp-stock.low{color:#9A6A00}
.pdp-stock.sold-out{color:#6B7280}
.pdp-desc{font-weight:500;font-size:1rem;line-height:1.6;color:#231C12;margin:6px 0 22px;max-width:52ch}
/* catalog-fact fallback (no owner copy in Square yet): quieter than real
   descriptions so owner-written text reads as the richer thing when it lands */
.pdp-desc--auto{color:#5A4A36;font-size:.95rem}

/* spec list */
.specs{margin-top:24px;background:var(--paper);border:var(--die) solid #fff;outline:var(--keyline) solid var(--ink);
  border-radius:14px;box-shadow:var(--shadow);padding:18px 20px}
/* spec table header = deep card blue with a blue keyline rule under it */
.specs h2{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:15px;color:var(--blue-deep);margin:0 0 12px;
  padding-bottom:10px;border-bottom:3px solid var(--blue)}
.spec-row{display:flex;justify-content:space-between;gap:14px;padding:9px 0;border-bottom:2px dashed #D8CEB8;
  font-size:0.95rem}
.spec-row:last-child{border-bottom:none}
.spec-row .k{font-weight:800;color:#5A4A36}
.spec-row .v{font-weight:700;color:var(--ink);text-align:right}

/* product 404 */
.notfound{text-align:center;padding:70px 20px;margin:24px 0;
  background:var(--paper);border:var(--die) solid #fff;outline:var(--keyline) solid var(--ink);
  border-radius:18px;box-shadow:var(--shadow)}
.notfound .big{font-size:60px;margin-bottom:8px}
.notfound h1{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:28px;color:var(--ink);margin:0 0 10px}
.notfound p{font-weight:600;color:#5A4A36;margin:0 0 24px}
/* ===== EVENTS PAGE ===== */
/* ============================================================ EVENTS PAGE
   Page-scoped .ev-* bits — the liveliest page on the site. Same sticker-bomb
   brand (Bungee / Permanent Marker / Rubik, #fff die-cut borders, ink keylines,
   hard offset shadows, slight tilts) with the energy turned up: confetti rain,
   twinkling stars — plus an anime.js trading-card DUEL in the hero and a
   single-row week CALENDAR below.

   MOTION POLICY: the duel + day-card hovers are driven by anime.js (transform &
   opacity only, paused off-screen). Cheap CSS keeps the infinite loops here
   (confetti, twinkle, ticker). Under prefers-reduced-motion OR if window.anime
   is missing, the inline script holds the duel on a clean static mid-duel
   tableau (both Actives placed & facing each other). Everything below is built
   from existing tokens in styles.css.
   ============================================================ */

/* ---- HERO: copy on the left, the duel on the right ---- */
.ev-hero{position:relative;padding:54px 0 26px;overflow:hidden}
.ev-hero-grid{position:relative;z-index:2;display:grid;grid-template-columns:1fr 1.05fr;gap:40px;align-items:center}
.ev-hero-copy{min-width:0}
.ev-hero-title{
  font-family:'Bungee','Bungee Fallback',sans-serif;line-height:.95;margin:0 0 6px;
  font-size:clamp(46px,7vw,96px);letter-spacing:-1px;
  color:var(--orange);-webkit-text-stroke:3px var(--ink);
  text-shadow:4px 4px 0 var(--gold-deep),8px 8px 0 var(--ink);
}
.ev-hero-title .l2{color:var(--magenta-bright);text-shadow:4px 4px 0 var(--magenta),8px 8px 0 var(--ink)}
.ev-hero-sub{font-size:1.0625rem;font-weight:500;line-height:1.55;max-width:46ch;margin:14px 0 24px;color:#231C12}
.ev-hero-sub b{background:var(--yellow);padding:1px 6px;border-radius:4px;font-weight:800;box-shadow:1px 1px 0 rgba(0,0,0,.4)}
.ev-hero-cta{display:flex;gap:14px;flex-wrap:wrap;align-items:center;margin-bottom:6px}
.ev-hero .ticker{margin-top:30px}

/* confetti rain — 16 absolutely-placed dots falling on staggered loops (CSS loop) */
.ev-confetti{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.ev-confetti i{position:absolute;top:-24px;width:11px;height:14px;border-radius:2px;
  opacity:.9;animation:evFall 6.5s linear infinite}
.ev-confetti i:nth-child(5n+1){background:var(--magenta)}
.ev-confetti i:nth-child(5n+2){background:var(--blue)}
.ev-confetti i:nth-child(5n+3){background:var(--orange)}
.ev-confetti i:nth-child(5n+4){background:var(--vib-green)}
.ev-confetti i:nth-child(5n+5){background:var(--vib-red)}
.ev-confetti i:nth-child(1){left:4%;animation-delay:0s;animation-duration:6s}
.ev-confetti i:nth-child(2){left:11%;animation-delay:1.4s;animation-duration:7s}
.ev-confetti i:nth-child(3){left:19%;animation-delay:.6s;animation-duration:5.6s}
.ev-confetti i:nth-child(4){left:27%;animation-delay:2.2s;animation-duration:6.8s}
.ev-confetti i:nth-child(5){left:35%;animation-delay:.2s;animation-duration:6.2s}
.ev-confetti i:nth-child(6){left:43%;animation-delay:1.8s;animation-duration:7.4s}
.ev-confetti i:nth-child(7){left:51%;animation-delay:.9s;animation-duration:5.4s}
.ev-confetti i:nth-child(8){left:59%;animation-delay:2.6s;animation-duration:6.6s}
.ev-confetti i:nth-child(9){left:66%;animation-delay:.4s;animation-duration:7.2s}
.ev-confetti i:nth-child(10){left:73%;animation-delay:1.6s;animation-duration:5.8s}
.ev-confetti i:nth-child(11){left:80%;animation-delay:.7s;animation-duration:6.4s}
.ev-confetti i:nth-child(12){left:86%;animation-delay:2.4s;animation-duration:7.6s}
.ev-confetti i:nth-child(13){left:92%;animation-delay:1.1s;animation-duration:6s}
.ev-confetti i:nth-child(14){left:96%;animation-delay:.3s;animation-duration:5.6s}
.ev-confetti i:nth-child(15){left:15%;animation-delay:3s;animation-duration:7s}
.ev-confetti i:nth-child(16){left:63%;animation-delay:3.4s;animation-duration:6.2s}
@keyframes evFall{
  0%{transform:translateY(0) rotate(0);opacity:0}
  8%{opacity:.95}
  100%{transform:translateY(118%) rotate(540deg);opacity:.9}
}
/* floating star bursts in the corners — gentle twinkle (CSS loop) */
.ev-burst{position:absolute;z-index:0;pointer-events:none;font-size:clamp(28px,5vw,54px);
  color:var(--orange);text-shadow:2px 2px 0 var(--ink);animation:evTwinkle 3.4s ease-in-out infinite}
.ev-burst.b-tl{top:12px;left:3%;color:var(--magenta-bright)}
.ev-burst.b-tr{top:24px;right:5%;color:var(--blue);animation-delay:.8s}
.ev-burst.b-bl{bottom:64px;left:7%;color:var(--vib-green);animation-delay:1.6s}
.ev-burst.b-br{bottom:80px;right:4%;color:var(--vib-red);animation-delay:.4s}
@keyframes evTwinkle{0%,100%{transform:scale(1) rotate(-6deg);opacity:.85}50%{transform:scale(1.22) rotate(6deg);opacity:1}}

/* =========================================================================
   THE DUEL — an anime.js-driven Pokémon-style TCG turn. Two opposing playmats
   (real shop art behind a dark scrim so cards stay legible) and invented
   placeholder cards (NO trademarked art/names). All motion is JS (transform &
   opacity only); the static look below is the start/fallback frame.
   ========================================================================= */
.ev-duel{position:relative;min-width:0}
.duel-stage{
  position:relative;width:100%;aspect-ratio:5/4;max-width:560px;margin:0 auto;
  border:var(--die) solid #fff;outline:var(--keyline) solid var(--ink);border-radius:18px;
  box-shadow:var(--shadow);overflow:hidden;background:var(--ink);
}
/* the two facing playmats — far behind/top (opponent), near front/bottom (you) */
.mat{position:absolute;left:0;right:0;height:54%;overflow:hidden;background-size:cover;background-position:center}
.mat::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(20,17,12,.62),rgba(20,17,12,.42))}
.mat-far{
  top:0;background-image:url("../images/shop/art-starry.jpg");
  border-bottom:3px solid rgba(255,255,255,.18);
}
.mat-near{
  bottom:0;background-image:url("../images/shop/art-wave.jpg");
}
.mat-label{position:absolute;z-index:6;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:9px;letter-spacing:1px;
  color:#fff;background:rgba(20,17,12,.6);border:1.5px solid rgba(255,255,255,.35);
  padding:3px 8px;border-radius:6px}
.mat-far .mat-label{top:8px;left:10px}
.mat-near .mat-label{bottom:8px;right:10px}

/* deck piles in the corners */
.deck{position:absolute;z-index:5;width:34px;height:48px}
.deck span{position:absolute;inset:0;background:linear-gradient(135deg,var(--magenta),var(--blue-deep));
  border:2px solid var(--ink);border-radius:5px;box-shadow:1px 1px 0 rgba(0,0,0,.5)}
.deck span:nth-child(2){transform:translate(2px,-2px)}
.deck span:nth-child(3){transform:translate(4px,-4px)}
.deck-far{top:14px;right:14px}
.deck-near{bottom:14px;left:14px}

/* battle zone — holds each side's draw card + Active, centered on its mat.
   The FAR (opponent) zone is rotated 180° so its cards point DOWN toward the
   near player: a real tabletop face-off, not both facing up. */
.zone{position:absolute;left:50%;width:84px;height:116px;margin-left:-42px;z-index:4}
.zone-near{bottom:7%}
.zone-far{top:7%;transform:rotate(180deg);transform-origin:center}

/* ---- placeholder card: rounded rect, thick type-colored border ---- */
.tcard{
  position:absolute;inset:0;width:84px;height:116px;background:var(--cream,#FBF5E9);
  border:4px solid var(--ink);border-radius:9px;
  box-shadow:2px 3px 0 rgba(0,0,0,.5);will-change:transform,opacity;
  display:flex;flex-direction:column;padding:4px;gap:3px;overflow:hidden;
}
.c-top{display:flex;align-items:center;justify-content:space-between;gap:3px}
.c-name{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:7px;letter-spacing:.2px;color:var(--ink);line-height:1}
.c-hp{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:7px;color:var(--vib-red-deep);line-height:1;white-space:nowrap}
.c-art{display:block;flex:1;border-radius:5px;border:2px solid var(--ink);overflow:hidden}
.c-atk{display:flex;align-items:center;gap:4px}
.c-dmg{margin-left:auto;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:10px;color:var(--ink)}
.energy{width:9px;height:9px;border-radius:50%;border:2px solid var(--ink);box-shadow:inset 0 0 0 1px rgba(255,255,255,.5)}
/* type color systems (border + art + energy dots) */
.t-grass{border-color:var(--vib-green-deep)} .a-grass{background:radial-gradient(circle at 35% 30%,#A6E07A,var(--vib-green-deep))} .e-grass{background:var(--vib-green)}
.t-fire{border-color:var(--vib-red)} .a-fire{background:radial-gradient(circle at 35% 30%,var(--orange-bright),var(--vib-red-deep))} .e-fire{background:var(--vib-red)}
.t-water{border-color:var(--blue)} .a-water{background:radial-gradient(circle at 35% 30%,var(--blue-bright),var(--blue-deep))} .e-water{background:var(--blue-bright)}
.t-lightning{border-color:var(--gold-deep)} .a-lightning{background:radial-gradient(circle at 35% 30%,#FFE08A,var(--gold-deep))} .e-lightning{background:var(--orange-bright)}
.t-psychic{border-color:var(--magenta)} .a-psychic{background:radial-gradient(circle at 35% 30%,var(--vib-amethyst),var(--brand-purple-deep,#4A2A73))} .e-psychic{background:var(--vib-amethyst)}

/* the draw card sits hidden behind the Active until the timeline slides it in;
   the Active starts hidden too (anime.set + the static fallback reveal it). */
.draw-near,.draw-far{z-index:7;opacity:0}
.active-near,.active-far{z-index:6;opacity:0}

/* the energy token that snaps onto the attacking Active */
.energy-token{position:absolute;z-index:9;top:-6px;left:-6px;width:18px;height:18px;border-radius:50%;
  background:radial-gradient(circle at 35% 30%,var(--orange-bright),var(--gold-deep));
  border:2.5px solid var(--ink);box-shadow:1px 1px 0 rgba(0,0,0,.5);opacity:0;will-change:transform,opacity}

/* the impact flash — repositioned onto whoever's hit by the timeline */
.hit-flash{position:absolute;z-index:8;top:26%;left:50%;width:120px;height:120px;margin:-60px 0 0 -60px;
  border-radius:50%;pointer-events:none;opacity:0;will-change:transform,opacity;
  background:radial-gradient(circle,rgba(255,255,255,.95),rgba(242,185,64,.6) 40%,rgba(206,59,43,0) 70%)}

/* rising damage number over the defender (one per side; lives inside the zone) */
.dmg-pop{position:absolute;z-index:10;top:2px;left:50%;
  font-family:'Bungee','Bungee Fallback',sans-serif;font-size:17px;color:#fff;white-space:nowrap;
  text-shadow:0 0 6px var(--vib-red),2px 2px 0 var(--ink);opacity:0;will-change:transform,opacity}

/* PRIZE cards — flip face-up after a KO (anime rotateY) */
.prize{position:absolute;z-index:5;width:30px;height:42px;perspective:300px}
.prize-far{top:14px;left:14px}
.prize-near{bottom:14px;right:14px}
.prize span{position:absolute;inset:0;border:2px solid var(--ink);border-radius:5px;backface-visibility:hidden;
  display:grid;place-items:center;box-shadow:1px 1px 0 rgba(0,0,0,.5);will-change:transform}
.prize-back{background:linear-gradient(135deg,var(--magenta),var(--blue-deep))}
.prize-face{background:var(--orange);color:var(--ink);font-family:'Bungee','Bungee Fallback',sans-serif;font-size:16px;transform:rotateY(-180deg)}

/* editor's note above the schedule */
.ev-note{font-weight:600;font-size:1rem;line-height:1.6;color:#3A2E1C;max-width:66ch;margin:0 0 22px}
.ev-note b{background:var(--yellow);padding:1px 6px;border-radius:4px;font-weight:800;box-shadow:1px 1px 0 rgba(0,0,0,.35)}

/* ---- WEEK SCHEDULE: a single horizontal row of 7 compact day columns ----
   Desktop intent is ONE clean row (repeat(7,1fr)); narrow screens scroll. */
.ev-week{display:grid;grid-template-columns:repeat(7,1fr);gap:12px;align-items:stretch}
.ev-day{
  position:relative;display:flex;flex-direction:column;align-items:center;text-align:center;
  background:var(--paper);border:5px solid #fff;outline:var(--keyline) solid var(--ink);
  border-radius:14px;box-shadow:var(--shadow);padding:16px 12px 16px;min-width:0;
  will-change:transform;
}
/* WED & FRI are the marquee nights — keep them visually highlighted */
.ev-day-star{background:#FFFBEF;outline-color:var(--vib-red)}
.ev-flag{position:absolute;top:-11px;left:50%;transform:translateX(-50%);z-index:3;
  font-family:'Bungee','Bungee Fallback',sans-serif;font-size:8px;letter-spacing:.6px;color:#fff;background:var(--vib-red);
  padding:3px 8px;border-radius:20px;border:2px solid var(--ink);box-shadow:2px 2px 0 rgba(0,0,0,.45);white-space:nowrap}
.ev-day-star .ev-badge{box-shadow:3px 3px 0 var(--ink)}
/* big day badge — a slapped circular sticker */
.ev-badge{display:inline-flex;flex-direction:column;align-items:center;justify-content:center;
  width:62px;height:62px;border-radius:50%;color:#fff;line-height:1;text-align:center;
  border:3px solid var(--ink);box-shadow:3px 3px 0 var(--ink);margin:6px 0 12px;
  transform:rotate(-5deg);will-change:transform}
.ev-badge b{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:15px;letter-spacing:.5px}
.ev-badge i{font-family:'Rubik','Rubik Fallback',sans-serif;font-style:normal;font-weight:800;font-size:8.5px;
  text-transform:uppercase;letter-spacing:.5px;opacity:.92;margin-top:2px}
.ev-badge.bd-purple{background:var(--magenta)}
.ev-badge.bd-blue{background:var(--blue)}
.ev-badge.bd-green{background:var(--vib-green-deep)}
.ev-badge.bd-red{background:var(--vib-red)}
.ev-badge.bd-gold{background:var(--orange);color:var(--ink);box-shadow:3px 3px 0 var(--ink)}
.ev-badge.bd-amethyst{background:#4A2A73}
.ev-name{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:13px;line-height:1.15;color:var(--ink);margin:0 0 7px;min-height:2.3em;display:flex;align-items:center}
.ev-blurb{font-weight:500;font-size:0.8rem;line-height:1.45;color:#3A2E1C;margin:0 0 12px;flex:1}
.ev-time{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:10px;letter-spacing:.2px;color:var(--ink);
  background:var(--yellow);padding:5px 10px;border-radius:20px;border:2.5px solid var(--ink);
  box-shadow:2px 2px 0 rgba(0,0,0,.45);white-space:nowrap}

/* ---- COME THROUGH: closing CTA card ---- */
.ev-come{position:relative;overflow:hidden;text-align:center;
  background:var(--ink);color:#F3ECDD;border:var(--die) solid #fff;outline:var(--keyline) solid var(--ink);
  border-radius:20px;box-shadow:var(--shadow);padding:42px 28px 38px}
.ev-come-star{position:absolute;z-index:0;font-size:clamp(60px,12vw,140px);opacity:.16;color:var(--orange);pointer-events:none}
.ev-come-star.s1{top:-10px;left:14px;transform:rotate(-12deg)}
.ev-come-star.s2{bottom:-18px;right:18px;color:var(--blue-bright);transform:rotate(10deg)}
.ev-come-title{position:relative;z-index:1;font-family:'Bungee','Bungee Fallback',sans-serif;line-height:.96;margin:0 0 10px;
  font-size:clamp(34px,6vw,66px);color:var(--yellow);-webkit-text-stroke:2px var(--ink);
  text-shadow:3px 3px 0 var(--magenta-bright),6px 6px 0 rgba(0,0,0,.5)}
.ev-come-sub{position:relative;z-index:1;font-weight:600;font-size:1.0625rem;line-height:1.55;
  max-width:54ch;margin:0 auto 26px;color:#F3ECDD}
.ev-come-facts{position:relative;z-index:1;display:grid;grid-template-columns:repeat(3,1fr);gap:18px;
  margin:0 auto 28px;max-width:920px;text-align:left}
.ev-fact{background:rgba(255,255,255,.06);border:2px solid rgba(255,255,255,.16);border-radius:14px;padding:16px 18px}
.ev-fk{display:block;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:12px;letter-spacing:.4px;color:var(--yellow);margin-bottom:8px}
.ev-fv{display:block;font-weight:600;font-size:0.95rem;line-height:1.5;color:#EDE4D2}
.ev-fv a{color:#fff;font-weight:800;border-bottom:2px solid rgba(255,255,255,.7)}
.ev-fv a:hover{border-color:#fff}
.ev-come-cta{position:relative;z-index:1;display:flex;gap:14px;flex-wrap:wrap;justify-content:center}

/* ---- responsive: stack the hero; let the 7-day calendar scroll on narrow ---- */
@media(max-width:900px){
  .ev-hero-grid{grid-template-columns:1fr;gap:26px}
  .duel-stage{max-width:460px}
  /* keep the single-row calendar intent: shrink, then allow horizontal scroll */
  /* overflow-x:auto makes overflow-y compute to auto and clips all edges, so reserve
     top room for the .ev-flag (top:-11px) and pull the box back up by the same amount
     so the calendar's position is unchanged; bigger padding-bottom clears the shadow. */
  .ev-week{grid-auto-flow:column;grid-auto-columns:minmax(132px,1fr);grid-template-columns:none;
    overflow-x:auto;-webkit-overflow-scrolling:touch;
    padding-top:18px;margin-top:-18px;padding-bottom:14px;
    scroll-snap-type:x mandatory}
  .ev-day{scroll-snap-align:start}
}
@media(max-width:760px){
  .ev-come-facts{grid-template-columns:1fr;text-align:center}
}
@media(max-width:560px){
  .duel-stage{max-width:340px}
  .tcard,.zone{width:74px}
  .zone{margin-left:-37px}
  .tcard{height:102px}
}

/* ---- REDUCED MOTION: kill confetti, twinkle; the inline script holds the duel
   on a static mid-duel tableau (both Actives placed & facing each other). ---- */
@media(prefers-reduced-motion:reduce){
  .ev-confetti{display:none}
  .ev-burst{animation:none!important}
  .ev-badge{transform:rotate(-5deg)!important}
  /* hold the duel on a clean, readable frame (JS also enforces this) */
  .draw-near,.draw-far,.hit-flash,.dmg-pop{opacity:0!important}
  .active-near,.active-far,.energy-token{opacity:1!important;transform:none!important}
  .prize-near .prize-back,.prize-far .prize-back{transform:rotateY(0)!important}
  .prize-near .prize-face,.prize-far .prize-face{transform:rotateY(-180deg)!important}
}

/* Global image auto-fit safety net lives in the base rule near the top of this
   file: `img{display:block;max-width:100%}` — that already prevents any <img>
   from overflowing its container on every page, without touching the fixed-ratio
   object-fit frames (.thumb img, .pdp-stage .img-frame img, .photo-sticker img). */

/* ============================================================ ABOUT v2 (.ab-)
   Redesigned about.html — editorial, gradient-rich, on the dark Starry-Night
   backdrop that body:has(.ab-page) already paints. All NEW class names are
   prefixed .ab- so nothing collides with the legacy .about-* rules.
   Reuses shared: .wrap .skip + .reveal.
   Gradients echo the logo card-fan: purple → blue → gold → red.
   GPU-cheap: hover/entrance touch transform & opacity only.
   ============================================================ */

/* brand-fan gradient reused in several places */
:root{
  --ab-fan:linear-gradient(100deg,var(--magenta-bright) 0%,var(--blue-bright) 34%,var(--orange-bright) 64%,var(--vib-red) 100%);
  /* mockup card-fan rainbow: violet → periwinkle → gold → red (stat-card caps) */
  --ab-rainbow:linear-gradient(90deg,#8A63D2 0%,#5D87D0 32%,#F1B740 67%,#D1472D 100%);
  --ab-card:#10141F;                 /* opaque card/panel surface */
  --ab-card-stroke:#44433E;
}

/* ---------------------------------------------------------------- HERO */
.ab-hero{padding:0 0 12px}
.ab-hero-grid{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:42px;align-items:stretch}
.ab-hero-grid > *{min-width:0}   /* side column can't push the hero (and its text) past the screen */
@media(max-width:880px){.ab-hero-grid{grid-template-columns:1fr;gap:30px}}
.ab-hero-copy{padding:44px 0 46px}
.ab-hero-side{display:flex;flex-direction:column;padding:44px 0 46px;max-width:540px;width:100%;justify-self:end}
.ab-cta{
  display:inline-block;margin-top:16px;
  font-family:'Bungee','Bungee Fallback',sans-serif;font-size:12px;letter-spacing:.4px;color:#fff;
  background:var(--brand-blue,#3A6BB0);border:1px solid #14110C;border-radius:10px;
  padding:10px 18px;box-shadow:0 6px 16px rgba(0,0,0,.4);
  transition:transform .14s,box-shadow .14s;
}
.ab-cta:hover,.ab-cta:focus-visible{transform:translateY(-2px);box-shadow:0 10px 22px rgba(0,0,0,.5)}
.ab-title{
  font-family:'Bungee','Bungee Fallback',sans-serif;font-size:clamp(40px,5.7vw,64px);line-height:.94;margin:0;
  color:#fff;letter-spacing:-1px;
  text-shadow:3px 3px 0 rgba(0,0,0,.55), 0 6px 26px rgba(0,0,0,.5);
}

/* ------------------------------------------------- HERO STAT CARDS
   Two review cards + the wide 7-days card, each capped with the brand
   rainbow. */
.ab-stats{
  list-style:none;display:grid;grid-template-columns:1fr 1fr;gap:16px;
  margin:0;padding:0;
}
.ab-stat{
  position:relative;overflow:hidden;text-align:center;
  border:1px solid var(--ab-card-stroke);border-radius:16px;
  background:rgba(13,17,26,.78);padding:17px 10px 13px;
}
.ab-stat::before{content:"";position:absolute;top:0;left:0;right:0;height:7px;background:var(--ab-rainbow)}
.ab-stat-n{
  display:block;font-family:'Bungee','Bungee Fallback',sans-serif;font-weight:400;
  font-size:clamp(27px,3vw,34px);line-height:1;color:#fff;
}
.ab-stat-star{color:#E0A526;font-size:.68em;vertical-align:.12em;margin-left:2px}
.ab-stat-plus{color:#5183BC;margin-left:1px}
.ab-stat-l{
  display:block;margin-top:8px;font-weight:800;font-size:12px;letter-spacing:1.3px;
  text-transform:uppercase;color:#C9BFA7;
}
.ab-week{
  position:relative;overflow:hidden;text-align:center;margin:12px 0 0;
  border-radius:16px;background:var(--ab-card);border:1px solid rgba(68,67,62,.6);
  padding:24px 18px 20px;
  /* stretch to the copy column's height so both hero columns end together */
  flex:1;display:flex;flex-direction:column;justify-content:center;
}
.ab-week::before{content:"";position:absolute;top:0;left:0;right:0;height:12px;background:var(--ab-rainbow)}
.ab-week-line{
  display:block;font-family:'Bungee','Bungee Fallback',sans-serif;
  font-size:clamp(19px,2.2vw,24px);line-height:1;color:#B79AD6;
}
.ab-week-line b{font-weight:400;color:#fff;font-size:1.5em;vertical-align:-.08em;margin-right:6px}
.ab-week-sub{
  display:block;margin-top:11px;font-weight:800;font-size:12.5px;letter-spacing:1.6px;
  text-transform:uppercase;color:#C9BFA7;
}
/* gradient headline text — the logo fan, on the dark sky */
.ab-grad{
  background:linear-gradient(96deg,var(--brand-purple-tint,#B79AD6) 0%,var(--blue-bright) 30%,var(--gold-tint,#F2D38A) 62%,#F2998C 100%);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;
  text-shadow:none;filter:drop-shadow(2px 3px 0 rgba(0,0,0,.5));
}
.ab-lede{
  font-size:1.09rem;font-weight:500;line-height:1.6;max-width:46ch;margin:20px 0 26px;
  color:#F3ECDD;text-shadow:0 2px 10px rgba(0,0,0,.6);
}
/* about page runs the mockup's tighter editorial scale (contact keeps its own) */
[data-about] .ab-lede{font-size:15.5px;line-height:1.5;max-width:430px;margin:18px 0 0}
[data-about] .ab-h2{font-size:clamp(24px,2.9vw,33px)}
/* --------------------------------------------------- POLAROID PHOTOS
   Thick white frame, slight tilt, handwritten tag pill. The CSS :hover
   fallback reads --ab-tilt; the anime hover/reveal in app.js mirrors the
   same values as literals (-1.6 / 1.3) — keep them in sync. */
.ab-polaroid{
  position:relative;margin:0;border-radius:18px;overflow:hidden;
  border:9px solid #fff;background:#fff;
  box-shadow:0 22px 52px rgba(0,0,0,.55);
}
.ab-polaroid img{width:100%;height:auto;display:block;border-radius:9px}
.ab-polaroid{--ab-tilt:0deg;transform:rotate(var(--ab-tilt));transition:transform .18s ease,box-shadow .18s ease}
.ab-tilt-l{--ab-tilt:-1.6deg}
.ab-tilt-r{--ab-tilt:1.3deg}
/* CSS fallback pop (reduced-motion / no-anime); anime owns it under .js-anime-hover */
@media(hover:hover){
  .ab-polaroid:hover{transform:translateY(-5px) rotate(var(--ab-tilt))}
}
.js-anime-hover .ab-polaroid{transition:box-shadow .18s}
.js-anime-hover .ab-polaroid:hover{transform:rotate(var(--ab-tilt))}
.js-anime-hover .ab-polaroid.is-hot{box-shadow:0 30px 60px rgba(0,0,0,.6)}
@media(prefers-reduced-motion:reduce){
  .ab-polaroid,.ab-polaroid:hover{transform:rotate(var(--ab-tilt))!important}
}
.ab-pol-tag{
  position:absolute;left:12px;bottom:12px;z-index:2;display:flex;align-items:center;gap:8px;
  font-family:'Permanent Marker',cursive;font-size:14px;color:#fff;
  padding:7px 14px;border-radius:10px;background:rgba(14,12,8,.78);
}
.ab-photo-dot{flex:0 0 auto;width:11px;height:11px;border-radius:50%;background:var(--orange);border:2px solid #fff}

/* ----------------------------------------------------------- OUR STORY */
.ab-story-sec{padding:12px 0 0}
.ab-story{display:grid;grid-template-columns:.98fr 1.02fr;gap:56px;align-items:center}
@media(max-width:880px){.ab-story{grid-template-columns:1fr;gap:28px}}
.ab-story .ab-polaroid img{aspect-ratio:1.38/1;object-fit:cover}
.ab-story-stamp{
  position:absolute;top:14px;left:14px;z-index:2;
  font-family:'Bungee','Bungee Fallback',sans-serif;font-size:11px;letter-spacing:.6px;color:var(--ink);
  background:var(--brand-gold,#E0A526);padding:6px 12px;border-radius:8px;
  border:2.5px solid var(--ink);box-shadow:2px 2px 0 rgba(0,0,0,.55);transform:rotate(-3deg)}
.ab-h2{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:clamp(26px,4.4vw,42px);line-height:1.02;margin:0 0 16px;
  color:#fff;text-shadow:2px 2px 0 rgba(0,0,0,.5)}
.ab-grad-2{
  background:linear-gradient(96deg,var(--blue-bright),var(--gold-tint,#F2D38A) 70%,#F2998C);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;
  text-shadow:none;filter:drop-shadow(2px 2px 0 rgba(0,0,0,.45))}
.ab-story-copy p{font-size:15px;line-height:1.45;font-weight:500;color:#EDE6D6;margin:0 0 14px;max-width:68ch;
  text-shadow:0 1px 6px rgba(0,0,0,.45)}
.ab-story-copy p:last-child{margin-bottom:0}
.ab-story-copy p b{color:#fff;background:rgba(224,165,38,.22);padding:1px 6px;border-radius:5px;font-weight:800}
.ab-story-copy > p{margin-top:20px}

/* ------------------------------------------------------------ THE GOAL */
.ab-grow-sec{padding:38px 0 10px}
.ab-grow{display:grid;grid-template-columns:1.08fr .92fr;gap:48px;align-items:center}
@media(max-width:880px){.ab-grow{grid-template-columns:1fr;gap:28px}}
.ab-grow .ab-polaroid img{aspect-ratio:2.2/1;object-fit:cover}
/* deeper mockup fan (periwinkle → gold → red) for "THAT STARTED IT" */
.ab-grad-3{
  background:linear-gradient(96deg,#5D87D0 0%,#F1B740 62%,#D1472D 100%);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;
  text-shadow:none;filter:drop-shadow(2px 2px 0 rgba(0,0,0,.45));
}
.ab-purple{color:#B79AD6}
.ab-grow-p{
  margin:22px 0 0;max-width:38ch;
  font-size:clamp(17px,1.7vw,19.5px);font-weight:500;line-height:1.8;color:#EDE4D2;
  text-shadow:0 1px 6px rgba(0,0,0,.45);
}

/* --------------------------------------------------------- MEET THE TEAM
   Name-tag cards from the SVG handoff: gold tag pinned at a tilt over a
   white-framed 4:5 photo, cream sticky-note bio overlapping the photo's
   foot. Mockup measures halved (it's drawn at 2x): card≈250, gap≈50,
   bio indented 30 / overhanging 22 on the right. The mockup pulled the bio
   up 73 over the photo; softened to 40 per Jin so more of the photo shows. */
.ab-team-sec{padding:72px 0 18px}
.ab-team-h{text-align:center;margin:0 0 42px}
/* larger than the page's tightened editorial h2 scale — this one's a marquee */
[data-about] .ab-team-h{font-size:clamp(30px,4.6vw,48px)}
.ab-team{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(26px,3.6vw,50px);
}
@media(max-width:1080px){.ab-team{grid-template-columns:repeat(2,minmax(0,1fr));row-gap:42px}}
@media(max-width:520px){.ab-team{grid-template-columns:minmax(0,1fr);max-width:330px;margin:0 auto;row-gap:38px}}
/* whole card (tag+photo+bio together) zooms on hover — anime drives the liquid
   elastic pop via hoverPop in app.js; this is the CSS fallback, same pattern as
   .ab-polaroid. Hovered card rises above its neighbors while scaled.
   Fallback values must match the mate branch in hoverPop (app.js). */
.ab-mate{position:relative;min-width:0;transition:transform .18s ease}
@media(hover:hover){.ab-mate:hover{transform:translateY(-8px) scale(1.06);z-index:5}}
.js-anime-hover .ab-mate{transition:none}
.ab-mate.is-hot{z-index:5}
.ab-mate.is-hot .ab-mate-photo{box-shadow:0 26px 56px rgba(0,0,0,.62)}
@media(prefers-reduced-motion:reduce){
  .ab-mate,.ab-mate:hover{transform:none!important;transition:none}
}
.ab-mate-tag{
  position:absolute;top:-16px;left:-12px;z-index:3;margin:0;
  font-family:'Bungee','Bungee Fallback',sans-serif;font-weight:400;font-size:14px;
  letter-spacing:2px;line-height:1.2;color:var(--ink);
  background:var(--brand-gold,#E0A526);padding:9px 18px;border-radius:9px;
  box-shadow:0 6px 14px rgba(0,0,0,.45);
  transform:rotate(-7deg);transform-origin:left bottom;
}
/* same thick white polaroid frame as the story photos, minus the hover lift
   (the tag + bio are pinned to it, so it stays put) */
.ab-mate-photo{
  margin:0;border-radius:22px;overflow:hidden;
  border:8px solid #fff;background:#fff;
  box-shadow:0 18px 42px rgba(0,0,0,.5);
  transition:box-shadow .18s;   /* smooths the .is-hot shadow pop */
}
.ab-mate-photo img{width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;display:block;border-radius:14px}
.ab-mate-bio{
  position:relative;z-index:2;
  margin:-40px -22px 0 30px;
  background:#F8F1E2;border:3px solid #14110C;border-radius:18px;
  padding:14px 16px;
  box-shadow:0 14px 30px rgba(0,0,0,.45);
  color:#241B10;font-weight:600;font-size:14.5px;line-height:1.45;
}
@media(max-width:1080px){.ab-mate-bio{margin-right:0}}
.ab-mate-bio p{margin:0 0 12px}
.ab-mate-bio p:last-child{margin-bottom:0}
.ab-mate-link{color:inherit;text-decoration:underline;text-underline-offset:2px}
.ab-mate-link:hover,.ab-mate-link:focus-visible{color:var(--brand-blue,#3A6BB0)}

/* --------------------------------------------------- FIND US + BUYLIST */
.ab-find-sec{padding:30px 0 22px}
/* ------------------------------------------- MERGED VISIT + SELL PANEL
   One opaque dark surface, two columns, dashed divider. Recolors are scoped
   under .ab-close because .ab-card-h is shared with contact.html. */
.ab-close{
  display:grid;grid-template-columns:1fr 1fr;gap:0;
  border-radius:18px;border:1px solid var(--ab-card-stroke);
  background:var(--ab-card);
  box-shadow:0 14px 34px rgba(0,0,0,.45);
}
@media(max-width:820px){.ab-close{grid-template-columns:1fr}}
.ab-find,.ab-buylist{
  position:relative;display:flex;flex-direction:column;gap:10px;
  padding:26px clamp(22px,3.2vw,36px) 28px;
}
/* mockup icon chips: soft-shadowed, no die-cut ink border (contact keeps its own) */
[data-about] .ab-card-ic{width:36px;height:36px;border:0;border-radius:10px;box-shadow:0 3px 8px rgba(0,0,0,.4)}
[data-about] .ab-card-ic svg{width:19px;height:19px}
/* footer "Sell to us" deep-link lands here; clear the 72px sticky header + band */
.ab-buylist{color:#fff;border-left:2px dashed rgba(122,119,108,.55);scroll-margin-top:96px}
@media(max-width:820px){.ab-buylist{border-left:none;border-top:2px dashed rgba(122,119,108,.55)}}
.ab-close .ab-card-h{color:#fff;text-shadow:2px 2px 0 rgba(0,0,0,.5)}
/* card icon chip */
.ab-card-ic{width:48px;height:48px;border-radius:12px;display:grid;place-items:center;
  border:2.5px solid var(--ink);box-shadow:2px 2px 0 rgba(0,0,0,.45)}
.ab-card-ic svg{width:24px;height:24px}
.ab-ic-blue{background:var(--blue);color:#fff}
.ab-ic-gold{background:var(--brand-gold,#E0A526);color:var(--ink)}
.ab-card-h,.ab-buy-h{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:clamp(20px,3vw,26px);margin:2px 0 0;line-height:1}
.ab-card-h{color:var(--ink)}
.ab-buy-h{color:#fff;text-shadow:2px 2px 0 rgba(0,0,0,.5)}
.ab-addr{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:17px;line-height:1.35;color:#fff;margin:4px 0 4px}
.ab-find-list{margin:6px 0 4px;display:flex;flex-direction:column;gap:10px}
.ab-find-row{display:flex;gap:14px;align-items:baseline;border-top:2px dashed rgba(122,119,108,.45);padding-top:12px}
.ab-find-row:first-child{border-top:none;padding-top:0}
.ab-find-row dt{flex:0 0 64px;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:11px;letter-spacing:.4px;
  text-transform:uppercase;color:var(--gold-tint,#F2D38A)}
.ab-find-row dd{margin:0;font-weight:700;font-size:.96rem;color:#EDE6D6;line-height:1.4}
.ab-link{color:#BDD3F5;border-bottom:2px solid rgba(189,211,245,.5)}
.ab-link:hover{color:var(--primary);border-color:var(--primary)}
.ab-map-link{margin-top:auto;align-self:flex-start;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:12px;
  letter-spacing:.4px;color:#fff;background:#5183BC;padding:12px 18px;border-radius:10px;
  box-shadow:0 5px 14px rgba(0,0,0,.4);
  transition:transform .14s,box-shadow .14s,background .18s}
.ab-map-link:hover,.ab-map-link:focus-visible{transform:translateY(-2px);box-shadow:0 9px 20px rgba(0,0,0,.5);background:var(--blue-lively)}

/* ============================== CONTACT PAGE ============================== */
/* Contact hero = two columns: copy on the left, the message form card on the
   right, so the form is above the fold instead of a scroll below the title.
   Under 880px it stacks copy-then-form (the lede's "below" stays true). */
.ct-hero{padding:clamp(44px,6.5vw,84px) 0 64px}
.ct-hero .ab-title{font-size:clamp(32px,5.4vw,62px)}
.ct-hero .ab-lede{max-width:46ch;margin:16px 0 0}
.ct-hero-grid{display:grid;grid-template-columns:minmax(0,.94fr) minmax(0,1.06fr);
  gap:clamp(28px,4vw,54px);align-items:center}
.ct-hero-grid > *{min-width:0}
@media(max-width:880px){.ct-hero-grid{grid-template-columns:1fr;gap:30px}}
/* "call us" inside the lede is a live phone link — same weight as the copy,
   underlined so it reads as tappable on the dark backdrop */
.ct-call-link{color:#fff;font-weight:800;border-bottom:2px solid rgba(255,255,255,.65)}
.ct-call-link:hover,.ct-call-link:focus-visible{color:var(--gold-tint,#F2D38A);border-color:var(--gold-tint,#F2D38A)}
/* Instagram + Discord under the lede — a mini rainbow eyebrow over the
   footer's .soc icon links, sized up to 32px with a roomy tap target */
.ct-hero-socials{margin-top:32px}
.ct-socials-eyebrow{display:block;width:fit-content;margin-bottom:12px;
  font-family:'Bungee','Bungee Fallback',sans-serif;font-size:12.5px;letter-spacing:1px;
  /* warm-first bright fan: gold leads so the label pops off the blue mural
     (purple/blue-led gradients sink into the sky at this size) */
  background:linear-gradient(96deg,#FFE066 0%,#FFA94D 28%,#FF6B9D 58%,#C7A6FF 88%);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;
  filter:drop-shadow(0 2px 3px rgba(0,0,0,.75))}
.ct-socials-icons{display:flex;gap:10px}
.ct-hero-socials .soc{padding:8px;margin:-8px 0 -8px -8px;color:#E6DECB}
.ct-hero-socials .soc + .soc{margin-left:0}
.ct-hero-socials .soc svg{width:32px;height:32px}
.ct-hero-socials .soc:focus-visible{outline:3px solid #fff;outline-offset:2px;border-radius:8px}
.ct-map-sec{margin:26px 0}
.ct-map{border-radius:18px;overflow:hidden;border:var(--keyline) solid var(--ink);box-shadow:var(--shadow)}
.ct-map iframe{display:block}
/* form gets the same cream die-cut card as .ab-find — ink text needs it */
.ct-form-panel{max-width:640px;width:100%;margin:0 auto;
  padding:28px clamp(20px,3vw,32px) 32px;border-radius:20px;
  border:var(--keyline) solid var(--ink);box-shadow:var(--shadow);
  background:linear-gradient(165deg,var(--cream,#FBF5E9),#EFE3CA)}
.ct-hero-grid .ct-form-panel{margin:0;justify-self:end}
@media(max-width:880px){.ct-hero-grid .ct-form-panel{justify-self:stretch;max-width:none}}
.ct-form-panel .ab-h2{color:var(--ink);text-shadow:none}
.ct-form-sub{margin:8px 0 22px;color:#5C4A2C}
.ct-field{margin-bottom:16px}
.ct-field label{display:block;font-weight:800;margin-bottom:6px;color:var(--ink)}
/* live character count sits under the textarea's bottom-right corner */
.ct-count-row{display:flex;justify-content:flex-end;margin-top:5px}
.ct-count{font-size:12.5px;font-weight:700;color:#7A6A4C;font-variant-numeric:tabular-nums}
.ct-count.is-low{color:var(--sold-out,#9B3A2E)}
.ct-field input,.ct-field textarea{
  width:100%;padding:12px 14px;font:inherit;
  border:var(--keyline) solid var(--ink);border-radius:12px;background:#fff;
}
/* no drag-to-resize handle — long messages scroll inside the fixed box */
.ct-field textarea{resize:none;overflow-y:auto}
.ct-field input:focus-visible,.ct-field textarea:focus-visible{outline:3px solid var(--blue);outline-offset:2px}
/* Honeypot: off-screen, not display:none (naive bots check for that). */
.ct-hp{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden}
.ct-error{color:var(--sold-out,#9B3A2E);font-weight:700}
.ct-success{text-align:center;padding:26px 0}
.ct-success-note{margin-top:10px;font-size:.92rem;color:#5C4A2C}

.ab-buy-p{margin:2px 0 6px;font-weight:500;font-size:1rem;line-height:1.6;color:#EDE6D6;max-width:48ch}

/* ------------------------------------------------------- MOBILE ---- */
@media(max-width:880px){
  .ab-hero-copy{padding:34px 0 8px}
  .ab-hero-side{padding:0 0 6px;max-width:none;justify-self:stretch}
}

/* ============================================================ SCOPE 3 — ANIME
   Reveal helpers, anime-hover neutralization, and the promo announcement bar.
   60fps / compositor-only: transform + opacity only. Reduced-motion safe — the
   reveal/hover JS no-ops, and CSS :hover keeps working when JS motion is off. */

/* --- REVEAL: when anime drives the entrance, suppress the CSS keyframes so the
   two engines don't fight. wireReveal() never adds .in to an anime-animated node
   until it has claimed it, and clears inline opacity in the fallback path, so the
   only job here is to make .slap/.reveal animate transform+opacity (already do). */

/* --- HOVER NEUTRALIZATION ---------------------------------------------------
   body.js-anime-hover is set ONLY when anime hover is wired. Under it, anime owns
   the transform on these exact selectors; we strip the CSS :hover transform (and
   its transition, to avoid a double-ease) but KEEP the non-transform hover styling
   (shadow / outline-color pop). .ev-day keeps its resting rotate via anime. */
.js-anime-hover .card,
.js-anime-hover .ev-day,
.js-anime-hover .btn-slap{transition:box-shadow .18s, outline-color .22s}
.js-anime-hover .card:hover,
.js-anime-hover .ev-day:hover,
.js-anime-hover .ev-day:focus-within,
.js-anime-hover .btn-slap:hover,
.js-anime-hover .btn-slap:focus-visible{transform:none}
/* ev-day rests at a slight tilt; let anime own it (don't snap to 0 via CSS) */
.js-anime-hover .ev-day:nth-child(odd),
.js-anime-hover .ev-day:nth-child(even){transform:none}
/* the lifted-card shadow pop, folded onto a class anime toggles (non-transform) */
.js-anime-hover .card.is-hot{box-shadow:0 16px 0 rgba(0,0,0,.15),0 26px 42px rgba(0,0,0,.4);z-index:5;outline-color:var(--blue)}
.js-anime-hover .ev-day.is-hot{box-shadow:0 16px 0 rgba(0,0,0,.15),0 26px 42px rgba(0,0,0,.4);z-index:5}
.js-anime-hover .btn-slap.is-hot{box-shadow:7px 7px 0 var(--ink)}

/* ===== SHOP/PRODUCT accents ===== */
/* =====================================================================
   ABOUT-STYLE GRADIENT TREATMENT — STORE + PRODUCT titles
   Reuses the about hero's brand-fan gradient idiom (purple -> blue ->
   gold -> red, same 96deg sweep as .ab-grad) but in the DEEPER, AA-safe
   shades so the clipped text stays legible on the cream/parchment page
   (the about .ab-grad uses pale tints made for the dark night sky).
   ===================================================================== */
:root{
  /* deep brand fan for gradient text on light surfaces — mirrors .ab-grad's
     purple->blue->gold->red sweep using the AA-safe deep shades (same set the
     .scrawl accents use on parchment). */
  --grad-fan-deep:linear-gradient(96deg,
    var(--purple) 0%,
    var(--blue-deep) 32%,
    var(--gold-deep) 64%,
    var(--vib-red-deep) 100%);
}

/* shared clip mechanics — solid ink fallback first so the title is NEVER
   invisible if background-clip:text is unsupported; the gradient only paints
   where it's actually supported. */
.page-title--grad,
.sec-title--grad{ color:var(--ink); }
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .page-title--grad,
  .pdp-title--grad,
  .sec-title--grad{
    background-image:var(--grad-fan-deep);
    -webkit-background-clip:text;background-clip:text;
    -webkit-text-fill-color:transparent;color:transparent;
    /* soft ink lift for depth on the cream page (echoes .ab-grad's drop-shadow) */
    filter:drop-shadow(2px 2px 0 rgba(20,17,12,.16));
  }
}

/* ---- STORE page heading: drop the yellow sticker box, become a clean
   about-style gradient headline sitting on the page ---- */
.page-title.page-title--grad{
  display:block;background-color:transparent;border:0;box-shadow:none;
  padding:0;border-radius:0;margin:10px 0 0;
  letter-spacing:-.5px;line-height:.98;
  font-size:clamp(34px,6vw,60px);
}
/* slim brand-fan rule under the whole head row = a tasteful about-style band */
.store-head-row{position:relative;padding-bottom:18px}
.store-head-row::after{
  content:"";display:block;height:5px;border-radius:5px;margin-top:14px;
  background:var(--ab-fan);
  /* keep the bright fan rule from washing out — clamp its reach on wide screens */
  max-width:560px;
}

/* ---- PRODUCT "MORE ON THE WALL" related heading: keep the boxed sticker
   look (.sec-title base: cream box + hard offset shadow) but clip the text
   with the brand fan so it reads as the about page's sibling. The base
   .sec-title shadow stays (magenta), matching the rest of the site. ---- */
.sec-title.sec-title--grad{
  /* base box/shadow inherited from .sec-title; nothing to override here. */
}

/* reduced-motion / no-anime is unaffected — these are pure paint, no transform. */
@media(max-width:560px){
  .store-head-row::after{max-width:none}
}

/* ===== ABOUT PAGE backdrop = "the starry night" mural image ===== */
/* About carries .ab-page; a dark scrim over art-starry keeps the white .ab- text readable. */
body:has(.ab-page){
  background:linear-gradient(rgba(11,16,38,.82),rgba(11,16,38,.9)), url("../images/shop/art-starry.jpg") center/cover fixed;
  background-color:#0b1026;
}

/* ================================================================
   PHASE 4.5 — SOFT-UI DESIGN SYSTEM (buttons + tape + type)
   The sticker-shop look stays primary; every BUTTON is re-cast as
   neumorphic: soft dual-light extrusion + thin (1.5px) ink border +
   press-IN active state (replacing hard 4px-offset slap shadows).
   Two shadow palettes, one per surface:
     --sb-*     tuned for the warm parchment page
     --sb-dk-*  tuned for the near-black header bar
   ================================================================ */
:root{
  /* deeper parchment for hover fills / badges / notice panels — referenced
     by 7 rules but never defined until 2026-07-20 (silent fallback) */
  --parchment-deep:#EADFC8;
  --sb-shd:rgba(203,189,158,.62);  --sb-shl:rgba(255,255,255,.85);
  --sb-ext:       7px 7px 14px var(--sb-shd), -7px -7px 14px var(--sb-shl);
  /* (hover-glow variants removed — Jin's call: buttons never brighten on hover) */
  --sb-ext-sm:    4px 4px 9px var(--sb-shd), -4px -4px 9px var(--sb-shl);
  --sb-inset:     inset 5px 5px 9px var(--sb-shd), inset -5px -5px 9px var(--sb-shl);
  --sb-inset-sm:  inset 3px 3px 6px var(--sb-shd), inset -3px -3px 6px var(--sb-shl);
  /* colored (gold/blue) buttons need neutral inner shading to read as pressed */
  --sb-inset-tint:inset 4px 4px 8px rgba(0,0,0,.22), inset -4px -4px 8px rgba(255,255,255,.28);
  /* dark header bar: deep black drop + faint cool rim light (no white halo) */
  --sb-dk-ext:       4px 4px 9px rgba(0,0,0,.55), -2px -2px 6px rgba(255,255,255,.10);
  --sb-dk-inset:     inset 4px 4px 8px rgba(0,0,0,.5), inset -2px -2px 5px rgba(255,255,255,.10);
}

/* ---- primary/secondary CTAs (all pages) ---- */
.btn-slap{
  border-width:1.5px;border-radius:14px;
  box-shadow:var(--sb-ext);
  transition:transform .2s ease-out, box-shadow .2s ease-out;
}
/* Jin's call: NO glow pop on hover anywhere — every button holds its resting
   shadow; feedback is the 1px lift + press-IN active only */
.btn-slap:hover,.btn-slap:focus-visible{transform:translateY(-1px);box-shadow:var(--sb-ext)}
.btn-slap:active{transform:translateY(1px);box-shadow:var(--sb-inset-tint)}
.js-anime-hover .btn-slap{transition:box-shadow .2s ease-out}
.js-anime-hover .btn-slap.is-hot{box-shadow:var(--sb-ext)}
.js-anime-hover .btn-slap:active{box-shadow:var(--sb-inset-tint)}
/* visit-panel CTA sits on a parchment card — the neumorphic white halo reads
   as a smear against that surface, so hold one calm shadow in every state
   (press-in stays for tactile feedback) */
.visit-actions .btn-slap,
.visit-actions .btn-slap:hover,
.visit-actions .btn-slap:focus-visible,
.js-anime-hover .visit-actions .btn-slap.is-hot{box-shadow:var(--sb-ext-sm)}
.visit-actions .btn-slap:active,
.js-anime-hover .visit-actions .btn-slap:active{box-shadow:var(--sb-inset-tint)}

/* ---- header nav pills: SHOP ▾ toggle + nav links (dark surface) ---- */
.nav-link,.shop-toggle{
  border-width:1.5px;border-radius:10px;
  box-shadow:var(--sb-dk-ext);
  transition:transform .2s ease-out, box-shadow .2s ease-out, background .18s;
}
.nav-link:hover,.nav-link:focus-visible,
.shop-toggle:hover,.shop-toggle:focus-visible{
  transform:translateY(-1px);box-shadow:var(--sb-dk-ext);
}
.nav-link:active,.shop-toggle:active{transform:translateY(1px);box-shadow:var(--sb-dk-inset)}

/* ---- header search: inset input well + soft blue submit (dark surface) ---- */
.search input{
  border-width:1.5px;border-right:none;
  box-shadow:var(--sb-dk-inset);
}
.search button{
  border-width:1.5px;
  box-shadow:var(--sb-dk-ext);
  transition:transform .2s ease-out, box-shadow .2s ease-out, background .18s;
}
.search button:hover{transform:translateY(-1px);box-shadow:var(--sb-dk-ext)}
.search button:active{transform:translateY(1px);box-shadow:var(--sb-inset-tint)}

/* ---- mobile header tool buttons (magnifier / hamburger, dark surface) ---- */
.header-tool{
  border-width:1.5px;
  box-shadow:var(--sb-dk-ext);
  transition:transform .2s ease-out, box-shadow .2s ease-out, background .18s;
}
.header-tool:hover,.header-tool:focus-visible{transform:translateY(-1px);box-shadow:var(--sb-dk-ext)}
.header-tool:active{transform:translateY(1px);box-shadow:var(--sb-inset-tint)}

/* ---- review-card CTA chip ---- */
.hero-photo .rev-card .rc-cta{
  border-width:1.5px;
  box-shadow:var(--sb-ext-sm);
}

/* ---- typography: Ranchers = the one display face for headings.
   Hierarchy is expressed by SIZE, not by switching typefaces. ---- */
.spray-title{
  font-family:'Ranchers','Ranchers Fallback','Bungee','Bungee Fallback',sans-serif;
  -webkit-text-stroke:2px var(--ink);
  letter-spacing:.14em; /* spread the stacked wordmark into a bolder poster rhythm */
}
.sec-title{
  font-family:'Ranchers','Ranchers Fallback','Bungee','Bungee Fallback',sans-serif;
  letter-spacing:1.2px;
  font-size:clamp(28px,4.8vw,46px); /* Ranchers is condensed — a notch up keeps optical weight */
}

/* ---- tape → brand "sticker tabs": crisp rounded tabs, thin ink
   keyline (same language as the buttons), glass top-light, soft drop.
   Both photo-corner tapes are card blue. ---- */
.tape{
  width:92px;height:24px;border-radius:7px;
  border:1.5px solid var(--ink);
  background:linear-gradient(135deg, rgba(58,107,176,.95), rgba(90,138,208,.72));
  box-shadow:2px 3px 6px rgba(20,17,12,.22), inset 0 1.5px 0 rgba(255,255,255,.5);
}
.tape.tl,.tape.tr{background:linear-gradient(135deg, rgba(58,107,176,.95), rgba(90,138,208,.72))}

/* ---- greeter badge: circle → CENTER TAPE (yellow, straight, clickable).
   Sized for one line of text; no glow ring. Nested spans give anime.js
   separate layers (idle bob vs click pop) so transforms never fight. ---- */
.hero-photo .greeter-badge{
  width:auto;min-width:134px;height:34px;padding:0 16px;
  top:-9px;border-radius:7px;
  font-size:12.5px;line-height:1;letter-spacing:.4px;
  background:linear-gradient(135deg, rgba(255,196,0,.97), rgba(242,185,64,.8));
  border:1.5px solid var(--ink);
  box-shadow:2px 3px 6px rgba(20,17,12,.22), inset 0 1.5px 0 rgba(255,255,255,.5);
  transform:translateX(-50%); /* straight — no tilt */
  display:grid;place-items:center;overflow:visible;
  transition:box-shadow .2s ease-out;
}
.hero-photo .greeter-badge:hover{box-shadow:3px 5px 9px rgba(20,17,12,.3), inset 0 1.5px 0 rgba(255,255,255,.5)}
.hero-photo .greeter-badge:active{box-shadow:var(--sb-inset-tint)}
.greeter-badge .gb-bob{display:grid;place-items:center;width:100%;height:100%;will-change:transform}
.greeter-badge .gb-txt{display:block;white-space:nowrap;will-change:transform,opacity}

/* pre-release announce mode only: clip to the tape's rounded shape so the
   shine sweep below reads as a foil glint, not a highlight spilling past
   the badge. Fallback ("SAY HEY!") mode keeps overflow:visible (needed so
   .gb-bob's idle offset isn't clipped) — this override only ever applies
   alongside .gb-announce. Same sweep recipe as the hero review card's
   .rc-shine/@keyframes revFoil, just faster/brighter for a small tape. */
.hero-photo .greeter-badge.gb-announce{overflow:hidden}
/* text sits in its own stacked layer above the shine (same recipe as
   .rev-card > *{z-index:2} over .rc-shine's z-index:1) — otherwise the
   sweep washes out the letters it passes over instead of glinting behind
   them. */
.greeter-badge.gb-announce .gb-label{position:relative;z-index:2}
.greeter-badge.gb-announce .gb-shine{
  position:absolute;top:-60%;left:-40%;width:45%;height:220%;z-index:1;pointer-events:none;
  background:linear-gradient(115deg,rgba(255,255,255,0),rgba(255,255,255,.9) 50%,rgba(255,255,255,0));
  transform:rotate(8deg);animation:gbShine 6.8s ease-in-out infinite;will-change:transform;
}
/* sweep right (0-35%, ~2.4s), hold there (35-65%, ~2s), sweep back (65-100%,
   ~2.4s) — a deliberate there-and-back glint instead of a continuous
   oscillation. */
@keyframes gbShine{
  0%{transform:translateX(0) rotate(8deg)}
  35%,65%{transform:translateX(340%) rotate(8deg)}
  100%{transform:translateX(0) rotate(8deg)}
}
@media(prefers-reduced-motion:reduce){.greeter-badge.gb-announce .gb-shine{animation:none;opacity:.3}}

@media(max-width:480px){
  .hero-photo .greeter-badge{width:auto;min-width:112px;height:30px;font-size:10.5px;top:-8px}
}

/* ================================================================
   STORE + PRODUCT — BLUE COIN CONVERSION (2026-07-05)
   Converts the last two page bodies off the sticker-bomb skin.
   Two primitives, reused everywhere below — nothing new invented:
     PANEL  = the hairline `.card` recipe (thin ink border, soft
              blur shadow, no die-cut/keyline/hard-offset shadow)
     PILL/BUTTON = the neumorphic --sb-ext recipe already
              established for .btn-slap/.nav-link/.search above
   ================================================================ */

/* ---- shared hairline PANEL (sidebar filter groups + PDP specs card) ---- */
.filter-block,.specs{
  background:var(--parchment);border:0.5px solid var(--ink);outline:none;
  border-radius:14px;box-shadow:0 8px 18px rgba(20,17,12,.16);
}
.filter-block h2,.specs h2{border-bottom-width:1.5px}

/* ---- shared hairline PILL (filter buttons, chips, tag pills, variant/format pills) ---- */
.filter-list button,.chip,.variant-pill,.fmt{
  border-width:1.5px;box-shadow:var(--sb-ext-sm);
  transition:transform .2s ease-out, box-shadow .2s ease-out, background .18s;
}
.filter-list button:hover{background:var(--parchment-deep);transform:translateY(-1px);box-shadow:var(--sb-ext-hover)}
.filter-list button:active{transform:translateY(1px);box-shadow:var(--sb-inset-tint)}
.filter-list button.active{background:var(--primary);color:var(--on-primary);border-color:var(--primary-deep);box-shadow:var(--sb-inset-tint)}
.filter-list button.active .fcount{background:rgba(255,255,255,.25);color:#fff}
.fcount{background:var(--parchment-deep);color:var(--ink)}

/* the sheet-markup restructure moved the filter blocks into
   .filters-sheet-body, which lost the 18px gap the old .filters container
   gave them — the panels sat conjoined. Restore the rhythm on the wrapper
   the blocks actually live in now (desktop rail AND mobile sheet). */
.filters-sheet-body{display:flex;flex-direction:column;gap:18px}

/* ---- collapsible filter groups: header is the toggle; CATEGORY starts
   open, the rest closed (open state lives in JS across re-renders) ---- */
.fb-toggle{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;
  background:none;border:none;padding:0;margin:0;cursor:pointer;
  font:inherit;color:inherit;letter-spacing:inherit;text-align:left}
/* .filter-list's own display:flex outranks the UA's [hidden]{display:none}
   (author beats UA at equal specificity) — restate it or collapse is a no-op */
.filter-list[hidden]{display:none}
.fb-toggle .caret{font-size:11px;transition:transform .2s ease-out}
.filter-block.collapsed .fb-toggle .caret{transform:rotate(-90deg)}
/* collapsed: the header keeps its underline but drops the list's breathing room */
.filter-block.collapsed h2{margin-bottom:0}
@media(prefers-reduced-motion:reduce){.fb-toggle .caret{transition:none}}

/* ---- mobile centering (Jin's call, 2026-07-06): under centered product
   photography the text reads as one balanced unit centered too. Desktop
   keeps left alignment — wider cards/columns make centered text gappy. ---- */
/* wall cards: only where the 2-up phone grid runs */
@media(max-width:560px){
  .card .body{text-align:center}
  .card .meta-row{justify-content:center}
}
/* PDP: only where the layout stacks to one column (photo above info).
   Body copy (description, specs, visit panel) stays left — centered
   paragraphs read poorly; this centers the title / price / stock / pills. */
@media(max-width:860px){
  .pdp-title{text-align:center}
  .pdp-price-row{justify-content:center}
  .variant-pills{justify-content:center}
  .pdp-formats{justify-content:center}
  .pdp-formats .fmt-head{width:100%;text-align:center;margin:0}
}

/* zero-count category rows: present (we carry the line in-store) but muted —
   entirely count-driven, so a restock un-mutes on the next sync */
.filter-list button.cat-zero{opacity:.55}
.filter-list button.cat-zero:hover{opacity:.85}
.filter-list button.cat-zero.active{opacity:1}
/* the tailored category-empty message links the shop's phone number */
.empty p a{color:var(--blue-deep);font-weight:800}

/* active filters read the same card-blue as the sidebar's active state,
   whether shown as a sidebar button or a removable chip */
.chip{background:var(--primary);color:#fff;box-shadow:var(--sb-ext-sm)}
.chip button{background:rgba(255,255,255,.25);color:#fff}
.chip button:hover{background:rgba(255,255,255,.4)}
.chip.clear{background:var(--ink);color:#fff}
.chip.clear:hover{background:var(--primary-hover)}

/* ---- sort control ---- */
.sort-select{
  background:var(--paper);border-width:1.5px;box-shadow:var(--sb-inset-sm);
}

/* ---- sold-out on the wall (2026-07-06 walkthrough P0-1): the grid tells the
   truth about availability at a glance. Driven purely by catalog.js stock —
   a Square sell-out flags itself here on the next hourly sync. ---- */
.card-sold .thumb img{filter:grayscale(.45) brightness(.94);opacity:.75}
.card-sold .price-tab{opacity:.65}
.sold-flag{position:absolute;top:10px;left:10px;z-index:2;
  font-family:'Bungee','Bungee Fallback',sans-serif;font-size:10.5px;letter-spacing:.4px;line-height:1;
  color:#fff;background:var(--sold-out);padding:5px 9px 4px;border-radius:7px;
  border:1.5px solid var(--ink);box-shadow:var(--sb-ext-sm)}

/* ---- store head (walkthrough P2-2): quiet professional result count —
   the count is information, not a sticker ---- */
.result-count{background:transparent;border:none;box-shadow:none;padding:8px 0;
  font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:800;font-size:14px;letter-spacing:.2px}

/* ---- wall ergonomics (walkthrough P1-1): the head sticks under the site
   header, so count · sort · Filters stay reachable anywhere on the wall ---- */
/* minmax(0,1fr): a plain 1fr floors at the column's min-content, so the
   nowrap sticky-head row could force the whole column past the viewport on
   narrow phones — cap it at the track size instead */
.store-layout{grid-template-columns:268px minmax(0,1fr)}
@media(max-width:860px){.store-layout{grid-template-columns:minmax(0,1fr)}}
.store-main-head{position:sticky;top:80px;z-index:20;
  background:var(--parchment);border:0.5px solid var(--ink);border-radius:12px;
  box-shadow:0 8px 18px rgba(20,17,12,.16);padding:6px 14px}
.result-count{padding:6px 0}
/* mobile Filters toggle inside the sticky head; desktop keeps the sidebar.
   (.store-main-head prefix outranks the sheet block's generic .filters-toggle
   rules regardless of source order) */
.store-main-head .head-filters{display:none}
@media(max-width:860px){
  .store-main-head .head-filters{display:inline-flex;align-items:center;gap:7px;margin:0;flex:0 0 auto;
    font-family:'Bungee','Bungee Fallback',sans-serif;font-size:11px;letter-spacing:.3px;color:var(--on-primary);
    background:var(--primary);border:1.5px solid var(--ink);border-radius:9px;
    padding:0 13px;min-height:40px;box-shadow:var(--sb-ext-sm);cursor:pointer}
  .store-main-head .head-filters .ft-count{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:10px;background:rgba(255,255,255,.25);
    color:#fff;padding:2px 8px;border-radius:20px;min-width:20px;text-align:center}
  /* one slim row on phones: count · sort · Filters — never a stacked panel */
  .store-main-head{flex-wrap:nowrap;gap:8px;padding:6px 10px}
  .result-count{font-size:12px;padding:4px 0;white-space:nowrap;min-width:0;overflow:hidden;text-overflow:ellipsis}
  .sort-wrap{margin-left:auto;gap:5px;flex:0 0 auto}
  .sort-wrap label{position:absolute;left:-9999px}
  .sort-select{min-height:40px;padding:8px 10px;font-size:12.5px;max-width:150px}
}

/* "Show more" block spans the grid; count context above the button */
.wall-more{grid-column:1/-1;display:flex;flex-direction:column;align-items:center;gap:10px;
  padding:20px 0 8px;text-align:center}
.wall-more .wm-count{margin:0;font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:700;font-size:13.5px;color:#5A4A36}
.wall-more .wm-count b{color:var(--blue-deep)}

/* back-to-top: fades in after ~1.5 screens; below the sheet/scrim z-order */
.to-top{position:fixed;right:18px;bottom:18px;z-index:35;width:48px;height:48px;border-radius:50%;
  font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:800;font-size:20px;line-height:1;cursor:pointer;
  color:var(--on-primary);background:var(--primary);border:1.5px solid var(--ink);box-shadow:var(--sb-ext);
  opacity:0;pointer-events:none;transform:translateY(8px);
  transition:opacity .2s ease-out,transform .2s ease-out}
.to-top.show{opacity:1;pointer-events:auto;transform:none}
.to-top:hover{background:var(--primary-hover)}
.to-top:focus-visible{outline:3px solid var(--brand-gold);outline-offset:2px}
@media(prefers-reduced-motion:reduce){.to-top{transition:none}}

/* ---- empty state ---- */
.empty{background:var(--parchment);border:0.5px solid var(--ink);outline:none;box-shadow:0 8px 18px rgba(20,17,12,.16)}
.empty .btn-clear{border-width:1.5px;box-shadow:var(--sb-ext)}
.empty .btn-clear:hover{transform:translateY(-1px);box-shadow:var(--sb-ext-hover)}

/* ---- mobile filter bottom sheet (replaces the old inline-expand) ---- */
body.scroll-locked{overflow:hidden}

@media(max-width:860px){
  .filters-toggle{
    display:inline-flex;align-items:center;gap:9px;margin-top:14px;
    font-family:'Bungee','Bungee Fallback',sans-serif;font-size:13px;letter-spacing:.3px;color:var(--on-primary);
    background:var(--primary);border:1.5px solid var(--ink);border-radius:11px;
    padding:0 16px;min-height:48px;box-shadow:var(--sb-ext);cursor:pointer;
    transition:transform .2s ease-out, box-shadow .2s ease-out;
  }
  .filters-toggle:hover,.filters-toggle:focus-visible{transform:translateY(-1px);box-shadow:var(--sb-ext-hover)}
  .filters-toggle:active{transform:translateY(1px);box-shadow:var(--sb-inset-tint)}
  .filters-toggle .ft-count{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:11px;background:rgba(255,255,255,.25);color:#fff;
    padding:2px 9px;border-radius:20px;min-width:24px;text-align:center}
  .filters-toggle .caret{margin-left:2px;transition:transform .2s}
  .store-wrap.filters-open .filters-toggle .caret{transform:rotate(180deg)}

  .filters-scrim{
    position:fixed;inset:0;background:rgba(20,17,12,.55);z-index:40;
    opacity:0;pointer-events:none;transition:opacity .22s;
  }
  .store-wrap.filters-open .filters-scrim{opacity:1;pointer-events:auto}

  .filters{
    position:fixed;left:0;right:0;bottom:0;top:auto;z-index:41;
    max-height:82vh;margin:0;padding:0;
    background:var(--paper);border:0.5px solid var(--ink);border-bottom:none;
    border-radius:20px 20px 0 0;box-shadow:0 -10px 30px rgba(20,17,12,.35);
    transform:translateY(100%);transition:transform .28s cubic-bezier(.2,.9,.3,1);
    display:flex;flex-direction:column;overflow:hidden;
  }
  /* the pre-existing `.store-wrap .filters{display:none}` toggle (styles.css:1119-1120)
     outranks the bare `.filters{display:flex}` above (2 classes beat 1) — left in place
     per the "no deletion yet" constraint, so match its specificity here to win by source
     order instead. The sheet must stay display:flex at all times and rely solely on
     transform:translateY to hide/show itself, or the slide transition can't play (a
     display:none↔flex flip never animates, same reasoning as the scrim's `hidden`). Same
     fix for the old rule's leftover `margin-bottom:10px`, which otherwise left a 10px gap
     of visible scrim beneath the sheet instead of a flush bottom edge. */
  .store-wrap .filters{display:flex}
  .store-wrap.filters-open .filters{transform:translateY(0);margin-bottom:0}
  .filters-sheet-head{display:flex;align-items:center;justify-content:space-between;
    padding:14px 18px 12px;border-bottom:0.5px solid var(--ink);flex:0 0 auto}
  .filters-sheet-title{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:15px;color:var(--ink)}
  .filters-sheet-close{width:30px;height:30px;border-radius:50%;border:1.5px solid var(--ink);
    background:var(--paper);font-size:14px;line-height:1;box-shadow:var(--sb-ext-sm)}
  .filters-sheet-body{padding:14px 18px;overflow-y:auto;flex:1 1 auto}
  /* thumb-sized rows (walkthrough P2-4): 48px floor on the controls a thumb
     actually works, not just the toggle */
  .filters-sheet-body .filter-list button{min-height:48px}
  .filters-sheet-foot{padding:14px 18px;border-top:0.5px solid var(--ink);flex:0 0 auto}
  /* .btn-slap is display:inline-flex (styles.css:517); with the "Show <span>N</span>
     results" markup that turns "Show", the count, and "results" into separate
     anonymous flex items, and flexbox trims the whitespace at each item's edges —
     without an explicit gap the button reads as "Show207results". */
  .filters-sheet-apply{width:100%;justify-content:center;gap:0.3em}
}
/* desktop: sheet chrome never renders; the sidebar is a plain in-flow rail that scrolls with the page */
@media(min-width:861px){
  .filters-scrim,.filters-sheet-head,.filters-sheet-foot{display:none}
}
/* ---- PDP stock badge: semantic tokens (already loaded from brand/tokens.css),
   not the old sticker vib-green/yellow fills ---- */
.pdp-stock{border-width:1.5px;box-shadow:var(--sb-ext-sm)}
.pdp-stock.in{background:var(--in-stock);color:#fff}
.pdp-stock.low{background:var(--low-stock);color:#fff}
.pdp-stock.sold-out{background:var(--sold-out);color:#fff}

/* ---- variant pills (cross-product format picker) + in-listing format pills ---- */
.variant-pill.active{background:var(--primary);border-color:var(--primary-deep)}
.variant-pill.active .vp-name,.variant-pill.active .vp-price{color:#fff}
.variant-pill:hover{background:var(--parchment-deep);transform:translateY(-1px);box-shadow:var(--sb-ext-hover)}
.fmt{background:var(--paper)}
.fmt-price{color:var(--blue-deep)}

/* ---- related-products section: circular scroll arrows ---- */
.rel-arrow{border-width:1.5px;box-shadow:var(--sb-ext-sm);
  transition:box-shadow .2s ease-out, background .18s}
.rel-arrow:hover:not(:disabled){background:var(--parchment-deep);box-shadow:var(--sb-ext-hover)}
.rel-arrow:active:not(:disabled){box-shadow:var(--sb-inset-tint)}

/* ═══════════════════════════════════════════════════════════════════════
   EVENTS PAGE (Blue Coin)  —  events.html · renderEvents() in app.js
   Sticker/hard-shadow idiom: cream faces, ink keylines, gold + purple pops.
   Only transform/opacity animate; entrance guarded by reduced-motion.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── HERO: EVENT NIGHTS + featured pre-release ─────────────────────────── */
.ev2-hero{position:relative;overflow:hidden;padding:56px 0 40px}
.ev2-star{position:absolute;top:44px;left:22px;font-size:34px;color:var(--brand-purple);
  transform:rotate(-8deg);pointer-events:none;line-height:1}
.ev2-hero-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:40px;align-items:center}
.ev2-hero-grid:has(.ev2-featured[hidden]){grid-template-columns:1fr}
.ev2-hero-copy{min-width:0}

.ev2-title{font-family:'Bungee','Bungee Fallback',sans-serif;line-height:.9;margin:0 0 18px;
  font-size:clamp(46px,8vw,92px);letter-spacing:-1px;-webkit-text-stroke:2px var(--ink)}
.ev2-title .t-gold{color:var(--brand-gold);text-shadow:4px 4px 0 var(--gold-deep),8px 8px 0 var(--ink)}
.ev2-title .t-purple{color:var(--brand-purple);text-shadow:4px 4px 0 var(--brand-purple-deep),8px 8px 0 var(--ink)}
.ev2-sub{font-size:1.0625rem;font-weight:500;line-height:1.55;max-width:46ch;margin:0;color:#231C12}
.ev2-sub b{background:var(--brand-gold);padding:1px 6px;border-radius:4px;font-weight:800;
  box-shadow:1px 1px 0 rgba(0,0,0,.4)}

/* featured event card — poster layout: full-width photo banner on top, copy
   below. Event names run long (owner marketing sentences) and event art is
   often a text-heavy flyer; a top banner gives the title the card's full width
   (2–3 tidy lines, not a 5–7 line strip) and shows the art landscape instead
   of side-cropping it. Same stack the mobile card already used — now unified. */
.ev2-featured{position:relative;display:flex;flex-direction:column;min-width:0;
  background:var(--cream);border:4px solid var(--ink);border-radius:14px;
  box-shadow:var(--shadow-hard)}
.ev2-featured[hidden]{display:none}
/* tab wears the same sticker treatment as UPCOMING EVENTS: white face, ink
   keyline, red offset shadow — Ranchers, the site's heading face (Jin) */
.ev2-feat-tab{position:absolute;top:-22px;left:20px;z-index:3;
  font-family:'Ranchers','Ranchers Fallback','Bungee','Bungee Fallback',sans-serif;font-size:clamp(20px,2.4vw,27px);letter-spacing:1.2px;color:var(--ink);
  background:#fff;padding:6px 18px;border-radius:12px;border:3px solid var(--ink);
  box-shadow:6px 6px 0 var(--vib-red)}
/* photo banner — fixed 21:10 (a shallow landscape band) so the card stays
   compact and a portrait flyer can't stretch it tall; rounded to the card's
   top corners, ink rule at the seam below */
.ev2-featured>img{display:block;width:100%;height:auto;aspect-ratio:21/10;
  object-fit:cover;object-position:center;background:var(--photo-bg);
  border-bottom:3px solid var(--ink);border-radius:10px 10px 0 0}
.ev2-feat-body{min-width:0;display:flex;flex-direction:column;padding:0 20px 18px}
/* gold date badge rides UP onto the banner's bottom-left corner (the site's
   sticker-overlap idiom) — anchors the copy to the photo and saves height */
.ev2-feat-datebadge{align-self:flex-start;display:inline-flex;flex-direction:column;
  background:var(--brand-gold);padding:9px 14px;border-radius:10px;border:3px solid var(--ink);
  box-shadow:3px 3px 0 var(--ink);position:relative;z-index:2;margin:-38px 0 12px}
.ev2-feat-date{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:clamp(24px,2.9vw,32px);
  line-height:1;color:var(--ink)}
.ev2-feat-time{display:block;font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:800;font-size:.8rem;
  color:var(--ink);margin-top:6px;padding-top:6px;border-top:2px solid rgba(20,17,12,.25);
  text-align:center}
.ev2-feat-more{cursor:pointer;align-self:flex-start;margin-top:2px}
.ev2-feat-name{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:clamp(17px,1.55vw,19px);line-height:1.16;
  letter-spacing:.2px;margin:0 0 8px;color:var(--ink);overflow-wrap:anywhere}
.ev2-feat-desc{font-size:.9rem;line-height:1.42;color:#3A2F20;margin:0 0 14px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* CTA row: button left, bare price text bottom-right — no pill on this card
   (Jin). Pair must fit INSIDE the card at ≥1280px; in the cramped 961–1140px
   band the row may wrap (wrapping is fine there — clipping is not). */
/* wrap:wrap so a second CTA (anniversary's "SEE THE FULL PAGE") drops to its
   own line instead of overflowing the narrow body column at in-between widths */
.ev2-feat-cta{display:flex;flex-wrap:wrap;align-items:flex-end;gap:12px;margin-top:auto;min-width:0}
.ev2-feat-cta .btn-slap{white-space:nowrap;flex:0 0 auto;font-size:13px;padding:12px 18px}
.ev2-feat-price{margin-left:auto;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:13px;
  letter-spacing:.3px;color:var(--ink);white-space:nowrap;padding-bottom:2px}
@media(max-width:1230px){.ev2-feat-cta{flex-wrap:wrap}}

/* ── UPCOMING EVENTS ───────────────────────────────────────────────────── */
.ev2-upcoming{padding:8px 0 64px}
.ev2-sticker{display:inline-block;font-family:'Ranchers','Ranchers Fallback','Bungee','Bungee Fallback',sans-serif;letter-spacing:1.2px;
  font-size:clamp(26px,3.8vw,38px);line-height:1.05;color:var(--ink);
  background:#fff;padding:12px 20px;border-radius:12px;border:3px solid var(--ink);
  box-shadow:6px 6px 0 var(--vib-red);margin:0 0 16px}
.ev2-blurb{font-size:1rem;font-weight:500;line-height:1.55;max-width:62ch;margin:0 0 26px;color:#3A2F20}
.ev2-blurb b{background:var(--brand-gold);padding:1px 6px;border-radius:4px;font-weight:700;
  box-shadow:1px 1px 0 rgba(0,0,0,.35)}

.ev2-grid{display:grid;grid-template-columns:1.4fr 1fr;gap:36px;align-items:start}
.ev2-list{display:flex;flex-direction:column;gap:18px;min-width:0}

/* event card — photo · purple date block · name/desc/time */
.ev2-card{position:relative;display:flex;min-width:0;background:var(--cream);
  border:3px solid var(--ink);border-radius:14px;box-shadow:var(--shadow-hard);overflow:hidden;cursor:pointer}
.ev2-card:focus-visible{outline:3px solid var(--brand-blue);outline-offset:2px}
/* photo panel fills the card's height; card height is owned by the content
   column, so cards stay short (absolute keeps the img height attr out of layout) */
/* photo panel width matches the mockup's ratio (342/1072 in the source SVG,
   AtlantaTCG Event - Rough Layout.svg — repo root) so the photo reads as
   prominently as the design intends, not cropped down to a thin strip.
   object-fit:cover ("fill frame", Jin's call) + object-position:top: most
   real event photos are portrait in a landscape panel, so cover crops
   top/bottom — anchoring to the top keeps box-art logos/titles in frame
   instead of centering the crop on the middle of the photo. */
.ev2-card>img{position:absolute;left:0;top:0;width:31.9%;min-width:135px;height:100%;object-fit:cover;
  object-position:top;background:var(--photo-bg);border-right:3px solid var(--ink);display:block}
.ev2-card .ev2-card-body{margin-left:max(31.9%,135px)}
.ev2-card-body{flex:1;min-width:0;display:flex;gap:16px;align-items:flex-start;padding:14px 16px}
/* date badge + its time pill stack in one left column (per the mockup) — no
   fixed width on either: align-items:stretch makes both match the WIDEST
   one's intrinsic content width (always the time pill, since "5:00 – 9:30 PM"
   needs more room than a 2-digit day number), so they're always the same
   width and the pill text never wraps or overflows past the badge */
.ev2-datecol{flex:0 0 auto;display:flex;flex-direction:column;align-items:stretch;gap:9px}
.ev2-date{display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:12px 14px;background:var(--brand-purple);color:#fff;
  border-radius:12px;border:3px solid var(--ink);box-shadow:3px 3px 0 var(--ink)}
.ev2-date b{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:15px;letter-spacing:.5px;line-height:1}
.ev2-date i{font-family:'Bungee','Bungee Fallback',sans-serif;font-style:normal;font-size:34px;line-height:1.05}
.ev2-card-text{min-width:0;flex:1}
.ev2-card-text h3{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:clamp(15px,1.9vw,20px);line-height:1.1;
  margin:2px 0 6px;color:var(--ink);overflow-wrap:anywhere}
.ev2-card-text p{font-size:.9rem;line-height:1.4;color:#3A2F20;margin:0 0 4px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* opens the shared detail pop-up (see renderEvents) — not an inline expand */
.ev2-more{display:block;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:10.5px;letter-spacing:.3px;
  color:var(--brand-blue);background:none;border:none;padding:0 0 8px;margin:0;cursor:pointer}
.ev2-more:hover,.ev2-more:focus-visible{text-decoration:underline}
.ev2-time{display:block;box-sizing:border-box;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:11.5px;letter-spacing:.4px;
  text-align:center;color:var(--ink);background:var(--brand-gold);padding:6px 11px;border-radius:12px;
  border:2px solid var(--ink);box-shadow:2px 2px 0 var(--ink);white-space:nowrap}
.ev2-price{display:inline-block;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:12px;letter-spacing:.3px;
  color:var(--ink);background:var(--brand-gold-tint);padding:6px 12px;border-radius:999px;
  border:2px solid var(--ink);margin-left:8px}
/* upcoming-card price: bare text pinned to the card's bottom-right (no pill);
   the text column reserves a line so wrapped copy can't collide with it */
.ev2-card-price{position:absolute;right:14px;bottom:12px;font-family:'Bungee','Bungee Fallback',sans-serif;
  font-size:12px;letter-spacing:.3px;color:var(--ink);white-space:nowrap}
.ev2-card:has(.ev2-card-price) .ev2-card-text{padding-bottom:16px}
.ev2-empty{font-size:1rem;line-height:1.5;color:#3A2F20;background:var(--parchment);
  padding:20px 22px;border-radius:12px;border:2px dashed rgba(20,17,12,.28)}
.ev2-empty a{color:var(--brand-blue);font-weight:700}

.ev2-seeall{margin:28px 0 0}
.ev2-seeall-btn{display:inline-flex;align-items:center;gap:10px;cursor:pointer;
  font-family:'Bungee','Bungee Fallback',sans-serif;font-size:14px;letter-spacing:.5px;color:var(--brand-blue);
  background:none;border:none;padding:6px 2px}
.ev2-seeall-btn span{transition:transform .16s}
.ev2-seeall-btn:hover span,.ev2-seeall-btn:focus-visible span{transform:translateX(5px)}

/* ── CALENDAR ──────────────────────────────────────────────────────────── */
.ev2-calwrap{min-width:0}
.ev2-cal{background:var(--cream);border:3px solid var(--ink);border-radius:16px;
  box-shadow:var(--shadow-hard);padding:20px 18px}
.ev2-cal-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}
.ev2-cal-label{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:17px;color:var(--ink)}
.ev2-cal-nav{cursor:pointer;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:20px;line-height:1;
  color:var(--ink);background:#fff;width:40px;height:40px;display:inline-flex;
  align-items:center;justify-content:center;border-radius:9px;border:2px solid var(--ink);
  box-shadow:2px 2px 0 var(--ink);transition:transform .12s}
.ev2-cal-nav:hover,.ev2-cal-nav:focus-visible{transform:translate(-1px,-1px)}
.ev2-cal-nav:active{transform:translate(2px,2px)}
.ev2-cal-nav[disabled]{opacity:.4;cursor:default;pointer-events:none;box-shadow:1px 1px 0 var(--ink)}
.ev2-cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:5px}
.ev2-cal-wd{text-align:center;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:11px;letter-spacing:.3px;
  color:var(--brown-tint);padding-bottom:4px}
.ev2-cal-cell{aspect-ratio:1;display:flex;align-items:center;justify-content:center;
  font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:600;font-size:14px;color:#3A2F20;
  border:none;background:none;border-radius:50%;padding:0}
.ev2-cal-cell.is-blank{visibility:hidden}
.ev2-cal-cell.is-today{outline:2px solid var(--brand-purple);outline-offset:-2px}
button.ev2-cal-cell{cursor:pointer}
.ev2-cal-cell.is-event{background:var(--brand-gold);color:var(--ink);font-weight:800;
  border:2px solid var(--ink);transition:transform .12s}
.ev2-cal-cell.is-event:hover,.ev2-cal-cell.is-event:focus-visible{transform:scale(1.08)}
.ev2-cal-cell.is-selected{background:var(--brand-blue);color:#fff;border-color:var(--ink)}

/* day panel — events on the selected day */
.ev2-daypanel{margin-top:14px}
.ev2-daypanel:empty{display:none}
.ev2-daypanel h3{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:15px;color:var(--ink);margin:0 0 10px}
.ev2-daypanel ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
.ev2-daypanel li{background:var(--parchment);border:2px solid rgba(20,17,12,.18);border-radius:11px;
  padding:12px 14px;display:flex;flex-direction:column;gap:4px}
.ev2-daypanel li b{font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:800;font-size:.95rem;color:var(--ink)}
.ev2-daypanel li span{font-size:.85rem;color:#3A2F20}
.ev2-daypanel .ev2-price{margin-left:0;align-self:flex-start;margin-top:2px}
.ev2-daypanel li{cursor:pointer}
.ev2-daypanel li:hover{border-color:var(--ink)}
.ev2-daypanel li:focus-visible{outline:3px solid var(--brand-blue);outline-offset:2px}

/* ── SEE ALL EVENTS — week modal ───────────────────────────────────────── */
.ev2-modal{position:fixed;inset:0;z-index:200;display:flex;align-items:center;justify-content:center;
  padding:20px}
.ev2-modal[hidden]{display:none}
.ev2-mod-backdrop{position:absolute;inset:0;background:rgba(20,17,12,.55)}
.ev2-mod-card{position:relative;z-index:1;width:100%;max-width:560px;max-height:80vh;overflow-y:auto;
  background:var(--cream);border:3px solid var(--ink);border-radius:16px;
  box-shadow:0 18px 40px rgba(20,17,12,.4);padding:28px 24px 24px}
.ev2-mod-x{position:absolute;top:14px;right:14px;cursor:pointer;font-size:16px;line-height:1;
  color:var(--ink);background:#fff;width:40px;height:40px;display:inline-flex;
  align-items:center;justify-content:center;border-radius:9px;border:2px solid var(--ink);
  box-shadow:2px 2px 0 var(--ink);transition:transform .12s}
.ev2-mod-x:hover,.ev2-mod-x:focus-visible{transform:translate(-1px,-1px)}
.ev2-mod-card h2{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:22px;color:var(--ink);margin:0 0 16px}
.ev2-mod-nav{display:flex;align-items:center;gap:8px;margin-bottom:18px;flex-wrap:wrap}
.ev2-mod-nav button{cursor:pointer;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:14px;color:var(--ink);
  background:#fff;min-width:38px;height:38px;padding:0 10px;display:inline-flex;
  align-items:center;justify-content:center;border-radius:9px;border:2px solid var(--ink);
  box-shadow:2px 2px 0 var(--ink);transition:transform .12s}
.ev2-mod-nav button:hover,.ev2-mod-nav button:focus-visible{transform:translate(-1px,-1px)}
.ev2-mod-nav .ev2-mod-this{flex:1;background:var(--brand-blue);color:#fff;font-size:12px}
.ev2-mod-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
.ev2-mod-list li{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  background:var(--parchment);border:2px solid rgba(20,17,12,.18);border-radius:11px;padding:12px 14px}
.ev2-mod-date{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:12px;color:#fff;background:var(--brand-purple);
  padding:5px 10px;border-radius:7px;flex:0 0 auto}
.ev2-mod-list li b{font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:800;font-size:.92rem;color:var(--ink);
  flex:1;min-width:120px}
.ev2-mod-time{font-size:.82rem;color:#3A2F20;flex:0 0 auto}
.ev2-mod-list .ev2-price{margin-left:0}
.ev2-mod-list li{cursor:pointer}
.ev2-mod-list li:hover{border-color:var(--ink)}
.ev2-mod-list li:focus-visible{outline:3px solid var(--brand-blue);outline-offset:2px}
.ev2-mod-list .ev2-mod-empty{cursor:default}
.ev2-mod-empty{justify-content:center;color:#3A2F20;font-size:.95rem}

/* ── EVENT DETAIL — pop-up view inside the events modal ────────────────── */
.ev2-det{display:flex;flex-direction:column;gap:14px}
/* three-track grid: back | date·time (true-centered) | close ✕. The 1fr side
   tracks are equal, so the auto center track sits at the card's true midpoint
   regardless of the two buttons' differing widths. */
.ev2-det-top{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  gap:8px;min-height:40px}
.ev2-det-back{justify-self:start;white-space:nowrap}
/* the date·time between the buttons — centered, shrinks on narrow screens */
.ev2-det-when{justify-self:center;text-align:center;min-width:0;
  font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:800;color:var(--ink);
  font-size:clamp(11px,2.6vw,14px);white-space:nowrap}
/* on phones the back label would crowd the centered date, so the back button
   collapses to just the ‹ glyph (its aria-label keeps it accessible) */
@media(max-width:520px){
  .ev2-det-back-lbl{display:none}
  .ev2-det-back{min-width:40px;padding:0}
}
/* in the detail view the close ✕ sits in-flow on the same line as the back
   arrow (not pinned to the card corner like the list view's absolute ✕) */
.ev2-det-top .ev2-mod-x{position:static;top:auto;right:auto;justify-self:end}
/* back arrow — same slap button as .ev2-mod-nav, glyph only */
.ev2-det-back{cursor:pointer;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:16px;line-height:1;
  color:var(--ink);background:#fff;min-width:40px;height:40px;padding:0 12px;
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  border-radius:9px;border:2px solid var(--ink);box-shadow:2px 2px 0 var(--ink);
  transition:transform .12s}
.ev2-det-back:hover,.ev2-det-back:focus-visible{transform:translate(-1px,-1px)}
.ev2-det-back:active{transform:translate(2px,2px)}
.ev2-det-media{width:100%;aspect-ratio:16/9;border-radius:12px;overflow:hidden;
  border:2px solid var(--ink);background:var(--parchment)}
.ev2-det-media img{width:100%;height:100%;object-fit:cover;display:block}
.ev2-det-tag{align-self:flex-start;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:11px;
  letter-spacing:.06em;color:#fff;background:var(--brand-purple);
  padding:5px 10px;border-radius:7px}
.ev2-det-meta{display:flex;align-items:baseline;justify-content:space-between;
  gap:12px;flex-wrap:wrap}
.ev2-det-price{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:14px;color:var(--brand-blue)}
.ev2-det-name{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:20px;line-height:1.15;
  color:var(--ink);margin:0;overflow-wrap:anywhere}
.ev2-det-desc{font-size:.95rem;line-height:1.5;color:#3A2F20;margin:0;overflow-wrap:anywhere}
.ev2-det-addr{display:inline-flex;align-items:center;gap:6px;
  font-size:.9rem;color:var(--brand-blue);text-decoration:none;font-weight:700}
.ev2-det-addr:hover,.ev2-det-addr:focus-visible{text-decoration:underline}
/* anniversary-only closing CTA in the detail pop-up (gold, matches the card) */
.ev2-det-page{align-self:flex-start;margin-top:2px;font-size:13px;padding:12px 18px}
@media(max-width:480px){
  .ev2-det-name{font-size:18px}
  .ev2-det-media{aspect-ratio:4/3}
}

/* entrance — subtle, transform/opacity only, off under reduced motion */
@media(prefers-reduced-motion:no-preference){
  .ev2-card{animation:ev2-rise .4s ease-out both}
  .ev2-card:nth-child(2){animation-delay:.06s}
  .ev2-card:nth-child(3){animation-delay:.12s}
  @keyframes ev2-rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}

  /* pre-release "stamp" entrance: card rises, then the ribbon tab + gold date
     badge land a beat later with a small overshoot, like a sticker pressed
     onto the card. Shared .ev2-det-tag reuses the same stamp inside the
     detail pop-up (which has no other entrance motion of its own). */
  .ev2-featured{animation:ev2-feat-rise .5s ease-out both}
  .ev2-feat-tab{animation:ev2-stamp .42s ease-out both;animation-delay:.22s}
  .ev2-feat-datebadge{animation:ev2-stamp .42s ease-out both;animation-delay:.3s}
  .ev2-det-tag{animation:ev2-stamp .42s ease-out both;animation-delay:.1s}
  @keyframes ev2-feat-rise{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
  @keyframes ev2-stamp{
    0%{opacity:0;transform:translateY(-10px) scale(.75) rotate(-6deg)}
    55%{opacity:1;transform:translateY(1px) scale(1.06) rotate(2deg)}
    100%{opacity:1;transform:translateY(0) scale(1) rotate(0deg)}
  }

  /* homepage hero: the "SAY HEY!" greeter badge takes over as a pre-release
     announcement (app.js renderHome()). Same stamp shape as .ev2-stamp above,
     but with translateX(-50%) composed into every step — the badge's resting
     transform centers it on its anchor (left:50%), so a bare reuse of
     .ev2-stamp would snap it off-center mid-animation. gb-wiggle then loops:
     still for ~92% of each cycle, one quick double-rotate flick near the end,
     a periodic nudge rather than continuous motion. */
  .greeter-badge.gb-announce{
    animation: gb-stamp .42s ease-out both, gb-wiggle 5.6s ease-in-out .5s infinite;
  }
  @keyframes gb-stamp{
    0%  {opacity:0; transform:translateX(-50%) translateY(-10px) scale(.75) rotate(-6deg)}
    55% {opacity:1; transform:translateX(-50%) translateY(1px)  scale(1.06) rotate(2deg)}
    100%{opacity:1; transform:translateX(-50%) translateY(0)    scale(1)    rotate(0deg)}
  }
  @keyframes gb-wiggle{
    0%,92%,100%{transform:translateX(-50%) rotate(0deg)  scale(1)}
    94%        {transform:translateX(-50%) rotate(-4deg) scale(1.04)}
    96%        {transform:translateX(-50%) rotate(3deg)  scale(1.04)}
    98%        {transform:translateX(-50%) rotate(-2deg) scale(1)}
  }
}

/* ── RESPONSIVE ────────────────────────────────────────────────────────── */
@media(max-width:960px){
  .ev2-hero-grid{grid-template-columns:1fr;gap:28px}
}
@media(max-width:860px){
  .ev2-grid{grid-template-columns:1fr;gap:26px}
  .ev2-calwrap{order:-1}
}
@media(max-width:560px){
  .ev2-hero{padding:44px 0 32px}
  /* featured card is poster-stacked at every width now (see .ev2-featured base) */
  .ev2-card>img{width:31.9%;min-width:110px}
  .ev2-card .ev2-card-body{margin-left:max(31.9%,110px)}
  .ev2-card-body{flex-direction:column;gap:12px}
  /* stay in the same stacked column as desktop (per the mockup) — a row
     layout here pushed the wider time pill off the edge of the phone screen */
  .ev2-datecol{align-self:flex-start}
  .ev2-date i{font-size:22px}
  /* 40px min tap targets for calendar day cells at phone widths */
  .ev2-cal{padding:14px 6px}
  .ev2-cal-grid{gap:3px}
}

/* ============================== LEGAL PAGES (privacy / terms / shipping / a11y)
   These sit on the STANDARD parchment page background (same as home/store/
   events), not the About mural — and drop the gradient headline for a solid,
   professional look (Jin). .lg-page intentionally does NOT use .ab-page, so
   the body:has(.ab-page) dark scrim never applies here. */
.lg-page .ab-title{color:var(--ink);text-shadow:none}
.lg-page .ab-grad{background:none;-webkit-background-clip:initial;background-clip:initial;
  -webkit-text-fill-color:var(--blue-deep);color:var(--blue-deep);filter:none}
.lg-page .ab-lede{color:#5A4A36;text-shadow:none}
.lg-hero{padding-bottom:14px}
.lg-sec{padding:10px 0 64px}
.lg-body{max-width:760px;font-size:15.5px;line-height:1.68;font-weight:500;color:#3A2F21}
.lg-body h2{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:clamp(17px,2.4vw,21px);letter-spacing:.4px;
  text-transform:uppercase;color:var(--ink);margin:34px 0 10px;
  padding-bottom:8px;border-bottom:3px solid var(--blue)}
.lg-body p{margin:0 0 14px}
.lg-body ul{margin:0 0 14px;padding-left:22px}
.lg-body li{margin-bottom:6px}
.lg-body b{color:var(--ink)}
.lg-body a{color:var(--blue-deep);font-weight:700;text-decoration:underline;text-underline-offset:2px}
.lg-updated{font-size:13px;letter-spacing:.3px;text-transform:uppercase;color:#8A7A5F;margin-bottom:22px}
.lg-note{font-size:13px;color:#8A7A5F;margin-top:30px}
/* footer disclaimer line (trademarks + pricing) under the copyright row */
.foot-disclaimer{display:block;padding:0 0 26px;margin-top:-16px;font-size:11.5px;line-height:1.6;color:#6E6350;max-width:860px}
.foot-disclaimer a{color:#8C8069;text-decoration:underline;text-underline-offset:2px}
.foot-disclaimer a:hover{color:#fff}
.lg-body h3{font-family:'Rubik','Rubik Fallback',sans-serif;font-weight:800;font-size:1.02rem;color:var(--ink);margin:20px 0 6px}

/* PDP shipping & returns — collapsed <details>, styled like the specs card */
.pdp-policy{margin-top:24px;background:var(--paper);border:var(--die) solid #fff;outline:var(--keyline) solid var(--ink);
  border-radius:14px;box-shadow:var(--shadow);padding:0;overflow:hidden}
.pdp-policy summary{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;
  gap:12px;padding:16px 20px;font-family:'Bungee','Bungee Fallback',sans-serif;font-size:15px;color:var(--blue-deep)}
.pdp-policy summary::-webkit-details-marker{display:none}
.pdp-policy-caret{transition:transform .15s;font-size:13px}
.pdp-policy[open] .pdp-policy-caret{transform:rotate(180deg)}
.pdp-policy[open] summary{border-bottom:3px solid var(--blue)}
.pdp-policy-body{padding:14px 20px 18px;font-size:0.93rem;line-height:1.6;color:#4A3E2E}
.pdp-policy-body h3{font-family:'Bungee','Bungee Fallback',sans-serif;font-size:13px;color:var(--blue-deep);margin:16px 0 6px}
.pdp-policy-body p{margin:0 0 10px}
.pdp-policy-body p:last-child{margin-bottom:0}
.pdp-policy-body b{color:var(--ink)}
.pdp-policy-body a{color:var(--blue-deep);font-weight:700;text-decoration:underline;text-underline-offset:2px}
@media(prefers-reduced-motion:reduce){.pdp-policy-caret{transition:none}}

/* ── Cart chrome (flag-gated; ships hidden) ─────────────────────── */
/* CRITICAL: .nav-link/.header-tool/.m-link set their own display, which
   outranks the UA's [hidden]{display:none} (styles.css documents this
   footgun at the filter-list rules). Without this rule the cart chrome is
   VISIBLE on flag-off production. */
.nav-cart[hidden] { display: none !important; }
.nav-cart { position: relative; }
/* same footgun as .nav-cart: the badge's own display would beat UA [hidden],
   leaving a permanent "0" pill on an empty cart when checkout is enabled */
.cart-badge[hidden] { display: none !important; }
.cart-badge {
  display: inline-grid; place-items: center;
  min-width: 18px; height: 18px; padding: 0 4px;
  border-radius: 999px;
  background: var(--brand-red); color: #fff;
  font: 700 11px/1 var(--font-body);
}
/* bare cart icon — deliberately unboxed (desktop nav + mobile header slot).
   The badge overlaps the icon's top-right corner. */
.nav-cart-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex: 0 0 auto;
  color: var(--paper); text-decoration: none;
  transition: transform .2s ease-out, color .18s;
}
.nav-cart-icon svg { width: 26px; height: 26px; }
.nav-cart-icon:hover, .nav-cart-icon:focus-visible { color: var(--yellow); transform: translateY(-2px); }
.nav-cart-icon:focus-visible { outline: 2px solid var(--yellow); outline-offset: 2px; border-radius: 8px; }
.nav-cart-icon:active { transform: translateY(1px); }
.nav-cart-icon .cart-badge { position: absolute; top: 0; right: 0; }
/* mobile slot keeps .header-tool for layout/visibility but sheds its box */
.header-tool.nav-cart,
.header-tool.nav-cart:hover, .header-tool.nav-cart:focus-visible, .header-tool.nav-cart:active {
  background: none; border: 0; box-shadow: none;
}
.header-tool.nav-cart { color: var(--paper); }
.header-tool.nav-cart:hover, .header-tool.nav-cart:focus-visible { color: var(--yellow); }
.header-tool.nav-cart svg { width: 26px; height: 26px; }
/* PDP add-to-cart: content-hugging, first in the visit-actions row — primary
   by position and icon, same height as its sibling (a stretched full-width
   bar reads as a banner, not a button). Mobile ≤560px stacks it full-width
   via the existing .visit-actions column rule. */
.cart-add { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-width: 200px; }
.cart-add svg { width: 19px; height: 19px; flex: 0 0 auto; }
.cart-add:disabled { opacity: .55; cursor: default; }
.cart-add:disabled:hover { transform: none; }
/* fly-to-cart ghost + cart-icon landing pop (transform/opacity only) */
.cart-fly {
  position: fixed; z-index: 300; pointer-events: none;
  object-fit: cover; border-radius: 10px;
  box-shadow: 0 4px 14px rgba(0,0,0,.35);   /* static — never animated */
  will-change: transform, opacity;
}
.nav-cart-icon.cart-pop { animation: cartPop .4s cubic-bezier(.34,1.56,.64,1); }
@keyframes cartPop { 0% { transform: scale(1); } 45% { transform: scale(1.35); } 100% { transform: scale(1); } }
@media (prefers-reduced-motion: reduce) {
  .nav-cart-icon.cart-pop { animation: none; }
}
/* live "N in your cart · See in cart" line under the PDP button row */
.cart-inline-status { margin: 10px 0 0; font-size: 13.5px; font-weight: 600; color: var(--brand-brown); }
.cart-inline-status .cis-check { color: var(--vib-green); font-weight: 800; }
.cart-inline-status a { color: var(--blue-deep); font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }
/* Small phones + visible cart = 4 header items: tighten the row so the
   hamburger doesn't wrap to a second line. Scoped with :has() to a VISIBLE
   cart so flag-off production renders byte-identically to today (safety
   invariant); pre-:has browsers just keep the wrap fallback. */
@media (max-width: 430px) {
  .bar-inner:has(.nav-cart:not([hidden])) { gap: 8px; padding: 10px 12px; }
  .bar-inner:has(.nav-cart:not([hidden])) .brand { gap: 8px; }
  .bar-inner:has(.nav-cart:not([hidden])) .brand .logo { width: 40px; height: 40px; }
  .bar-inner:has(.nav-cart:not([hidden])) .wordmark { font-size: 19px; }
  .bar-inner:has(.nav-cart:not([hidden])) .header-tool.nav-cart { width: 36px; }
}

/* ── Cart page ──────────────────────────────────────────────────── */
/* sticky footer: .cart-screen (header + cart main, cart.html) always fills
   one viewport, so the footer starts at the fold whether the cart holds 0
   items or 3 — the page only grows (and scrolls) when the cart is long */
.cart-screen { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }
.cart-screen .cart-wrap { flex: 1 0 auto; width: 100%; }
/* .wrap has no bottom padding (other pages end in their own spaced
   sections); without this the summary card sits flush on the footer */
.cart-wrap { max-width: 980px; padding-bottom: 64px; }
.cart-count { margin: -8px 0 16px; font-weight: 700; font-size: 14px; color: var(--brand-brown); }
.cart-each { font-size: 12px; font-weight: 600; color: var(--brand-brown); }
.qty-max-note { font-size: 11px; font-weight: 700; color: var(--brand-brown); }
.cart-layout { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 20px; align-items: start; }
.cart-lines { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.cart-line {
  display: grid; grid-template-columns: 72px minmax(0, 1fr) auto; gap: 12px; align-items: center;
  background: var(--parchment); border: var(--keyline) solid var(--ink);
  border-radius: var(--r-card); padding: 12px;
}
.cart-line.has-issue { outline: 3px dashed var(--sold-out); outline-offset: -6px; }
.cart-thumb { width: 72px; height: 96px; object-fit: cover; border-radius: 8px; background: #fff; }
.cart-line-info { display: grid; gap: 4px; justify-items: start; }
.cart-line-name { font-weight: 700; color: var(--ink); text-decoration: none; }
.cart-line-name:hover { text-decoration: underline; }
.cart-fmt { font-size: 12px; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: var(--parchment-deep); }
.cart-price { font-weight: 800; color: var(--price); }
.cart-issue { font-size: 13px; font-weight: 600; color: var(--sold-out); }
.cart-issue-ok { border: 2px solid var(--ink); background: #fff; border-radius: 8px; padding: 2px 10px; font-weight: 700; cursor: pointer; }
.cart-line-tools { display: grid; gap: 8px; justify-items: end; }
.qty-step { display: inline-flex; align-items: center; border: 2px solid var(--ink); border-radius: 999px; background: #fff; }
.qty-step button {
  width: 44px; height: 44px; border: 0; background: none;
  font: 800 18px/1 var(--font-body); cursor: pointer;
}
.qty-step button:disabled { opacity: .35; cursor: default; }
.qty-n { min-width: 24px; text-align: center; font-weight: 800; }
.cart-remove {
  border: 0; background: none; font: 600 13px var(--font-body);
  color: var(--brand-brown); cursor: pointer; min-height: 44px;
  display: inline-flex; align-items: center; gap: 5px;
}
.cart-remove svg { width: 12px; height: 12px; }
.cart-remove:hover, .cart-remove:focus-visible { color: var(--sold-out); text-decoration: underline; }
.fulfill-pick { display: grid; gap: 8px; }
.fulfill-opt {
  display: grid; gap: 2px; justify-items: start; text-align: left;
  border: 2px solid var(--ink); border-radius: 12px; background: #fff;
  padding: 10px 12px; cursor: pointer; font-family: var(--font-body); min-height: 44px;
}
.fulfill-opt b { font-size: 14px; letter-spacing: .03em; }
.fulfill-opt span { font-size: 12px; color: var(--brand-brown); }
/* selected = blue, matching the PDP variant pills' active state — gold is
   reserved for the commerce actions (add-to-cart / checkout) */
.fulfill-opt.is-on { border-color: var(--ink); background: var(--blue); }
.fulfill-opt.is-on b { color: #fff; }
.fulfill-opt.is-on span { color: #E8EFFA; }
.ship-speed { display: grid; gap: 8px; }
.speed-opt { margin-left: 0; }
/* progressive delivery accordion: the box owns the border; the selected
   option's body unfolds inside it */
.fulfill-box { border: 2px solid var(--ink); border-radius: 12px; background: #fff; min-width: 0; }
.fulfill-box > .fulfill-opt { border: 0; border-radius: 10px; width: 100%; }
.fulfill-box.is-open > .fulfill-opt { border-radius: 10px 10px 0 0; }
.fulfill-body { border-top: 2px solid var(--ink); padding: 12px; display: grid; gap: 10px; background: var(--paper); border-radius: 0 0 10px 10px; }
.co-sub-head { font-family: var(--font-display); font-size: 13px; letter-spacing: .5px; margin: 4px 0 0; }
.co-sub-head:first-child { margin-top: 0; }

/* ---- split-ledger money pages (cart + checkout) — spec 2026-07-20 ----
   The ink-black "ledger" panel pins LEFT and tells the money story; the
   working surface (items / form cards) breathes on the right. The ledger
   is a brand moment (nav-black), not a dark theme. */
.ledger-layout { display: grid; grid-template-columns: minmax(260px, 1fr) 1.6fr; gap: 18px; align-items: start; }
.ledger {
  background: var(--paper); color: var(--ink); border: var(--keyline) solid var(--ink);
  border-radius: var(--r-card); box-shadow: 0 5px 0 rgba(20, 17, 12, .15);
  padding: 16px; display: grid; gap: 10px; position: sticky; top: 12px;
}
.ledger-row { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; font-size: 14px; }
.ledger-total { border-top: 2px solid var(--ink); padding-top: 10px; font-size: 17px; font-weight: 900; }
.ledger-total b { font-size: 19px; }
.ledger-note { margin: 0; font-size: 12px; color: var(--brand-brown); }
.ledger-note a { color: var(--blue-deep); }
/* over-limit purchase notice: formal, bordered, reads as policy not chatter */
.ledger-notice {
  border: 1.5px solid var(--ink); border-radius: 10px;
  padding: 10px 12px; margin: 2px 0;
  font-size: 12.5px; line-height: 1.55; color: var(--ink);
  background: var(--parchment-deep);
}
.ledger-notice b {
  display: block; font-size: 11px; letter-spacing: .08em;
  text-transform: uppercase; margin-bottom: 4px;
}
.ledger-notice a { color: var(--blue-deep); white-space: nowrap; }
/* PDP variant of the notice: leads the visit-panel CTA area */
.pdp-instore-note { margin: 12px 0 4px; }
/* disabled CTAs (over-limit cart, in-flight pay): fully inert — no hover
   lift, no press animation, no anime is-hot pop. pointer-events:none keeps
   the JS hover system from ever seeing the element. The server re-validates
   every request regardless — this styling is honesty, not the security. */
.btn-slap:disabled,
.btn-slap:disabled:hover,
.btn-slap:disabled:focus-visible,
.btn-slap:disabled:active,
.js-anime-hover .btn-slap:disabled,
.js-anime-hover .btn-slap:disabled.is-hot {
  opacity: .45; filter: grayscale(1); cursor: not-allowed; pointer-events: none;
  transform: none; box-shadow: var(--sb-inset-tint); transition: none;
}
.ledger .co-items { padding-bottom: 8px; border-bottom: 1px solid var(--parchment-deep); }
.ledger .co-item img { border: 1.5px solid var(--ink); border-radius: 4px; }
.ledger-handoff { margin: 2px 0 0; font-size: 11.5px; color: var(--brand-brown); text-align: center; line-height: 1.45; }
.ledger-cta, .ledger-cta:hover {
  display: block; text-align: center; margin-top: 2px;
  background: var(--orange); color: var(--ink); border-color: var(--ink);
  box-shadow: 0 4px 0 var(--ink), 0 0 20px rgba(224, 165, 38, .45);
}
.ledger-cta:hover { background: var(--orange-bright); }
.ledger-cta:disabled { opacity: .55; box-shadow: 0 4px 0 var(--ink); }
.ship-meter { background: #FCF3DC; border: 2px solid var(--orange); border-radius: 10px; padding: 8px 10px; font-size: 12px; line-height: 1.35; }
.ship-meter b { color: var(--ink); font-weight: 700; }
.meter-track { height: 8px; background: #EDE2C8; border: 1.5px solid var(--ink); border-radius: 6px; overflow: hidden; margin-top: 6px; }
.meter-fill { height: 100%; background: linear-gradient(90deg, var(--gold-deep), var(--orange-bright)); }
.info-pills { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; margin-top: 22px; }
.info-pills a {
  border: 2px solid var(--ink); border-radius: 999px; padding: 9px 18px;
  font-weight: 700; font-size: 13px; color: var(--ink); background: #fff; text-decoration: none;
}
.info-pills a:hover { background: var(--gold-tint); }
.wallet-badges { display: flex; gap: 6px; justify-content: center; flex-wrap: wrap; }
.wallet-badges span {
  border: 1.5px solid var(--ink); border-radius: 6px; background: #fff; color: var(--ink);
  font-size: 10.5px; font-weight: 800; padding: 3px 8px;
}
.co-ledger-wrap { position: sticky; top: 12px; display: grid; gap: 10px; min-width: 0; }
.co-ledger-wrap .ledger { position: static; }
.co-ledger-bar { display: none; }
@media (min-width: 900px) {
  /* the mobile expander sets [hidden]; desktop always shows the ledger */
  .ledger[hidden] { display: grid; }
}
@media (max-width: 899px) {
  .ledger-layout { grid-template-columns: 1fr; }
  .ledger { position: static; }
  .co-ledger-wrap { position: static; }
  .co-ledger-bar {
    display: flex; justify-content: space-between; align-items: center; width: 100%;
    background: var(--paper); color: var(--ink); border: var(--keyline) solid var(--ink);
    border-radius: var(--r-card); padding: 12px 14px; font-weight: 800; font-size: 14px;
    font-family: var(--font-body); cursor: pointer; box-shadow: 0 4px 0 rgba(20, 17, 12, .15);
  }
  .co-ledger-bar b { color: var(--gold-deep); }
  .ledger[hidden] { display: none; }
}
.cart-checkout { width: 100%; }
.cart-err { margin: 0; font-size: 14px; font-weight: 600; color: var(--sold-out); }

/* ---- CHECKOUT page (professional two-column: steps left, summary right) ---- */
.co-main { display: grid; gap: 16px; min-width: 0; align-content: start; }
.co-step {
  background: var(--parchment); border: var(--keyline) solid var(--ink);
  border-radius: var(--r-card); padding: 16px; display: grid; gap: 12px; min-width: 0;
}
.co-step-head { font-family: var(--font-display); font-size: 16px; margin: 0; }
.co-pickup-note { margin: 0; font-size: 13px; color: var(--brand-brown); }
.co-edit { color: var(--blue-deep); font-weight: 700; }
.co-items { list-style: none; margin: 0; padding: 0 0 4px; display: grid; gap: 8px; }
.co-item { display: grid; grid-template-columns: 40px minmax(0, 1fr) auto; gap: 8px; align-items: center; font-size: 13px; }
.co-item img { border-radius: 6px; object-fit: cover; background: var(--photo-bg); }
.co-item-name { min-width: 0; overflow-wrap: anywhere; }
.co-item-name small { color: var(--brand-brown); font-weight: 700; white-space: nowrap; }
.ship-in[aria-invalid="true"] { border-color: var(--sold-out); }
.ship-field-err { color: var(--sold-out); font-size: 12px; font-weight: 700; }

/* SHIP TO fieldset — the step card is the visual container; the legend stays
   for screen readers only (the step heading carries the visible label) */
.ship-to { border: 0; padding: 0; margin: 0; display: grid; gap: 10px; min-width: 0; }
.ship-to-head {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
.ship-lab { display: grid; gap: 3px; font-size: 12px; font-weight: 700; color: var(--brand-brown); min-width: 0; position: relative; }
/* address-finder pop-up — anchored under the street input */
.ship-suggest {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 30; margin-top: 4px;
  background: #fff; border: 2px solid var(--ink); border-radius: 10px;
  box-shadow: 0 6px 0 rgba(20, 17, 12, .18); overflow: hidden; display: grid;
}
.ship-suggest[hidden] { display: none; }
.ship-suggest-item {
  display: block; width: 100%; text-align: left; cursor: pointer;
  font: 500 14px/1.35 var(--font-body); color: var(--ink);
  background: #fff; border: 0; border-bottom: 1px solid var(--parchment);
  padding: 10px 12px; min-height: 44px;
}
.ship-suggest-item:last-child { border-bottom: 0; }
.ship-suggest-item:hover, .ship-suggest-item[aria-selected="true"] { background: var(--gold-tint); }
.ship-in {
  min-height: 44px; padding: 8px 10px; font-family: var(--font-body); font-size: 16px;
  color: var(--ink); background: #fff; border: 2px solid var(--ink); border-radius: 8px;
  width: 100%; min-width: 0;
}
.ship-in:focus { outline: 3px solid var(--blue); outline-offset: 1px; }
.ship-duo { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.ship-row { display: grid; grid-template-columns: 130px minmax(0, 1fr) 90px; gap: 10px; }
@media (max-width: 820px) {
  .ship-duo { grid-template-columns: 1fr; }
  .ship-row { grid-template-columns: 104px minmax(0, 1fr) 76px; }
}

.cart-empty, .cart-done { text-align: center; display: grid; gap: 14px; justify-items: center; padding: 24px 0 48px; }
.sandbox-strip {
  background: repeating-linear-gradient(-45deg, #ffce31, #ffce31 14px, var(--ink) 14px, var(--ink) 28px);
}
.sandbox-strip { color: #fff; }
.sandbox-strip {
  text-align: center; font: 800 13px/1.2 var(--font-body);
  padding: 8px 12px; text-shadow: 0 1px 2px rgba(0,0,0,.85); letter-spacing: .04em;
}
@media (max-width: 820px) {
  .cart-layout { grid-template-columns: 1fr; }
  .cart-line { grid-template-columns: 56px minmax(0, 1fr); }
  .cart-thumb { width: 56px; height: 74px; }
  .cart-line-tools { grid-column: 1 / -1; grid-template-columns: auto auto; justify-content: space-between; width: 100%; }
}
