/* =============================================================================
   market.css — the INTELTRADE marketplace surface.

   WHAT THIS STYLES. A Getgems-shaped market: trending bar, filter rail, card
   grid. It reads the terminal's exact palette (mirrored into #it-tokens in
   index.html — see the comment there for why it is mirrored, not linked) and
   adds only marketplace-specific structure on top.

   RULES THIS FILE ENFORCES VISUALLY
   ---------------------------------
   * Every card carries a VENUE CHIP. Spec §5: no unlabelled inventory. The
     chip is styled, not optional — a card without one is a template bug.
   * OURS rows get emphasis (purple edge), never fabricated placement inside
     an explicit sort — that logic lives in market.js with its own comment.
   * Missing values render as an em-dash with a title, styled dim but PRESENT
     (spec §3 rule 1). There is no display:none for an unknown number.
   * prefers-reduced-motion kills the trending rotation, the needle sweep and
     every transition here. Motion is decoration on this page, never data.

   LAYOUT. Desktop/PC: FULL-BLEED — a 260px filter rail pinned left, a fluid
   grid that fills all remaining viewport width and grows column count on wide
   screens (no max-width cap on the shop). Under 720px: single column, the rail
   collapses behind a toggle button, the tester panel becomes a bottom sheet.
   Same DOM, CSS only.
   ========================================================================== */

/* ---------------------------------------------------------------------------
   0a · THEME MODES — TWO skins, pink/red identity. The whole marketplace is
   re-skinned by REDEFINING THE VALUES of the existing variable names (never
   renaming them), so every component below inherits the new palette for free.

   <html data-theme> drives it: "wtf" (the DEFAULT — soft blue→lavender pastel,
   frosted panels, deep-plum ink, pink+red brand) and "dark" (a real dark mode —
   deep near-black indigo canvas, light ink, same pink/red brand). The old
   light + blue/hashtag skins were removed 2026-08; stored 'light'/'hashtag'/
   legacy values migrate to 'wtf'. market.js owns the attribute + localStorage;
   the index.html inline #it-tokens carries the WTF values as first-paint default.

   TOKEN --on-accent: the text/ink colour placed ON a --p400 fill, per theme,
   AA-legible (white on the pink→red accent in both modes).

   HELPER TOKENS (theme-scoped so DARK is not just an inversion):
     --tint       accent tint for pressed / selected surfaces
     --tint-weak  faint accent wash behind section bands + headers
     --ring       focus glow ring
     --shadow-card lifted-card drop shadow (soft on wtf, deep on dark)
   ------------------------------------------------------------------------ */
/* BUBBLY DISPLAY FONT — Shrikhand (SIL OFL): heavy slightly-slanted BULBOUS
   SERIF, the closest OFL letterform to the /giftswtf-logo.png wordmark
   (Cooper-Black-like). Self-hosted woff2, CSP-clean (font-src 'self').
   Display headings only; the wordmark itself is the PNG. Weight declared as a
   RANGE so 700–900 requests use the face as-is (no synthetic bold). Fredoka
   stays as the self-hosted fallback face. */
@font-face{
  font-family:"Shrikhand"; font-style:normal; font-weight:400 900; font-display:swap;
  src:url(shrikhand.woff2) format("woff2");
}
@font-face{
  font-family:"Fredoka"; font-style:normal; font-weight:700; font-display:swap;
  src:url(fredoka-700.woff2) format("woff2");
}
@font-face{
  font-family:"Fredoka"; font-style:normal; font-weight:600; font-display:swap;
  src:url(fredoka-600.woff2) format("woff2");
}

:root {
  /* fallbacks if no data-theme is present yet — PASTEL default values */
  --font-bubble:"Shrikhand","Fredoka","Baloo 2","Arial Rounded MT Bold",system-ui,sans-serif;
  --on-accent:#FFFFFF;
  --tint: rgba(247,168,216,.30);
  --tint-weak: rgba(247,168,216,.15);
  --ring: rgba(224,57,43,.32);
  --shadow-card: rgba(74,60,120,.20);
  --page-bg:linear-gradient(120deg,#9EB4F2 0%,#B7ADF0 50%,#C9B7EF 100%);
}

/* WTF — the DEFAULT gifts.wtf look (soft blue→lavender canvas, frosted
   near-white panels, deep-plum ink, pink+red brand). This is what the site
   loads with; Dark is the one alternate toggle. */
:root[data-theme="wtf"] {
  color-scheme:light;
  --void:#E9E4FA; --panel:#FCFAFF; --raised:#FFFFFF; --hover:#F3EDFC; --well:#ECE6F8;
  --hairline:rgba(42,33,64,.14); --hairline-2:rgba(42,33,64,.26);
  --grid:#E4DBF4; --axis:#CFC2EA;
  --ink-hi:#2A2140; --ink-mid:#4A4166; --ink-lo:#7B7299; --ink-faint:#A79EC2;
  --p100:#FCE1F0; --p200:#F7A8D8; --p300:#F06AAE; --p400:#E0392B; --p500:#CB281D; --p600:#A81F16; --p700:#7A140E;
  --sweep:#B4790A; --gain:#12854B; --loss:#C42F36;
  --r1:#F7A8D8; --r2:#EF6FA9; --r3:#E0392B; --r4:#A81F16;
  --on-accent:#FFFFFF;
  --tint:rgba(247,168,216,.30); --tint-weak:rgba(247,168,216,.15);
  --ring:rgba(224,57,43,.32); --shadow-card:rgba(74,60,120,.20);
  --page-bg:linear-gradient(120deg,#9EB4F2 0%,#B7ADF0 50%,#C9B7EF 100%);
}

/* DARK — a real dark mode (not an inverted pastel). Deep near-black indigo
   canvas, light ink, the SAME pink/red brand accents, translucent-dark panels
   that stay readable; the mono belts, grid cards, terminal + headings are all
   legible. Surface vars go dark, ink vars go light; the ramp ends flip role:
   --p100 (light tint-fill in wtf) -> dark plum; --p600/--p700 (dark accent-text
   in wtf) -> light pinks so icons/labels/links stay legible on the dark canvas. */
:root[data-theme="dark"] {
  color-scheme:dark;
  --void:#0B0912; --panel:#171226; --raised:#1E1830; --hover:#271F3D; --well:#100C1C;
  --hairline:rgba(247,168,216,.15); --hairline-2:rgba(247,168,216,.30);
  --grid:rgba(255,255,255,.07); --axis:rgba(255,255,255,.16);
  --ink-hi:#F6F1FA; --ink-mid:#CFC4E4; --ink-lo:#9C8FC0; --ink-faint:#6E6194;
  --p100:#2A1424; --p200:#F7A8D8; --p300:#F06AAE; --p400:#F0493B; --p500:#E0392B; --p600:#F7A8D8; --p700:#FCE1F0;
  --sweep:#E7B23A; --gain:#3FD08A; --loss:#FF6B6B;
  --r1:#F7A8D8; --r2:#F06AAE; --r3:#F0493B; --r4:#FF8E80;
  --on-accent:#FFFFFF;
  --tint:rgba(247,168,216,.18); --tint-weak:rgba(247,168,216,.09);
  --ring:rgba(247,168,216,.42); --shadow-card:rgba(0,0,0,.55);
  --page-bg:radial-gradient(130% 100% at 50% -12%, #1C1436 0%, #0E0A1C 52%, #070510 100%);
}

/* .nascar heading: on DARK the wtf white top-shadow reads as grime — swap it
   for a soft red glow so the brand-red heading pops on the dark canvas. */
:root[data-theme="dark"] .nascar{
  color:var(--p300);
  text-shadow:0 1px 0 rgba(0,0,0,.5), 0 6px 22px rgba(240,73,59,.38);
}

/* selection colour follows the accent tint in every theme (was an implicit
   browser default that clashed in light mode). */
::selection { background: var(--tint); color: var(--ink-hi); }

/* ---------------------------------------------------------------------------
   0b · NASCAR — the display-heading treatment. Matches the PNG wordmark's
   bubbly-serif mood (Shrikhand via --font-bubble), solid brand red with a soft
   white lift for the frosted pastel panels. The pink-fill/red-outline look
   lives ONLY in the wordmark PNG; headings stay solid so the mark reads as
   the one brand mark. Applied to the .sec-tag section labels (HOT RIGHT NOW /
   TOP GIFTS…) and the section h2s (everything in one shop / GIFTS & GOATS…).
   ------------------------------------------------------------------------ */
.nascar {
  font-family: var(--font-bubble);
  font-weight: 700; font-style: normal; text-transform: uppercase;
  letter-spacing: .02em; line-height: .96;
  color: var(--p400);
  text-shadow:
    0 2px 0 rgba(255,255,255,.30),
    0 8px 22px rgba(224,57,43,.16);
}
/* section headers: huge and loud (bubbly serif, solid brand red) */
.sec-tag.nascar {
  font-size: clamp(30px, 5.5vw, 64px);
  letter-spacing: .01em; gap: 10px;
}
/* legacy compact brand line (old #brand block) — inherits the .nascar look */
.b-name.nascar {
  font-size: clamp(38px, 6vw, 70px);
  letter-spacing: .01em; line-height: 1;
  padding: 2px 14px 8px 2px;
  overflow: visible;
}

/* STOREFRONT-STYLE BRAND HEADER — mirrors theme.css .gw-brandbar so the main
   pages match the sub-shops: The Hashtag Network (left) · big centered gifts.wtf
   wordmark · Powered by $PYONYA (right). Replaces the old #topcredit strip. */
.gw-brandbar{ position:relative; z-index:200; display:flex; align-items:center; justify-content:space-between; gap:14px; padding:18px clamp(14px,3vw,40px) 6px; flex-wrap:wrap; }
.gw-net-wrap{ display:inline-flex; flex-direction:column; gap:2px; align-items:flex-start; }
.gw-clue{ color:var(--ink-faint); font-size:11px; letter-spacing:.02em; text-decoration:none; padding-left:26px; }
.gw-clue:hover{ color:var(--p400); }
.gw-net{ display:inline-flex; align-items:center; gap:8px; color:var(--ink-mid); font-weight:700; font-size:14px; text-decoration:none; }
.gw-net .b-hashicon{ width:18px; height:18px; border-radius:50%; }
.gw-net:hover{ color:var(--ink-hi); }
.gw-pyonya{ position:relative; display:inline-flex; align-items:center; gap:8px; color:var(--p400); font-weight:800; font-size:14px; text-decoration:none; white-space:nowrap; padding-bottom:2px; margin-right:104px; }
.gw-pyonya:hover{ color:var(--p500); }
@media (max-width:640px){ .gw-pyonya{ margin-right:0; } }
/* the $PYONYA pom mascot peeks off the bottom edge of the header, next to the
   "Powered by $PYONYA" line. */
/* the Pomeranian is drawn to grip a ledge (paws at the image bottom) — perch it
   on the header's bottom edge as a top layer, paws hanging over onto the row
   below. Absolute to the brandbar; pointer-events off so it never blocks the
   search row it overhangs. */
/* The art is tight-cropped so the PAWS sit at the image's own bottom edge
   (no transparent padding below them). bottom:0 anchors that paw-line to the
   brandbar's bottom edge; a small positive translateY drapes the paws just OVER
   the edge onto the row below, so it reads as gripping the header — flush, no
   float gap — on both desktop and mobile. height:auto keeps the cropped aspect. */
.gw-pom{
  position:absolute; z-index:6; right:16px; bottom:0;
  width:104px; height:auto; object-fit:contain;
  transform:translateY(16%);
  filter:drop-shadow(0 8px 10px rgba(0,0,0,.45));
  transition:transform .18s ease; pointer-events:none;
}
.gw-pyonya:hover .gw-pom{ transform:translateY(12%) rotate(-3deg); }
@media (max-width:640px){ .gw-pom{ width:80px; right:10px; transform:translateY(16%); } }
/* THE WORDMARK — /giftswtf-logo.png (2400×1350, transparent bg; the bg-removed
   first frame of the hero video): pink-fill / red-outline bubbly-serif
   GIFTS.WTF. The PNG carries huge transparent margins, so the link is a tight
   CROP BOX: .gw-wm-crop holds a fixed aspect via padding-top and the oversized
   centred <img> crops its margins away — glyphs span ~98% of the box width. */
.gw-wordmark{
  display:block; text-decoration:none; order:0; flex:0 1 auto;
  width:clamp(250px, 36vw, 520px);
  transition:transform .18s ease;
}
.gw-wordmark:hover{ transform:translateY(-1px) scale(1.01); }
.gw-wm-crop{
  display:block; position:relative; overflow:hidden;
  width:100%; height:0; padding-top:14%;          /* crop-box ≈ the glyph band */
}
.gw-wm-crop img{
  position:absolute; left:50%; top:50%;
  width:160%; max-width:none; height:auto;        /* glyphs span the box; margins crop */
  transform:translate(-50%,-50%);
}
@media (max-width:640px){ .gw-brandbar{ justify-content:center; gap:8px; } .gw-wordmark{ order:-1; flex-basis:100%; } }

/* ---------------------------------------------------------------------------
   0 · SKIP LINK — first tabbable thing on the page.
   ------------------------------------------------------------------------ */
.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--raised); color: var(--ink-hi);
  padding: 8px 14px; border-radius: 0 0 8px 0; z-index: 100;
}
.skip:focus { left: 0; }

/* ---------------------------------------------------------------------------
   1 · TOPBAR
   ------------------------------------------------------------------------ */
#topbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: 14px;
  padding: 10px 16px;
  background: var(--panel);
  border-bottom: 1px solid var(--hairline-2);
}

/* BRAND — the gifts.wtf wordmark stacked over a compact "powered by" line that
   carries the circular Hashtag Network mark. #brand is a column so the two
   lines sit tight; the mark is forced round with border-radius:50%. */
#brand { display: flex; flex-direction: column; justify-content: center; gap: 2px; white-space: nowrap; line-height: 1.1; }
.b-mark { color: var(--p400); font-size: 15px; text-shadow: 0 0 14px var(--ring); }
.b-name { color: var(--ink-hi); font-weight: 800; letter-spacing: .005em; font-size: 17px; line-height: 1; }
.b-powered { display: inline-flex; align-items: center; gap: 5px; color: var(--ink-lo); font-size: 9.5px; letter-spacing: .02em; line-height: 1; }
.b-hashicon { width: 14px; height: 14px; border-radius: 50%; flex: 0 0 auto; display: block; }
.b-by   { color: var(--ink-lo); font-size: 10px; letter-spacing: .06em; text-transform: uppercase; }
.b-name { text-decoration: none; display: inline-block; }

/* centered top-credit bar — powered by The Hashtag Network × $PYONYA */
#topcredit {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap;
  padding: 7px clamp(14px, 3vw, 40px); font-size: 12px;
  background: var(--panel); border-bottom: 1px solid var(--hairline);
  color: var(--ink-lo);
}
#topcredit .tc-lead { color: var(--ink-faint); }
#topcredit .tc-hash { display: inline-flex; align-items: center; gap: 6px; color: var(--ink-mid); font-weight: 700; }
#topcredit .tc-hash .b-hashicon { width: 16px; height: 16px; border-radius: 50%; }
#topcredit .tc-x { color: var(--ink-faint); }
#topcredit .tc-pyonya { color: var(--p400); font-weight: 800; text-decoration: none; }
#topcredit .tc-pyonya:hover { color: var(--p500); }

/* search — the shop's front door: a leading magnifier and a roomier, rounder
   field make it read as "browse here", not "enter a query". */
#searchwrap { position: relative; flex: 1 1 auto; min-width: 0; max-width: 520px; }
.s-icon {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  display: flex; color: var(--ink-lo); pointer-events: none;
}
#searchwrap:focus-within .s-icon { color: var(--p600); }
#q {
  width: 100%;
  background: var(--raised);
  border: 1px solid var(--hairline-2);
  border-radius: 10px;
  padding: 9px 12px 9px 36px;
  color: var(--ink-hi);
}
#q::placeholder { color: var(--ink-faint); }
#q:focus { border-color: var(--p500); box-shadow: 0 0 0 3px var(--ring); }

#topctl { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.ctl-label { color: var(--ink-lo); font-size: 11px; text-transform: uppercase; letter-spacing: .06em; }
#sort {
  background: var(--raised);
  border: 1px solid var(--hairline-2);
  border-radius: 8px;
  padding: 6px 8px;
  color: var(--ink-hi);
}
#sort:focus { border-color: var(--p500); }

#viewtoggle { display: flex; border: 1px solid var(--hairline-2); border-radius: 8px; overflow: hidden; }
#viewtoggle button { padding: 5px 10px; color: var(--ink-lo); font-size: 14px; line-height: 1; }
#viewtoggle button[aria-pressed="true"] { background: var(--hover); color: var(--ink-hi); }

/* TUTORIAL launcher (build #4) — a compact "? Tutorial" pill in the topbar.
   tutorial-gw.js opens the #gwTut slideshow on click; the "?" glyph is always
   there and the word "Tutorial" collapses away on narrow topbars. */
#gwTutStart {
  display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto;
  background: var(--raised);
  border: 1px solid var(--hairline-2);
  border-radius: 8px;
  padding: 5px 10px;
  color: var(--ink-mid); font-size: 12px; font-weight: 700;
  white-space: nowrap;
}
#gwTutStart:hover { border-color: var(--p500); color: var(--ink-hi); }
#gwTutStart .gts-q {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--p300); color: var(--on-accent);
  font-size: 11px; font-weight: 900; line-height: 1;
}

/* OURS-lane entry — exists only when the trade book answered the probe. */
#listWithUs {
  background: var(--p300);
  color: var(--on-accent);
  border: 1px solid var(--p500);
  border-radius: 8px;
  padding: 6px 12px;
  font-weight: 700;
  white-space: nowrap;
}
#listWithUs:hover { background: var(--p400); }

/* general guard: an element carrying [hidden] must stay hidden even when a
   later flex/grid rule would otherwise give it a display. The view wrappers
   and the compare bar rely on this. */
[hidden] { display: none !important; }

/* ---------------------------------------------------------------------------
   1b · TAB BAR — Getgems-style section switch under the topbar. Two in-page
   tabs (Gifts, Stats) + two link tabs to the sibling storefronts. Active state
   is a purple underline driven by aria-selected, so the highlight and the a11y
   state can never disagree. The tester FAB/panel are hidden on any non-Gifts
   tab here — the market.js switch only stamps body[data-tab].
   ------------------------------------------------------------------------ */
#tabbar {
  position: sticky; top: 58px; z-index: 29;   /* directly under the sticky topbar */
  display: flex; align-items: stretch; gap: 2px;
  padding: 0 12px;
  background: var(--panel);
  border-bottom: 1px solid var(--hairline-2);
  overflow-x: auto;
  scrollbar-width: none;
}
#tabbar::-webkit-scrollbar { display: none; }
.tab {
  display: inline-flex; align-items: center; gap: 7px;
  flex: 0 0 auto;
  padding: 11px 14px;
  color: var(--ink-lo);
  font-size: 13px; font-weight: 600;
  text-decoration: none; white-space: nowrap;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;                          /* sit on the bar's hairline */
}
.tab:hover { color: var(--ink-hi); }
.tab .tab-ic { color: var(--ink-faint); font-size: 13px; line-height: 1; }
.tab:hover .tab-ic { color: var(--p600); }
.tab[aria-selected="true"] {
  color: var(--ink-hi);
  border-bottom-color: var(--p400);
}
.tab[aria-selected="true"] .tab-ic { color: var(--p500); }

