/* Uppies v3 base: light studio system. Tokens, shell (header, footer), shared components. See /DESIGN.md. */
@font-face { font-family: 'General Sans'; src: url('../fonts/general-sans-400.woff2') format('woff2'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'General Sans'; src: url('../fonts/general-sans-500.woff2') format('woff2'); font-weight: 500; font-display: swap; }
@font-face { font-family: 'General Sans'; src: url('../fonts/general-sans-600.woff2') format('woff2'); font-weight: 600; font-display: swap; }
@font-face { font-family: 'Geist Mono'; src: url('../fonts/geist-mono-500.woff2') format('woff2'); font-weight: 400 500; font-display: swap; }

:root {
  /* studio */
  --wall: #e8e9eb;
  --wall-top: #e2e3e6;
  --key: #f7f7f8;
  --floor-far: #e0e0e0;
  --floor-near: #d8d8d6;
  --shade: 22 23 26;              /* rgb of contact shadows */
  /* surfaces on the wall */
  --surface: #f3f4f5;             /* panels, cards */
  --surface-2: #fbfbfc;           /* raised: dialogs, popovers */
  --line: #d0d2d6;                /* hairlines */
  --line-2: #808389;              /* control borders (3:1 on wall) */
  /* ink */
  --ink: #121315;
  --ink-2: #4f5258;               /* secondary text */
  --ink-3: #595c62;               /* meta (>= 4.5:1 on wall and floor) */
  --on-ink: #ffffff;
  /* signals: market only, never decoration */
  --up: #17643a;                  /* >= 4.5:1 on wall, floor and surfaces */
  --down: #962821;

  --f-sans: 'General Sans', system-ui, sans-serif;
  --f-num: 'Geist Mono', ui-monospace, monospace;

  /* type scale (max 4 per view) */
  --t-display: clamp(40px, 3.2vw + 20px, 76px);
  --t-h2: clamp(28px, 1.4vw + 16px, 36px);
  --t-body: 17px;
  --t-small: 15px;

  /* 4px spacing scale */
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-6: 24px; --s-8: 32px; --s-12: 48px; --s-16: 64px; --s-24: 96px;
  --gut: clamp(20px, 4.4vw, 64px);
  --max: 1328px;
  --top: 72px;
  --sub: 68px;
  --r: 14px;                      /* panels */
  --r-pill: 999px;                /* buttons, chips */

  --ease: cubic-bezier(.2, .7, .2, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  color-scheme: light;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
/* keyboard focus and in-page jumps never land under the sticky sub bar */
html:has(.subbar) { scroll-padding-top: calc(var(--top) + var(--sub)); }
/* no page scroll behind a modal dialog (token sheet, filter sheet) */
html:has(dialog[open]) { overflow: hidden; }
html:has(.subbar) { scrollbar-gutter: stable; } /* the lock above must not shift the page sideways */
body {
  margin: 0;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  font: 400 var(--t-body)/1.5 var(--f-sans);
  color: var(--ink);
  background: var(--wall);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  overflow-x: hidden;
}
main { flex: 1; }
main:focus { outline: none; } /* focused by the skip link */
h1, h2, h3 { margin: 0; font-weight: 500; text-wrap: balance; }
h1 { font-size: var(--t-display); line-height: 1; letter-spacing: -0.036em; }
h2 { font-size: var(--t-h2); line-height: 1.1; letter-spacing: -0.03em; }
h3 { font-size: 19px; line-height: 1.3; letter-spacing: -0.015em; }
p { margin: 0; text-wrap: pretty; }
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }
button { font: inherit; color: inherit; }
::selection { background: var(--ink); color: var(--on-ink); }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; border-radius: 6px; }
[hidden] { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* skip link: first focus stop on every page */
.skip {
  position: absolute; left: var(--s-2); top: var(--s-2); z-index: 60;
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--s-4);
  border-radius: var(--r-pill); background: var(--ink); color: var(--on-ink); font-size: var(--t-small); font-weight: 500;
  transform: translateY(calc(-100% - var(--s-4)));
}
.skip:focus-visible { transform: none; outline-offset: 2px; }
.frame { width: 100%; max-width: calc(var(--max) + 2 * var(--gut)); margin: 0 auto; padding: 0 var(--gut); }
.num { font-family: var(--f-num); font-weight: 500; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
/* mono gives "." a full cell: pull it in so "+1.24" never reads "+1 . 24"; "%" sits in the sans (see STONK.num) */
.num .dp { margin: 0 -0.2em; }
.num .pct { font-family: var(--f-sans); font-weight: inherit; letter-spacing: 0; margin-left: 0.04em; }
.muted { color: var(--ink-2); }
.pixel { image-rendering: pixelated; }

/* studio backdrop for any page */
.studio {
  background:
    radial-gradient(42% 46% at 44% 58%, #fafafb 0%, rgb(248 248 249 / .6) 45%, rgb(248 248 249 / 0) 100%),
    linear-gradient(to bottom, var(--wall-top) 0%, var(--wall) 40%);
}

/* ---------- header ---------- */
.top { position: relative; z-index: 30; height: var(--top); }
/* One header on every page: brand | tabs | end. The two side columns are equal (1fr), so the tabs sit at the
   same x on Home, NFT and Game at every width. The side groups are sized to fit down to 320px (see mobile). */
.top-inner { height: 100%; display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: var(--s-4); }
.brand { flex: none; display: inline-flex; align-items: center; gap: 10px; justify-self: start; min-height: 44px; font-weight: 500; font-size: 17px; letter-spacing: -0.01em; white-space: nowrap; }
.brand img { flex: none; width: 32px; height: 32px; min-width: 32px; max-width: none; border-radius: 50%; }
.tabs { display: flex; gap: var(--s-4); font-size: var(--t-small); }
/* 44 x 44 targets: the 8px side padding + 16px gap keep the same 32px visual spacing as before */
.tabs a { position: relative; display: inline-flex; align-items: center; justify-content: center; min-height: 44px; min-width: 44px; padding: 0 var(--s-2); color: var(--ink-2); transition: color .15s ease-out; }
.tabs a[aria-current='page'] { color: var(--ink); }
.tabs a[aria-current='page']::after { content: ''; position: absolute; left: 50%; bottom: 2px; width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: var(--ink); }
.top-end { justify-self: end; display: flex; align-items: center; gap: var(--s-3); }
@media (hover: hover) and (pointer: fine) { .tabs a:hover { color: var(--ink); } }

/* header round buttons (X, wallet on phones): 40px circles, 44px hit area */
.x-btn {
  position: relative; flex: none;
  width: 40px; height: 40px; display: inline-grid; place-items: center; border-radius: 50%;
  box-shadow: inset 0 0 0 1px var(--line-2); transition: background-color .15s ease-out, opacity .15s ease-out;
}
.x-btn::before, .wallet-btn::before { content: ''; position: absolute; inset: -2px; border-radius: 50%; }
.x-btn svg { width: 14px; height: 14px; fill: currentColor; }
@media (hover: hover) and (pointer: fine) { .x-btn:not([aria-disabled='true']):hover { background: rgb(255 255 255 / .7); } }
/* X account not live yet (STONK.config.xUrl empty): visibly disabled, not a dead live-looking button */
.x-btn[aria-disabled='true'] { opacity: .42; cursor: default; }

/* header wallet button (NFT, Game). Markup contract (DESIGN.md):
   <button class="btn-ghost btn-sm wallet-btn" id="wallet-btn" type="button"><svg class="wallet-ico">..</svg><span class="wallet-label">Connect</span></button>
   >= 760px: pill with icon + label. < 760px: 40px icon-only circle, label visually hidden but still the accessible name. */
.wallet { position: relative; }
.wallet-btn { position: relative; gap: var(--s-2); padding: 0 var(--s-4) 0 14px; }
.wallet-btn::before { border-radius: var(--r-pill); } /* inset -2px: the 40px pill has a 44px hit area */
.wallet-ico { flex: none; width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.wallet-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* ---------- sub tabs (second bar on NFT and Game): section title + a clear segmented switch ---------- */
.subbar { position: sticky; top: 0; z-index: 25; height: var(--sub); background: rgb(232 233 235 / .86); backdrop-filter: saturate(160%) blur(16px); -webkit-backdrop-filter: saturate(160%) blur(16px); border-bottom: 1px solid var(--line); }
.subbar-inner { height: 100%; display: flex; align-items: center; gap: var(--s-6); }
.subbar-title { font-weight: 600; font-size: 22px; letter-spacing: -0.02em; }
.subtabs {
  display: inline-flex; gap: 2px; padding: 4px;
  background: rgb(255 255 255 / .55); border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 1px var(--line);
}
.subtabs a {
  position: relative;
  display: inline-flex; align-items: center; height: 40px; padding: 0 var(--s-4);
  border-radius: var(--r-pill); font-size: var(--t-small); font-weight: 500; color: var(--ink-2); white-space: nowrap;
  transition: background-color .18s var(--ease-out), color .15s ease-out;
}
.subtabs a[aria-current='page'] { background: var(--ink); color: var(--on-ink); }
.subtabs a::before { content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 44px; transform: translateY(-50%); } /* 44px hit area */
/* ring inside the segment so it never spills onto the neighbour or the track; on the dark pill a white inset keeps it readable */
.subtabs a:focus-visible { outline-offset: -2px; border-radius: var(--r-pill); }
.subtabs a[aria-current='page']:focus-visible { box-shadow: inset 0 0 0 4px var(--on-ink); }
@media (hover: hover) and (pointer: fine) { .subtabs a:not([aria-current='page']):hover { color: var(--ink); background: rgb(255 255 255 / .8); } }
.view { display: none; }
.view.is-active { display: block; animation: view-in .22s var(--ease-out); }
/* opacity only: a moving view would resample the pixel art during the switch */
@keyframes view-in { from { opacity: 0; } to { opacity: 1; } }

/* ---------- buttons ---------- */
.btn, .btn-ghost {
  appearance: none; border: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  height: 48px; padding: 0 var(--s-6); border-radius: var(--r-pill);
  font: 500 var(--t-small)/1 var(--f-sans); white-space: nowrap;
  touch-action: manipulation;
  transition: background-color .15s ease-out, box-shadow .15s ease-out, transform .12s ease-out;
}
.btn { background: var(--ink); color: var(--on-ink); }
.btn svg { width: 14px; height: 14px; fill: currentColor; }
.btn-ghost { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1px var(--line-2); }
.btn-sm { height: 40px; padding: 0 var(--s-4); }
.btn:active, .btn-ghost:active { transform: scale(.97); }
@media (hover: hover) and (pointer: fine) {
  .btn:hover { background: #2a2c30; }
  .btn-ghost:hover { background: rgb(255 255 255 / .6); }
}
.btn[disabled], .btn[aria-disabled='true'] { background: #c9cbcf; color: #45484d; cursor: not-allowed; transform: none; }
.link { font-weight: 500; background: linear-gradient(currentColor, currentColor) 0 100% / 100% 1px no-repeat; padding-bottom: 2px; }
@media (hover: hover) and (pointer: fine) { .link:hover { background-size: 0 1px; background-position: 100% 100%; transition: background-size .25s ease-out; } }

/* ---------- surfaces ---------- */
.panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); }
.chip {
  display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 var(--s-3);
  border-radius: var(--r-pill); box-shadow: inset 0 0 0 1px var(--line-2);
  font-size: 14px; font-weight: 500; color: var(--ink-2); white-space: nowrap;
}
.chip[aria-pressed='true'] { background: var(--ink); color: var(--on-ink); box-shadow: none; }
.dot-up, .dot-down { display: inline-block; width: 8px; height: 8px; border-radius: 50%; }
.dot-up { background: var(--up); } .dot-down { background: var(--down); }
.spec { margin: 0; display: grid; }
.spec > div { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s-4); padding: 14px 0; border-top: 1px solid var(--line); }
.spec > div:last-child { border-bottom: 1px solid var(--line); }
.spec dt { color: var(--ink-2); font-size: var(--t-small); }
.spec dd { margin: 0; font-size: var(--t-small); font-weight: 500; text-align: right; }

/* pet art tile: the NFT image on its own background */
.art { border-radius: var(--r); overflow: hidden; background: var(--surface); }
.art img, .art canvas { width: 100%; height: auto; image-rendering: pixelated; }

/* dialog */
dialog.sheet {
  border: 1px solid var(--line); border-radius: 20px; padding: 0; background: var(--surface-2); color: var(--ink);
  width: min(920px, calc(100vw - 2 * var(--gut))); max-height: calc(100svh - 48px);
  overscroll-behavior: contain;
}
dialog.sheet::backdrop { background: rgb(18 19 21 / .32); backdrop-filter: blur(2px); }

/* ================================================================
   HEADER WALLET PANEL (built by StonkWallet.mountButton in js/wallet.js; used on NFT and Game)
   ================================================================ */
.wallet-btn .wallet-label.num { font-size: 14px; }
.wallet-pop {
  position: absolute; top: calc(100% + var(--s-2)); right: 0; z-index: 40;
  width: 300px; padding: var(--s-4); border: 1px solid var(--line); border-radius: var(--r);
  background: var(--surface-2); box-shadow: 0 16px 40px rgb(var(--shade) / .12);
  font-size: var(--t-small);
}
.wp-sec { display: grid; gap: var(--s-3); }
.wp-title { font-weight: 500; }
.wp-title.num { font-size: var(--t-small); }
.wp-text { color: var(--ink-2); }
.wp-actions { display: grid; gap: var(--s-2); }
.wp-actions .btn-ghost { width: 100%; }
/* install links: side by side when the panel is wide enough (phones from 360px), stacked otherwise */
.wp-actions.wp-install { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
/* connecting: on phones the label is hidden, so the icon dims and a small dot pulses (aria-busy is set too).
   Spinner-free; under reduced motion the dot stays still. */
@keyframes wallet-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
@media (max-width: 759px) {
  .wallet-btn[data-state='CONNECTING'] .wallet-ico { opacity: .5; }
  .wallet-btn[data-state='CONNECTING']::after {
    content: ''; position: absolute; top: 5px; right: 5px; width: 8px; height: 8px; border-radius: 50%;
    background: var(--ink-2); box-shadow: 0 0 0 2px var(--wall); animation: wallet-pulse 1.2s ease-in-out infinite;
  }
}
@media (max-width: 759px) {
  .wallet-pop { position: fixed; top: calc(var(--top) - var(--s-1)); left: var(--s-3); right: var(--s-3); width: auto; }
  /* connected: a small ink dot on the round icon button */
  .wallet-btn.is-on::after {
    content: ''; position: absolute; top: 5px; right: 5px; width: 8px; height: 8px; border-radius: 50%;
    background: var(--ink); box-shadow: 0 0 0 2px var(--wall);
  }
}
/* phones: the round wallet button sits 4px from the X, so their hit areas meet halfway; the wallet's grows 2px more to
   the left (into the empty gap before it) so it is a full 44x44 target on its own */
@media (max-width: 759px) { .top-end .wallet-btn::before { left: -4px; } }
/* touch screens: every panel control is at least 44px tall */
@media (pointer: coarse) {
  .wallet-pop .btn, .wallet-pop .btn-ghost { height: 44px; }
}


/* ---------- footer ---------- */
.foot { border-top: 1px solid var(--line); padding: var(--s-6) 0 calc(var(--s-6) + env(safe-area-inset-bottom)); }
.foot-inner { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: var(--s-3) var(--s-8); font-size: 14px; color: var(--ink-2); }
.foot-legal { display: grid; gap: var(--s-1); }
.foot-inner nav { display: flex; flex-wrap: wrap; gap: 0 var(--s-6); }
.foot-inner nav a { position: relative; display: inline-flex; align-items: center; min-height: 24px; }
.foot-inner nav a::before { content: ''; position: absolute; left: -4px; right: -4px; top: 50%; height: 44px; transform: translateY(-50%); } /* 44px hit area */
@media (hover: hover) and (pointer: fine) { .foot-inner a:hover { color: var(--ink); } }

/* ---------- 404 (404.html): a sleepy pet standing on the studio floor (js/lost.js draws it) ---------- */
.lost {
  position: relative; display: grid; grid-template-rows: minmax(0, 1fr) auto;
  margin-top: calc(-1 * var(--top)); padding-top: var(--top); overflow: hidden;
}
.lost-inner { position: relative; z-index: 1; display: grid; justify-items: start; align-content: center; gap: var(--s-4); padding-top: var(--s-12); padding-bottom: var(--s-6); }
.lost-lede { max-width: 36ch; color: var(--ink-2); }
.lost-actions { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-top: var(--s-4); }
/* the set: a floor band across the page; the pet's feet stand a little into it */
.lost-stage { position: relative; height: clamp(240px, 42svh, 480px); }
.lost-floor {
  position: absolute; left: 0; right: 0; bottom: 0; height: 58%;
  background: linear-gradient(to bottom, rgb(224 224 224 / 0), var(--floor-far) 34%, var(--floor-near) 78%, var(--wall));
}
.lost-pet { --s: 4; --foot: 0px; position: absolute; left: 0; bottom: 0; display: block; }
.lost-pet:not(.is-in) { display: none; } /* shown once js/lost.js has sized and placed it: it appears, it never jumps */
.lost-pet canvas { position: relative; z-index: 1; display: block; image-rendering: pixelated; image-rendering: crisp-edges; }
.lost-pet::before, .lost-pet::after { content: ''; position: absolute; z-index: 0; pointer-events: none; border-radius: 50%; }
.lost-pet::after {
  left: 16%; right: 10%; bottom: calc(var(--foot) - var(--s) * 1.6px); height: calc(var(--s) * 3.2px);
  background: radial-gradient(closest-side, rgb(var(--shade) / .5), rgb(var(--shade) / .2) 60%, rgb(var(--shade) / 0));
  filter: blur(calc(var(--s) * .5px));
}
.lost-pet::before {
  left: 4%; right: -2%; bottom: calc(var(--foot) - var(--s) * 5px); height: calc(var(--s) * 10px);
  background: radial-gradient(closest-side, rgb(var(--shade) / .16), rgb(var(--shade) / 0));
}
@media (max-width: 759px) {
  .lost-inner { padding-top: var(--s-8); padding-bottom: var(--s-2); align-content: start; }
  .lost-stage { height: clamp(208px, 38svh, 320px); }
}

/* ---------- mobile shell ---------- */
@media (max-width: 759px) {
  :root { --top: 60px; --t-body: 16px; --tab-pad: 10px; }
  /* same 1fr auto 1fr grid as desktop: the tabs never move between pages */
  .top-inner { gap: var(--s-2); }
  .brand { min-width: 44px; }
  .brand span { display: none; }
  /* tabs: contiguous 44px-tall targets, the visual gap comes from their padding */
  .tabs { gap: 0; }
  .tabs a { min-width: 44px; padding: 0 var(--tab-pad); }
  .top .top-end { gap: var(--s-1); } /* same group width on every page (page css must not override) */
  /* wallet: icon-only circle, the label stays the accessible name */
  .top-end #wallet-btn.wallet-btn { width: 40px; min-width: 0; max-width: none; height: 40px; padding: 0; border-radius: 50%; }
  .wallet-btn::before { border-radius: 50%; }
  .wallet-btn .wallet-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .wallet-btn .wallet-ico { display: block; }
  .subbar-title { display: none; }
  .subbar-inner { overflow-x: auto; scrollbar-width: none; justify-content: center; }
  .subtabs a { height: 44px; padding: 0 var(--s-4); }
  .foot-inner nav a { min-height: 44px; }
}
@media (max-width: 399px) { :root { --tab-pad: 6px; } .top-inner { gap: var(--s-1); } }
@media (max-width: 369px) { :root { --gut: 16px; --tab-pad: 4px; } }
/* small phones: round buttons 36px (hit area still 44px), so the tab boxes never touch the side groups */
@media (max-width: 359px) {
  .top-inner { gap: 0; }
  .x-btn, .top-end #wallet-btn.wallet-btn { width: 36px; height: 36px; }
  .x-btn::before, .wallet-btn::before { inset: -4px; }
}
/* 320: smallest phones. Tabs one size down */
@media (max-width: 339px) {
  /* the X icon is disabled until the account exists: on the smallest phones it steps aside so the tabs keep clear gaps */
  :root { --tab-pad: 8px; }
  .top-end .x-btn[aria-disabled='true'] { display: none; }
  .top-inner { padding: 0 var(--s-3); }
  .tabs { font-size: 14px; }
}

@media (prefers-reduced-motion: reduce) {
  .view.is-active { animation: fade .15s linear; }
  .skip { transition: none; }
  @keyframes fade { from { opacity: 0; } to { opacity: 1; } }
  .btn:active, .btn-ghost:active { transform: none; }
  .wallet-btn[data-state='CONNECTING']::after { animation: none; }
}
