/* =========================================================
   SOGGY — Launchpad
   A trading-floor surface: dark vault greens, brass accents, and the market
   furniture (odometers, shelves, live re-sorting) a token market needs.
   Self-contained — it does not load the marketing site's stylesheet.
   ========================================================= */

:root {
  /* Surfaces — the vault, from deepest to card fill. */
  --bg: #0a1a12;
  --surface-1: #0f2419;
  --surface-2: #132e20;      /* card fill */
  --surface-3: #1a3c2a;
  --surface-4: #24513a;

  --border: rgba(243, 236, 217, .085);
  --border-strong: rgba(243, 236, 217, .19);
  --border-gold: rgba(214, 174, 74, .42);

  --text-1: #f7f3e6;
  --text-2: rgba(247, 243, 230, .64);
  --text-3: rgba(247, 243, 230, .40);

  --gold: #d6ae4a;
  --gold-light: #f0d77c;
  --gold-deep: #a8842f;
  --cream: #f3ecd9;

  --positive: #7bd44f;
  --negative: #ef6a45;

  --radius-lg: 22px;
  --radius: 16px;
  --radius-sm: 11px;
  --radius-pill: 999px;

  --dur-fast: .15s;
  --dur-base: .22s;
  --dur-slow: .34s;
  --ease: cubic-bezier(.2, .8, .2, 1);
  --ease-emphasized: cubic-bezier(.23, 1, .32, 1);

  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --serif: Georgia, "Times New Roman", serif;

  --header-h: 62px;
  --rail-w: 372px;
  --container: 1420px;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  /* Sticky footer. Without it a short or still-loading page leaves the footer
     stranded in the middle, with page background running on below it. */
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--text-1);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
/* The faint vault texture the marketing site uses, at half strength. */
body::before {
  content: "";
  position: fixed; inset: 0; z-index: 0;
  opacity: .03; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E");
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button, input, select { font: inherit; color: inherit; }
button { -webkit-tap-highlight-color: transparent; }
::selection { background: var(--gold); color: #0a1a12; }

.container { width: min(calc(100% - 40px), var(--container)); margin-inline: auto; }
.mono { font-family: var(--mono); }
.tnum { font-variant-numeric: tabular-nums; }
.hidden { display: none !important; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.pos { color: var(--positive); }
.neg { color: var(--negative); }
.muted { color: var(--text-2); }

:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-radius: 6px; }

/* ============================================================ top bar === */

.topbar {
  position: sticky; top: 0; z-index: 40;
  height: var(--header-h);
  display: flex; align-items: center;
  background: rgba(10, 26, 18, .86);
  border-bottom: 1px solid var(--border);
  backdrop-filter: blur(18px) saturate(1.3);
}
.topbar-inner {
  width: min(calc(100% - 32px), var(--container));
  margin-inline: auto;
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; gap: 18px;
}

.brand { display: inline-flex; align-items: center; gap: 10px; min-width: max-content; }
.brand img { width: 30px; height: 30px; border-radius: 50%; box-shadow: 0 0 0 1px var(--border-gold); }
.brand-name { font-family: var(--serif); font-size: 17px; letter-spacing: -.02em; }
.brand-tag {
  padding: 2px 8px; border-radius: var(--radius-pill);
  background: rgba(214, 174, 74, .16); color: var(--gold-light);
  font-size: 10px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
}

.search-wrap { position: relative; justify-self: center; width: min(100%, 420px); }
.search-wrap .icon {
  position: absolute; left: 13px; top: 50%; transform: translateY(-50%);
  width: 15px; height: 15px; color: var(--text-3); pointer-events: none;
}
.search-input {
  width: 100%; height: 38px; padding: 0 40px 0 36px;
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  background: var(--surface-1); color: var(--text-1);
  font-size: 13.5px; outline: none;
  transition: border-color var(--dur-base) var(--ease), background var(--dur-base) var(--ease);
}
.search-input::placeholder { color: var(--text-3); }
.search-input:focus { border-color: var(--border-gold); background: var(--surface-2); }
.search-kbd {
  position: absolute; right: 11px; top: 50%; transform: translateY(-50%);
  min-width: 20px; height: 20px; padding: 0 6px;
  display: grid; place-items: center;
  border: 1px solid var(--border); border-radius: 6px;
  color: var(--text-3); font-size: 11px; font-family: var(--mono); pointer-events: none;
}

.topbar-actions { display: flex; align-items: center; gap: 9px; }

/* ============================================================= buttons === */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  height: 38px; padding: 0 17px; border: 1px solid transparent; cursor: pointer;
  border-radius: var(--radius-pill); background: var(--surface-3); color: var(--text-1);
  font-size: 13.5px; font-weight: 700; white-space: nowrap;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease), filter var(--dur-fast) var(--ease);
}
.btn:hover { background: var(--surface-4); }
.btn:active { transform: scale(.975); }
.btn:disabled { opacity: .42; cursor: not-allowed; transform: none; }

.btn-gold { background: var(--gold); color: #0a1a12; }
.btn-gold:hover { background: var(--gold-light); }
.btn-ghost { background: transparent; border-color: var(--border-strong); }
.btn-ghost:hover { background: var(--surface-2); border-color: var(--border-gold); }
.btn-buy { background: var(--positive); color: #08170c; }
.btn-buy:hover { filter: brightness(1.08); background: var(--positive); }
.btn-sell { background: var(--negative); color: #1c0803; }
.btn-sell:hover { filter: brightness(1.08); background: var(--negative); }
.btn-lg { height: 48px; padding: 0 22px; font-size: 15px; border-radius: var(--radius); width: 100%; }
.btn-sm { height: 32px; padding: 0 13px; font-size: 12.5px; }
.btn-icon { width: 38px; padding: 0; }

.wallet-btn[data-state="connected"] {
  background: var(--surface-2); border-color: var(--border-strong); color: var(--text-1);
}
.wallet-btn[data-state="connected"]::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--positive); box-shadow: 0 0 0 3px rgba(123, 212, 79, .2);
}

/* ================================================================ hero === */

.hero {
  position: relative; z-index: 1;
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; flex-wrap: wrap;
  padding: 42px 0 34px;
}
.hero-copy { font-family: var(--serif); font-size: clamp(21px, 2.6vw, 30px); line-height: 1.24; letter-spacing: -.025em; }
.hero-copy span { display: block; }
.hero-copy .dim { color: var(--text-2); }
.hero-copy em { font-style: italic; color: var(--gold-light); }
.hero-side { display: flex; align-items: center; gap: 10px; }

/* =============================================================== shelf === */

.shelf-head, .board-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; margin-bottom: 14px;
}
.shelf-title {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 15px; font-weight: 800; letter-spacing: -.01em;
}
.shelf-title .info {
  width: 15px; height: 15px; display: grid; place-items: center; cursor: help;
  border: 1px solid var(--border-strong); border-radius: 50%;
  color: var(--text-3); font-size: 9.5px; font-weight: 700;
}

.shelf {
  display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; padding-bottom: 2px;
}
.shelf::-webkit-scrollbar { display: none; }

/* ======================================================== market cards === */

/* Shared card chrome: fill, hairline, hover lift and the brass sheen sweep. */
.card-base {
  position: relative; overflow: hidden;
  background: var(--surface-2);
  border: 1px solid var(--border);
  transition: border-color var(--dur-base) var(--ease),
              transform var(--dur-base) var(--ease),
              box-shadow var(--dur-base) var(--ease);
}
.card-base::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 38%, rgba(240, 215, 124, .11) 50%, transparent 62%);
  transform: translateX(-120%);
  transition: transform .7s var(--ease-emphasized);
}
.card-base:hover { border-color: var(--border-gold); transform: translateY(-2px); box-shadow: 0 14px 34px rgba(0, 0, 0, .38); }
.card-base:hover::after { transform: translateX(120%); }