/* tester lives on the Gifts tab only — on ANY other tab (NFTs, Stats) both the
   FAB and the readout panel are removed from view (scanning a hidden grid is
   meaningless). Driven off the absence of the gifts tab so a new section never
   needs a new rule here, and the switch never reaches into tester.js's DOM. */
/* The diamond tester scans GIFTS — that's the main grid AND a collection's
   own items grid (#cvGrid), which opens under data-tab="collection". Allow both
   so you can scan on a collection page; still hidden on non-gift tabs. */
body:not([data-tab="gifts"]):not([data-tab="collection"]) #testerFab,
body:not([data-tab="gifts"]):not([data-tab="collection"]) #sniperFab,
body:not([data-tab="gifts"]):not([data-tab="collection"]) #tester { display: none !important; }

/* ---------------------------------------------------------------------------
   1c · HOME VIEW — the default landing. PURE marketing: the relocated
   super-animated hero + pillars (#gwLanding, skinned by landing.css) sits at
   the top; a "features & shops" showcase of animated cards sits below. No
   marketplace grid lives here. Theme-aware (all colours are tokens); cards are
   visible at rest and only ADD decorative motion, so reduced motion (§7) leaves
   them fully readable.
   ------------------------------------------------------------------------ */
#view-home { width: 100%; }

#homeShowcase { padding: 44px clamp(16px, 2vw, 40px) 96px; max-width: 1280px; margin: 0 auto; }
.hs-head { text-align: center; margin: 0 auto 26px; max-width: 640px; }
/* section h2s wear the wordmark's bubbly-serif family (higher specificity than
   .nascar, so the family/colour must be re-stated here) — solid brand red. */
.hs-head h2 {
  margin: 0 0 8px; font-size: clamp(24px, 3.6vw, 38px); line-height: 1.08;
  font-family: var(--font-bubble);
  font-weight: 700; letter-spacing: .02em; color: var(--p400);
}
.hs-head .hs-sub { margin: 0; color: var(--ink-lo); font-size: 14px; line-height: 1.5; }
.hs-head .hs-fee-flag { display: block; margin-top: 6px; color: var(--p700); font-weight: 800; letter-spacing: .01em; }

.hs-grid {
  display: grid; gap: 16px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.hs-card {
  position: relative; overflow: hidden; isolation: isolate;
  display: flex; flex-direction: column; align-items: flex-start;
  min-height: 176px; padding: 20px 20px 18px;
  border: 1px solid var(--hairline-2); border-radius: 18px;
  background:
    radial-gradient(120% 90% at 15% -10%, rgba(77,169,238,.10) 0%, transparent 55%),
    var(--panel);
  color: var(--ink-mid); text-decoration: none;
  box-shadow: 0 1px 0 rgba(255,255,255,.03) inset, 0 10px 28px -18px rgba(0,0,0,.6);
  transform: translateZ(0);
  transition: transform .32s cubic-bezier(.16,.8,.24,1),
              border-color .32s ease, box-shadow .32s ease;
  /* gentle continuous float — decorative only; §7 nukes it, card stays put */
  animation: hsFloat 7s ease-in-out infinite;
}
.hs-card.hs-c2 { animation-delay: -1.1s; }
.hs-card.hs-c3 { animation-delay: -2.3s; }
.hs-card.hs-c4 { animation-delay: -3.4s; }
.hs-card.hs-c5 { animation-delay: -4.6s; }
.hs-card.hs-c6 { animation-delay: -5.7s; }
@keyframes hsFloat {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}

.hs-card:hover, .hs-card:focus-visible {
  border-color: var(--p400);
  box-shadow: 0 1px 0 rgba(255,255,255,.05) inset, 0 18px 42px -20px rgba(77,169,238,.5);
}

/* sweeping sheen orb that drifts across the card */
.hs-glow {
  position: absolute; z-index: -1; top: -40%; left: -30%;
  width: 60%; height: 180%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(77,169,238,.22) 0%, transparent 70%);
  filter: blur(6px);
  animation: hsSweep 9s linear infinite;
  pointer-events: none;
}
.hs-c2 .hs-glow { animation-delay: -1.5s; }
.hs-c3 .hs-glow { animation-delay: -3s; }
.hs-c4 .hs-glow { animation-delay: -4.5s; }
.hs-c5 .hs-glow { animation-delay: -6s; }
.hs-c6 .hs-glow { animation-delay: -7.5s; }
@keyframes hsSweep {
  0%   { transform: translateX(0) rotate(8deg); opacity: 0; }
  15%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { transform: translateX(320%) rotate(8deg); opacity: 0; }
}

.hs-ic {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; margin-bottom: 14px;
  border-radius: 12px;
  background: linear-gradient(180deg, var(--raised), var(--hover));
  border: 1px solid var(--hairline-2);
  color: var(--p400); font-size: 20px; line-height: 1;
  transition: transform .32s cubic-bezier(.16,.8,.24,1), color .32s ease;
}
.hs-card:hover .hs-ic { transform: translateY(-2px) rotate(-6deg) scale(1.06); color: var(--p500); }

.hs-t { font-size: 16px; font-weight: 700; color: var(--ink-hi); margin-bottom: 6px; }
.hs-s { font-size: 12.5px; line-height: 1.5; color: var(--ink-lo); margin-bottom: 14px; }
.hs-s b { color: var(--ink-mid); font-weight: 700; }
.hs-go {
  margin-top: auto; font-size: 12px; font-weight: 700; letter-spacing: .02em;
  color: var(--p500);
  transition: color .3s ease, transform .3s ease;
}
.hs-card:hover .hs-go { color: var(--p600); transform: translateX(3px); }

/* GIFTS & GOATS — the demoted plug/obey/frag storefronts as a tidy secondary
   section (was the top-of-page landing hero). Reuses the .hs-* card tokens;
   this only adds the section frame, the payment line, and a centered 2-up grid
   so the pair reads as a compact storefront block, not a full-width showcase. */
#giftsGoats { padding: 8px clamp(16px, 2vw, 40px) 84px; max-width: 1280px; margin: 0 auto; }
#giftsGoats .gg-pay {
  margin: 12px 0 0; font-size: 12.5px; font-weight: 700; letter-spacing: .02em;
  color: var(--p400);
}
#giftsGoats .gg-grid {
  max-width: 760px; margin: 0 auto;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (max-width: 560px) { #giftsGoats .gg-grid { grid-template-columns: 1fr; } }

/* GIFTS & GOATS partner faces — the frag/plug/obey pfps + the Hashtag plush-pepe
   mascot, re-homed from the old top hero into a tidy avatar row under the
   section head. Frosted near-white chips with a pink -> red ring; partner chips
   link to their t.me, the mascot chip is brand-only (no link). Pure var() tokens
   so the ring tracks the active pastel theme; the soft glow is the red accent. */
#giftsGoats .gg-faces {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start;
  gap: clamp(18px, 4vw, 40px); margin: 18px auto 26px; max-width: 560px;
}
#giftsGoats .gg-face {
  display: flex; flex-direction: column; align-items: center; gap: 9px;
  text-decoration: none; color: var(--ink-hi);
}
#giftsGoats .gg-face-av {
  width: clamp(58px, 14vw, 78px); height: clamp(58px, 14vw, 78px);
  border-radius: 50%; overflow: hidden; background: var(--panel);
  border: 2.5px solid var(--p300);
  box-shadow: 0 0 0 4px var(--panel), 0 10px 26px rgba(224,57,43,.22);
  transition: border-color .18s ease, transform .18s ease, box-shadow .18s ease;
}
#giftsGoats .gg-face-av img { width: 100%; height: 100%; object-fit: cover; display: block; }
#giftsGoats a.gg-face:hover .gg-face-av,
#giftsGoats a.gg-face:focus-visible .gg-face-av {
  border-color: var(--p400); transform: translateY(-3px) scale(1.03);
  box-shadow: 0 0 0 4px var(--panel), 0 14px 32px rgba(224,57,43,.4);
}
#giftsGoats .gg-face-lbl { font-weight: 800; font-size: 13px; color: var(--ink-mid); letter-spacing: .01em; }
#giftsGoats a.gg-face:hover .gg-face-lbl,
#giftsGoats a.gg-face:focus-visible .gg-face-lbl { color: var(--p400); }
#giftsGoats .gg-face-mascot .gg-face-av { border-style: dashed; border-color: var(--p200); }

/* SCROLL-REVEAL — landing.js tags the section head + cards with .gw-sr on load,
   then adds .gw-sr-in (staggered) as each section enters the viewport, so they
   fade/slide/scale in. .gw-sr also parks the card's continuous hsFloat until it
   is revealed (the .hs-glow sheen still sweeps, so the card stays alive). Under
   reduced motion / no-IO landing.js never adds .gw-sr, so cards render fully
   visible by default — nothing here depends on a stopped animation. */
#homeShowcase .gw-sr, #giftsGoats .gw-sr {
  opacity: 0;
  transform: translateY(28px) scale(.97);
  animation: none;
  transition: opacity .72s cubic-bezier(.16,.8,.24,1),
              transform .72s cubic-bezier(.16,.8,.24,1);
  will-change: opacity, transform;
}
#homeShowcase .gw-sr.gw-sr-in, #giftsGoats .gw-sr.gw-sr-in {
  opacity: 1;
  transform: none;
}

/* ---------------------------------------------------------------------------
   2 · RECENT SALES — a full-bleed band: a labelled header over a horizontal,
   auto-scrolling TICKER of the latest gifts that changed hands. The marquee is
   a pure CSS transform loop (.rs-track animates translateX 0 -> -50% over a
   track market.js builds TWICE), so the wrap is seamless; market.js only sets
   the duration for a constant speed. It pauses on hover/focus, and under
   reduced motion (§7) the animation is killed and the window stays a
   hand-scrollable strip. Soft accent wash + a pulsing dot, our skin.
   ------------------------------------------------------------------------ */
#recentsales {
  padding: 12px clamp(16px, 2vw, 40px) 14px;
  background:
    linear-gradient(180deg, var(--tint-weak), transparent),
    var(--panel);
  border-bottom: 1px solid var(--hairline);
}
#rsHead {
  display: flex; align-items: baseline; gap: 12px;
  margin-bottom: 10px;
}
#rsTag {
  display: inline-flex; align-items: center; gap: 7px;
  color: var(--gain); font-size: 11px; font-weight: 800;
  letter-spacing: .18em; white-space: nowrap;
}
.tt-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--sweep); box-shadow: 0 0 8px rgba(242,166,25,.8);
  animation: tt-pulse 2.4s ease-in-out infinite;
}
@keyframes tt-pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
#rsSub { color: var(--ink-lo); font-size: 11px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.trend-wait { color: var(--ink-faint); font-size: 12px; }

/* the moving window: overflow-hidden viewport with faded edges so cards slide
   IN and OUT rather than hard-cutting. Hand-scrollable when the marquee is
   stilled (reduced motion). */
#rsWindow {
  position: relative;
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 3%, #000 97%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 3%, #000 97%, transparent 100%);
}
#rsWindow::-webkit-scrollbar { display: none; }
#rsWindow:focus-visible { outline: 2px solid var(--p500); outline-offset: 3px; border-radius: 12px; }

/* the ticker track: one row, laid out at max-content, translated left forever.
   market.js builds the cards twice, so translateX(-50%) lands the copy exactly
   over the original — a seamless wrap. Only animates once .rs-live is set (the
   loading / empty state must not scroll). */
/* Key on the #rsTrack ID (always present) not the .rs-track class: market.js
   set the track's className to just "rs-live", so a class-scoped display:flex
   never applied and the ticker stacked VERTICALLY. The id is class-proof. */
#rsTrack { display: flex; gap: 12px; width: max-content; }
#rsTrack.rs-live { animation: rs-marquee linear infinite; will-change: transform; }
#rsWindow:hover #rsTrack, #rsWindow:focus-within #rsTrack { animation-play-state: paused; }
@keyframes rs-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

.rs-card {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 10px;
  background: var(--raised);
  border: 1px solid var(--hairline-2);
  border-radius: 12px;
  padding: 8px 13px 8px 8px;
  color: var(--ink-mid); text-align: left;
  transition: transform .16s ease, border-color .16s ease, background .16s ease;
  text-decoration: none;
}
.rs-card:hover { background: var(--hover); border-color: var(--p500); transform: translateY(-2px); }
.rs-art { flex: 0 0 auto; width: 44px; height: 44px; border-radius: 9px; overflow: hidden; background: var(--well); }
.rs-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rs-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.rs-coll { color: var(--ink-hi); font-weight: 700; font-size: 12px; white-space: nowrap; max-width: 160px; overflow: hidden; text-overflow: ellipsis; }
.rs-price-line { display: flex; align-items: baseline; gap: 4px; }
.rs-price { color: var(--ink-hi); font-weight: 700; font-size: 13px; }
.rs-price.is-unknown { color: var(--ink-faint); font-weight: 400; }
.rs-cur { color: var(--ink-lo); font-size: 9px; letter-spacing: .04em; }
.rs-time { color: var(--ink-lo); font-size: 10px; white-space: nowrap; }

/* Wave 4: the old price-only Recent Sales chip now carries a complete factual
   Tape line. It stays compact enough for the marquee, but text has room to say
   why the event qualifies and where its receipt goes. */
.rs-card.rs-story { width: clamp(300px, 32vw, 470px); align-items: stretch; }
.rs-story .rs-art { width: 54px; height: 54px; align-self: center; }
.rs-story .rs-meta { flex: 1 1 auto; justify-content: center; max-width: calc(100% - 64px); }
.rs-story-top { display: flex; align-items: center; gap: 8px; min-width: 0; }
.rs-kind {
  display: inline-flex; align-items: center; min-height: 18px; padding: 0 6px;
  border: 1px solid var(--hairline-2); border-radius: 999px;
  color: var(--ink-mid); background: var(--well);
  font-size: 9px; font-weight: 850; letter-spacing: .09em; white-space: nowrap;
}
.rs-kind-whale_sale { color: var(--gain); border-color: color-mix(in srgb, var(--gain) 45%, transparent); }
.rs-kind-floor_break { color: var(--loss); border-color: color-mix(in srgb, var(--loss) 45%, transparent); }
.rs-kind-rarity_listing { color: var(--p700); border-color: color-mix(in srgb, var(--p500) 45%, transparent); }
.rs-kind-cluster_move { color: var(--sweep); border-color: color-mix(in srgb, var(--sweep) 45%, transparent); }
.rs-storyline {
  color: var(--ink-hi); font-size: 12px; font-weight: 650; line-height: 1.28;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
}
.rs-evidence { color: var(--ink-lo); font-size: 9px; letter-spacing: .08em; }
@media (max-width: 560px) {
  .rs-card.rs-story { width: min(82vw, 360px); }
  .rs-story .rs-art { width: 46px; height: 46px; }
  .rs-storyline { font-size: 11px; }
}

/* ---------------------------------------------------------------------------
   3 · LAYOUT + FILTER RAIL
   ------------------------------------------------------------------------ */
/* FULL-BLEED SHOP. No max-width cap and no centring margin: on desktop/PC the
   store fills the whole viewport width — a fixed 260px filter rail pinned left,
   the grid taking every remaining pixel. The grid's auto-fill track (see §4)
   then lays down MORE columns the wider the screen gets. Gutters scale with the
   viewport so a 4K monitor breathes without the content drifting to one edge. */
#layout {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: clamp(12px, 1.4vw, 26px);
  padding: 14px clamp(16px, 2vw, 40px) 80px;   /* bottom room for the tester FAB */
  width: 100%;
}

#filtersToggle { display: none; }      /* mobile only — see §8 */

#filters {
  align-self: start;
  position: sticky; top: 100px;        /* below the sticky topbar + tab bar */
  display: flex; flex-direction: column; gap: 14px;
  background: var(--panel);
  border: 1px solid var(--hairline-2);
  border-radius: 10px;
  padding: 12px;
  max-height: calc(100vh - 112px);
  overflow-y: auto;
}

.f-block h3 {
  margin: 0 0 6px;
  color: var(--ink-lo);
  font-size: 10px; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase;
}
.f-unit { color: var(--ink-faint); font-weight: 600; }
.f-note { margin: 0 0 6px; color: var(--ink-faint); font-size: 10px; }
.f-wait { color: var(--ink-faint); font-size: 11px; }

.f-list { display: flex; flex-direction: column; gap: 2px; max-height: 300px; overflow-y: auto; }
.f-item {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 6px; border-radius: 6px;
  color: var(--ink-mid); text-align: left; width: 100%;
}
.f-item:hover { background: var(--hover); }
.f-item[aria-pressed="true"] { background: var(--tint); color: var(--ink-hi); }
.f-item img { width: 18px; height: 18px; border-radius: 4px; flex: 0 0 auto; }
.f-item .fi-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.f-item .fi-n { color: var(--ink-lo); font-size: 11px; }

.f-seg { display: flex; border: 1px solid var(--hairline-2); border-radius: 8px; overflow: hidden; }
.f-seg button { flex: 1 1 0; padding: 6px 4px; color: var(--ink-lo); font-size: 11px; }
.f-seg button[aria-pressed="true"] { background: var(--hover); color: var(--ink-hi); }

.f-range { display: flex; align-items: center; gap: 6px; }
.f-range input {
  width: 0; flex: 1 1 0;
  background: var(--raised);
  border: 1px solid var(--hairline-2);
  border-radius: 6px;
  padding: 5px 7px;
  color: var(--ink-hi);
}
.f-range input:focus { border-color: var(--p500); }
.f-dash { color: var(--ink-faint); }
#fRangeGo {
  background: var(--raised); border: 1px solid var(--hairline-2);
  border-radius: 6px; padding: 5px 9px; color: var(--ink-mid);
}
#fRangeGo:hover { border-color: var(--p500); color: var(--ink-hi); }

#fClear {
  align-self: flex-start;
  color: var(--loss); font-size: 11px;
  padding: 4px 6px; border-radius: 6px;
}
#fClear:hover { background: var(--hover); }

/* ATTRIBUTE FACET GROUPS — one collapsible group per trait TYPE (backdrop,
   model, symbol, colour, and any other facet the loaded listings expose).
   market.js builds these; only groups with real values ever render (an empty
   facet is hidden, not shown blank). Each group: a header with a count badge,
   an optional in-group search once it has more than eight values, and a
   multi-select value list where a lit check means the value is an active OR
   term within its type. */
#fTraitList { display: flex; flex-direction: column; gap: 8px; }
.f-group {
  border: 1px solid var(--hairline); border-radius: 8px;
  background: var(--well);
  overflow: hidden;
}
.f-ghead {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px 9px;
  color: var(--ink-mid); text-align: left;
}
.f-ghead:hover { background: var(--hover); }
.fg-name {
  flex: 1 1 auto; min-width: 0;
  color: var(--ink-hi); font-weight: 600; font-size: 12px;
  text-transform: capitalize;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fg-count {
  flex: 0 0 auto;
  color: var(--ink-lo); font-size: 10px; font-weight: 700;
  background: var(--raised); border: 1px solid var(--hairline-2);
  border-radius: 5px; padding: 1px 6px;
}
.f-ghead[aria-expanded="false"] + .f-gbody { display: none; }
.f-gbody { padding: 6px; display: flex; flex-direction: column; gap: 6px; }

.f-gsearch {
  width: 100%;
  background: var(--raised); border: 1px solid var(--hairline-2);
  border-radius: 6px; padding: 5px 8px;
  color: var(--ink-hi);
}
.f-gsearch::placeholder { color: var(--ink-faint); }
.f-gsearch:focus { border-color: var(--p500); }
.f-vlist { max-height: 220px; }

/* a value row: a check box drawn in CSS, the value, and its count */
.f-vitem { gap: 8px; }
.f-check {
  flex: 0 0 auto;
  width: 14px; height: 14px; border-radius: 4px;
  border: 1px solid var(--hairline-2); background: var(--raised);
  position: relative;
}
.f-vitem[aria-pressed="true"] .f-check {
  background: var(--p400); border-color: var(--p500);
}
.f-vitem[aria-pressed="true"] .f-check::after {
  content: ""; position: absolute; left: 4px; top: 1px;
  width: 4px; height: 8px;
  border: solid var(--on-accent); border-width: 0 2px 2px 0;
  transform: rotate(42deg);
}
.f-vitem .fi-name { text-transform: capitalize; }

/* ---------------------------------------------------------------------------
   4 · RESULTS — meta line, grid and list views.
   ------------------------------------------------------------------------ */
#meta {
  display: flex; align-items: baseline; gap: 10px;
  padding: 2px 2px 10px;
  color: var(--ink-lo); font-size: 12px;
}
#metaCount { color: var(--ink-hi); font-weight: 700; }

#grid.view-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: clamp(12px, 1.2vw, 18px);
}
#grid.view-list { display: flex; flex-direction: column; gap: 6px; }

/* ---- the card, grid form: art-first, and it lifts to the touch so the grid
   feels like a shop shelf rather than a table. Only transform/opacity/shadow
   move — all compositor-friendly, all killed under reduced motion (§7). ---- */
.card {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--raised);
  border: 1px solid var(--hairline-2);
  border-radius: 16px;
  overflow: hidden;
  transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.card:hover {
  border-color: var(--p500);
  transform: translateY(-4px);
  box-shadow: 0 18px 42px var(--shadow-card);
}

/* OURS emphasis — the seller's reason to move (spec §5 cold start). A purple
   edge and a lifted chip, NOT reordering inside an explicit sort — a price
   sort that is not price-ordered would be a lie about prices. */
.card.is-ours { border-color: var(--p400); box-shadow: 0 0 0 1px var(--p300) inset; }

.c-art { position: relative; aspect-ratio: 1; background: var(--well); overflow: hidden; }
.c-art img { width: 100%; height: 100%; object-fit: cover; transition: transform .35s ease; }
.card:hover .c-art img { transform: scale(1.05); }

.c-body { display: flex; flex-direction: column; gap: 5px; padding: 10px 11px 12px; }
.c-name {
  color: var(--ink-hi); font-weight: 600; font-size: 13px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.c-priceline { display: flex; align-items: baseline; gap: 4px; }
.c-price { color: var(--ink-hi); font-weight: 700; font-size: 15px; }
.c-cur { color: var(--ink-lo); font-size: 10px; letter-spacing: .04em; }
.c-price.is-unknown { color: var(--ink-faint); font-weight: 400; font-size: 14px; }

.c-chips { display: flex; flex-wrap: wrap; gap: 4px; }

/* venue chip — every card, always (spec §3 rule 7 / §5). */
.chip {
  display: inline-flex; align-items: center;
  border-radius: 5px; padding: 1px 6px;
  font-size: 9px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  background: var(--hover); color: var(--ink-lo);
  border: 1px solid var(--hairline-2);
}
.chip.v-ours { background: var(--p300); color: var(--on-accent); border-color: var(--p500); }
.chip.k-auction { color: var(--sweep); border-color: rgba(242,166,25,.35); }
.chip.r-rare { color: var(--p700); border-color: var(--p500); }

.c-act {
  margin-top: 2px;
  display: inline-flex; align-items: center; gap: 4px;
  color: var(--p600); font-size: 11px; font-weight: 600;
  text-decoration: none;
}
.c-act:hover { color: var(--p700); text-decoration: underline; }

/* ---- the card, list form: same DOM, one row. A row is a row — the shelf
   lift and art zoom are grid-only, so list stays a calm, scannable table. ---- */
.view-list .card { flex-direction: row; align-items: center; gap: 10px; padding: 6px 10px; }
.view-list .card:hover { transform: none; box-shadow: none; }
.view-list .card:hover .c-art img { transform: none; }
.view-list .c-art { width: 44px; height: 44px; aspect-ratio: auto; flex: 0 0 auto; border-radius: 8px; overflow: hidden; }
.view-list .c-body { flex: 1 1 auto; flex-direction: row; align-items: center; gap: 10px; padding: 0; min-width: 0; }
.view-list .c-name { flex: 1 1 30%; }
.view-list .c-rarity { flex: 0 0 auto; color: var(--ink-lo); font-size: 11px; min-width: 74px; }
.view-list .c-priceline { flex: 0 0 auto; min-width: 110px; justify-content: flex-end; }
.view-list .c-chips { flex: 0 0 auto; }
.view-list .c-act { margin: 0; flex: 0 0 auto; }
/* grid view has no rarity column — the chip carries it. Hidden HERE, not
   removed in JS, so toggling views never rebuilds a card. */
.view-grid .c-rarity { display: none; }

/* ---------------------------------------------------------------------------
   5 · STATES — loading / error / empty are said out loud, never blank.
   ------------------------------------------------------------------------ */
#gridState {
  padding: 40px 16px;
  text-align: center;
  color: var(--ink-lo);
  background: var(--panel);
  border: 1px dashed var(--hairline-2);
  border-radius: 10px;
}
#gridState .gs-title { color: var(--ink-hi); font-weight: 700; margin-bottom: 4px; }
#gridState button {
  margin-top: 10px;
  background: var(--raised); border: 1px solid var(--hairline-2);
  border-radius: 8px; padding: 6px 14px; color: var(--ink-hi);
}
#gridState button:hover { border-color: var(--p500); }

#more {
  display: block;
  margin: 16px auto 0;
  background: var(--raised);
  border: 1px solid var(--hairline-2);
  border-radius: 8px;
  padding: 8px 22px;
  color: var(--ink-hi);
}
#more:hover { border-color: var(--p500); }
#more[disabled] { color: var(--ink-faint); cursor: default; }

/* the OURS capability sheet (shown from "List with us"; built by market.js) */
#oursSheet {
  position: fixed; right: 16px; top: 58px; z-index: 40;
  width: min(340px, calc(100vw - 32px));
  background: var(--raised);
  border: 1px solid var(--p500);
  border-radius: 10px;
  padding: 14px;
  box-shadow: 0 24px 64px rgba(0,0,0,.72);
}
#oursSheet h3 { margin: 0 0 8px; color: var(--ink-hi); font-size: 12px; letter-spacing: .1em; }
#oursSheet p, #oursSheet li { color: var(--ink-mid); font-size: 12px; }
#oursSheet .os-close { float: right; color: var(--ink-lo); padding: 0 4px; }

/* ---------------------------------------------------------------------------
   5b · STATS VIEW — collection-stats table + the cross-chain compare. Both
   read the same /v1/market/collections rollup as the rail; a "—" cell is an
   honest missing number, never a fabricated zero, and it is styled dim but
   present. The compare is a head-to-head board (modelled on the chains board)
   with the pinned collections as columns; its chain row is TON for every
   column, because that is the only chain Intel Maps indexes today.
   ------------------------------------------------------------------------ */
/* Stats is full-bleed too (no max-width cap) so the table can use the whole
   width on desktop, matching the shop; gutters scale with the viewport. */
#view-stats { width: 100%; padding: 18px clamp(16px, 2vw, 40px) 90px; }
#statsHead { margin-bottom: 14px; }
#statsHead h2 { margin: 0 0 4px; color: var(--ink-hi); font-size: 17px; font-weight: 800; letter-spacing: .01em; }
#statsNote { margin: 0; color: var(--ink-lo); font-size: 12px; max-width: 70ch; }

#statsState {
  padding: 40px 16px; text-align: center; color: var(--ink-lo);
  background: var(--panel); border: 1px dashed var(--hairline-2); border-radius: 10px;
}
#statsState .gs-title { color: var(--ink-hi); font-weight: 700; margin-bottom: 4px; }

#statsTableWrap { overflow-x: auto; }
#statsTable {
  width: 100%; border-collapse: collapse;
  background: var(--panel); border: 1px solid var(--hairline-2); border-radius: 10px;
  overflow: hidden;
}
#statsTable thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--raised);
  color: var(--ink-lo); font-size: 10px; font-weight: 800;
  letter-spacing: .1em; text-transform: uppercase;
  text-align: right; padding: 9px 12px;
  border-bottom: 1px solid var(--hairline-2); white-space: nowrap;
}
#statsTable thead th.st-cmp, #statsTable thead th.st-col { text-align: left; }
#statsTable tbody td { padding: 9px 12px; border-bottom: 1px solid var(--hairline); vertical-align: middle; }
#statsTable tbody tr:last-child td { border-bottom: 0; }
#statsTable tbody tr:hover { background: var(--hover); }
.st-num { text-align: right; color: var(--ink-hi); white-space: nowrap; }
.st-unit { color: var(--ink-lo); font-size: 10px; margin-left: 3px; }
.st-miss { color: var(--ink-faint); }
.st-col { min-width: 160px; }
.st-who { display: flex; align-items: center; gap: 9px; min-width: 0; }
.st-who img { width: 22px; height: 22px; border-radius: 5px; flex: 0 0 auto; }
.st-name { color: var(--ink-hi); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.st-cmp { width: 34px; }
.st-check {
  width: 16px; height: 16px; border-radius: 4px;
  border: 1px solid var(--hairline-2); background: var(--raised);
  position: relative; display: block;
}
.st-check:hover { border-color: var(--p500); }
.st-check[aria-pressed="true"] { background: var(--p400); border-color: var(--p500); }
.st-check[aria-pressed="true"] .st-checkmark::after {
  content: ""; position: absolute; left: 5px; top: 2px;
  width: 4px; height: 8px;
  border: solid var(--on-accent); border-width: 0 2px 2px 0;
  transform: rotate(42deg);
}

/* CROSS-CHAIN COMPARE — pinned collections side by side. */
#compareBar {
  margin-bottom: 16px;
  background: var(--panel); border: 1px solid var(--p500); border-radius: 10px;
  padding: 12px; box-shadow: 0 0 0 1px var(--tint) inset;
}
#compareHead { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.cmp-title { color: var(--ink-hi); font-weight: 800; font-size: 11px; letter-spacing: .14em; }
.cmp-chain {
  color: var(--p700); font-size: 10px; font-weight: 800; letter-spacing: .06em;
  border: 1px solid var(--p500); border-radius: 5px; padding: 1px 7px;
}
#cmpClear {
  margin-left: auto; color: var(--loss); font-size: 11px;
  padding: 3px 8px; border-radius: 6px;
}
#cmpClear:hover { background: var(--hover); }
#cmpNote { margin: 0 0 10px; color: var(--ink-faint); font-size: 11px; max-width: 78ch; }
#cmpNote b { color: var(--ink-lo); }

#compareGrid { overflow-x: auto; }
.cmp-table { border-collapse: collapse; min-width: 100%; }
.cmp-table th, .cmp-table td {
  padding: 8px 12px; border-bottom: 1px solid var(--hairline);
  text-align: right; white-space: nowrap;
}
.cmp-corner { border-bottom: 1px solid var(--hairline-2) !important; }
.cmp-colh { border-bottom: 1px solid var(--hairline-2) !important; text-align: right; min-width: 120px; }
.cmp-colhead { display: flex; align-items: center; gap: 7px; justify-content: flex-end; }
.cmp-colhead img { width: 20px; height: 20px; border-radius: 5px; flex: 0 0 auto; }
.cmp-cname {
  color: var(--ink-hi); font-weight: 700; font-size: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 130px;
}
.cmp-rm { color: var(--ink-lo); font-size: 14px; line-height: 1; padding: 0 2px; flex: 0 0 auto; }
.cmp-rm:hover { color: var(--loss); }
.cmp-rowh {
  text-align: left; color: var(--ink-lo);
  font-size: 10px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  position: sticky; left: 0; background: var(--panel);
}
.cmp-cell { color: var(--ink-hi); }
.cmp-cell .st-miss { color: var(--ink-faint); }
.cmp-chaincell { }
.cmp-chip {
  color: var(--p700); font-size: 10px; font-weight: 800; letter-spacing: .06em;
  border: 1px solid var(--p500); border-radius: 5px; padding: 1px 7px;
}
.cmp-table tbody tr:last-child th, .cmp-table tbody tr:last-child td { border-bottom: 0; }

/* ---------------------------------------------------------------------------
   5c · NFTs VIEW — a distinct top-level category beside Gifts. Full-bleed like
   the shop. Because the market feed carries no NFT (Sol/Eth) inventory today,
   the default render is an HONEST empty state — the same styled, spoken-aloud
   panel the grid uses for its own states, never a blank and never fake rows.
   #nftsGrid stays hidden unless market.js finds a real non-TON collection.
   ------------------------------------------------------------------------ */
#view-nfts { width: 100%; padding: 18px clamp(16px, 2vw, 40px) 90px; }
#nftsHead { margin-bottom: 16px; }
#nftsHead h2 { margin: 0 0 4px; color: var(--ink-hi); font-size: 17px; font-weight: 800; letter-spacing: .01em; }
#nftsNote { margin: 0; color: var(--ink-lo); font-size: 12px; max-width: 74ch; }
#nftsState {
  padding: 48px 20px; text-align: center; color: var(--ink-lo);
  background:
    radial-gradient(120% 140% at 50% 0%, var(--tint-weak), transparent 60%),
    var(--panel);
  border: 1px dashed var(--hairline-2); border-radius: 12px;
}
#nftsState .gs-title { color: var(--ink-hi); font-weight: 800; font-size: 15px; margin-bottom: 6px; }
#nftsState > div:not(.gs-title) { max-width: 60ch; margin: 0 auto; }
#nftsToGifts {
  margin-top: 16px;
  background: var(--p300); border: 1px solid var(--p500);
  border-radius: 8px; padding: 8px 18px; color: var(--on-accent); font-weight: 700;
}
#nftsToGifts:hover { background: var(--p400); }
#nftsGrid { margin-top: 14px; }

/* ---------------------------------------------------------------------------
   6 · DIAMOND TESTER — FAB + readout panel.

   HEAT COLOURS. The terminal reserves --gain/--loss for signed text, and that
   contract holds THERE. The tester meter is the one surface in the product
   where heat is drawn as colour (spec §6: "sweeps green→red"), so the three
   heat stops are declared as their own tokens here — same hexes, different
   contract, and no component outside the tester may use them.
   ------------------------------------------------------------------------ */
:root {
  --t-cold: #3BE08A;
  --t-warm: #F2A619;
  --t-hot:  #F2545B;
}

#testerFab {
  position: fixed; right: 18px; bottom: 18px; z-index: 50;
  width: 52px; height: 52px;
  border-radius: 50%;
  background: var(--p300);
  border: 1px solid var(--p500);
  color: var(--on-accent);
  font-size: 22px; line-height: 1;
  box-shadow: 0 8px 24px rgba(0,0,0,.55);
}
#testerFab:hover { background: var(--p400); }
#testerFab[aria-pressed="true"] { background: var(--p400); border-color: var(--p700); }

/* TESTER EXPLAINER POPUP (build #2) — a small speech-bubble anchored just above
   the ◇ FAB. tester.js toggles [hidden]; shown on first load and re-openable.
   pointer-events stay live (it has an X to close). Hidden on non-Gifts tabs by
   the same guard that hides the FAB (added below). */
#testerAbout {
  position: fixed; right: 18px; bottom: 80px; z-index: 51;
  width: min(280px, calc(100vw - 36px));
  background: var(--raised);
  border: 1px solid var(--p500);
  border-radius: 12px;
  padding: 13px 14px 12px;
  box-shadow: 0 14px 40px var(--shadow-card);
}
/* the little pointer tail aiming down at the FAB */
#testerAbout::after {
  content: ""; position: absolute; right: 22px; bottom: -7px;
  width: 12px; height: 12px;
  background: var(--raised);
  border-right: 1px solid var(--p500); border-bottom: 1px solid var(--p500);
  transform: rotate(45deg);
}
#testerAboutClose {
  position: absolute; top: 6px; right: 8px;
  color: var(--ink-lo); font-size: 16px; line-height: 1; padding: 2px 5px;
  border-radius: 6px;
}
#testerAboutClose:hover { color: var(--ink-hi); background: var(--hover); }
.ta-head {
  display: flex; align-items: center; gap: 7px;
  color: var(--ink-hi); font-weight: 800; font-size: 11px; letter-spacing: .12em;
  margin-bottom: 6px;
}
.ta-head .ta-ic { color: var(--p400); font-size: 13px; }
.ta-body { margin: 0 0 8px; color: var(--ink-mid); font-size: 12px; line-height: 1.5; }
.ta-body b { color: var(--ink-hi); }
.ta-body i { color: var(--p500); font-style: normal; font-weight: 700; }
.ta-tip { color: var(--ink-faint); font-size: 10.5px; letter-spacing: .02em; }

/* the explainer lives with the FAB — gone on any non-Gifts tab, like the FAB */
body:not([data-tab="gifts"]) #testerAbout { display: none !important; }

/* scan mode: the cursor says the page is an instrument now */
body.tester-on #grid .card { cursor: crosshair; }
body.tester-on #grid .card:hover { border-color: var(--sweep); }

#tester {
  position: fixed; right: 18px; bottom: 82px; z-index: 50;
  width: min(300px, calc(100vw - 36px));
  background: var(--raised);
  border: 1px solid var(--hairline-2);
  border-radius: 10px;
  padding: 12px;
  box-shadow: 0 8px 24px rgba(0,0,0,.55);
}

/* ---------------------------------------------------------------------------
   SCAN MODE = TESTER-AS-CURSOR. When scan is armed, tester.js adds body.it-scan
   and positions #tester at the pointer via transform (set inline on mousemove).
   The device leaves its docked corner and floats over the page at FULL readable
   size — never shrunk — and is pointer-events:none so it never blocks a click or
   a card hover. The native cursor is hidden over the gift surfaces so the tester
   reads AS the cursor. Higher specificity than the docked + mobile-sheet rules,
   so it wins on every breakpoint; on the non-Gifts tabs #tester is still hidden.
   ------------------------------------------------------------------------ */
body.it-scan #tester {
  position: fixed; left: 0; top: 0; right: auto; bottom: auto;
  pointer-events: none;
  z-index: 90;
  width: min(300px, calc(100vw - 36px));   /* same big size — do NOT shrink */
  will-change: transform;
  /* the tester reads AS the cursor: drop the boxed panel chrome so only the
     transparent #testerDevice SVG floats (spec §6 "use the device, not the box").
     tester.js still fills the hidden readout nodes — they are hidden VISUALLY,
     not removed — so the SVG meter/verdict keep updating live. */
  background: transparent; border-color: transparent;
  box-shadow: none; padding: 0; border-radius: 0;
}
body.it-scan #tester .t-head,
body.it-scan #tester .t-item,
body.it-scan #tester .t-lamps { display: none; }
body.it-scan #tester .t-scan { margin: 0; }
/* the floating device keeps a soft drop so it reads over any art */
body.it-scan #tester .t-device { filter: drop-shadow(0 6px 16px rgba(0,0,0,.6)); }
/* hide the OS cursor over the scannable gift surfaces — the tester is the cursor */
body.it-scan #grid,
body.it-scan #hotnowTrack,
body.it-scan #hotdealsGrid,
body.it-scan #topgiftsList,
body.it-scan #topgiftsReels,
body.it-scan #cvGrid,
body.it-scan #aggGrid { cursor: none; }
body.it-scan #grid .card,
body.it-scan #hotnowTrack .hn-card,
body.it-scan #hotdealsGrid .card,
body.it-scan #topgiftsList .tg-row,
body.it-scan #topgiftsReels .tgr-cell,
body.it-scan #cvGrid .card,
body.it-scan #aggGrid .agg-card { cursor: none; }