/* --- trending shelf card: square art on the left, figures on the right --- */
.shelf-card {
  flex: 0 0 auto; scroll-snap-align: start;
  width: min(78vw, 340px); height: 112px;
  display: flex; border-radius: var(--radius-lg);
}
@media (min-width: 900px) { .shelf-card { width: calc((100% - 36px) / 4); min-width: 258px; } }
.shelf-art { position: relative; flex: 0 0 112px; width: 112px; height: 112px; overflow: hidden; }
.shelf-body { min-width: 0; flex: 1; padding: 13px 15px; display: flex; flex-direction: column; justify-content: center; gap: 4px; }
.shelf-name { font-size: 14.5px; font-weight: 700; letter-spacing: -.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.shelf-price { display: flex; align-items: center; gap: 9px; font-size: 14px; font-weight: 700; }
.shelf-stats { display: flex; align-items: center; gap: 16px; margin-top: 5px; color: var(--text-2); font-size: 11.5px; }
.shelf-stats span { display: inline-flex; align-items: center; gap: 5px; }
.shelf-stats svg { width: 11px; height: 11px; opacity: .7; }

/* --- grid card: square art on top, figures beneath ---------------------- */
.grid-card {
  display: flex; flex-direction: column; border-radius: var(--radius);
  text-align: left; cursor: pointer; padding: 0; font: inherit; color: inherit;
}
.grid-art { position: relative; width: 100%; aspect-ratio: 1; overflow: hidden; }
.grid-body { padding: 11px 13px 13px; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.grid-name {
  display: flex; align-items: center; gap: 5px;
  font-size: 13.5px; font-weight: 700; letter-spacing: -.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.grid-figures { display: flex; align-items: center; gap: 9px; font-size: 13px; font-weight: 700; }

/* --- art: generated crest, overlay pills, hover scrim + buy button ------ */
.art-crest {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-family: var(--serif); font-weight: 700; letter-spacing: -.04em;
  color: rgba(255, 255, 255, .93);
  text-shadow: 0 2px 14px rgba(0, 0, 0, .4);
  transition: transform var(--dur-slow) var(--ease);
}
.shelf-card:hover .art-crest, .grid-card:hover .art-crest { transform: scale(1.05); }
.shelf-art .art-crest { font-size: 40px; }
.grid-art .art-crest { font-size: clamp(38px, 7vw, 60px); }

.art-overlay {
  position: absolute; inset: 8px 8px auto 8px;
  display: flex; align-items: flex-start; justify-content: space-between; gap: 8px;
  pointer-events: none;
}
.art-pill {
  display: inline-flex; align-items: center; gap: 5px;
  max-width: 100%; padding: 3px 8px; border-radius: var(--radius-pill);
  background: rgba(8, 20, 13, .68); color: rgba(255, 255, 255, .88);
  backdrop-filter: blur(8px);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .1);
  font-size: 11px; font-weight: 600; white-space: nowrap;
}
.art-pill svg { width: 11px; height: 11px; flex: 0 0 auto; }
.art-pill .handle { overflow: hidden; text-overflow: ellipsis; }
.art-pill.gold { background: rgba(214, 174, 74, .82); color: #0a1a12; box-shadow: none; font-weight: 800; }

.art-scrim {
  position: absolute; inset: auto 0 0 0; height: 46px; pointer-events: none;
  background: linear-gradient(to top, rgba(6, 16, 11, .9), transparent);
  opacity: 0; transition: opacity var(--dur-base) var(--ease);
}
.art-buy {
  position: absolute; right: 8px; bottom: 8px;
  height: 30px; padding: 0 14px; border: 0; cursor: pointer;
  border-radius: var(--radius-pill); background: var(--cream); color: #0a1a12;
  font-size: 12.5px; font-weight: 800; white-space: nowrap;
  opacity: 0; filter: blur(4px); transform: translateY(6px);
  transition: opacity var(--dur-base) var(--ease-emphasized),
              transform var(--dur-base) var(--ease-emphasized),
              filter var(--dur-base) var(--ease-emphasized);
}
.art-buy:hover { background: var(--gold-light); }
.art-buy:active { transform: scale(.97); }
@media (hover: hover) {
  .shelf-card:hover .art-scrim, .grid-card:hover .art-scrim { opacity: 1; }
  .shelf-card:hover .art-buy, .grid-card:hover .art-buy,
  .grid-card:focus-within .art-buy { opacity: 1; filter: blur(0); transform: translateY(0); }
}
@media (hover: none) { .art-buy { display: none; } }

/* ============================================================ odometer === */

/*
  Each digit is a 0–9 reel inside a one-line window. Changing a figure moves
  the reel instead of swapping the glyph, and the per-digit delay makes the
  columns settle right-to-left the way a counter does.
*/
/* Every cell is the same box so the digit windows and the symbols between
   them sit on one line — a baseline mix here shows up as jittering digits. */
.odo { display: inline-flex; align-items: flex-end; height: 1.2em; font-variant-numeric: tabular-nums; }
.odo-digit { display: block; height: 1.2em; line-height: 1.2em; overflow: hidden; }
.odo-reel { display: block; will-change: transform; transition: transform .62s var(--ease-emphasized); }
.odo-reel > span { display: block; height: 1.2em; line-height: 1.2em; }
.odo-sym { display: block; height: 1.2em; line-height: 1.2em; }

.delta { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 700; }
.delta svg { width: 8px; height: 8px; flex: 0 0 auto; }

/* Flashes the row when a figure moves, so a change is visible mid-scroll. */
@keyframes tick-up { 0% { background-color: rgba(123, 212, 79, .16); } 100% { background-color: transparent; } }
@keyframes tick-down { 0% { background-color: rgba(239, 106, 69, .16); } 100% { background-color: transparent; } }
.tick-up { animation: tick-up 1s var(--ease); }
.tick-down { animation: tick-down 1s var(--ease); }

/* =============================================================== board === */

.board { padding-bottom: 70px; }
.board-controls { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.filter-row { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; }
.filter-row::-webkit-scrollbar { display: none; }

.pill {
  display: inline-flex; align-items: center; gap: 6px;
  height: 34px; padding: 0 14px; border: 1px solid var(--border); cursor: pointer;
  border-radius: var(--radius-pill); background: var(--surface-1); color: var(--text-2);
  font-size: 13px; font-weight: 700; white-space: nowrap;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.pill:hover { background: var(--surface-2); color: var(--text-1); }
.pill svg { width: 13px; height: 13px; }
.pill[aria-pressed="true"] { background: var(--cream); border-color: var(--cream); color: #0a1a12; }

.seg { display: flex; gap: 2px; padding: 3px; border: 1px solid var(--border); border-radius: var(--radius-pill); background: var(--surface-1); }
.seg button {
  width: 30px; height: 28px; display: grid; place-items: center;
  border: 0; cursor: pointer; border-radius: var(--radius-pill);
  background: transparent; color: var(--text-3);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.seg button svg { width: 15px; height: 15px; }
.seg button[aria-pressed="true"] { background: var(--surface-3); color: var(--text-1); }

.select-wrap { position: relative; }
.select-wrap select {
  height: 34px; padding: 0 30px 0 14px; border: 1px solid var(--border); cursor: pointer;
  border-radius: var(--radius-pill); background: var(--surface-1); color: var(--text-1);
  font-size: 13px; font-weight: 700; appearance: none; outline: none;
}
.select-wrap::after {
  content: ""; position: absolute; right: 13px; top: 50%; pointer-events: none;
  width: 6px; height: 6px; border-right: 1.6px solid var(--text-3); border-bottom: 1.6px solid var(--text-3);
  transform: translateY(-70%) rotate(45deg);
}

.grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
}
@media (min-width: 1180px) { .grid { grid-template-columns: repeat(6, minmax(0, 1fr)); } }

/* ============================================================== table === */

.table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-1); }
.market-table { width: 100%; border-collapse: collapse; font-size: 13.5px; min-width: 860px; }
/* Not sticky: the wrapper scrolls horizontally, which makes a sticky header
   position against the scrollport and paint underneath the first row. */
.market-table thead th {
  padding: 11px 14px; text-align: right;
  background: var(--surface-1); border-bottom: 1px solid var(--border);
  color: var(--text-3); font-size: 10.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
}
.market-table thead th:first-child, .market-table thead th:nth-child(2) { text-align: left; }
.market-table tbody tr { cursor: pointer; transition: background var(--dur-fast) var(--ease); }
.market-table tbody tr:hover { background: var(--surface-2); }
.market-table td { padding: 11px 14px; text-align: right; border-bottom: 1px solid var(--border); vertical-align: middle; }
.market-table tbody tr:last-child td { border-bottom: 0; }
.market-table td:first-child { text-align: left; color: var(--text-3); font-variant-numeric: tabular-nums; width: 46px; }
.market-table td:nth-child(2) { text-align: left; }
.row-token { display: flex; align-items: center; gap: 10px; min-width: 0; }
.row-crest { flex: 0 0 auto; width: 32px; height: 32px; border-radius: 9px; display: grid; place-items: center; font-family: var(--serif); font-size: 14px; color: #fff; overflow: hidden; }
.row-id { min-width: 0; }
.row-id strong { display: block; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-id span { display: block; color: var(--text-3); font-size: 11.5px; }

/* ============================================================= states === */

.board-state { padding: 66px 20px; text-align: center; color: var(--text-2); }
.board-state strong { display: block; margin-bottom: 6px; color: var(--text-1); font-size: 15px; }

.skeleton { position: relative; overflow: hidden; background: var(--surface-2); border-radius: var(--radius); }
.skeleton::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(243, 236, 217, .06), transparent);
  animation: sweep 1.3s linear infinite;
}
@keyframes sweep { to { transform: translateX(100%); } }
.skeleton-card { height: 240px; }
.skeleton-shelf { height: 112px; border-radius: var(--radius-lg); }

.spinner {
  display: inline-block; width: 13px; height: 13px; vertical-align: -2px;
  border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ============================================================== token === */

.token-page { padding: 22px 0 80px; }
.back-link {
  display: inline-flex; align-items: center; gap: 7px; margin-bottom: 18px;
  color: var(--text-2); font-size: 13px; font-weight: 700; cursor: pointer;
  background: none; border: 0; padding: 0;
}
.back-link:hover { color: var(--text-1); }
.back-link svg { width: 14px; height: 14px; }

.token-layout { display: grid; grid-template-columns: minmax(0, 1fr) var(--rail-w); gap: 20px; align-items: start; }
@media (max-width: 1080px) { .token-layout { grid-template-columns: 1fr; } }

.panel { background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--radius); }
.panel + .panel { margin-top: 16px; }
.panel-pad { padding: 20px; }
.panel-title { margin: 0 0 14px; font-size: 14.5px; font-weight: 800; letter-spacing: -.01em; }

.token-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; flex-wrap: wrap; padding: 20px; }
.token-ident { display: flex; align-items: center; gap: 14px; min-width: 0; }
.token-crest { flex: 0 0 auto; width: 58px; height: 58px; border-radius: 15px; display: grid; place-items: center; font-family: var(--serif); font-size: 25px; color: #fff; }
.token-ident h1 { margin: 0; font-family: var(--serif); font-size: 27px; letter-spacing: -.03em; }
.token-sub { margin-top: 5px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; color: var(--text-2); font-size: 12.5px; }
.tag {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px;
  border-radius: var(--radius-pill); background: var(--surface-3);
  font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--text-1);
}
.tag.gold { background: rgba(214, 174, 74, .2); color: var(--gold-light); }
.tag.good { background: rgba(123, 212, 79, .16); color: var(--positive); }
.tag.warn { background: rgba(239, 106, 69, .15); color: var(--negative); }

.token-price { text-align: right; }
.token-price .big { font-family: var(--serif); font-size: 32px; letter-spacing: -.03em; }
.token-price .delta { justify-content: flex-end; margin-top: 5px; font-size: 13px; }

.stat-row {
  display: grid; grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--border);
}
.stat-row > div { padding: 14px 20px; border-right: 1px solid var(--border); }
.stat-row > div:last-child { border-right: 0; }
.stat-row span { display: block; color: var(--text-3); font-size: 10px; font-weight: 800; letter-spacing: .11em; text-transform: uppercase; }
.stat-row strong { display: block; margin-top: 5px; font-size: 16px; font-weight: 700; }
@media (max-width: 720px) {
  .stat-row { grid-template-columns: repeat(2, 1fr); }
  .stat-row > div:nth-child(2n) { border-right: 0; }
  .stat-row > div:nth-child(-n+2) { border-bottom: 1px solid var(--border); }
}

.chart-frame { height: 460px; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: #0a1210; }
.chart-frame iframe { display: block; width: 100%; height: 100%; border: 0; }
.chart-empty { height: 100%; display: grid; place-items: center; padding: 28px; text-align: center; }
.chart-empty strong { display: block; font-size: 14.5px; }
.chart-empty span { display: block; margin-top: 6px; max-width: 44ch; color: var(--text-2); font-size: 12.5px; }
@media (max-width: 720px) { .chart-frame { height: auto; aspect-ratio: 1; } }

/* ============================================================== trade === */

.rail { position: sticky; top: calc(var(--header-h) + 16px); }
.trade-switch { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; padding: 4px; border-radius: var(--radius); background: var(--surface-2); margin-bottom: 16px; }
.trade-switch button {
  height: 38px; border: 0; cursor: pointer; border-radius: var(--radius-sm);
  background: transparent; color: var(--text-2); font-size: 13.5px; font-weight: 800;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.trade-switch button[aria-pressed="true"][data-side="buy"] { background: var(--positive); color: #08170c; }
.trade-switch button[aria-pressed="true"][data-side="sell"] { background: var(--negative); color: #1c0803; }

.amount-field { padding: 14px 16px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2); transition: border-color var(--dur-base) var(--ease); }
.amount-field:focus-within { border-color: var(--border-gold); }
.amount-field .top { display: flex; align-items: center; gap: 10px; }
.amount-field input {
  width: 100%; min-width: 0; border: 0; outline: none; background: transparent;
  font-family: var(--serif); font-size: 27px; letter-spacing: -.03em; color: var(--text-1);
}
.amount-field input::placeholder { color: var(--text-3); }
.amount-asset { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; border-radius: var(--radius-pill); background: var(--surface-3); font-size: 12.5px; font-weight: 800; }
.amount-field .bottom { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 8px; color: var(--text-3); font-size: 12px; }
.amount-field .bottom button { border: 0; cursor: pointer; background: transparent; color: var(--gold-light); font-size: 12px; font-weight: 800; }

/* The unit badge is a button now. It keeps the pill look but gains a pointer,
   a focus ring and the swap arrows, so it reads as something you can press. */
.amount-asset { border: 0; cursor: pointer; font-family: inherit; color: inherit; }
.amount-asset:hover { background: var(--surface-3); color: var(--text-1); }
/* Selling is token-denominated, so the badge is a label there, not a control. */
.amount-asset.is-static { cursor: default; }
.amount-asset .swap-mark { opacity: .65; font-size: 11px; }
.amount-alt { margin-top: 6px; min-height: 15px; color: var(--text-3); font-size: 12px; }

/* Six amount presets sit as two rows of three; four percentages stay on one
   row. Fixed counts rather than auto-fit, which left one chip stranded. */
.chips { display: grid; gap: 6px; margin-top: 10px; }
.chips.chips-3 { grid-template-columns: repeat(3, 1fr); }
.chips.chips-4 { grid-template-columns: repeat(4, 1fr); }
.chips button {
  height: 30px; border: 1px solid var(--border); cursor: pointer;
  border-radius: var(--radius-sm); background: var(--surface-2); color: var(--text-2);
  font-size: 12px; font-weight: 700;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.chips button:hover { background: var(--surface-3); color: var(--text-1); }

.receive { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-top: 12px; padding: 13px 16px; border-radius: var(--radius); background: var(--surface-2); }
.receive span { color: var(--text-3); font-size: 12px; }
.receive strong { font-family: var(--serif); font-size: 19px; letter-spacing: -.02em; text-align: right; word-break: break-all; }

.slip { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 12px; color: var(--text-3); font-size: 12.5px; }
.slip input { width: 62px; height: 30px; padding: 0 9px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-2); text-align: right; outline: none; }

.note { margin-top: 14px; padding: 12px 14px; border-radius: var(--radius-sm); font-size: 12.5px; line-height: 1.55; }
.note.info { background: var(--surface-2); color: var(--text-2); }
.note.warn { background: rgba(214, 174, 74, .12); color: var(--gold-light); }
.note.error { background: rgba(239, 106, 69, .13); color: #ffb49c; }
.note.success { background: rgba(123, 212, 79, .13); color: #c4f0a3; }
.note a { color: inherit; text-decoration: underline; font-weight: 700; }

/* ================================================================ kv ==== */

.kv { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 10px 16px; margin: 0; }
.kv dt { color: var(--text-2); font-size: 12.5px; }
.kv dd { margin: 0; text-align: right; font-size: 12.5px; font-weight: 700; word-break: break-word; }

.addr { display: flex; align-items: center; justify-content: flex-end; gap: 6px; }
.addr code { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--mono); font-size: 11.5px; font-weight: 400; }
.mini {
  flex: 0 0 auto; width: 25px; height: 25px; display: grid; place-items: center;
  border: 0; cursor: pointer; border-radius: 7px; background: var(--surface-3);
  color: var(--text-2); font-size: 11px; text-decoration: none;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.mini:hover { background: var(--surface-4); color: var(--text-1); }

.vest-bar { height: 8px; margin: 14px 0 12px; border-radius: var(--radius-pill); background: var(--surface-3); overflow: hidden; }
.vest-bar i { display: block; height: 100%; border-radius: var(--radius-pill); background: linear-gradient(90deg, var(--positive), var(--gold)); transition: width .5s var(--ease); }

.tabs { display: flex; gap: 4px; padding: 4px; margin-bottom: 16px; border-radius: var(--radius-pill); background: var(--surface-2); overflow-x: auto; scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }
.tabs button {
  flex: 1; min-width: max-content; height: 32px; padding: 0 15px;
  border: 0; cursor: pointer; border-radius: var(--radius-pill);
  background: transparent; color: var(--text-2); font-size: 12.5px; font-weight: 800;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.tabs button[aria-selected="true"] { background: var(--surface-4); color: var(--text-1); }

/* ============================================================== modal === */

dialog.modal {
  width: min(560px, calc(100vw - 28px)); max-height: min(90dvh, 860px);
  padding: 0; border: 1px solid var(--border-strong); border-radius: var(--radius-lg);
  background: var(--surface-1); color: var(--text-1); overflow: hidden;
}
/* The head is free to wrap to any number of lines, so the body takes whatever
   height is left instead of a hardcoded offset. Guessing the head height is
   what clipped the bottom of the form — the dialog overflowed its own
   max-height with overflow:hidden, so the cut-off part could not be reached. */
dialog.modal[open] { display: flex; flex-direction: column; }
.modal-head { flex: 0 0 auto; }
dialog.modal::backdrop { background: rgba(4, 12, 8, .74); backdrop-filter: blur(4px); }
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 22px 24px 0; }
.modal-head h2 { margin: 0; font-family: var(--serif); font-size: 23px; letter-spacing: -.03em; }
.modal-head p { margin: 6px 0 0; color: var(--text-2); font-size: 13px; max-width: 44ch; }
.modal-close { width: 32px; height: 32px; flex: 0 0 auto; border: 0; cursor: pointer; border-radius: 50%; background: var(--surface-3); color: var(--text-2); font-size: 15px; line-height: 1; }
.modal-close:hover { background: var(--surface-4); color: var(--text-1); }
.modal-body { padding: 20px 24px 26px; overflow-y: auto; flex: 1 1 auto; min-height: 0; }

.field { margin-bottom: 15px; }
/* Direct child only: the radio options below are labels too, and they carry
   sentence-case copy that must not inherit the caption treatment. */
.field > label { display: block; margin-bottom: 7px; color: var(--text-3); font-size: 10.5px; font-weight: 800; letter-spacing: .11em; text-transform: uppercase; }
.field input[type="text"], .field input[type="url"], .field textarea, .field select {
  width: 100%; height: 46px; padding: 0 14px; outline: none;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--text-1); font-size: 14.5px;
  transition: border-color var(--dur-base) var(--ease);
}
.field input:focus, .field textarea:focus, .field select:focus { border-color: var(--border-gold); }
.field textarea { height: auto; padding: 11px 14px; resize: vertical; font-family: inherit; line-height: 1.5; }
.field-row.three { grid-template-columns: repeat(3, 1fr); }
.field .hint { display: block; margin-top: 6px; color: var(--text-3); font-size: 11.5px; }
.field .hint.err { color: var(--negative); font-weight: 700; }
/* The unit sits inside the box rather than after it, so a long amount never
   pushes "ETH" onto its own line. Padding on the input reserves the space. */
.devbuy-row { position: relative; }
.devbuy-row input { padding-right: 58px !important; }
.devbuy-row .devbuy-unit {
  position: absolute; top: 50%; right: 14px; transform: translateY(-50%);
  pointer-events: none; color: var(--text-3); font-size: 12px; font-weight: 800; letter-spacing: .08em;
}
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 520px) { .field-row { grid-template-columns: 1fr; } }

.pair-pick { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.pair-pick label {
  position: relative; display: block; padding: 13px 15px; cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-2);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.pair-pick input { position: absolute; opacity: 0; pointer-events: none; }
.pair-pick strong { display: block; font-size: 14px; }
.pair-pick span { display: block; margin-top: 4px; color: var(--text-2); font-size: 11.5px; line-height: 1.45; }
.pair-pick label:has(input:checked) { border-color: var(--gold); background: rgba(214, 174, 74, .1); }

/* ---- launch terms & creator allocation, laid out like SOGGY ---- */

.terms { margin-top: 18px; padding-top: 16px; border-top: 1px dashed var(--border-strong); }
.terms-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.terms-head h4 { margin: 0; font-size: 14.5px; font-weight: 800; letter-spacing: -.01em; }

/* Two-colour bar: creator slice against locked liquidity. */
.split-bar { display: flex; height: 8px; margin-bottom: 9px; border-radius: var(--radius-pill); overflow: hidden; background: var(--surface-3); }
.split-bar > span.creator { background: var(--gold); }
/* The airdrop slice is a fifth of the creator slice, so it needs a colour of
   its own to be legible at all rather than a shade of its neighbour. */
.split-bar > span.airdrop { background: var(--gold-deep, #A9791F); }
.split-bar > span.market { background: var(--positive); }
.split-legend { display: flex; flex-wrap: wrap; gap: 16px; margin-bottom: 16px; color: var(--text-2); font-size: 12px; }
.split-legend span { display: inline-flex; align-items: center; gap: 6px; }
.split-legend i { width: 8px; height: 8px; border-radius: 2px; }
.split-legend i.creator { background: var(--gold); }
.split-legend i.market { background: var(--positive); }
.split-legend i.airdrop { background: var(--gold-deep, #A9791F); }

/* One immutable term per row. */
.fixed-term {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  /* The brutalist skin draws a border on this row, so the value needs side
     padding or it sits flush against the line and reads as clipped text. */
  padding: 10px 12px; border-bottom: 1px solid var(--border);
}
.fixed-term:last-of-type { border-bottom: 0; }
.fixed-term > span { color: var(--text-2); font-size: 12.5px; }
.fixed-term > strong { text-align: right; font-size: 12.5px; font-weight: 700; }
.terms-note { margin: 14px 0 0; color: var(--text-3); font-size: 12px; line-height: 1.65; }
.terms-note strong { color: var(--text-2); }

/* Creator allocation block on a token page. */
.side-block-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.side-block-head h4 { margin: 0; font-size: 14.5px; font-weight: 800; letter-spacing: -.01em; }
.side-block-head .muted { font-size: 12px; }
.side-stat { margin-top: 12px; font-family: var(--serif); font-size: 26px; letter-spacing: -.03em; }
.side-stat em { font-style: normal; font-size: 15px; color: var(--text-2); }
.side-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border);
}
.side-row span { color: var(--text-2); font-size: 12.5px; }
.side-row strong { font-size: 13px; font-weight: 700; }

/* ============================================================== toast === */

.toast {
  position: fixed; left: 50%; bottom: 24px; z-index: 90;
  max-width: min(520px, calc(100vw - 28px)); padding: 13px 19px;
  border: 1px solid var(--border-strong); border-radius: var(--radius);
  background: var(--surface-2); color: var(--text-1);
  font-size: 13px; font-weight: 600;
  box-shadow: 0 18px 46px rgba(0, 0, 0, .5);
  transform: translate(-50%, 130%); opacity: 0;
  transition: transform var(--dur-slow) var(--ease), opacity var(--dur-slow) var(--ease);
}
.toast.show { transform: translate(-50%, 0); opacity: 1; }
.toast a { color: var(--gold-light); text-decoration: underline; }

/* ============================================================= footer === */

.foot { margin-top: auto; padding: 30px 0 46px; border-top: 1px solid var(--border); color: var(--text-3); font-size: 12px; line-height: 1.65; }
.foot-row { display: flex; align-items: center; justify-content: space-between; gap: 18px; flex-wrap: wrap; margin-bottom: 14px; }
.foot-links { display: flex; gap: 16px; flex-wrap: wrap; }
.foot-links a { color: var(--text-2); font-weight: 700; }
.foot-links a:hover { color: var(--text-1); }

/* ========================================================= breakpoints === */

@media (max-width: 860px) {
  :root { --header-h: 108px; }
  .topbar { height: auto; padding: 9px 0; }
  .topbar-inner { grid-template-columns: minmax(0, 1fr) auto; row-gap: 9px; gap: 10px; }
  .search-wrap { grid-column: 1 / -1; grid-row: 2; width: 100%; }
  .search-kbd { display: none; }
  .brand-name { font-size: 15px; }
  .hero { padding: 26px 0 22px; }
  .token-head { padding: 16px; }
  .token-price { text-align: left; }
  .token-price .delta { justify-content: flex-start; }
  .grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
}

@media (max-width: 560px) {
  /* The hero carries its own launch button; two in view is just clutter. */
  #launch-open { display: none; }
  .brand-tag { display: none; }
  .hero-side { width: 100%; }
  .hero-side .btn { flex: 1; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  .card-base::after { display: none; }
}

/* --- token profiles: uploaded logo, picker, blurb ----------------------- */

/* Sits exactly where the crest would, so a token gains artwork without the
   card changing shape. */
.art-logo {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; display: block;
  transition: transform var(--dur-slow) var(--ease);
}
.shelf-card:hover .art-logo, .grid-card:hover .art-logo { transform: scale(1.05); }
.row-crest .art-logo, .token-crest .art-logo { position: static; border-radius: inherit; }
/* `position` is load-bearing, not decoration. `.art-crest` is absolutely
   positioned, so without a positioned ancestor here it resolves against the
   page instead of the 58px crest and lays an invisible sheet over the whole
   token page — which is what swallowed clicks on "Back to the market".
   `overflow` alone does not clip a descendant whose containing block is
   outside this element. Same reason `.row-crest` is positioned. */
.token-crest, .row-crest { position: relative; overflow: hidden; }

.file-pick { display: flex; align-items: center; gap: 12px; }
.file-pick input[type="file"] {
  flex: 1 1 auto; min-width: 0;
  color: var(--text-3); font-size: 12.5px;
}
.file-pick input[type="file"]::file-selector-button {
  margin-right: 10px; padding: 8px 13px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--text-1);
  font: inherit; font-size: 12.5px; font-weight: 700; cursor: pointer;
}
.file-pick input[type="file"]::file-selector-button:hover { border-color: var(--border-gold); }

.logo-preview {
  flex: 0 0 auto; position: relative;
  width: 58px; height: 58px; border-radius: 15px; overflow: hidden;
  display: grid; place-items: center;
  border: 1px solid var(--border); background: var(--surface-2);
  font-family: var(--serif); font-size: 22px; color: rgba(255, 255, 255, .93);
}
.logo-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.logo-preview .art-crest { position: absolute; inset: 0; }

.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.panel-head .panel-title { margin: 0; }
.profile-blurb { margin: 0; color: var(--text-2); font-size: 14px; line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; }
.profile-links { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }

/* =========================================================
   SOGGY identity layer — light brutalist pond UI
   Cream + ink + electric pond lime. Hard borders. No glows.
   ========================================================= */
:root{
  --bg:#F2EEE3;--surface-1:#FFFEFB;--surface-2:#FFFEFB;--surface-3:#ECE7D9;--surface-4:#E2DDCE;
  --border:#141414;--border-strong:#141414;--border-gold:#141414;
  --text-1:#141414;--text-2:#5F5F59;--text-3:#8C8C84;
  --gold:#BFFF00;--gold-light:#D0FF3B;--gold-deep:#4D7A00;--cream:#F2EEE3;
  --positive:#11864B;--negative:#D43B3B;
  --radius-lg:0;--radius:0;--radius-sm:0;--radius-pill:0;
  --mono:"Kode Mono",ui-monospace,SFMono-Regular,Menlo,monospace;--serif:"Kode Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
}
body{background-color:var(--bg);background-image:url("../assets/pond-pattern.svg");color:var(--text-1);font-family:"Inter",system-ui,sans-serif}
body::before{display:none}::selection{background:var(--gold);color:var(--text-1)}
:focus-visible{outline:3px solid var(--gold-deep);outline-offset:2px;border-radius:0}
.topbar{height:66px;background:rgba(242,238,227,.96);border-bottom:2px solid var(--text-1);backdrop-filter:blur(10px)}
.topbar-inner{width:min(calc(100% - 32px),1420px)}
.brand{gap:10px}.brand img{width:34px;height:34px;border-radius:0;box-shadow:none}.brand-name{font-family:var(--mono);font-weight:800;font-size:20px;letter-spacing:-.05em}.brand-tag{background:var(--gold);color:var(--text-1);border:1px solid var(--text-1);font:700 9px var(--mono);border-radius:0;padding:3px 7px}
.search-input{height:40px;border:2px solid var(--text-1);border-radius:0;background:var(--surface-2);font-family:var(--mono);box-shadow:3px 3px 0 var(--text-1)}.search-input:focus{border-color:var(--text-1);background:#fff}.search-kbd{border:1px solid var(--text-1);border-radius:0;background:var(--cream)}
.btn{height:40px;border:2px solid var(--text-1);border-radius:0;background:var(--surface-2);color:var(--text-1);font:700 11px var(--mono);box-shadow:3px 3px 0 var(--text-1);transition:transform .12s,box-shadow .12s,background .12s}.btn:hover{background:#fff;transform:translate(1px,1px);box-shadow:2px 2px 0 var(--text-1)}.btn:active{transform:translate(3px,3px);box-shadow:none}.btn-gold{background:var(--gold);color:var(--text-1)}.btn-gold:hover{background:var(--gold-light)}.btn-ghost{background:var(--surface-2);border-color:var(--text-1)}.btn-buy{background:var(--gold);color:var(--text-1)}.btn-sell{background:#FF6B5F;color:#141414}.btn-lg{height:48px;border-radius:0}
.wallet-btn[data-state="connected"]{background:var(--surface-2);border-color:var(--text-1)}.wallet-btn[data-state="connected"]::before{background:var(--gold-deep);box-shadow:none}
.hero{padding:44px 0 34px}.hero-copy{font-family:var(--mono);font-size:clamp(20px,2.5vw,31px);font-weight:700;letter-spacing:-.04em}.hero-copy .dim{font-size:.67em;margin-top:5px;font-weight:500}.hero-copy em{color:var(--gold-deep);font-style:normal}.shelf-title{font-family:var(--mono);font-weight:800;text-transform:uppercase;font-size:12px}.shelf-title .info{border:1px solid var(--text-1);border-radius:0;color:var(--text-1)}
.card-base{background:var(--surface-2);border:2px solid var(--text-1);box-shadow:4px 4px 0 var(--text-1)}.card-base::after{display:none}.card-base:hover{border-color:var(--text-1);transform:translate(-1px,-1px);box-shadow:6px 6px 0 var(--text-1)}
.shelf-card,.grid-card{border-radius:0}.shelf-art,.grid-art{background:#DCEBB3}.shelf-body,.grid-body{background:var(--surface-2)}.grid-name,.shelf-name{font-family:var(--mono);font-weight:700}.art-pill{border:1px solid var(--text-1);background:var(--surface-2);color:var(--text-1);border-radius:0}.art-pill.gold,.tag.gold{background:var(--gold);color:var(--text-1)}.art-buy{background:var(--gold);color:var(--text-1);border:2px solid var(--text-1);border-radius:0}
.board{padding-bottom:72px}.board-head{border-top:2px solid var(--text-1);padding-top:20px}.select-wrap select,.pill,.seg{border:2px solid var(--text-1);border-radius:0;background:var(--surface-2);font-family:var(--mono)}.pill{box-shadow:2px 2px 0 var(--text-1)}.pill[aria-pressed="true"]{background:var(--gold);color:var(--text-1);border-color:var(--text-1)}.seg button{border-radius:0}.seg button[aria-pressed="true"]{background:var(--gold);color:var(--text-1)}
.table-wrap{border:2px solid var(--text-1);border-radius:0;box-shadow:4px 4px 0 var(--text-1);background:var(--surface-2)}.market-table th{background:#E9E4D5;color:var(--text-2);font-family:var(--mono);border-bottom:2px solid var(--text-1)}.market-table td{border-bottom:1px solid #A7A293}.market-table tbody tr:hover{background:#F7F4EA}
.token-page{padding-top:34px}.back-link{font:700 11px var(--mono);color:var(--gold-deep)}.token-head{border-bottom:2px solid var(--text-1);padding-bottom:22px}.token-crest,.row-crest,.logo-preview{border-radius:0;border:2px solid var(--text-1);background:#DCEBB3}.token-ident h1{font-family:var(--mono);font-weight:800;letter-spacing:-.04em}.token-price{font-family:var(--mono);font-weight:700}.tag{border:1px solid var(--text-1);border-radius:0;background:var(--surface-2);color:var(--text-1);font-family:var(--mono)}
.panel,.rail{background:var(--surface-2);border:2px solid var(--text-1);border-radius:0;box-shadow:4px 4px 0 var(--text-1)}.panel-head,.side-block-head{border-bottom:1px solid var(--text-1);font-family:var(--mono)}.tabs{border-bottom:2px solid var(--text-1);background:#E9E4D5}.tabs button{font-family:var(--mono)}.tabs button[aria-selected="true"]{color:var(--text-1);background:var(--gold)}.tabs button[aria-selected="true"]::after{background:var(--text-1)}
.chart-frame{border:1px solid var(--text-1);border-radius:0;background:#111}.chart-empty{background:#E9E4D5;color:var(--text-2)}.kv,.stat-row,.side-row{border-bottom:1px solid #BEB8A9}.fixed-term{border:1px solid var(--text-1);background:#F7F4EA;border-radius:0}.split-bar,.vest-bar{border-radius:0;border:1px solid var(--text-1);background:#E8E3D4}.split-bar .market,.vest-bar>i{background:var(--gold-deep)}.split-bar .creator{background:var(--gold)}.split-bar .airdrop{background:var(--text-1)}
.trade-switch{border:2px solid var(--text-1);border-radius:0;background:#E9E4D5}.trade-switch button{border-radius:0}.trade-switch button[aria-pressed="true"]{background:var(--gold);color:var(--text-1)}.amount-field,input,textarea,select{border-radius:0!important}.amount-field{border:2px solid var(--text-1);background:#fff}.field input,.field textarea,.field select{border:2px solid var(--text-1);background:#fff}.pair-pick{border:2px solid var(--text-1);background:#fff;border-radius:0}.slip button{border:1px solid var(--text-1);border-radius:0}.slip button[aria-pressed="true"]{background:var(--gold);color:var(--text-1)}
.modal{border:2px solid var(--text-1);border-radius:0;background:var(--cream);color:var(--text-1);box-shadow:10px 10px 0 var(--text-1)}.modal::backdrop{background:rgba(20,20,20,.58);backdrop-filter:none}.modal-head{background:var(--surface-2);border-bottom:2px solid var(--text-1)}.modal-head h2{font-family:var(--mono)}.modal-close{border:2px solid var(--text-1);border-radius:0;background:var(--gold)}.note{border:1px solid var(--text-1);border-radius:0;background:#E9E4D5;color:var(--text-1)}.note.info{background:#DDF5F8}.note.warn{background:#FFF0B8}
.terms{border:2px solid var(--text-1);border-radius:0;background:var(--surface-2)}.terms-head{border-bottom:2px solid var(--text-1);font-family:var(--mono)}.terms-note{background:#E9E4D5;border-top:1px solid var(--text-1)}
.foot{background:var(--text-1);color:var(--cream);border-top:2px solid var(--text-1)}.foot .muted,.foot p{color:#A9A79F}.foot-links a:hover{color:var(--gold)}
.toast{border:2px solid var(--text-1);border-radius:0;background:var(--surface-2);color:var(--text-1);box-shadow:5px 5px 0 var(--text-1)}
.skeleton{background:linear-gradient(90deg,#E5E0D2 25%,#F7F4EA 50%,#E5E0D2 75%)}
@media(max-width:760px){.topbar{height:auto;min-height:64px}.topbar-inner{grid-template-columns:1fr auto;gap:10px;padding:10px 0}.search-wrap{grid-column:1/-1;grid-row:2}.brand-tag{display:none}.hero{padding-top:30px}.hero-copy{font-size:21px}.container{width:min(calc(100% - 24px),var(--container))}}

/* =========================================================
   Mobile polish
   Keep every desktop surface, but give dense market controls and forms a
   predictable single-column flow on phones. The horizontal token filters
   intentionally remain swipeable.
   ========================================================= */
@media (max-width: 760px) {
  :root { --header-h: 118px; --rail-w: 100%; }

  body { font-size: 13.5px; }
  .container { width: calc(100% - 24px); }

  .topbar { min-height: var(--header-h); padding: 0; }
  .topbar-inner {
    width: calc(100% - 24px);
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 10px 8px;
    padding: 10px 0 12px;
  }
  .brand { min-width: 0; }
  .brand img { width: 32px; height: 32px; }
  .brand-name { overflow: hidden; text-overflow: ellipsis; font-size: 18px; }
  .topbar-actions { min-width: 0; }
  .topbar-actions .btn { min-height: 42px; padding-inline: 13px; }
  .wallet-btn { max-width: 132px; overflow: hidden; text-overflow: ellipsis; }
  .search-wrap { grid-column: 1 / -1; width: 100%; }
  .search-input { height: 44px; padding-right: 14px; font-size: 16px; }

  .hero {
    align-items: stretch;
    flex-direction: column;
    gap: 20px;
    padding: 28px 0 30px;
  }
  .hero-copy { width: 100%; font-size: clamp(22px, 7vw, 28px); line-height: 1.16; }
  .hero-copy .dim { max-width: 34ch; margin-top: 10px; font-size: 13px; line-height: 1.5; letter-spacing: -.02em; }
  .hero-side { display: grid; grid-template-columns: 1fr 1.25fr; width: 100%; gap: 10px; }
  .hero-side .btn { width: 100%; min-width: 0; min-height: 44px; padding-inline: 10px; }

  .shelf-head { min-height: 44px; margin-bottom: 10px; }
  .shelf-title { min-width: 0; }
  .shelf-card { width: min(88vw, 330px); height: 104px; }
  .shelf-art { width: 104px; height: 104px; flex-basis: 104px; }
  .shelf-body { padding: 11px 12px; }
  /* Two nowrap pills side by side need ~117px; the art tile only offers 88px
     here, so the pair badge used to run under the body panel and get clipped
     mid-word. Stack them instead — the tile has height to spare. */
  .art-overlay { flex-direction: column; align-items: flex-start; gap: 4px; }
  .art-pill { max-width: 100%; min-width: 0; }

  .board-head {
    align-items: stretch;
    flex-direction: column;
    gap: 12px;
    margin-bottom: 12px;
  }
  .board-controls {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    width: 100%;
    gap: 10px;
  }
  .select-wrap, .select-wrap select { width: 100%; }
  .select-wrap select { height: 42px; font-size: 16px; }
  .seg { min-height: 42px; }
  .seg button { width: 38px; height: 34px; }

  .filter-row {
    width: calc(100% + 12px);
    margin-right: -12px;
    padding: 2px 12px 6px 1px;
    scroll-snap-type: x proximity;
  }
  .pill { min-height: 40px; scroll-snap-align: start; }

  .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .grid-body { padding: 10px; }
  .grid-name, .grid-figures { min-width: 0; }
  .board-state { padding: 48px 18px; }

  .token-page { padding: 20px 0 56px; }
  .token-layout { gap: 14px; }
  .token-head { flex-direction: column; gap: 16px; }
  .token-ident { width: 100%; align-items: flex-start; }
  .token-ident > div:last-child { min-width: 0; }
  .token-ident h1 { overflow-wrap: anywhere; font-size: 23px; }
  .token-price { width: 100%; text-align: left; }
  .token-price .big { overflow-wrap: anywhere; font-size: 27px; }
  .token-price .delta { justify-content: flex-start; }
  .panel-pad { padding: 16px; }
  .rail { position: static; top: auto; }
  .chart-frame { min-height: 300px; aspect-ratio: 1 / 1; }
  .amount-field input { font-size: 24px; }
  .receive { align-items: flex-start; }
  .receive strong { min-width: 0; overflow-wrap: anywhere; font-size: 17px; }

  .kv { grid-template-columns: minmax(88px, auto) minmax(0, 1fr); gap: 11px 12px; }
  .kv dt, .kv dd { min-width: 0; }
  .addr { min-width: 0; }

  dialog.modal {
    width: calc(100vw - 16px);
    max-width: none;
    max-height: calc(100dvh - 16px);
    margin: auto;
    box-shadow: 5px 5px 0 var(--text-1);
  }
  .modal-head { padding: 17px 16px 14px; }
  .modal-head h2 { font-size: 20px; }
  .modal-head p { font-size: 12px; line-height: 1.45; }
  .modal-body { padding: 16px 16px 22px; overscroll-behavior: contain; }
  .field-row, .field-row.three { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .field input[type="text"], .field input[type="url"], .field textarea, .field select { font-size: 16px; }
  .pair-pick { grid-template-columns: minmax(0, 1fr); }
  .terms-head { align-items: flex-start; flex-direction: column; }
  .fixed-term { align-items: flex-start; flex-direction: column; gap: 4px; }
  .fixed-term > strong { max-width: 100%; text-align: left; overflow-wrap: anywhere; }

  .foot { padding: 26px 0 34px; }
  .foot-row { align-items: flex-start; flex-direction: column; gap: 12px; }
  .foot-links { gap: 12px 16px; }
}

@media (max-width: 360px) {
  .brand-name { font-size: 16px; }
  .topbar-actions .btn { padding-inline: 10px; }
  .hero-side { grid-template-columns: 1fr; }
  .grid { grid-template-columns: minmax(0, 1fr); }
  .stat-row { grid-template-columns: minmax(0, 1fr); }
  .stat-row > div { border-right: 0; border-bottom: 1px solid var(--border); }
  .stat-row > div:last-child { border-bottom: 0; }
  .file-pick { align-items: flex-start; flex-direction: column; }
}

/* =========================================================
   Market-board detail layer
   More information density, while keeping SOGGY's existing brutalist skin.
   ========================================================= */
.market-tape { position:relative;z-index:2;height:28px;overflow:hidden;border-bottom:2px solid var(--text-1);background:var(--text-1);color:var(--cream);font:700 10px/28px var(--mono);letter-spacing:.08em;white-space:nowrap }
.market-tape div { width:max-content;animation:market-ticker 28s linear infinite }
.market-tape i { padding:0 16px;color:var(--gold);font-style:normal }
@keyframes market-ticker { to { transform:translateX(-42%) } }
.hero { align-items:stretch }
.hero-copy { align-self:center }
.market-label { display:flex!important;align-items:center;gap:9px;margin-bottom:14px;color:var(--text-2);font:700 10px var(--mono);letter-spacing:.08em }
.market-label b { width:9px;height:9px;border:2px solid var(--text-1);background:var(--gold);box-shadow:2px 2px 0 var(--text-1) }
.hero-market { width:min(100%,560px);border:2px solid var(--text-1);background:var(--surface-2);box-shadow:5px 5px 0 var(--text-1) }
.hero-market-head { display:flex;align-items:center;justify-content:space-between;gap:18px;padding:9px 12px;border-bottom:2px solid var(--text-1);background:var(--gold);font:800 10px var(--mono);letter-spacing:.08em }
.hero-market-head span:last-child { color:var(--gold-deep) }
.hero-market-grid { display:grid;grid-template-columns:repeat(4,minmax(0,1fr)) }
.hero-market-grid>div { min-width:0;padding:13px 12px;border-right:1px solid var(--text-1) }
.hero-market-grid>div:last-child { border-right:0 }
.hero-market-grid span { display:block;margin-bottom:4px;color:var(--text-2);font:700 8px var(--mono);letter-spacing:.06em;text-transform:uppercase }
.hero-market-grid strong { display:block;overflow:hidden;text-overflow:ellipsis;font:800 16px var(--mono);letter-spacing:-.04em;white-space:nowrap }
.hero-market .hero-side { padding:12px;border-top:1px solid var(--text-1) }
.hero-market .hero-side .btn { flex:1 }
.shelf-title>small { padding-left:2px;color:var(--text-3);font:600 10px var(--mono);letter-spacing:0;text-transform:none }
.grid-meta { display:flex;align-items:center;justify-content:space-between;gap:8px;color:var(--text-3);font:600 9px var(--mono) }
.grid-creator { min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap }
.grid-age { flex:0 0 auto;color:var(--gold-deep);font-weight:800 }
.grid-market { display:grid;grid-template-columns:repeat(3,minmax(0,1fr));margin-top:6px;border-top:1px solid var(--text-1) }
.grid-market>div { min-width:0;padding:8px 6px 0 0 }
.grid-market>div+div { padding-left:7px;border-left:1px solid #beb8a9 }
.grid-market span { display:block;color:var(--text-3);font:700 7.5px var(--mono);letter-spacing:.06em;text-transform:uppercase }
.grid-market strong { display:block;margin-top:2px;overflow:hidden;text-overflow:ellipsis;font:700 10px var(--mono);white-space:nowrap }
.grid-proof { display:flex;align-items:center;gap:5px;margin-top:7px;color:var(--text-2);font:700 8px var(--mono);letter-spacing:.03em }
.grid-proof span { padding:2px 4px;border:1px solid var(--text-1);background:#f7f4ea }
.grid-proof span:first-child { background:var(--gold);color:var(--text-1) }
.token-proof-grid { display:grid;grid-template-columns:repeat(4,minmax(0,1fr));margin:16px;border:1px solid var(--text-1) }
.token-proof-grid>div { min-width:0;padding:11px 12px;border-right:1px solid var(--text-1) }
.token-proof-grid>div:last-child { border-right:0 }
.token-proof-grid span { display:block;color:var(--text-3);font:700 8px var(--mono);text-transform:uppercase }
.token-proof-grid strong { display:block;margin-top:4px;overflow:hidden;text-overflow:ellipsis;font:700 11px var(--mono);white-space:nowrap }
.token-detail-grid { display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;margin:16px 0 }
.token-detail-grid .panel { margin:0 }
.snapshot-grid { display:grid;grid-template-columns:repeat(4,minmax(0,1fr));border:1px solid var(--text-1) }
.snapshot-grid>div { min-width:0;padding:11px 9px;border-right:1px solid var(--text-1) }
.snapshot-grid>div:last-child { border-right:0 }
.snapshot-grid span { display:block;color:var(--text-3);font:700 7.5px var(--mono);letter-spacing:.05em;text-transform:uppercase }
.snapshot-grid strong { display:block;margin-top:4px;overflow:hidden;text-overflow:ellipsis;font:800 12px var(--mono);white-space:nowrap }
.detail-foot { margin:11px 0 0;color:var(--text-3);font-size:11px;line-height:1.5 }
.contract-list { border:1px solid var(--text-1) }
.contract-list>div { display:grid;grid-template-columns:72px minmax(0,1fr) auto;align-items:center;gap:8px;padding:7px 9px;border-bottom:1px solid #beb8a9 }
.contract-list>div:last-child { border-bottom:0 }
.contract-list>div>span:first-child { color:var(--text-3);font:700 8px var(--mono);text-transform:uppercase }
.contract-list strong { overflow:hidden;text-overflow:ellipsis;font:700 10px var(--mono);white-space:nowrap }
.contract-actions { display:flex;gap:4px }
.service-hint { display:block;margin-top:5px;padding:6px 8px;border-left:3px solid var(--negative);background:#fff0e8 }
.service-hint.service-ready { border-left-color:var(--positive);background:#e7f6df;color:#356320 }
@media (max-width:920px) { .hero{flex-direction:column}.hero-market{width:100%} }
@media (max-width:760px) {
  .market-tape{height:24px;font-size:9px;line-height:24px}.hero-market-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.hero-market-grid>div:nth-child(2){border-right:0}.hero-market-grid>div:nth-child(-n+2){border-bottom:1px solid var(--text-1)}.hero-market .hero-side{display:grid}.shelf-title>small{display:none}.token-proof-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.token-proof-grid>div:nth-child(2){border-right:0}.token-proof-grid>div:nth-child(-n+2){border-bottom:1px solid var(--text-1)}.token-detail-grid{grid-template-columns:1fr}.snapshot-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.snapshot-grid>div:nth-child(2){border-right:0}.snapshot-grid>div:nth-child(-n+2){border-bottom:1px solid var(--text-1)}
}
@media (max-width:430px) { .grid-market{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-market>div:nth-child(3){display:none}.grid-proof{flex-wrap:wrap} }

/* =========================================================
   UI polish pass — precision, legibility, new controls
   Layered last so it wins over the identity block above.
   ========================================================= */

/* --- odometer -----------------------------------------------------------
   The reel used to be a black chip per digit, which turned every figure into
   a row of separate boxes and made a price harder to read than plain text.
   The reel motion is the point; the chip was not. Digits now sit on the page
   like text, and only the shared baseline box remains so they cannot jitter. */
.odo { line-height: 1.2; }
.odo-digit { background: none; color: inherit; }
.odo-reel > span, .odo-sym { font-variant-numeric: tabular-nums; }

/* Price on the token page: one clear figure, no per-digit furniture. */
.token-price .big { font-size: clamp(24px, 4.2vw, 34px); line-height: 1.15; letter-spacing: -.03em; }
.token-price { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; min-width: 0; }
.token-price .delta { font-size: 12.5px; }

/* --- page nav (Back / Market) ------------------------------------------- */
.page-nav { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.back-link {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 34px; padding: 6px 12px;
  border: 2px solid var(--text-1); background: var(--surface-2);
  box-shadow: 2px 2px 0 var(--text-1);
  cursor: pointer; transition: transform .12s, box-shadow .12s, background .12s;
}
.back-link:hover { background: #fff; transform: translate(1px, 1px); box-shadow: 1px 1px 0 var(--text-1); }
.back-link:active { transform: translate(2px, 2px); box-shadow: none; }
.back-link svg { width: 13px; height: 13px; flex: 0 0 auto; }

/* --- wallet menu --------------------------------------------------------- */
.wallet-wrap { position: relative; }
.wallet-menu {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  min-width: 216px; padding: 6px;
  border: 2px solid var(--text-1); background: var(--surface-2);
  box-shadow: 5px 5px 0 var(--text-1);
}
.wallet-menu-head { padding: 8px 10px 10px; border-bottom: 1px solid var(--text-1); }
.wallet-menu-head span {
  display: block; color: var(--text-3);
  font: 700 8px var(--mono); letter-spacing: .08em; text-transform: uppercase;
}
.wallet-menu-head strong { display: block; margin-top: 3px; font: 700 12px var(--mono); }
.wallet-menu > button, .wallet-menu > a {
  display: block; width: 100%; padding: 9px 10px;
  border: 0; background: none; text-align: left;
  font: 700 11px var(--mono); color: var(--text-1); cursor: pointer;
}
.wallet-menu > button:hover, .wallet-menu > a:hover { background: var(--gold); }
.wallet-menu > .danger { color: #A32219; }
.wallet-menu > .danger:hover { background: #FFD9D4; }

/* --- trade history ------------------------------------------------------- */
.trades-wrap { overflow-x: auto; border: 1px solid var(--text-1); background: #fff; }
.trades-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.trades-table th {
  position: sticky; top: 0;
  padding: 8px 10px; border-bottom: 2px solid var(--text-1);
  background: #E9E4D5; color: var(--text-2);
  font: 700 9px var(--mono); letter-spacing: .07em; text-transform: uppercase; text-align: left;
  white-space: nowrap;
}
.trades-table td {
  padding: 8px 10px; border-bottom: 1px solid #D8D3C4;
  font-family: var(--mono); white-space: nowrap;
}
.trades-table tbody tr:last-child td { border-bottom: 0; }
.trades-table tbody tr:hover { background: #F7F4EA; }
.trades-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.trades-table .when { text-align: right; color: var(--text-2); }
.trades-table .when a, .trade-who { color: inherit; text-decoration: none; }
.trades-table .when a:hover, .trade-who:hover { text-decoration: underline; }
.trade-side {
  display: inline-block; min-width: 42px; padding: 2px 7px;
  border: 1px solid var(--text-1); font: 700 9px var(--mono);
  letter-spacing: .05em; text-transform: uppercase; text-align: center;
}
.trade-side.buy { background: var(--gold); color: var(--text-1); }
.trade-side.sell { background: #FFB3AB; color: #4A0F0A; }

/* Phones read this table as cards: five columns of monospace numbers in
   360px is a scrollbar nobody finds. */
@media (max-width: 560px) {
  .trades-wrap { border: 0; background: none; overflow: visible; }
  .trades-table, .trades-table tbody, .trades-table tr, .trades-table td { display: block; width: 100%; }
  .trades-table thead { display: none; }
  /* Two tight rows: what happened and when, then the two amounts, with the
     trader tucked under them. Explicit areas rather than auto-placement —
     auto-flow gave every cell its own line and turned five short values into
     a card taller than the phone. */
  .trades-table tr {
    margin-bottom: 6px; padding: 8px 10px;
    border: 1px solid var(--text-1); background: #fff;
    display: grid; align-items: baseline;
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
      "side  amount  time"
      "who   paid    paid";
    gap: 3px 10px;
  }
  .trades-table td { padding: 0; border: 0; white-space: nowrap; }
  .trades-table td:nth-child(1) { grid-area: side; }
  .trades-table td:nth-child(2) { grid-area: amount; text-align: right; font-size: 13px; font-weight: 700; }
  .trades-table td:nth-child(3) { grid-area: paid; text-align: right; font-size: 11.5px; color: var(--text-2); }
  .trades-table td:nth-child(4) { grid-area: who; font-size: 10.5px; color: var(--text-2); }
  .trades-table td:nth-child(5) { grid-area: time; text-align: right; font-size: 10.5px; }
  .trades-table td:nth-child(3)::before { content: "for "; color: var(--text-3); }
}

/* --- responsive precision ------------------------------------------------ */
@media (max-width: 1080px) {
  /* The rail stops being a sidebar here, so it must not keep a sidebar's
     width or it sits stranded in the middle of a full-width column. */
  .rail { width: 100%; position: static; }
}

@media (max-width: 760px) {
  /* The header wraps to two rows on phones; anything pinned under it has to
     use the same measurement or it hides behind the search field. */
  .token-head { flex-direction: column; align-items: flex-start; gap: 14px; }
  .token-price { align-items: flex-start; }
  .token-ident h1 { font-size: 21px; }
  .token-crest { width: 46px; height: 46px; font-size: 19px; }
  .page-nav { margin-bottom: 12px; }
  .tabs { overflow-x: auto; scrollbar-width: none; }
  .tabs::-webkit-scrollbar { display: none; }
  .tabs button { white-space: nowrap; }
  /* Full-width tap targets: a 40px control at the edge of a phone is a miss. */
  .wallet-menu { right: 0; min-width: min(260px, calc(100vw - 32px)); }
}

@media (max-width: 380px) {
  .page-nav .back-link { flex: 1 1 0; justify-content: center; }
}

/* --- touch targets -------------------------------------------------------
   Copy/explorer chips and the links inside the trade table are sized for a
   mouse. On a touch screen a 25px chip sits under the ~44px a fingertip
   actually covers, so they grow an invisible hit area rather than getting
   visually bulkier — the layout is unchanged, the misses stop. */
@media (hover: none) {
  .mini { position: relative; }
  .mini::after {
    content: ""; position: absolute;
    top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: 44px; height: 44px;
  }
  .trades-table a, .trade-who { position: relative; display: inline-block; padding: 6px 0; }
  .contract-actions { gap: 8px; }
}

/* The header's launch button is hidden on phones only because the market
   hero already offers one. The token page has no hero, so on that route it
   is the sole way in and must stay. */
@media (max-width: 560px) {
  body[data-route="token"] #launch-open { display: inline-flex; }
  body[data-route="token"] .topbar-actions .btn { padding-inline: 11px; font-size: 10px; }
}

/* The reel is shifted in em (see applyReels), so the slots must be sized in
   the same unit and the window must clip to exactly one of them. Any
   mismatch here reintroduces the half-digit drift. */
.odo-digit { height: 1.2em; line-height: 1.2em; overflow: hidden; }
.odo-reel > span { height: 1.2em; line-height: 1.2em; }
.odo-sym { height: 1.2em; line-height: 1.2em; }

/* Used for the very first placement of a reel, which must not slide in from
   zero. Removed on the next frame so real updates still roll. */
.odo.odo-instant .odo-reel { transition: none; }