.t-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.t-title { color: var(--ink-hi); font-weight: 800; font-size: 11px; letter-spacing: .14em; }
.t-headctl { display: flex; align-items: center; gap: 6px; }
#testerClose { color: var(--ink-lo); font-size: 14px; line-height: 1; padding: 0 4px; }
#testerClose:hover { color: var(--ink-hi); }
#testerMute {
  color: var(--ink-lo); font-size: 9px; font-weight: 800; letter-spacing: .08em;
  border: 1px solid var(--hairline-2); border-radius: 5px; padding: 2px 6px;
}
#testerMute[aria-pressed="true"] { color: var(--ink-faint); text-decoration: line-through; }

/* ---------------------------------------------------------------------------
   THE DEVICE — a handheld diamond tester, drawn in inline SVG (index.html).
   The chassis is static SVG; this block only styles the parts tester.js drives:
   the LED bar gauge (rarity ladder), the LCD verdict, the power LED and the
   probe glow. All motion here is opacity/transform or a small colour fade, and
   the global prefers-reduced-motion rule (§7) kills every transition/animation.
   ------------------------------------------------------------------------ */
.t-scan { margin-bottom: 6px; }
.t-device {
  position: relative;
  width: 100%;
  aspect-ratio: 280 / 132;
  filter: drop-shadow(0 6px 12px rgba(0,0,0,.55));
}
.t-body { display: block; width: 100%; height: 100%; overflow: visible; }

/* etched zone labels flanking the gauge */
.t-zone { fill: var(--ink-faint); font-size: 6px; font-weight: 700; letter-spacing: .08em; }

/* LED BAR GAUGE — rarity ladder. The rungs are in document order bottom→top,
   so tester.js lighting rung[0..lit) fills from the bottom up. Colour is fixed
   by position, not by lit state: cool at the AVG end, hot green at the RARE end,
   matching the green→amber→green heat the panel uses elsewhere. The green top
   band starts at rung 7 = heat 0.70 = the ping threshold, so light and sound
   agree on where "rare" begins. */
.t-led { fill: #17141f; }
.t-ladder .t-led { transition: fill .14s ease, filter .14s ease; }
.t-ladder .t-led:nth-child(-n+3) { color: #4FA8E0; }        /* AVG — cool     */
.t-ladder .t-led:nth-child(n+4)  { color: var(--t-warm); }  /* warming        */
.t-ladder .t-led:nth-child(n+7)  { color: var(--t-cold); }  /* RARE — hot grn */
.t-led.lit { fill: currentColor; filter: drop-shadow(0 0 2.4px currentColor); }
/* the rungs light bottom-up in a quick cascade — the needle "climbing" */
.t-ladder .t-led:nth-child(1) { transition-delay: 0s; }
.t-ladder .t-led:nth-child(2) { transition-delay: .016s; }
.t-ladder .t-led:nth-child(3) { transition-delay: .032s; }
.t-ladder .t-led:nth-child(4) { transition-delay: .048s; }
.t-ladder .t-led:nth-child(5) { transition-delay: .064s; }
.t-ladder .t-led:nth-child(6) { transition-delay: .080s; }
.t-ladder .t-led:nth-child(7) { transition-delay: .096s; }
.t-ladder .t-led:nth-child(8) { transition-delay: .112s; }
.t-ladder .t-led:nth-child(9) { transition-delay: .128s; }
.t-ladder .t-led:nth-child(10){ transition-delay: .144s; }

/* POWER LED — dark until the tester is armed, then a steady green */
.t-power { fill: #2a2430; transition: fill .2s ease; }
.t-device[data-state="idle"]   .t-power,
.t-device[data-state="read"]   .t-power,
.t-device[data-state="nodata"] .t-power {
  fill: var(--gain); filter: drop-shadow(0 0 3px var(--gain));
}

/* PROBE GLOW — dark on idle (honest: no contact, no reading); lights only on a
   real reading, and pulses once as the device "beeps" */
.t-probe-glow {
  opacity: 0; transition: opacity .18s ease;
  transform-box: fill-box; transform-origin: center;
}
.t-device[data-state="read"] .t-probe-glow { opacity: .9; }
@keyframes t-beep { 0% { transform: scale(1); } 40% { transform: scale(1.6); } 100% { transform: scale(1); } }
.t-device.t-beep .t-probe-glow { animation: t-beep .28s ease-out; }

/* LCD verdict — dim on idle, green on a reading, red when there is no data */
.t-lcd-text { fill: #2f6f52; font-size: 12px; font-weight: 700; letter-spacing: .04em; }
.t-device[data-state="read"]   .t-lcd-text { fill: var(--t-cold); }
.t-device[data-state="nodata"] .t-lcd-text { fill: var(--t-hot); }
.t-item { margin: 6px 0 8px; color: var(--ink-lo); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.t-lamps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; }
.t-lamp { display: flex; align-items: baseline; gap: 7px; font-size: 11px; }
.t-dot {
  width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto;
  align-self: center;
  background: var(--well);
  border: 1px solid var(--hairline-2);
}
.t-lamp[data-lit="1"] .t-dot { background: var(--gain); border-color: var(--gain); }
.t-lamp .t-k { color: var(--ink-lo); font-weight: 800; font-size: 9px; letter-spacing: .1em; width: 44px; flex: 0 0 auto; }
.t-lamp .t-v { color: var(--ink-mid); min-width: 0; }
.t-lamp[data-lit="0"] .t-v { color: var(--ink-faint); }

/* ---------------------------------------------------------------------------
   TRUE RARITY BREAKDOWN — the diamond-scanner readout tester.js injects into
   #tester. Unlike .t-item/.t-lamps it stays VISIBLE while armed (it is NOT in
   the it-scan hide list), so as the device floats over a gift it shows the True
   Rarity score + the four component signals (Classic / Monochrome / Theme /
   Symbol self). It carries its own card background so it reads over any art.
   Only rendered when there is a reading; an absent signal shows an empty bar. */
.t-break {
  margin-top: 8px;
  background: var(--raised);
  border: 1px solid var(--hairline-2);
  border-radius: 9px;
  padding: 8px 10px;
  box-shadow: 0 8px 20px rgba(0,0,0,.5);
}
.t-break-head { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; }
.t-break-lab { color: var(--ink-lo); font-weight: 800; font-size: 9px; letter-spacing: .12em; }
.t-break-score { color: var(--t-cold); font-weight: 900; font-size: 18px; font-variant-numeric: tabular-nums; margin-left: auto; line-height: 1; }
.t-break-caret { color: var(--ink-faint); font-size: 10px; transition: transform .15s ease; }
.t-break[data-collapsed="1"] .t-break-caret { transform: rotate(-90deg); }
.t-break-body { display: flex; flex-direction: column; gap: 5px; margin-top: 7px; }
.t-break[data-collapsed="1"] .t-break-body { display: none; }
.t-break-row { display: flex; align-items: center; gap: 8px; font-size: 10px; }
.t-break-k { color: var(--ink-lo); font-weight: 700; width: 100px; flex: 0 0 auto; }
.t-break-bar { position: relative; flex: 1; height: 5px; border-radius: 3px; background: var(--well); overflow: hidden; min-width: 0; }
.t-break-fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: var(--p400); border-radius: 3px; transition: width .18s ease; }
.t-break-fill[data-empty] { background: transparent; }
.t-break-v { color: var(--ink-mid); font-weight: 800; font-variant-numeric: tabular-nums; width: 26px; text-align: right; flex: 0 0 auto; }

/* visually hidden live region for screen readers */
.t-live {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   6b · THEME TOGGLE — a three-button segmented group in the topbar (moon / sun
   / hashtag). The pressed button is filled with the brand accent and inks with
   --on-accent so it stays legible in every skin. aria-pressed is the single
   source of truth; the highlight can never disagree with the a11y state.
   ------------------------------------------------------------------------ */
#themeToggle {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 2px;
  background: var(--raised);
  border: 1px solid var(--hairline-2);
  border-radius: 9px;
  flex: 0 0 auto;
}
#themeToggle button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  border-radius: 7px;
  background: transparent;
  color: var(--ink-lo);
  font-size: 15px; line-height: 1;
}
#themeToggle button:hover { background: var(--hover); color: var(--ink-hi); }
#themeToggle button[aria-pressed="true"] { background: var(--p400); color: var(--on-accent); }

/* ---------------------------------------------------------------------------
   6c · SHARED SECTION HEADERS — the big getgems-style band header used by
   HOT RIGHT NOW and HOTTEST DEALS. A coloured tag (amber for hot, blue for
   deal) plus a muted subline. Wraps cleanly on phones instead of clipping.
   ------------------------------------------------------------------------ */
.sec-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.sec-tag {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 12px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase;
  white-space: nowrap;
}
.sec-tag.hot  { color: var(--sweep); }
.sec-tag.deal { color: var(--p500); }
.sec-sub { color: var(--ink-lo); font-size: 12px; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* honest empty / wait state shared by the new live sections */
.sec-empty { color: var(--ink-lo); font-size: 12px; padding: 10px 2px; }

/* ---------------------------------------------------------------------------
   6d · HOT RIGHT NOW — a single horizontal strip of the gifts everyone is on,
   ranked by their collection's 24h sales and auto-rotated by market.js. The
   track scrolls in its OWN overflow-x container so the page body never scrolls
   sideways. Cards are compact and art-first; the collection label is a button
   that opens the collection detail view.
   ------------------------------------------------------------------------ */
#hotnow { padding: 24px clamp(16px, 2vw, 40px) 8px; }
#hotnowTrack {
  display: flex; gap: 12px;
  overflow-x: auto; scroll-behavior: smooth;
  scrollbar-width: none; min-width: 0;
  padding-bottom: 4px;
  -webkit-overflow-scrolling: touch;
}
#hotnowTrack::-webkit-scrollbar { display: none; }
#hotnowTrack:focus-visible { outline: 2px solid var(--p500); outline-offset: 3px; border-radius: 12px; }

/* IMAGE-FORWARD: the art IS the card. Big square cover fills it; the only
   label is a big bold number chip overlaid on the art (no collection name). */
.hn-card {
  flex: 0 0 auto; width: clamp(180px, 22vw, 300px);
  position: relative;
  display: flex; flex-direction: column;
  background: var(--raised);
  border: 1px solid var(--hairline-2);
  border-radius: 16px; overflow: hidden;
  transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.hn-card:hover { border-color: var(--p500); transform: translateY(-4px); box-shadow: 0 18px 42px var(--shadow-card); }
.hn-art { position: relative; aspect-ratio: 1; background: var(--well); overflow: hidden; }
.hn-art img { width: 100%; height: 100%; object-fit: cover; transition: transform .35s ease; }
.hn-card:hover .hn-art img { transform: scale(1.06); }
/* number-only label: a big bold chip on a translucent overlay — .nascar-ish
   weight, --ink-hi, honest #NN fallback comes from market.js. */
.hn-num {
  position: absolute; left: 10px; bottom: 10px; z-index: 1;
  display: inline-flex; align-items: center;
  padding: 4px 12px; border-radius: 12px;
  background: rgba(4,10,20,.55);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  color: var(--ink-hi);
  font-family: "Arial Narrow", "Roboto Condensed", "Oswald", "Impact", system-ui, sans-serif;
  font-weight: 900; font-style: italic; letter-spacing: -.01em; line-height: 1;
  font-size: clamp(22px, 2.8vw, 38px);
  text-shadow: 0 2px 6px rgba(0,0,0,.55);
}

/* ---------------------------------------------------------------------------
   6e · HOTTEST DEALS — a grid of listings whose rarity/demand is out of line
   with the floor. Cards reuse the standard .card builder; each one MUST show
   the WHY via a reason chip, so the deal is always explained, never asserted.
   The reason chip rides the existing .chip system (gain-coloured, honest).
   ------------------------------------------------------------------------ */
#hotdeals { padding: 24px clamp(16px, 2vw, 40px) 8px; }
#hotdealsGrid.view-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: clamp(12px, 1.2vw, 18px);
}
/* the reason chip: -NN% vs floor / top N% · at floor. Gain hue, honest wash. */
.chip.r-deal { color: var(--gain); border-color: var(--hairline-2); background: var(--tint-weak); }
/* a fuller "why" line, if the builder prints one under the price */
.c-reason { display: inline-flex; align-items: center; gap: 5px; font-size: 10px; font-weight: 800; letter-spacing: .02em; color: var(--gain); }

/* ---------------------------------------------------------------------------
   6e2 · TOP GIFTS — the getgems "Top Telegram Gifts" ranked list. Full-bleed
   band below HOTTEST DEALS (inside #view-gifts). market.js ranks the gift
   COLLECTIONS by 24h then 7d sales and builds ranked rows into #topgiftsList:
   a big skewed rank number, a round collection avatar, the bold name, and the
   right-aligned floor + 24h-sold stats. Unknown money => dim em-dash via gram().
   ------------------------------------------------------------------------ */
#topgifts { padding: 24px clamp(16px, 2vw, 40px) 8px; }
/* the ranked 1-10 list as TWO COLUMNS OF FIVE. grid-auto-flow:column with five
   fixed rows fills column-major, so ranks 1-5 land in the left column and 6-10
   in the right (never row-major 1,2 / 3,4). Collapses to one column on phones. */
#topgiftsList {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: repeat(5, auto);
  grid-auto-flow: column;
  gap: 4px clamp(14px, 2.4vw, 36px);
}
.tg-row {
  display: flex; align-items: center; gap: 14px; width: 100%;
  padding: 10px 12px; border-radius: 14px;
  border: 1px solid transparent;
  color: var(--ink-mid); text-align: left;
  transition: background .16s ease, border-color .16s ease, transform .16s ease;
}
.tg-row:hover { background: var(--hover); border-color: var(--hairline-2); transform: translateX(2px); }
.tg-rank {
  flex: 0 0 auto; width: 2ch; text-align: center;
  font-family: "Arial Narrow", "Roboto Condensed", "Oswald", "Impact", system-ui, sans-serif;
  font-weight: 900; font-style: italic; transform: skewX(-7deg);
  font-size: clamp(22px, 2.6vw, 34px); line-height: 1;
  color: var(--p400);
}
.tg-img {
  flex: 0 0 auto; width: 54px; height: 54px;
  border-radius: 50%; object-fit: cover;
  background: var(--well); border: 1px solid var(--hairline-2);
}
.tg-name {
  flex: 1 1 auto; min-width: 0;
  color: var(--ink-hi); font-weight: 700; font-size: 15px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tg-floor {
  flex: 0 0 auto; text-align: right; min-width: 116px;
  color: var(--ink-hi); font-weight: 700; font-size: 14px; white-space: nowrap;
}
.tg-floor.is-unknown, .tg-floor .st-miss { color: var(--ink-faint); font-weight: 400; }
.tg-sales {
  flex: 0 0 auto; text-align: right; min-width: 116px;
  color: var(--ink-lo); font-size: 12px; white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   6e3 · TOP GIFTS REELS (build #5) — FIVE big SQUARE slot-machine reels
   stretching the full page width, sitting just under the TOP GIFTS header, above
   the ranked list. market.js renderTopGiftsReels() builds one .tgr-cell per
   TOP-5 collection; each holds a .tgr-reel viewport clipping a vertical
   .tgr-strip of square .tgr-slide item images that it steps with translateY
   (staggered, paused on hover, still under reduced motion). The square is never
   blank — an ITIcon monogram is the base slide — and each opens its collection.
   Responsive: 5-up on desktop, wrapping to fewer columns on smaller screens.
   ------------------------------------------------------------------------ */
#topgiftsReels {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(10px, 1.3vw, 18px);
  margin-bottom: 20px;
}
#topgiftsReels .trend-wait { display: inline-block; padding: 24px 2px; }

/* a reel square — the slot cabinet. Art fills it; the name chip rides the
   bottom, matching the HOT RIGHT NOW / cover treatment. padding:0 so the
   inset:0 reel aligns to the card edge (button default padding removed). */
.tgr-cell {
  position: relative;
  aspect-ratio: 1;
  padding: 0;
  border-radius: 16px; overflow: hidden;
  background: var(--well);
  border: 1px solid var(--hairline-2);
  text-align: left;
  transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.tgr-cell:hover {
  border-color: var(--p500);
  transform: translateY(-4px);
  box-shadow: 0 18px 42px var(--shadow-card);
}
/* the viewport: clips the reel to one square; the strip translates through it */
.tgr-reel { position: absolute; inset: 0; overflow: hidden; }
.tgr-strip { display: flex; flex-direction: column; will-change: transform; }
/* each slide is a square = the viewport size (the cell is square, slide is 100%
   wide with a 1:1 ratio), so a translateY of one slide-height is one step. */
.tgr-slide {
  flex: 0 0 auto;
  width: 100%; aspect-ratio: 1;
  background: var(--well); overflow: hidden;
}
.tgr-slide img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* the label chip: collection name (or honest short address) over a wash */
.tgr-label {
  position: absolute; left: 8px; right: 8px; bottom: 8px; z-index: 2;
  display: block;
  padding: 5px 10px; border-radius: 10px;
  background: rgba(4,10,20,.55);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  color: var(--ink-hi); font-weight: 700; font-size: 13px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  text-shadow: 0 2px 6px rgba(0,0,0,.55);
}
/* medium screens: 5-up gets cramped — wrap to three, then two */
@media (max-width: 1040px) { #topgiftsReels { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 980px) and (min-width: 720px) { .hs-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ---------------------------------------------------------------------------
   6f · COLLECTION DETAIL — a top-level in-page view with its own tabs, drawn in
   OUR blue theme. A cover + name + honest stat row header, an Items/Stats
   tablist, the reused card grid, and getgems-inlay-style compact stat cards.
   Every unknown number renders as a dim-but-present em-dash (never a fake 0).
   ------------------------------------------------------------------------ */
#view-collection { width: 100%; padding: 20px clamp(16px, 2vw, 40px) 90px; }
#cvBack {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--raised); border: 1px solid var(--hairline-2);
  border-radius: 8px; padding: 8px 14px; margin-bottom: 18px;
  color: var(--ink-mid); font-size: 12px; font-weight: 600;
}
#cvBack:hover { border-color: var(--p500); color: var(--ink-hi); }

#cvHead {
  display: flex; align-items: flex-end; gap: 18px; flex-wrap: wrap;
  padding: 18px; margin-bottom: 20px;
  background: linear-gradient(180deg, var(--tint-weak), transparent), var(--panel);
  border: 1px solid var(--hairline-2); border-radius: 14px;
}
#cvCover {
  width: 96px; height: 96px; flex: 0 0 auto;
  border-radius: 14px; object-fit: cover;
  background: var(--well); border: 1px solid var(--hairline-2);
}
#cvHeadMain { display: flex; flex-direction: column; gap: 10px; min-width: 0; flex: 1 1 260px; }
#cvName { margin: 0; color: var(--ink-hi); font-size: 22px; font-weight: 800; letter-spacing: .01em; }
#cvStatRow { display: flex; flex-wrap: wrap; gap: 20px; }
.cv-stat { display: flex; flex-direction: column; gap: 2px; }
#cvStatRow .cv-k { color: var(--ink-lo); font-size: 10px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
#cvStatRow .cv-v { color: var(--ink-hi); font-size: 15px; font-weight: 700; }
#cvStatRow .cv-v.is-unknown, #cvStatRow .cv-v .st-miss { color: var(--ink-faint); font-weight: 400; }
/* the id-named value spans (the builder puts the id on the value) */
#cvFloor, #cvOwners, #cvItemsN { color: var(--ink-hi); font-weight: 700; }
#cvFloor.is-unknown, #cvOwners.is-unknown, #cvItemsN.is-unknown { color: var(--ink-faint); font-weight: 400; }

#cvTabs {
  display: flex; gap: 2px; margin-bottom: 18px;
  border-bottom: 1px solid var(--hairline-2);
}
#cvTabs button[role="tab"] {
  padding: 11px 16px; margin-bottom: -1px;
  background: transparent; color: var(--ink-lo);
  font-size: 13px; font-weight: 600;
  border-bottom: 2px solid transparent;
}
#cvTabs button[role="tab"]:hover { color: var(--ink-hi); }
#cvTabs button[role="tab"][aria-selected="true"] { color: var(--ink-hi); border-bottom-color: var(--p400); }

#cvGrid.view-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: clamp(12px, 1.2vw, 18px);
}
#cvGridState {
  padding: 40px 16px; text-align: center; color: var(--ink-lo);
  background: var(--panel); border: 1px dashed var(--hairline-2); border-radius: 10px;
}
#cvGridState .gs-title { color: var(--ink-hi); font-weight: 700; margin-bottom: 4px; }

/* STATS TAB (build #1) — the holder MAP inlay stacked over the stat-card grid.
   #cvStats is now a vertical stack; #cvStatCards carries the grid the tiles used
   to sit in (cvFillStats fills it). Unknown numbers stay dim-but-present. */
#cvStats {
  display: flex; flex-direction: column; gap: 18px;
}

/* ---- the holder-cluster MAP, in our themed frame. A 16:9 same-origin iframe
   of the Intel Maps /app embed lives inside .cvmap-frame (market.js mounts it);
   the frame is rounded with a --hairline border and a labelled caption. The
   "loading" hint sits behind the iframe and is covered once it paints. ---- */
#cvMap { margin: 0; }
.cvmap-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  width: 100%;
  background:
    radial-gradient(120% 140% at 50% -10%, var(--tint-weak), transparent 60%),
    var(--well);
  border: 1px solid var(--hairline-2);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 0 0 1px var(--tint-weak) inset;
}
/* the iframe market.js drops in — style it whether it lands as .cvmap-mount's
   child or as a direct <iframe> of the frame, so the JS side is free either way */
.cvmap-mount { position: absolute; inset: 0; }
.cvmap-frame iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0; display: block;
  background: var(--well);
}
.cvmap-wait {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  color: var(--ink-faint); font-size: 12px; letter-spacing: .02em;
  pointer-events: none;
}
/* once the iframe exists, hide the waiting hint (the map covers it anyway) */
.cvmap-frame:has(iframe) .cvmap-wait { display: none; }
.cvmap-label {
  display: flex; align-items: center; gap: 8px;
  margin-top: 8px;
  color: var(--ink-lo); font-size: 11px; font-weight: 700;
  letter-spacing: .04em;
}
.cvmap-label .cvmap-via { color: var(--ink-faint); font-weight: 600; }
.cvmap-dot {
  width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto;
  background: var(--p400); box-shadow: 0 0 8px var(--ring);
}

/* optional forensic mini-stats (top-holder %, whales) — only shown when
   market.js has real numbers; laid out as compact inline facts. */
#cvForensic {
  display: flex; flex-wrap: wrap; gap: 10px 22px;
  padding: 12px 14px;
  background: var(--panel);
  border: 1px solid var(--hairline); border-radius: 12px;
}
#cvForensic .cvf-item { display: flex; flex-direction: column; gap: 2px; }
#cvForensic .cvf-k { color: var(--ink-lo); font-size: 10px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
#cvForensic .cvf-v { color: var(--ink-hi); font-size: 15px; font-weight: 700; }
#cvForensic .cvf-v.is-unknown, #cvForensic .cvf-v .st-miss { color: var(--ink-faint); font-weight: 400; }

/* getgems-inlay stat cards — compact tiles, one rollup field each */
#cvStatCards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px;
}
.cvstat-card {
  display: flex; flex-direction: column; gap: 6px;
  padding: 14px;
  background: var(--panel);
  border: 1px solid var(--hairline-2);
  border-radius: 12px;
  box-shadow: 0 0 0 1px var(--tint-weak) inset;
}
.cvstat-card .cvc-k { color: var(--ink-lo); font-size: 10px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.cvstat-card .cvc-v { color: var(--ink-hi); font-size: 20px; font-weight: 800; }
.cvstat-card .cvc-v .st-unit, .cvstat-card .cvc-cur { color: var(--ink-lo); font-size: 11px; font-weight: 600; margin-left: 3px; }
.cvstat-card .cvc-v.is-unknown, .cvstat-card .cvc-v .st-miss { color: var(--ink-faint); font-weight: 400; }

/* item-explorer extras — load-more, last-sale label, for-sale highlight */
.cv-more {
  display: block; margin: 22px auto 0; padding: 12px 26px;
  border: 1px solid var(--hairline-2); border-radius: 10px;
  background: var(--raised); color: var(--ink-hi); font-weight: 700; font-size: 13px;
}
.cv-more:hover { border-color: var(--p400); }
.cv-more[disabled] { opacity: .5; cursor: default; }
.c-price.c-last { color: var(--ink-mid); font-weight: 600; }
.c-lastk { color: var(--ink-faint); font-size: 10px; margin-left: 4px; text-transform: uppercase; letter-spacing: .06em; }
.card.is-forsale { outline: 1px solid var(--gain); outline-offset: -1px; }
.card.is-forsale .chip.r-deal { color: var(--gain); border-color: var(--gain); }

/* ---------------------------------------------------------------------------
   6g · SAFE AREA + TELEGRAM — keep chrome out from under the iOS notch and the
   Telegram header, and give the horizontal tracks native momentum scroll.
   Everything degrades to plain padding on browsers without env() support.
   ------------------------------------------------------------------------ */
#topbar {
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
}
#tabbar {
  padding-left: max(12px, env(safe-area-inset-left));
  padding-right: max(12px, env(safe-area-inset-right));
}
/* inside a Telegram Mini App the native header sits above us — nudge the sticky
   topbar down past the safe-area so the brand is never clipped. */
body.in-tg #topbar { padding-top: max(10px, env(safe-area-inset-top)); }
#rsWindow, #tabbar, #hotnowTrack { -webkit-overflow-scrolling: touch; }

/* ---------------------------------------------------------------------------
   6h · WTF? VIEW — our FACTS tab. A full-bleed grid of on-theme explainer cards:
   a big loud heading, a short punchy honest answer. No numbers, nothing
   fabricated. Cards lift on hover like the shop shelf (killed under §7).
   ------------------------------------------------------------------------ */
#view-wtf { width: 100%; padding: 18px clamp(16px, 2vw, 40px) 90px; }
#wtfHead { margin-bottom: 20px; }
#wtfHead h2 { margin: 0 0 8px; font-size: clamp(30px, 5.2vw, 58px); padding: 2px 12px 4px 2px; overflow: visible; }
#wtfNote { margin: 0; color: var(--ink-lo); font-size: 13px; max-width: 70ch; }
#wtfGrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: clamp(12px, 1.4vw, 20px);
}
.wtf-card {
  display: flex; flex-direction: column; gap: 10px;
  padding: 20px;
  background: linear-gradient(180deg, var(--tint-weak), transparent), var(--panel);
  border: 1px solid var(--hairline-2);
  border-radius: 16px;
  box-shadow: 0 0 0 1px var(--tint-weak) inset;
  transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.wtf-card:hover { border-color: var(--p500); transform: translateY(-3px); box-shadow: 0 18px 42px var(--shadow-card); }
.wtf-q { color: var(--ink-hi); font-weight: 800; font-size: 18px; line-height: 1.2; letter-spacing: -.01em; }
.wtf-a { margin: 0; color: var(--ink-mid); font-size: 13.5px; line-height: 1.55; }
.wtf-a a { color: var(--p500); font-weight: 700; text-decoration: none; }
.wtf-a a:hover { color: var(--p600); text-decoration: underline; }

/* ---------------------------------------------------------------------------
   6i · WALLET CONNECT — the header chip (#walletBtn) + its menu. Disconnected:
   a bordered "Connect Wallet" pill with a soft pulsing dot. Connected: an accent
   pill showing the truncated address; clicking opens the menu (Disconnect /
   Connect a different wallet). Theme-aware via the shared tokens.
   ------------------------------------------------------------------------ */
#degenRankChip {
  min-height: 40px; flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 11px; border: 1px solid var(--hairline-2); border-radius: 999px;
  background: var(--raised); color: var(--ink-mid);
  font-size: 11px; font-weight: 900; letter-spacing: .045em; text-transform: uppercase;
  white-space: nowrap; box-shadow: 0 3px 12px rgba(42,33,64,.08);
  transition: transform .14s ease, border-color .14s ease, box-shadow .14s ease;
}
#degenRankChip:hover {
  transform: translateY(-2px); border-color: var(--p400);
  box-shadow: 0 7px 18px rgba(224,57,43,.16);
}
#degenRankChip.is-live { color: var(--ink-hi); border-color: var(--p300); }
#degenRankChip .dr-gem {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--p100); color: var(--p500); font-size: 15px; line-height: 1;
}

/* Degen Rank detail / level-up sheet. Values come only from the read-only
   server profile; this surface never increments or computes XP. */
.dr-backdrop {
  position: fixed; inset: 0; z-index: 360; display: flex;
  align-items: center; justify-content: center; padding: 16px;
  background: rgba(8,6,15,.66); backdrop-filter: blur(4px);
  animation: dr-fade .16s ease both;
}
.dr-backdrop[hidden] { display: none; }
.dr-dialog {
  width: min(460px, 100%); max-height: min(680px, calc(100vh - 32px));
  max-height: min(680px, calc(100dvh - 32px)); overflow-y: auto;
  padding: 22px; border: 1px solid var(--hairline-2); border-radius: 20px;
  background: var(--panel); color: var(--ink-mid);
  box-shadow: 0 26px 80px rgba(7,9,14,.38);
  animation: dr-rise .2s cubic-bezier(.2,.8,.2,1) both;
}
.dr-head { display: flex; align-items: flex-start; gap: 12px; }
.dr-head-copy { min-width: 0; flex: 1; }
.dr-kicker {
  color: var(--p500); font-size: 10px; font-weight: 900;
  letter-spacing: .13em; text-transform: uppercase;
}
.dr-title { margin: 3px 0 0; color: var(--ink-hi); font-size: 25px; line-height: 1.15; }
.dr-close {
  width: 40px; height: 40px; flex: 0 0 auto; border-radius: 12px;
  border: 1px solid var(--hairline-2); background: var(--raised);
  color: var(--ink-lo); font-size: 22px; line-height: 1;
}
.dr-close:hover { color: var(--loss); border-color: var(--loss); }
.dr-hero {
  display: flex; align-items: center; gap: 14px; margin: 20px 0 16px;
  padding: 15px; border: 1px solid var(--hairline); border-radius: 16px;
  background: var(--well);
}
.dr-level {
  min-width: 82px; color: var(--p500); font: 900 34px/1 var(--font-num);
  letter-spacing: -.05em;
}
.dr-hero-copy { min-width: 0; }
.dr-rank-name { color: var(--ink-hi); font-size: 16px; font-weight: 900; }
.dr-xp-total { margin-top: 3px; color: var(--ink-lo); font-size: 12px; }
.dr-progress { width: 100%; height: 10px; display: block; accent-color: var(--p400); }
.dr-progress-copy { margin-top: 7px; color: var(--ink-lo); font-size: 11px; }
.dr-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 16px; }
.dr-stat {
  min-width: 0; padding: 13px; border: 1px solid var(--hairline);
  border-radius: 13px; background: var(--raised);
}
.dr-stat b { display: block; color: var(--ink-hi); font-size: 17px; }
.dr-stat span { display: block; margin-top: 2px; color: var(--ink-lo); font-size: 10px; }
.dr-foot { margin: 16px 0 0; color: var(--ink-lo); font-size: 11px; line-height: 1.5; }
@keyframes dr-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes dr-rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }

#walletCtl { position: relative; flex: 0 0 auto; }
#walletBtn {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--raised);
  border: 1px solid var(--hairline-2);
  border-radius: 8px;
  padding: 6px 12px;
  color: var(--ink-mid); font-size: 12px; font-weight: 700;
  white-space: nowrap;
  transition: border-color .16s ease, background .16s ease, color .16s ease, box-shadow .16s ease;
}
#walletBtn:hover { border-color: var(--p500); color: var(--ink-hi); }
#walletBtn .wc-dot {
  width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto;
  background: var(--ink-faint);
  box-shadow: 0 0 0 0 rgba(77,169,238,.5);
}
#walletBtn:not(.is-on) .wc-dot { background: var(--p400); animation: wc-pulse 2.2s ease-in-out infinite; }
#walletBtn.is-on {
  background: var(--tint);
  border-color: var(--p400);
  color: var(--ink-hi);
  box-shadow: 0 0 0 1px var(--p300) inset, 0 0 16px var(--ring);
}
#walletBtn.is-on .wc-dot { background: var(--gain); box-shadow: 0 0 10px var(--gain); animation: none; }
#walletBtn.is-on .wc-label { font-variant-numeric: tabular-nums lining-nums; }
#walletBtn[disabled] { opacity: .6; }
@keyframes wc-pulse {
  0%,100% { box-shadow: 0 0 0 0 var(--ring); }
  50%     { box-shadow: 0 0 0 5px transparent; }
}

/* the popover menu — pinned under the chip, right-aligned */
#walletMenu {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  min-width: 220px;
  display: flex; flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--hairline-2);
  border-radius: 12px;
  padding: 8px;
  box-shadow: 0 20px 60px var(--shadow-card);
  animation: wm-in .16s ease;
}
@keyframes wm-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }
.wm-addr {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 6px 8px 8px; margin-bottom: 4px;
  border-bottom: 1px solid var(--hairline);
}
.wm-addr-k { color: var(--ink-lo); font-size: 10px; text-transform: uppercase; letter-spacing: .08em; }
.wm-addr-v { color: var(--ink-hi); font-weight: 700; font-size: 13px; }
.wm-item {
  text-align: left; width: 100%;
  padding: 9px 8px; border-radius: 8px;
  color: var(--ink-mid); font-size: 13px; font-weight: 600;
}
.wm-item:hover { background: var(--hover); color: var(--ink-hi); }
.wm-danger { color: var(--loss); }
.wm-danger:hover { background: rgba(242,84,91,.12); color: var(--loss); }

/* ---------------------------------------------------------------------------
   6j · ACCOUNT VIEW — logged-out auth card + logged-in profile + holdings.
   Slick, animated, on-brand (sky-blue). The auth card carries a slow-rotating
   conic glow behind it; motion is killed under §7. Everything is theme-aware
   through the shared tokens.
   ------------------------------------------------------------------------ */
/* push the Account tab to the far right — the "you" corner of the shop */
.tab-account { margin-left: auto; }

#view-account { width: 100%; padding: 22px clamp(16px, 2vw, 40px) 90px; }
#accWrap { width: 100%; }

/* ---- logged-out: the auth card ---- */
#accAuth { display: flex; justify-content: center; }
#accAuthCard {
  position: relative;
  width: min(440px, 100%);
  display: flex; flex-direction: column; gap: 16px;
  padding: 26px 24px 24px;
  background: linear-gradient(180deg, var(--tint-weak), transparent), var(--panel);
  border: 1px solid var(--hairline-2);
  border-radius: 20px;
  box-shadow: 0 24px 70px var(--shadow-card), 0 0 0 1px var(--tint-weak) inset;
  overflow: hidden;
}
/* the slow conic halo behind the card content */
#accAuthCard::before {
  content: ""; position: absolute; inset: -40%; z-index: 0;
  background: conic-gradient(from 0deg, transparent 0 60%, var(--ring) 78%, transparent 92%);
  opacity: .5; filter: blur(24px);
  animation: acc-spin 14s linear infinite;
  pointer-events: none;
}
#accAuthCard > * { position: relative; z-index: 1; }
@keyframes acc-spin { to { transform: rotate(360deg); } }

.acc-head h2 { margin: 0 0 6px; font-size: clamp(28px, 5vw, 46px); padding: 2px 10px 4px 2px; overflow: visible; }
.acc-sub { margin: 0; color: var(--ink-lo); font-size: 13px; line-height: 1.5; }

#accModeToggle {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
  background: var(--well); border: 1px solid var(--hairline); border-radius: 10px; padding: 4px;
}
.acc-mode {
  padding: 9px 10px; border-radius: 7px;
  color: var(--ink-lo); font-size: 13px; font-weight: 700;
  transition: background .16s ease, color .16s ease;
}
.acc-mode[aria-pressed="true"] { background: var(--p400); color: var(--on-accent); box-shadow: 0 4px 14px var(--ring); }
.acc-mode[aria-pressed="false"]:hover { color: var(--ink-hi); background: var(--hover); }

#accAuthForm { display: flex; flex-direction: column; gap: 12px; }
.acc-field { display: flex; flex-direction: column; gap: 5px; }
.acc-lab { color: var(--ink-lo); font-size: 11px; text-transform: uppercase; letter-spacing: .06em; }
.acc-field input {
  width: 100%;
  background: var(--raised); border: 1px solid var(--hairline-2); border-radius: 10px;
  padding: 11px 12px; color: var(--ink-hi);
}
.acc-field input::placeholder { color: var(--ink-faint); }
.acc-field input:focus { border-color: var(--p500); box-shadow: 0 0 0 3px var(--ring); }

.acc-msg { font-size: 12.5px; line-height: 1.45; padding: 8px 10px; border-radius: 8px; }
.acc-msg.err { color: var(--loss); background: rgba(242,84,91,.10); border: 1px solid rgba(242,84,91,.30); }
.acc-msg.ok  { color: var(--gain); background: rgba(59,224,138,.10); border: 1px solid rgba(59,224,138,.28); }

.acc-primary {
  width: 100%;
  background: var(--p400); color: var(--on-accent);
  border: 1px solid var(--p500); border-radius: 10px;
  padding: 12px 14px; font-size: 14px; font-weight: 800; letter-spacing: .01em;
  transition: transform .12s ease, box-shadow .16s ease, background .16s ease;
}
.acc-primary:hover { background: var(--p500); box-shadow: 0 10px 30px var(--ring); transform: translateY(-1px); }
.acc-primary[disabled] { opacity: .7; transform: none; }

.acc-divider { display: flex; align-items: center; gap: 10px; color: var(--ink-faint); font-size: 11px; text-transform: uppercase; letter-spacing: .1em; }
.acc-divider::before, .acc-divider::after { content: ""; flex: 1 1 auto; height: 1px; background: var(--hairline-2); }

#accTgMount { display: flex; justify-content: center; min-height: 40px; }

.acc-ghost {
  width: 100%;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--raised); border: 1px solid var(--hairline-2); border-radius: 10px;
  padding: 11px 14px; color: var(--ink-hi); font-size: 13.5px; font-weight: 700;
  transition: border-color .16s ease, background .16s ease;
}
.acc-ghost:hover { border-color: var(--p500); background: var(--hover); }
.acc-ghost .wc-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--p400); box-shadow: 0 0 10px var(--ring); }
.acc-fine { margin: 0; color: var(--ink-faint); font-size: 11.5px; line-height: 1.45; text-align: center; }

/* ---- logged-in: profile ---- */
#accProfileHead {
  display: flex; align-items: center; gap: 16px;
  padding: 4px 2px 20px; margin-bottom: 18px;
  border-bottom: 1px solid var(--hairline);
}
#accAvatar {
  flex: 0 0 auto; width: 58px; height: 58px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--p300), var(--p500));
  color: var(--on-accent); font-weight: 900; font-size: 26px;
  box-shadow: 0 0 0 2px var(--panel), 0 0 22px var(--ring);
}
#accWho { flex: 1 1 auto; min-width: 0; }
#accName { margin: 0; font-size: clamp(24px, 4vw, 38px); padding: 2px 10px 3px 2px; overflow: visible; }
#accHandles { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 2px; }
.acc-tg { color: var(--p500); font-weight: 700; font-size: 13px; }
#accLogout {
  flex: 0 0 auto;
  background: var(--raised); border: 1px solid var(--hairline-2); border-radius: 8px;
  padding: 8px 14px; color: var(--ink-mid); font-size: 12.5px; font-weight: 700;
}
#accLogout:hover { border-color: var(--loss); color: var(--loss); }

#accWalletRow {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 14px 16px; margin-bottom: 24px;
  background: var(--panel); border: 1px solid var(--hairline-2); border-radius: 14px;
}
.acc-wallet-lab { color: var(--ink-lo); font-size: 11px; text-transform: uppercase; letter-spacing: .08em; }
#accWalletState { flex: 1 1 auto; min-width: 0; }
.acc-wchip { display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.acc-wchip-addr {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--tint); border: 1px solid var(--p400); border-radius: 8px;
  padding: 7px 12px; color: var(--ink-hi); font-weight: 700; font-size: 13px;
  box-shadow: 0 0 0 1px var(--p300) inset;
}
.acc-wlink { color: var(--ink-lo); font-size: 12px; font-weight: 700; padding: 4px 6px; border-radius: 6px; }
.acc-wlink:hover { background: var(--hover); color: var(--ink-hi); }
.acc-wdanger:hover { color: var(--loss); background: rgba(242,84,91,.12); }
.acc-connect { width: auto; display: inline-flex; }

/* ---- holdings ---- */
#accHoldings { width: 100%; }
#accHoldingsHead { display: flex; align-items: baseline; gap: 12px; margin-bottom: 12px; }
#accHoldingsHead h3 { margin: 0; font-size: clamp(20px, 3.4vw, 34px); padding: 2px 8px 3px 2px; overflow: visible; }
.acc-hcount { color: var(--ink-lo); font-size: 12px; font-weight: 700; }

#accHoldingsFilters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.acc-hchip {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--raised); border: 1px solid var(--hairline-2); border-radius: 999px;
  padding: 6px 12px; color: var(--ink-mid); font-size: 12.5px; font-weight: 700;
  transition: border-color .16s ease, background .16s ease, color .16s ease;
}
.acc-hchip:hover { border-color: var(--p500); color: var(--ink-hi); }
.acc-hchip.is-on { background: var(--p400); border-color: var(--p500); color: var(--on-accent); box-shadow: 0 4px 14px var(--ring); }
.acc-hchip-c {
  background: var(--well); border-radius: 999px; padding: 0 7px;
  font-size: 11px; color: var(--ink-lo);
}
.acc-hchip.is-on .acc-hchip-c { background: rgba(0,0,0,.18); color: var(--on-accent); }

#accHoldingsGrid.view-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: clamp(12px, 1.2vw, 18px);
}
.acc-hcoll { color: var(--ink-lo); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

#accHoldingsState {
  padding: 40px 18px; text-align: center;
  color: var(--ink-lo); font-size: 13px;
  border: 1px dashed var(--hairline-2); border-radius: 16px;
}
#accHoldingsState .gs-title { color: var(--ink-hi); font-weight: 800; font-size: 16px; margin-bottom: 6px; }

@media (max-width: 719px) {
  #view-account { padding: 14px 10px 90px; }
  #accProfileHead { gap: 12px; }
  #accAvatar { width: 48px; height: 48px; font-size: 22px; }
  #accHoldingsGrid.view-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tab-account { margin-left: 0; }   /* the tab bar scrolls on mobile — no push */
}
@media (max-width: 419px) {
  #accHoldingsGrid.view-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------------------------------------------------------------------------
   7 · REDUCED MOTION — rotation is stopped in JS (the timer never starts);
   everything else that moves is killed here. Motion on this page is
   decoration, never data, so nothing is lost.
   ------------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
  #rsWindow { scroll-behavior: auto; }
}

/* ---------------------------------------------------------------------------
   8 · MOBILE — single column under 720px (addendum A2). Same DOM: the rail
   collapses behind #filtersToggle, the tester panel becomes a bottom sheet.
   ------------------------------------------------------------------------ */
@media (max-width: 719px) {
  #topbar { flex-wrap: wrap; gap: 8px; padding: 8px 10px; }
  #searchwrap { order: 3; flex-basis: 100%; max-width: none; }
  .b-by, .ctl-label { display: none; }
  #gwTutStart .gts-t { display: none; }   /* "?" survives, the word collapses */
  #gwTutStart { padding: 5px 7px; }

  /* TOPCTL — the control cluster (sort · theme · wallet · view · tutorial) packs
     ~526px of non-shrinkable controls into one row. On a phone that forces the
     layout viewport wider than the screen (shrink-to-fit), which was clipping
     the centered brandbar wordmark and adding horizontal scroll. flex-wrap lets
     the controls flow onto a second line so the row fits the screen. */
  #topctl { flex-wrap: wrap; justify-content: flex-end; row-gap: 8px; margin-left: 0; }
  /* 16px inputs so iOS Safari never zooms the page on focus */
  #q, #sort { font-size: 16px; }
  /* finger-sized tap targets on the wrapped control row */
  #viewtoggle button { min-width: 40px; min-height: 40px; }
  #gwTutStart, #walletBtn, #sort { min-height: 38px; }
  #degenRankChip { min-height: 40px; padding: 7px 9px; }

  #layout {
    grid-template-columns: minmax(0, 1fr);
    padding: 10px 10px 90px;
  }

  #filtersToggle {
    display: block;
    background: var(--panel);
    border: 1px solid var(--hairline-2);
    border-radius: 8px;
    padding: 8px 12px;
    color: var(--ink-hi);
    text-align: left;
  }
  #filtersToggle[aria-expanded="true"] { border-color: var(--p500); }
  #filtersCount { color: var(--p600); font-size: 11px; }

  /* collapsed by default; the toggle flips this class */
  #filters { display: none; position: static; max-height: none; }
  #filters.open { display: flex; }

  #grid.view-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* the topbar wraps to two rows on mobile, so a fixed sticky offset would
     overlap it — the tab bar scrolls with the page instead. */
  #tabbar { position: static; }
  #homeShowcase { padding: 24px 12px 80px; }
  .hs-grid { grid-template-columns: 1fr; gap: 12px; }
  .hs-card { min-height: 0; animation: none; }   /* no float on phones */
  #view-stats, #view-nfts, #view-wtf { padding: 12px 10px 90px; }
  #recentsales { padding: 10px 10px 12px; }
  #rsSub { display: none; }            /* header stays one tidy line on phones */
  #nftsState { padding: 32px 14px; }

  /* list rows shed the trait column first — name and price survive */
  .view-list .c-rarity { display: none; }

  #tester {
    right: 0; left: 0; bottom: 0;
    width: auto;
    border-radius: 12px 12px 0 0;
    border-bottom: 0;
    /* bottom sheet clears the home indicator / TG bottom inset */
    padding-bottom: max(14px, env(safe-area-inset-bottom));
  }
  #testerFab {
    bottom: max(14px, env(safe-area-inset-bottom));
    right: max(14px, env(safe-area-inset-right));
  }
  body.tester-panel-open #testerFab { display: none; }  /* the sheet covers it */

  /* new-section rhythm + touch targets on phones */
  #hotnow, #hotdeals, #topgifts { padding: 18px 10px 6px; }
  /* reels wrap to two-up; the ranked list stacks to a single column */
  #topgiftsReels { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  #topgiftsList { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto; grid-auto-flow: row; gap: 4px; }
  /* ranked rows: keep name + one stat legible, drop rigid stat widths so a row
     never overflows the viewport */
  .tg-row { gap: 10px; padding: 9px 8px; }
  .tg-img { width: 46px; height: 46px; }
  .tg-name { font-size: 14px; }
  .tg-floor { min-width: 0; }
  .tg-sales { display: none; }             /* floor survives; 24h-sold sheds first */
  #view-collection { padding: 12px 10px 90px; }
  #cvHead { padding: 14px; gap: 12px; }
  #cvCover { width: 72px; height: 72px; }
  #cvName { font-size: 19px; }
  #cvTabs button[role="tab"] { padding: 12px 16px; }   /* >=40px tap height */
  /* theme toggle stays reachable and finger-sized when the topbar wraps */
  #themeToggle button { width: 40px; height: 40px; }
}

@media (max-width: 420px) {
  .dr-dialog { padding: 18px; border-radius: 17px; }
  .dr-stats { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  #degenRankChip, .dr-backdrop, .dr-dialog { animation: none; transition: none; }
}

@media (max-width: 419px) {
  #cvStatCards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hn-card { width: clamp(160px, 62vw, 220px); }   /* still image-forward, one-plus per view */
}

/* only drop the gift grids to a single column on the very narrowest phones —
   iPhone/Pixel-class widths (390–414px) keep two image-forward columns. */
@media (max-width: 359px) {
  #grid.view-grid { grid-template-columns: minmax(0, 1fr); }
  #hotdealsGrid.view-grid, #cvGrid.view-grid { grid-template-columns: minmax(0, 1fr); }
}

/* PLATFORM FOOTER — on every page */
.it-foot{
  display:flex; align-items:center; justify-content:center; flex-wrap:wrap;
  gap:12px; padding:26px 16px 40px; margin-top:24px;
  border-top:1px solid var(--hairline-2);
  color:var(--ink-faint); font-size:13px;
}
.it-foot .foot-net{ display:inline-flex; align-items:center; gap:8px; color:var(--ink-lo); }
.it-foot .foot-hash{ width:18px; height:18px; border-radius:50%; }
.it-foot a{ color:var(--ink-lo); text-decoration:none; }
.it-foot a:hover{ color:var(--ink-hi); }
.it-foot .foot-pyonya b{ color:var(--ink-mid); }
.it-foot .foot-sep{ opacity:.45; }
/* footer integrations — the branded Intel Maps launcher (theme-aware pill) */
.it-foot .foot-devs{ display:inline-flex; align-items:center; gap:10px; }
.it-foot .foot-devlabel{ color:var(--ink-faint); font-size:11px; text-transform:uppercase; letter-spacing:.06em; }
.it-foot .foot-dev{ display:inline-flex; align-items:center; gap:5px; color:var(--ink-lo); white-space:nowrap; }
.it-foot .foot-dev img{ width:20px; height:20px; border-radius:50%; object-fit:cover; border:1px solid var(--hairline-2); }
.it-foot .foot-dev:hover{ color:var(--ink-hi); }
.it-foot .foot-legal{ display:inline-flex; align-items:center; gap:12px; }
.it-foot .foot-legal-link{ color:var(--ink-lo); text-decoration:none; }
.it-foot .foot-legal-link:hover{ color:var(--ink-hi); }
.it-foot .foot-integrations{ display:inline-flex; align-items:center; gap:8px; }
.it-foot .foot-intlabel{ color:var(--ink-faint); font-size:11px; text-transform:uppercase; letter-spacing:.06em; }
.it-foot .im-pill{
  display:inline-flex; align-items:center; gap:7px;
  padding:5px 12px 5px 9px; border-radius:999px;
  background:var(--raised); border:1px solid var(--hairline);
  color:var(--ink-hi); font-weight:700; font-size:12px;
}
.it-foot .im-pill:hover{ border-color:var(--p500); color:var(--ink-hi); }
.it-foot .im-pill .im-pop-mark{ width:15px; height:15px; }

/* PROXY-SELLER DISCLOSURE — one shared, scoped class used sitewide (footer +
   aggregated buy modal). Small, grey, informational; never a warning banner.
   Theme-aware via --ink-lo/--ink-faint tokens. Additive: does not alter any
   existing layout. */
.proxy-notice{
  display:block; color:var(--ink-faint); font-size:11px; line-height:1.5;
  letter-spacing:.01em; text-align:center;
}
.proxy-notice--foot{ flex-basis:100%; max-width:640px; margin:2px auto 0; }
.proxy-notice--buy{ text-align:left; margin-top:8px; color:var(--ink-lo); }

/* ===========================================================================
   7 · INTEL MAPS HOLDER-MAP WIDGET (build #6)

   Two surfaces, one visual language, both same-origin /app iframes:
     (A) #imStatsInlay — the Stats-tab COMPARE inlay (two maps + left cluster
         drawer + VS stat table under it).
     (B) #imModal / #imFloat — the collection-page pop: a full-size modal widget
         plus a SECOND, draggable, independently-closeable floating widget for
         compare.
   Theme-aware throughout via the shared tokens (dark/light/hashtag). The blue
   accent orbs come from the embed's accent=4DA9EE param; clusters are the map's
   own rainbow. The ONLY deliberately-fixed colour is the Intel Maps brand mark
   / the black-and-white .im-pop launcher (the IM app-tile is #0B0D12 in every
   theme, by brand).
   ------------------------------------------------------------------------ */

/* the IM brand mark — a dark rounded tile with the white node glyph. Fixed
   colour by brand; market.js injects the inline SVG. */
.im-mark {
  width: 24px; height: 24px; flex: 0 0 auto;
  border-radius: 6px; background: #0B0D12; color: #fff;   /* white mark on the dark app-tile */
  display: inline-grid; place-items: center;
}
.im-mark svg { width: 14px; height: 14px; display: block; }

/* ---- (A) STATS-TAB COMPARE INLAY ---------------------------------------- */
#imStatsInlay { margin-bottom: 20px; }
#imInlayNote {
  margin: 0 0 14px; padding: 22px 18px; text-align: center;
  color: var(--ink-lo); font-size: 12.5px;
  background: var(--panel); border: 1px dashed var(--hairline-2); border-radius: 12px;
}
.im-inlay {
  background:
    radial-gradient(120% 140% at 50% -10%, var(--tint-weak), transparent 60%),
    var(--panel);
  border: 1px solid var(--hairline-2); border-radius: 14px; overflow: hidden;
  box-shadow: 0 0 0 1px var(--tint-weak) inset;
}
.im-ih {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 14px; border-bottom: 1px solid var(--hairline);
  background: linear-gradient(90deg, var(--tint-weak), transparent);
}
.im-ih > b { color: var(--ink-hi); font-size: 14px; font-weight: 800; }
.im-ih-sub { color: var(--ink-lo); font-size: 11px; font-weight: 600; }
.im-ih-ctl { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.im-sel-lab { display: inline-flex; align-items: center; gap: 5px; color: var(--ink-lo); font-size: 10px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.im-sel {
  border: 1px solid var(--hairline-2); border-radius: 8px; padding: 6px 9px;
  background: var(--raised); color: var(--ink-hi); font-size: 12px; font-weight: 600;
  max-width: 160px; cursor: pointer;
}
.im-sel:hover { border-color: var(--p400); }
.im-wbtn {
  border: 1px solid var(--hairline-2); border-radius: 8px; padding: 7px 11px;
  background: var(--raised); color: var(--ink-hi);
  font-size: 12px; font-weight: 800; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 5px;
}
.im-wbtn:hover { border-color: var(--p400); }
.im-wbtn.on { background: var(--p400); color: var(--on-accent); border-color: var(--p500); }
.im-tag {
  color: var(--p700); font-size: 8.5px; font-weight: 800; letter-spacing: .08em;
  border: 1px solid var(--p500); border-radius: 5px; padding: 3px 6px;
}
.im-inlay-grid { display: grid; grid-template-columns: 250px 1fr; min-height: 0; }
.im-drawer {
  border-right: 1px solid var(--hairline); overflow-y: auto;
  max-height: 540px; background: var(--well);
}
.im-maps { display: grid; grid-template-columns: 1fr; height: 540px; background: var(--hairline); }
.im-maps.im-maps-cmp { grid-template-columns: 1fr 1fr; gap: 1px; }
.im-frame { width: 100%; height: 100%; border: 0; display: block; background: var(--well); min-height: 0; }

/* cluster drawer rows — the getgems rail, in our tokens. Honest-empty note
   until the map's intelmaps:clusters broadcast arrives. */
.im-cl-h {
  padding: 12px 14px 8px; margin: 0;
  color: var(--ink-hi); font-size: 11px; font-weight: 900; letter-spacing: .04em;
}
.im-cl-h span { color: var(--ink-faint); font-weight: 700; }
.im-cl-empty { padding: 16px 14px; color: var(--ink-faint); font-size: 11.5px; line-height: 1.5; }
.im-cl-row {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 9px 14px; border: 0; border-top: 1px solid var(--hairline);
  background: transparent; color: var(--ink-mid); font-size: 12px; font-weight: 700;
  text-align: left; cursor: pointer;
}
.im-cl-row:hover { background: var(--hover); }
.im-cl-row.on { background: var(--tint); color: var(--ink-hi); }
.im-rc-rank { width: 14px; color: var(--ink-faint); font-weight: 800; }
.im-rc-dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
.im-rc-pct { font-weight: 900; color: var(--ink-hi); }
.im-rc-w { margin-left: auto; color: var(--ink-lo); font-weight: 600; font-size: 11px; }

/* VS stat table UNDER the inlay — column-next-to-column, both collections. */
.im-vs { margin-top: 14px; overflow-x: auto; }
.im-vs:empty { display: none; }
.im-vs-table {
  border-collapse: collapse; min-width: 100%;
  background: var(--panel); border: 1px solid var(--hairline-2); border-radius: 10px; overflow: hidden;
}
.im-vs-table th, .im-vs-table td {
  padding: 9px 14px; border-bottom: 1px solid var(--hairline);
  text-align: right; white-space: nowrap;
}
.im-vs-table tbody tr:last-child th, .im-vs-table tbody tr:last-child td { border-bottom: 0; }
.im-vs-corner, .im-vs-colh { border-bottom: 1px solid var(--hairline-2) !important; background: var(--raised); }
.im-vs-colh { text-align: right; min-width: 130px; }
.im-vs-colhead { display: flex; align-items: center; gap: 7px; justify-content: flex-end; }
.im-vs-colhead img { width: 20px; height: 20px; border-radius: 5px; flex: 0 0 auto; }
.im-vs-cname { color: var(--ink-hi); font-weight: 700; font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 150px; }
.im-vs-rowh {
  text-align: left; color: var(--ink-lo);
  font-size: 10px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  position: sticky; left: 0; background: var(--panel);
}
.im-vs-cell { color: var(--ink-hi); font-weight: 700; }
.im-vs-cell .st-unit { color: var(--ink-lo); font-size: 10px; margin-left: 3px; }
.im-vs-cell .st-miss { color: var(--ink-faint); font-weight: 400; }

/* ---- (B) COLLECTION-PAGE POP: black-and-white launcher ------------------ */
.im-pop {
  position: absolute; top: 12px; right: 12px; z-index: 6;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 14px; border: 0; border-radius: 11px;
  background: #0B0D12; color: #fff; font-size: 12.5px; font-weight: 800;
  box-shadow: 0 6px 22px rgba(11,13,18,.4);
  animation: imPulse 1.6s ease-in-out infinite;
}
.im-pop:hover { background: #14171F; }
.im-pop-mark {
  width: 15px; height: 15px; flex: 0 0 auto;
  display: inline-grid; place-items: center;
}
.im-pop-mark svg { width: 15px; height: 15px; display: block; }
@keyframes imPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(77,169,238,.55), 0 6px 22px rgba(11,13,18,.4); }
  50% { box-shadow: 0 0 0 8px rgba(77,169,238,0), 0 6px 22px rgba(11,13,18,.4); }
}
@media (prefers-reduced-motion: reduce) { .im-pop { animation: none; } }

/* ---- (B) MODAL WIDGET --------------------------------------------------- */
.im-backdrop {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(6,9,14,.62); backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center; padding: 22px;
}
.im-backdrop[hidden] { display: none; }
.im-modal {
  width: min(1200px, 96vw); height: min(800px, 92vh);
  background: var(--panel); border: 1px solid var(--hairline-2); border-radius: 16px;
  overflow: hidden; display: flex; flex-direction: column;
  box-shadow: 0 40px 120px rgba(0,0,0,.55);
}
.im-modal-h {
  display: flex; align-items: center; gap: 11px; flex-wrap: wrap;
  padding: 12px 16px; border-bottom: 1px solid var(--hairline);
}
.im-modal-tt { display: flex; flex-direction: column; gap: 2px; }
.im-modal-tt b { color: var(--ink-hi); font-size: 15px; font-weight: 800; }
.im-modal-sub { color: var(--ink-lo); font-size: 10.5px; font-weight: 600; }
.im-modal-sub a { color: var(--p400); text-decoration: none; }
.im-modal-sub a:hover { text-decoration: underline; }
.im-x {
  width: 34px; height: 34px; border-radius: 9px;
  border: 1px solid var(--hairline-2); background: var(--raised);
  color: var(--ink-hi); font-size: 18px; line-height: 1;
}
.im-x:hover { border-color: var(--loss); color: var(--loss); }
.im-modal-body { flex: 1; display: grid; grid-template-columns: 1fr 300px; min-height: 0; }
.im-modal-body .im-maps { height: 100%; }
.im-modal-side { border-left: 1px solid var(--hairline); overflow-y: auto; background: var(--well); }

/* ---- (B) SECOND FLOATING WIDGET (compare) — draggable + own close -------- */
.im-float {
  position: fixed; top: 90px; left: 90px; z-index: 210;
  width: min(460px, 92vw); height: min(460px, 70vh);
  background: var(--panel); border: 1px solid var(--p500); border-radius: 14px;
  overflow: hidden; display: flex; flex-direction: column;
  box-shadow: 0 30px 90px rgba(0,0,0,.55);
}
.im-float-h {
  display: flex; align-items: center; gap: 9px;
  padding: 10px 12px; border-bottom: 1px solid var(--hairline);
  background: linear-gradient(90deg, var(--tint-weak), transparent);
  cursor: move; touch-action: none; user-select: none;
}
.im-float-h b { color: var(--ink-hi); font-size: 12.5px; font-weight: 800; }
.im-float-h .im-sel { margin-left: 2px; }
.im-float-x {
  margin-left: auto; width: 28px; height: 28px; border-radius: 8px;
  border: 1px solid var(--hairline-2); background: var(--raised);
  color: var(--ink-hi); font-size: 16px; line-height: 1;
}
.im-float-x:hover { border-color: var(--loss); color: var(--loss); }
.im-float-body { flex: 1; min-height: 0; }
.im-float-body .im-frame { height: 100%; }

/* ---- responsive: stack the inlay, sheet the modal ----------------------- */
@media (max-width: 860px) {
  .im-inlay-grid { grid-template-columns: 1fr; }
  .im-drawer { border-right: 0; border-bottom: 1px solid var(--hairline); max-height: 200px; }
  .im-maps { height: 440px; }
  .im-maps.im-maps-cmp { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
  .im-modal-body { grid-template-columns: 1fr; grid-template-rows: 1fr auto; }
  .im-modal-body .im-maps.im-maps-cmp { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
  .im-modal-side { border-left: 0; border-top: 1px solid var(--hairline); max-height: 40%; }
}
@media (max-width: 560px) {
  .im-backdrop { padding: 0; }
  .im-modal { width: 100vw; height: 100vh; height: 100dvh; border-radius: 0; }
  .im-ih-ctl { width: 100%; }
  .im-sel { max-width: 120px; }
}

/* =============================================================================
   THE ITEM PAGE — #itemModal overlay. Opened by a grid card click; the ONLY
   surface that carries the "Ask seller" chat. Scroll-locked, theme-aware.
   ========================================================================== */
.iv-backdrop {
  position: fixed; inset: 0; z-index: 8000;
  display: flex; align-items: center; justify-content: center; padding: 24px;
  background: rgba(4,6,10,.72); backdrop-filter: blur(6px);
  animation: iv-fade .18s ease;
}
@keyframes iv-fade { from { opacity: 0 } to { opacity: 1 } }
.iv-card {
  position: relative; width: min(760px, 96vw); max-height: 92vh; overflow: auto;
  display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1.15fr);
  background: var(--panel); border: 1px solid var(--hairline); border-radius: 18px;
  box-shadow: 0 30px 90px rgba(0,0,0,.6);
  animation: iv-rise .22s cubic-bezier(.2,.9,.3,1);
}
@keyframes iv-rise { from { transform: translateY(14px) scale(.98); opacity: 0 } to { transform: none; opacity: 1 } }
.iv-x {
  position: absolute; top: 10px; right: 10px; z-index: 2;
  width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--hairline);
  background: var(--raised); color: var(--ink-mid); font-size: 20px; line-height: 1; cursor: pointer;
}
.iv-x:hover { background: var(--hover); color: var(--ink-hi); }
.iv-art {
  background: var(--well); display: flex; align-items: center; justify-content: center;
  padding: 22px; border-right: 1px solid var(--hairline);
}
.iv-art img { width: 100%; height: auto; max-height: 420px; object-fit: contain; border-radius: 12px; }
.iv-info { padding: 26px 26px 24px; display: flex; flex-direction: column; gap: 12px; }
.iv-coll { color: var(--ink-lo); font-size: 12px; text-transform: uppercase; letter-spacing: .06em; font-weight: 700; }
.iv-name { color: var(--ink-hi); font-size: 24px; font-weight: 800; line-height: 1.15; margin: 0; }
.iv-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.iv-priceline { display: flex; align-items: baseline; gap: 8px; margin-top: 2px; }
.iv-price { color: var(--ink-hi); font-size: 26px; font-weight: 800; }
.iv-price.is-unknown { color: var(--ink-lo); font-size: 16px; font-weight: 700; }
.iv-price.iv-last { color: var(--ink-mid); }
.iv-cur { color: var(--ink-lo); font-size: 13px; font-weight: 700; letter-spacing: .04em; }
.iv-lastk { color: var(--ink-faint); font-size: 11px; text-transform: uppercase; letter-spacing: .05em; }
.iv-venue {
  align-self: flex-start; color: var(--ink-mid); font-size: 13px; font-weight: 700;
  text-decoration: none; border-bottom: 1px dashed var(--hairline); padding-bottom: 1px;
}
.iv-venue:hover { color: var(--ink-hi); }
.iv-actions { padding-top: 10px; }
.iv-actions .gc-ask { width: 100%; justify-content: center; font-size: 15px; padding: 13px 18px; }

/* make-an-offer (buy/sell in GRAM or any accepted memecoin) */
.iv-offer { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--hairline); display: flex; flex-direction: column; gap: 10px; }
.iv-offer-h { color: var(--ink-hi); font-size: 13px; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; }
.iv-seg { display: inline-flex; background: var(--well); border: 1px solid var(--hairline); border-radius: 10px; padding: 3px; align-self: flex-start; }
.iv-seg-b { padding: 6px 18px; border: 0; background: transparent; color: var(--ink-lo); font-weight: 700; font-size: 13px; border-radius: 8px; cursor: pointer; }
.iv-seg-b.is-on { background: var(--p300); color: var(--on-accent); }
.iv-offer-row { display: flex; gap: 8px; }
.iv-amt { flex: 1 1 auto; min-width: 0; }
.iv-cur-in { width: 100px; text-transform: uppercase; }
.iv-offer input { background: var(--raised); border: 1px solid var(--hairline); border-radius: 10px; padding: 11px 12px; color: var(--ink-hi); font-size: 14px; }
.iv-offer input::placeholder { color: var(--ink-faint); }
.iv-offer input:focus { outline: none; border-color: var(--p500); }
.iv-omsg { width: 100%; }
.iv-offer-send { padding: 12px 18px; border: 0; border-radius: 12px; background: var(--p300); color: var(--on-accent); font-weight: 800; font-size: 14px; cursor: pointer; }
.iv-offer-send:hover { filter: brightness(1.06); }
.iv-offer-send:disabled { opacity: .55; cursor: default; }
.iv-offer-status { font-size: 12.5px; color: var(--ink-lo); min-height: 16px; }
.iv-offer-status.is-err { color: var(--loss, #F2545B); }
.iv-offer-status.is-ok { color: var(--gain, #37D39B); }
.iv-offer-status.is-wait { color: var(--sweep, #F2A619); }
.iv-book { font-size: 12.5px; color: var(--ink-mid); padding: 8px 11px; border-radius: 9px; background: var(--well); border: 1px solid var(--hairline); }
.iv-book b { color: var(--ink-hi); }
.iv-book .iv-book-co { color: var(--ink-lo); font-size: 11px; }
.iv-buynow { width: 100%; padding: 13px 18px; border: 0; border-radius: 12px; background: var(--gain, #3BE08A); color: #04160D; font-weight: 800; font-size: 14.5px; cursor: pointer; }
.iv-buynow:hover { filter: brightness(1.06); }

/* #41 — compact ASKS + BIDS order book on the item page. Scoped iv-ob-*. */
.iv-ob { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--hairline); display: flex; flex-direction: column; gap: 10px; }
.iv-ob-h { color: var(--ink-hi); font-size: 13px; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; }
.iv-ob-load { font-size: 12.5px; color: var(--ink-lo); }
.iv-ob-stats { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; }
.iv-ob-st { background: var(--well); border: 1px solid var(--hairline); border-radius: 9px; padding: 8px 10px; text-align: center; }
.iv-ob-st-v { font-size: 15px; font-weight: 800; color: var(--ink-hi); font-variant-numeric: tabular-nums; }
.iv-ob-st-v .is-miss { color: var(--ink-faint); font-weight: 700; }
.iv-ob-st-l { font-size: 10.5px; color: var(--ink-lo); text-transform: uppercase; letter-spacing: .04em; margin-top: 2px; }
.iv-ob-st-ask .iv-ob-st-v { color: var(--loss, #F2545B); }
.iv-ob-st-bid .iv-ob-st-v { color: var(--gain, #3BE08A); }
.iv-ob-body { display: flex; flex-direction: column; gap: 3px; }
.iv-ob-sech { font-size: 10.5px; color: var(--ink-lo); text-transform: uppercase; letter-spacing: .05em; margin-top: 6px; }
.iv-ob-row { position: relative; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 8px; padding: 6px 9px; border-radius: 8px; background: var(--raised); border: 1px solid var(--hairline); overflow: hidden; }
.iv-ob-row.is-best { border-color: var(--ring); }
.iv-ob-depth { position: absolute; top: 0; bottom: 0; right: 0; pointer-events: none; }
.iv-ob-ask .iv-ob-depth { background: linear-gradient(90deg, rgba(242,84,91,0), rgba(242,84,91,.14)); }
.iv-ob-bid .iv-ob-depth { background: linear-gradient(90deg, rgba(59,224,138,0), rgba(59,224,138,.14)); }
.iv-ob-price { position: relative; font-weight: 800; font-size: 13px; min-width: 50px; font-variant-numeric: tabular-nums; }
.iv-ob-ask .iv-ob-price { color: var(--loss, #F2545B); }
.iv-ob-bid .iv-ob-price { color: var(--gain, #3BE08A); }
.iv-ob-mid { position: relative; font-size: 12px; color: var(--ink-mid); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.iv-ob-rare { margin-left: 6px; font-size: 10px; font-weight: 700; color: var(--sweep, #F2A619); background: var(--tint-weak); padding: 1px 5px; border-radius: 6px; }
.iv-ob-sz { position: relative; font-size: 11.5px; color: var(--ink-lo); font-variant-numeric: tabular-nums; }
.iv-ob-empty { font-size: 12px; color: var(--ink-lo); padding: 6px 9px; background: var(--well); border: 1px dashed var(--hairline); border-radius: 8px; }
.iv-ob-note { font-size: 11px; color: var(--ink-faint); padding: 2px 2px 0; }

/* =============================================================================
   FULL GIFT DETAIL — attributes (with rarity %) · description · stats ·
   transfer timeline from mint · sale-price sparkline. Appended into .iv-info;
   all classes iv-dt-* / iv-at-*. Theme-aware via the shared vars, so both the
   WTF pastel and the real Dark canvas read cleanly.
   ========================================================================== */
.iv-dt { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--hairline); display: flex; flex-direction: column; gap: 18px; }
.iv-dt-load { display: flex; align-items: center; gap: 9px; font-size: 12.5px; color: var(--ink-lo); }
.iv-dt-spin { width: 15px; height: 15px; border-radius: 50%; border: 2px solid var(--hairline); border-top-color: var(--p300); display: inline-block; animation: iv-dt-sp .7s linear infinite; }
@keyframes iv-dt-sp { to { transform: rotate(360deg); } }
.iv-dt-sec { display: flex; flex-direction: column; gap: 9px; }
.iv-dt-h { color: var(--ink-hi); font-size: 13px; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; display: flex; align-items: center; gap: 8px; }
.iv-dt-badge { font-size: 10px; font-weight: 700; text-transform: none; letter-spacing: 0; color: var(--ink-lo); background: var(--well); border: 1px solid var(--hairline); border-radius: 20px; padding: 2px 8px; }
.iv-dt-empty { font-size: 12px; color: var(--ink-lo); padding: 8px 11px; background: var(--well); border: 1px dashed var(--hairline); border-radius: 9px; }

/* attributes — rarer traits carry more emphasis */
.iv-dt-attrs { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 8px; }
.iv-at { background: var(--well); border: 1px solid var(--hairline); border-radius: 11px; padding: 9px 11px; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.iv-at-t { font-size: 10px; color: var(--ink-lo); text-transform: uppercase; letter-spacing: .05em; font-weight: 700; }
.iv-at-v { font-size: 14px; color: var(--ink-hi); font-weight: 800; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.iv-at-m { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 2px; }
.iv-at-r { font-size: 11px; font-weight: 800; color: var(--ink-mid); font-variant-numeric: tabular-nums; }
.iv-at-f { font-size: 10.5px; color: var(--ink-lo); font-variant-numeric: tabular-nums; }
.iv-at.is-lg { border-color: var(--sweep, #F2A619); box-shadow: inset 0 0 0 1px var(--sweep, #F2A619); }
.iv-at.is-lg .iv-at-r { color: var(--sweep, #F2A619); }
.iv-at.is-rare { border-color: var(--p500); }
.iv-at.is-rare .iv-at-r { color: var(--p300); }
.iv-at.is-unc .iv-at-r { color: var(--ink-hi); }

/* stats row */
.iv-dt-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); gap: 8px; }
.iv-dt-st { background: var(--well); border: 1px solid var(--hairline); border-radius: 10px; padding: 9px 8px; text-align: center; }
.iv-dt-st-v { font-size: 15px; font-weight: 800; color: var(--ink-hi); font-variant-numeric: tabular-nums; }
.iv-dt-st-v .is-miss { color: var(--ink-faint); font-weight: 700; }
.iv-dt-st-l { font-size: 10px; color: var(--ink-lo); text-transform: uppercase; letter-spacing: .04em; margin-top: 3px; }

/* description */
.iv-dt-desc { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink-mid); }

/* transfer timeline (mint -> now) */
.iv-dt-tl { display: flex; flex-direction: column; max-height: 360px; overflow-y: auto; padding-right: 2px; }
.iv-dt-ev { display: flex; gap: 11px; padding: 8px 2px; border-bottom: 1px solid var(--hairline); }
.iv-dt-ev:last-child { border-bottom: 0; }
.iv-dt-dot { flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%; margin-top: 4px; background: var(--ink-faint); box-shadow: 0 0 0 3px var(--well); }
.iv-dt-dot.k-sale { background: var(--gain, #3BE08A); }
.iv-dt-dot.k-mint { background: var(--p300); }
.iv-dt-dot.k-transfer { background: var(--ink-lo); }
.iv-dt-ev-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.iv-dt-ev-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.iv-dt-ev-kind { font-size: 12.5px; font-weight: 800; color: var(--ink-mid); }
.iv-dt-ev-kind.k-sale { color: var(--gain, #3BE08A); }
.iv-dt-ev-kind.k-mint { color: var(--p300); }
.iv-dt-ev-price { display: inline-flex; align-items: baseline; gap: 4px; font-weight: 800; color: var(--ink-hi); font-variant-numeric: tabular-nums; }
.iv-dt-ev-cur { font-size: 10px; font-weight: 700; color: var(--ink-lo); letter-spacing: .03em; }
.iv-dt-ev-usd { font-size: 11px; font-weight: 700; color: var(--ink-lo); }
.iv-dt-ev-sub { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 11.5px; color: var(--ink-lo); }
.iv-dt-ev-addr { font-variant-numeric: tabular-nums; }
.iv-dt-ev-mk { text-transform: uppercase; letter-spacing: .04em; font-size: 10px; background: var(--well); border: 1px solid var(--hairline); border-radius: 6px; padding: 1px 6px; color: var(--ink-mid); }
.iv-dt-tl-note { font-size: 11px; color: var(--ink-faint); padding: 6px 0 6px 20px; font-style: italic; }

/* sale-price sparkline + compact list */
.iv-dt-chart { background: var(--well); border: 1px solid var(--hairline); border-radius: 11px; padding: 12px; }
.iv-dt-spark { width: 100%; height: 72px; display: block; overflow: visible; }
.iv-dt-spark-area { fill: var(--tint-weak, rgba(247,168,216,.12)); stroke: none; }
.iv-dt-spark-line { fill: none; stroke: var(--p300); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.iv-dt-spark-dot { fill: var(--p300); stroke: var(--panel); stroke-width: 2; }
.iv-dt-chart-lab { display: flex; justify-content: space-between; margin-top: 6px; font-size: 10.5px; color: var(--ink-lo); font-variant-numeric: tabular-nums; }
.iv-dt-slist { display: flex; flex-direction: column; gap: 2px; margin-top: 8px; }
.iv-dt-srow { display: flex; align-items: center; justify-content: space-between; padding: 6px 9px; border-radius: 8px; background: var(--raised); border: 1px solid var(--hairline); }
.iv-dt-sdate { font-size: 11.5px; color: var(--ink-lo); }
.iv-dt-sprice { display: inline-flex; align-items: baseline; gap: 4px; font-weight: 800; color: var(--ink-hi); font-variant-numeric: tabular-nums; }

/* on a phone the item card stacks (art over info) so the detail grids get the
   full width and never force a horizontal scroll */
@media (max-width: 620px) {
  .iv-card { grid-template-columns: 1fr; }
  .iv-art { border-right: 0; border-bottom: 1px solid var(--hairline); }
  .iv-art img { max-height: 300px; }
}

/* =============================================================================
   GIFT SNIPER SCOPE — a FAB above the ◇ tester opens a metric picker; the
   reticle then auto-scrolls onto the best-fit gift, NEXT TARGET cycles the rest.
   ========================================================================== */
#sniperFab {
  position: fixed; right: 18px; bottom: 82px; z-index: 50;
  width: 52px; height: 52px; border-radius: 50%;
  background: var(--panel); border: 1px solid var(--p500); color: var(--p300);
  font-size: 24px; line-height: 1; box-shadow: 0 8px 24px rgba(0,0,0,.55);
}
#sniperFab:hover { border-color: var(--p700); color: var(--p500); }
#sniperFab[aria-pressed="true"] { background: var(--p300); color: var(--on-accent); border-color: var(--p700); }

/* metric picker */
.snp-panel {
  position: fixed; right: 18px; bottom: 144px; z-index: 60; width: 300px;
  max-height: calc(100vh - 170px); overflow-y: auto; overscroll-behavior: contain;
  background: var(--panel); border: 1px solid var(--hairline); border-radius: 14px;
  box-shadow: 0 18px 50px rgba(0,0,0,.6); padding: 14px;
  display: flex; flex-direction: column; gap: 10px; animation: snp-in .16s ease;
}
@keyframes snp-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.snp-h { color: var(--ink-hi); font-weight: 800; font-size: 13px; text-transform: uppercase; letter-spacing: .05em; }
.snp-row { display: flex; flex-direction: column; gap: 4px; }
.snp-lab { color: var(--ink-lo); font-size: 11px; text-transform: uppercase; letter-spacing: .05em; }
.snp-panel select, .snp-panel input[type="text"] {
  background: var(--raised); border: 1px solid var(--hairline); border-radius: 9px;
  padding: 9px 10px; color: var(--ink-hi); font-size: 13px;
}
.snp-panel select:focus, .snp-panel input:focus { outline: none; border-color: var(--p500); }
.snp-chk { display: flex; align-items: center; gap: 8px; color: var(--ink-mid); font-size: 13px; cursor: pointer; }
.snp-go { padding: 11px; border: 0; border-radius: 10px; background: var(--p300); color: var(--on-accent); font-weight: 800; font-size: 13px; cursor: pointer; }
.snp-go:hover { filter: brightness(1.06); }
.snp-note { color: var(--loss, #F2545B); font-size: 12px; min-height: 14px; }
.snp-note.is-ok { color: var(--win, #35c989); }
.snp-alert-go { padding: 10px; border: 1px solid var(--p500); border-radius: 10px; background: transparent; color: var(--p300); font-weight: 800; font-size: 12px; cursor: pointer; }
.snp-alert-go:hover { background: color-mix(in srgb, var(--p300) 10%, transparent); }
.snp-alert-go:disabled { opacity: .55; cursor: wait; }
.snp-alert-truth { color: var(--ink-lo); font-size: 10.5px; line-height: 1.35; }
.snp-alerts { display: flex; flex-direction: column; gap: 6px; border-top: 1px solid var(--hairline); padding-top: 9px; }
.snp-alert-head { display: flex; align-items: center; justify-content: space-between; color: var(--ink-lo); font-size: 9.5px; font-weight: 800; letter-spacing: .07em; }
.snp-alert-count { display: inline-flex; min-width: 18px; height: 18px; padding: 0 5px; align-items: center; justify-content: center; border-radius: 999px; background: var(--raised); color: var(--p300); }
.snp-alert-row { display: flex; align-items: center; gap: 8px; padding: 8px; border: 1px solid var(--hairline); border-radius: 9px; background: var(--raised); }
.snp-alert-copy { min-width: 0; flex: 1; }
.snp-alert-name { color: var(--ink-hi); font-size: 11px; font-weight: 750; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.snp-alert-rule, .snp-alert-empty { color: var(--ink-lo); font-size: 10.5px; line-height: 1.35; }
.snp-alert-x { flex: 0 0 auto; width: 24px; height: 24px; border-radius: 50%; border: 1px solid var(--hairline); background: var(--panel); color: var(--ink-mid); cursor: pointer; line-height: 1; }
.snp-alert-x:hover { color: var(--loss, #F2545B); border-color: currentColor; }

/* A Sniped mark appears inside the real item history only after the server
   joins an alerted listing to an indexed sale into the account's verified wallet. */
.iv-sniped { display: flex; align-items: center; gap: 8px; padding: 9px 10px; margin-bottom: 9px; border: 1px solid color-mix(in srgb, var(--win, #35c989) 55%, var(--hairline)); border-radius: 10px; background: color-mix(in srgb, var(--win, #35c989) 9%, var(--raised)); }
.iv-sniped-mark { flex: 0 0 auto; color: var(--win, #35c989); font-size: 12px; font-weight: 900; }
.iv-sniped-copy { color: var(--ink-mid); font-size: 10.5px; line-height: 1.35; }

/* the reticle overlay — glides between targets, never eats clicks */
.snp-scope {
  position: fixed; z-index: 55; pointer-events: none; left: 0; top: 0; width: 0; height: 0;
  transition: left .26s cubic-bezier(.2,.8,.2,1), top .26s cubic-bezier(.2,.8,.2,1), width .2s, height .2s;
}
.snp-scope::before {
  content: ""; position: absolute; inset: 0; border: 2px solid var(--p300); border-radius: 12px;
  box-shadow: 0 0 0 3px rgba(0,0,0,.35), 0 0 22px rgba(77,169,238,.6) inset;
}
/* corner brackets */
.snp-scope::after {
  content: ""; position: absolute; inset: -4px; border-radius: 14px;
  background:
    linear-gradient(var(--p300),var(--p300)) left top, linear-gradient(var(--p300),var(--p300)) left top,
    linear-gradient(var(--p300),var(--p300)) right top, linear-gradient(var(--p300),var(--p300)) right top,
    linear-gradient(var(--p300),var(--p300)) left bottom, linear-gradient(var(--p300),var(--p300)) left bottom,
    linear-gradient(var(--p300),var(--p300)) right bottom, linear-gradient(var(--p300),var(--p300)) right bottom;
  background-repeat: no-repeat;
  background-size: 16px 2px, 2px 16px, 16px 2px, 2px 16px, 16px 2px, 2px 16px, 16px 2px, 2px 16px;
}
.snp-cross { position: absolute; left: 50%; top: 50%; width: 30px; height: 30px; transform: translate(-50%,-50%); }
.snp-cross::before, .snp-cross::after { content: ""; position: absolute; background: var(--p300); box-shadow: 0 0 8px rgba(77,169,238,.9); }
.snp-cross::before { left: 50%; top: 0; width: 2px; height: 100%; transform: translateX(-50%); }
.snp-cross::after { top: 50%; left: 0; height: 2px; width: 100%; transform: translateY(-50%); }
.snp-scope.is-lock { animation: snp-lock .5s ease; }
@keyframes snp-lock { 0% { transform: scale(1.35); } 60% { transform: scale(.96); } 100% { transform: scale(1); } }

/* HUD */
.snp-hud {
  position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%); z-index: 60;
  display: flex; align-items: center; gap: 12px;
  background: var(--panel); border: 1px solid var(--p500); border-radius: 999px;
  padding: 8px 10px 8px 16px; box-shadow: 0 12px 34px rgba(0,0,0,.6); max-width: 92vw;
}
.snp-hud-info { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.snp-hud-count { color: var(--p300); font-weight: 800; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; }
.snp-hud-name { color: var(--ink-hi); font-weight: 700; font-size: 13px; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.snp-hud-meta { color: var(--ink-lo); font-size: 11px; }
.snp-next { padding: 9px 14px; border: 0; border-radius: 999px; background: var(--p300); color: var(--on-accent); font-weight: 800; font-size: 12px; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.snp-next:hover { filter: brightness(1.08); }
.snp-x { width: 30px; height: 30px; border-radius: 50%; border: 1px solid var(--hairline); background: var(--raised); color: var(--ink-mid); cursor: pointer; font-size: 16px; line-height: 1; }
.snp-x:hover { color: var(--ink-hi); }
@media (prefers-reduced-motion: reduce) {
  .snp-scope { transition: none; } .snp-scope.is-lock { animation: none; } .snp-panel { animation: none; }
}
@media (max-width: 640px) {
  .snp-panel { left: 10px; right: 10px; top: 112px; bottom: 88px; width: auto; max-height: none; }
  .iv-card { grid-template-columns: 1fr; max-height: 94vh; }
  .iv-art { border-right: 0; border-bottom: 1px solid var(--hairline); }
  .iv-art img { max-height: 300px; }
}
@media (prefers-reduced-motion: reduce) {
  .iv-backdrop, .iv-card { animation: none; }
}

/* =============================================================================
   GG-OVERHAUL — collection page restyle (2026-08-17, spec §1 + addendum 2).
   Surgical OVERRIDES appended last so they win over §6f above and the phone
   media blocks, without rewriting any existing rule. Everything reads theme
   vars, so the wtf + dark skins both apply for free. Getgems "white" is mapped
   to var(--ink-hi) so the pastel theme stays legible (deliberate translation).
   ========================================================================== */

/* ---- ADDENDUM 2 · LANDING LEAK KILL — entering a collection or an item must
   show ONLY header/tabbar + that view. The founder's recording shows home shop
   cards leaking above "Back to shop": #gwLanding self-mounts into #view-gifts
   and is relocated into #view-home AFTER boot, so for a beat (or on a failed
   relocation) landing nodes live outside the hidden view wrapper. Kill every
   home slab at the CSS level in both states, regardless of where the nodes
   currently sit in the DOM and regardless of JS state. !important beats any
   later display given by landing.css / flex rules. ------------------------- */
body[data-tab="collection"] #view-home,
body[data-tab="item"] #view-home,
body[data-tab="collection"] #gwLanding,
body[data-tab="item"] #gwLanding,
body[data-tab="collection"] .gw-hero,
body[data-tab="item"] .gw-hero,
body[data-tab="collection"] .gw-marquee,
body[data-tab="item"] .gw-marquee,
body[data-tab="collection"] .gw-slab,
body[data-tab="item"] .gw-slab,
body[data-tab="collection"] .gw-outro,
body[data-tab="item"] .gw-outro,
body[data-tab="collection"] #gwPhone,
body[data-tab="item"] #gwPhone,
body[data-tab="collection"] #homeShowcase,
body[data-tab="item"] #homeShowcase,
body[data-tab="collection"] #giftsGoats,
body[data-tab="item"] #giftsGoats,
body[data-tab="collection"] #recentsales,
body[data-tab="item"] #recentsales { display: none !important; }

/* ---- back link — quiet 13px muted text link, not a bordered pill ---------- */
#cvBack {
  background: transparent; border: 0; padding: 4px 2px; margin-bottom: 10px;
  color: var(--ink-lo); font-size: 13px; font-weight: 600;
}
#cvBack:hover { color: var(--ink-hi); background: transparent; border: 0; }

/* ---- COMPACT HERO — one ~90px band, no banner, no panel chrome. 64px
   radius-14 avatar · 28/700 name left · right-aligned label-over-value stat
   strip (the existing #cvFloor/#cvOwners/#cvItemsN spans, re-slotted by CSS:
   #cvHeadMain flips to a row and #cvStatRow rides margin-left:auto). --------- */
#cvHead {
  align-items: center; gap: 16px;
  min-height: 90px; padding: 10px 0; margin-bottom: 8px;
  background: none; border: 0; border-radius: 0;
}
#cvCover { width: 64px; height: 64px; border-radius: 14px; }
#cvHeadMain {
  flex-direction: row; align-items: center; justify-content: space-between;
  gap: 12px 28px; flex-wrap: wrap;
}
#cvName {
  font-size: 28px; font-weight: 700; line-height: 1.1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#cvStatRow { margin-left: auto; gap: 24px; flex-wrap: nowrap; }
.cv-stat { gap: 3px; }
#cvStatRow .cv-k { font-size: 11px; font-weight: 700; letter-spacing: .08em; }
#cvStatRow .cv-v,
#cvFloor, #cvOwners, #cvItemsN { font-size: 16px; font-weight: 700; line-height: 1.15; }
/* honest unknown stays dim-but-present (inherited rules keep the colour) */

/* ---- UNDERLINE TABS — getgems grammar: 14/600, active = ink-hi label + 2px
   ink-hi underline riding the full-width 1px hairline, inactive muted. ------- */
#cvTabs { gap: 6px; margin-bottom: 16px; border-bottom: 1px solid var(--hairline); }
#cvTabs button[role="tab"] {
  padding: 11px 14px; font-size: 14px; font-weight: 600;
  color: var(--ink-lo); background: transparent; border-radius: 0;
  border-bottom: 2px solid transparent;
}
#cvTabs button[role="tab"][aria-selected="true"] {
  color: var(--ink-hi); border-bottom-color: var(--ink-hi);
}

/* ---- ITEMS TOOLBAR — one 40px row over the grid: flex-1 search pill +
   compact sort select. market.js builds <div class="cv-toolbar"> with an
   <input class="cv-search"> and a <select class="cv-sort">. ------------------ */
.cv-toolbar { display: flex; align-items: center; gap: 10px; margin: 0 0 16px; }
.cv-toolbar .cv-search {
  flex: 1 1 auto; min-width: 0; height: 40px;
  background: var(--raised); border: 1px solid var(--hairline-2);
  border-radius: 999px; padding: 0 16px;
  color: var(--ink-hi); font-size: 13px;
}
.cv-toolbar .cv-search::placeholder { color: var(--ink-faint); }
.cv-toolbar .cv-search:focus {
  outline: none; border-color: var(--p500); box-shadow: 0 0 0 3px var(--ring);
}
.cv-toolbar .cv-sort {
  flex: 0 0 auto; height: 40px; max-width: 46%;
  background: var(--raised); border: 1px solid var(--hairline-2);
  border-radius: 10px; padding: 0 12px;
  color: var(--ink-hi); font-size: 13px; font-weight: 600;
}
.cv-toolbar .cv-sort:focus { outline: none; border-color: var(--p500); }

/* ---- ITEM GRID — getgems density: auto-fill minmax(150px,1fr), 16px gap
   (6-up at 1160). Card anatomy: radius-12 square media, 13/600 name, 14/700
   price row / bordered "Not For Sale" pill / grey last-sale. Cards are real
   <a href="#item=…"> now — neutralise anchor text styling defensively. ------- */
#cvGrid.view-grid {
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 16px;
}
#cvGrid .card { border-radius: 12px; }
#cvGrid a.card { text-decoration: none; color: inherit; cursor: pointer; }
#cvGrid .c-name { font-size: 13px; font-weight: 600; }
#cvGrid .c-price { font-size: 14px; font-weight: 700; }
#cvGrid .c-price.c-last { color: var(--ink-lo); font-weight: 600; font-size: 12.5px; }
/* bordered "Not For Sale" pill — market.js emits <span class="c-nfs"> in the
   priceline slot when an item is honestly unlisted (never a fake price). */
#cvGrid .c-nfs {
  display: inline-flex; align-items: center; align-self: flex-start;
  padding: 3px 9px; margin-top: 1px;
  border: 1px solid var(--hairline-2); border-radius: 999px;
  color: var(--ink-lo); font-size: 11px; font-weight: 600;
  letter-spacing: .02em; white-space: nowrap;
}
/* state chips moved ONTO the art (venue/offchain bottom-left, auction
   top-left) — additive: only applies when market.js parents a .chip inside
   .c-art, and only for states that are true in the data. Translucent dark
   over the artwork in both themes (it sits on an image, not a surface). */
#cvGrid .c-art .chip {
  position: absolute; z-index: 2; left: 8px; bottom: 8px;
  background: rgba(10, 8, 20, .55); color: #fff; border-color: transparent;
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
}
#cvGrid .c-art .chip.k-auction { top: 8px; bottom: auto; }
/* hover affordance — centered translucent "View gift" pill over the art.
   Pure CSS (::after), so the JS card builder stays untouched. */
#cvGrid .card .c-art::after {
  content: "View gift";
  position: absolute; z-index: 3; left: 50%; top: 50%;
  transform: translate(-50%, -50%) scale(.96);
  padding: 8px 14px; border-radius: 999px;
  background: rgba(10, 8, 20, .62); color: #fff;
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  font-size: 12px; font-weight: 700; letter-spacing: .01em; white-space: nowrap;
  opacity: 0; pointer-events: none;
  transition: opacity .16s ease, transform .16s ease;
}
#cvGrid .card:hover .c-art::after,
#cvGrid a.card:focus-visible .c-art::after {
  opacity: 1; transform: translate(-50%, -50%) scale(1);
}

/* ---- SHAPE-TRUE SKELETONS — #cvGridState becomes a grid of cards matching
   the real card dims exactly (zero layout shift on fill): grey art square +
   two shimmer bars. market.js adds class "cv-skel" + .cv-skel-card children;
   the :has() form keys the layout off the markup alone as a belt-and-braces.
   When #cvGridState instead carries an honest error/empty message (no skeleton
   cards), the §6f dashed-box styling above still applies untouched. ---------- */
#cvGridState.cv-skel,
#cvGridState:has(.cv-skel-card) {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 16px; padding: 0; text-align: left;
  background: transparent; border: 0;
}
.cv-skel-card {
  display: flex; flex-direction: column;
  background: var(--raised); border: 1px solid var(--hairline-2);
  border-radius: 12px; overflow: hidden;
}
.cv-skel-art { aspect-ratio: 1; background: var(--well); }
.cv-skel-bars {
  display: flex; flex-direction: column; gap: 5px;
  padding: 10px 11px 12px;
}
.cv-skel-bar { height: 16px; width: 80%; border-radius: 6px; background: var(--well); }
.cv-skel-bar + .cv-skel-bar { height: 17px; width: 55%; }
.cv-skel-art, .cv-skel-bar {
  background-image: linear-gradient(100deg, transparent 32%, var(--hover) 50%, transparent 68%);
  background-size: 220% 100%;
  animation: cvSkelShimmer 1.4s ease-in-out infinite;
}
@keyframes cvSkelShimmer {
  from { background-position: 130% 0; }
  to   { background-position: -30% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .cv-skel-art, .cv-skel-bar { animation: none; }
  #cvGrid .card .c-art::after { transition: none; }
}

/* ---- phones — the hero re-tightens (the §7 phone block above is overridden
   by these later base rules, so restate the narrow sizes here) --------------- */
@media (max-width: 640px) {
  #cvHead { min-height: 0; padding: 8px 0; }
  #cvName { font-size: 22px; white-space: normal; }
  #cvStatRow { margin-left: 0; gap: 18px; flex-wrap: wrap; }
  .cv-toolbar { flex-wrap: wrap; }
  .cv-toolbar .cv-search { flex-basis: 100%; }
  .cv-toolbar .cv-sort { max-width: none; }
}

/* GG-OVERHAUL perf: the gamify cards (streak/badges/arcade/bagcheck/bingo/
   seasons) self-mount into #gwLanding at boot and are then MOVED to the
   account shelf by trimLanding() — that async move showed as a visible flash
   of cards popping into the landing and vanishing. They are never meant to
   render inside the landing anymore, so hide them there unconditionally;
   they display normally once re-parented into #gwShelf. */
#gwLanding #gwStreak, #gwLanding #gwBadges, #gwLanding #gwArcade,
#gwLanding #gwBagCheck, #gwLanding #gwBingo, #gwLanding #gwSeasons { display: none !important; }
