/* ══════════════════════════════════════════════════════════════════════════
   UPLIST — base
   ─────────────────────────────────────────────────────────────────────────
   The whole surface is one idea: a quote sheet. Pink paper, hairline rules,
   tabular figures, no rounded cards floating over anything. Depth comes from
   ruled boxes and one offset ink shadow on the things you press, the way a
   stamp sits on a page — not from blur.
   ══════════════════════════════════════════════════════════════════════════ */

:root{
  /* paper — matched to the ground the logo artwork is drawn on (#fef9f7) */
  --paper:#f8f1ec;
  --paper-2:#f1e8e1;
  --sheet:#fefaf7;
  --pink:#ffe4ea;
  --pink-2:#fbd0da;

  /* ink */
  --ink:#16130f;
  --ink-2:#4c463c;
  --ink-3:#8a8174;
  --ink-4:#b4ab9c;

  /* rules */
  --rule:rgba(22,19,15,.16);
  --rule-2:rgba(22,19,15,.075);
  --rule-hard:rgba(22,19,15,.5);

  /* ══ brand and signal ══
     `--brand` is the logo's pink, sampled off logo.png: #fa5d8b. It is used
     where the artwork is the artwork — the mark, the hero staircase, large
     decorative fills.

     It is NOT used for text or buttons. Against this paper it measures 2.7:1,
     and white on it measures 3.0:1 — both fail. `--accent` is the same hue
     taken down to a weight that passes (4.9:1), so the family reads as one
     colour while anything a person has to read stays legible. */
  --brand:#fa5d8b;
  --accent:#cf1a5f;
  --accent-2:#a5104a;
  --on-accent:#fff6f8;
  --up:#0b6b45;
  --up-bg:rgba(11,107,69,.1);
  --down:#b4232b;
  --down-bg:rgba(180,35,43,.1);
  --gold:#a2751b;
  --gold-bg:rgba(162,117,27,.12);

  /* mark */
  --mk-body:var(--brand);

  /* metrics */
  --wrap:1380px;
  --gut:26px;
  --r:3px;
  --tap:38px;
  /* Height of the sticky masthead. Scroll-into-view offsets measure from
     here, so changing the header changes them together. */
  --stick:61px;

  --sans:'Archivo','Helvetica Neue',Helvetica,Arial,sans-serif;
  --mono:'DM Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  --press:2px 2px 0 var(--ink);
  --press-a:2px 2px 0 var(--accent-2);
}

/* ══ after hours ══
   Same sheet, read under a desk lamp at 2am. The pink survives as a warm
   cast on the panels so the identity does not evaporate in the dark. */
:root[data-theme="dark"]{
  --paper:#100e0c;
  --paper-2:#191614;
  --sheet:#1c1917;
  --pink:#2e1820;
  --pink-2:#3f2029;

  --ink:#f4eee4;
  --ink-2:#b9ae9e;
  --ink-3:#8b8172;
  --ink-4:#635b50;

  --rule:rgba(244,238,228,.17);
  --rule-2:rgba(244,238,228,.08);
  --rule-hard:rgba(244,238,228,.44);

  /* On a dark ground the logo pink passes on its own, so brand and accent
     converge — which is the version of the identity that looks most like the
     artwork. */
  --brand:#fa5d8b;
  --accent:#fd7ba2;
  --accent-2:#ffa0bd;
  --on-accent:#1c0c13;
  --up:#43d494;
  --up-bg:rgba(67,212,148,.12);
  --down:#ff6f6f;
  --down-bg:rgba(255,111,111,.13);
  --gold:#e0b055;
  --gold-bg:rgba(224,176,85,.14);

  --mk-body:var(--brand);

  --press:2px 2px 0 rgba(244,238,228,.28);
  --press-a:2px 2px 0 rgba(255,92,121,.35);
}

/* The same palette again, for the state where nothing has stamped the root
   yet: a visitor whose OS is dark before the theme script has run, or a host
   that leaves the choice to the system. `:not([data-theme="light"])` so an
   explicit light choice still beats a dark OS. Duplicated rather than shared
   because a media query cannot join a selector list — if you edit the block
   above, edit this one with it. */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --paper:#100e0c;
    --paper-2:#191614;
    --sheet:#1c1917;
    --pink:#2e1820;
    --pink-2:#3f2029;

    --ink:#f4eee4;
    --ink-2:#b9ae9e;
    --ink-3:#8b8172;
    --ink-4:#635b50;

    --rule:rgba(244,238,228,.17);
    --rule-2:rgba(244,238,228,.08);
    --rule-hard:rgba(244,238,228,.44);

    --brand:#fa5d8b;
    --accent:#fd7ba2;
    --accent-2:#ffa0bd;
    --on-accent:#1c0c13;
    --up:#43d494;
    --up-bg:rgba(67,212,148,.12);
    --down:#ff6f6f;
    --down-bg:rgba(255,111,111,.13);
    --gold:#e0b055;
    --gold-bg:rgba(224,176,85,.14);

    --mk-body:var(--brand);

    --press:2px 2px 0 rgba(244,238,228,.28);
    --press-a:2px 2px 0 rgba(255,92,121,.35);
  }
  :root:not([data-theme="light"]) body{background-image:linear-gradient(rgba(244,238,228,.035) 1px,transparent 1px)}
  :root:not([data-theme="light"]) .ico-sun{display:none}
  :root:not([data-theme="light"]) .ico-moon{display:block}
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}

body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font:400 15px/1.55 var(--sans);
  font-feature-settings:'kern' 1;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  /* `clip`, not `hidden` — `hidden` turns body into a scroll container, which
     detaches the sticky masthead from the viewport and paints it adrift. */
  overflow-x:clip;
  /* the faintest ruled-paper texture — two hairlines, no images */
  background-image:
    linear-gradient(var(--rule-2) 1px,transparent 1px);
  background-size:100% 44px;
}
:root[data-theme="dark"] body{background-image:linear-gradient(rgba(244,238,228,.035) 1px,transparent 1px)}

h1,h2,h3,h4{margin:0;font-weight:700;letter-spacing:-.02em;line-height:1.12}
p{margin:0}
a{color:inherit;text-decoration:none}
button,input,select,textarea{font:inherit;color:inherit}
img{max-width:100%;display:block}
svg{display:block}

::selection{background:var(--accent);color:var(--on-accent)}

.skip{
  position:fixed;left:12px;top:-60px;z-index:200;
  background:var(--ink);color:var(--paper);padding:9px 14px;border-radius:var(--r);
  transition:top .16s
}
.skip:focus{top:12px}

:where(a,button,input,select,textarea,[tabindex]):focus-visible{
  outline:2px solid var(--accent);outline-offset:2px;border-radius:2px
}

.wrap{max-width:var(--wrap);margin:0 auto;padding:0 var(--gut);width:100%}

/* ══════════════ numbers ══════════════
   Everything countable is monospaced and tabular. A column of prices that
   does not line up is a column you cannot scan, and scanning is the whole
   job of a quote sheet. */
.num{font-family:var(--mono);font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.up{color:var(--up)}
.down{color:var(--down)}
.muted{color:var(--ink-3)}
.tiny{font-size:11px}

.lbl{
  font-size:10.5px;font-weight:600;letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink-3)
}

/* ══════════════ masthead ══════════════ */
.masthead{
  position:sticky;top:0;z-index:80;
  background:var(--paper);
  border-bottom:1px solid var(--rule-hard);
}
.masthead::after{
  content:'';position:absolute;left:0;right:0;bottom:-4px;height:3px;
  border-top:1px solid var(--rule);pointer-events:none
}

.mh-main-in{display:flex;align-items:center;gap:18px;min-height:60px}

.brand{display:flex;align-items:center;gap:9px;flex:none}
.wordmark{
  font-weight:800;font-size:21px;letter-spacing:.02em;text-transform:uppercase;
  line-height:1
}
/* The mark is a flat, hard-edged shape; a soft shadow under it just makes
   it look printed slightly out of register. */
.brand .mk{flex:none}

.mh-nav{display:flex;align-items:center;gap:2px;flex:none}
.mh-nav a{
  padding:7px 11px;font-size:13.5px;font-weight:600;color:var(--ink-2);
  border-radius:var(--r);white-space:nowrap
}
.mh-nav a:hover{color:var(--ink);background:var(--pink)}
:root[data-theme="dark"] .mh-nav a:hover{background:var(--paper-2)}
.mh-nav a.on{color:var(--ink);background:var(--pink);box-shadow:inset 0 -2px 0 var(--accent)}
:root[data-theme="dark"] .mh-nav a.on{background:var(--paper-2)}

.mh-search{position:relative;flex:1;min-width:120px;max-width:340px;margin-left:auto}
.mh-search svg{
  position:absolute;left:10px;top:50%;transform:translateY(-50%);
  width:15px;height:15px;fill:none;stroke:var(--ink-3);stroke-width:2;
  stroke-linecap:round;pointer-events:none
}
.mh-search input{
  width:100%;height:var(--tap);padding:0 12px 0 31px;
  background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r);
  font-size:13.5px;-webkit-appearance:none
}
.mh-search input::placeholder{color:var(--ink-4)}
.mh-search input:focus{border-color:var(--ink);outline:none;box-shadow:var(--press)}

.mh-actions{display:flex;align-items:center;gap:8px;flex:none}

.icobtn{
  width:var(--tap);height:var(--tap);flex:none;display:grid;place-items:center;
  background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r);cursor:pointer
}
.icobtn svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round}
.icobtn:hover{border-color:var(--ink);box-shadow:var(--press)}
.ico-moon{display:none}
:root[data-theme="dark"] .ico-sun{display:none}
:root[data-theme="dark"] .ico-moon{display:block}

.burger{
  display:none;width:var(--tap);height:var(--tap);flex:none;
  background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r);
  cursor:pointer;padding:0;place-items:center;gap:4px
}
.burger span{display:block;width:16px;height:1.8px;background:var(--ink);transition:.18s}
.burger[aria-expanded="true"] span:nth-child(1){transform:translateY(5.8px) rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0}
.burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-5.8px) rotate(-45deg)}

/* ══ autocomplete ══ */
.ac{
  position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:90;
  background:var(--sheet);border:1px solid var(--ink);border-radius:var(--r);
  box-shadow:var(--press);max-height:min(60vh,420px);overflow:auto
}
.ac-row{
  display:flex;align-items:center;gap:10px;padding:9px 11px;cursor:pointer;
  border-bottom:1px solid var(--rule-2)
}
.ac-row:last-child{border-bottom:0}
.ac-row:hover,.ac-row.sel{background:var(--pink)}
:root[data-theme="dark"] .ac-row:hover,:root[data-theme="dark"] .ac-row.sel{background:var(--paper-2)}
.ac-row .av{width:26px;height:26px;flex:none}
.ac-nm{flex:1;min-width:0;font-size:13.5px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ac-nm small{display:block;font-weight:400;font-size:11.5px;color:var(--ink-3)}
.ac-empty{padding:14px 12px;font-size:13px;color:var(--ink-3)}
.ac-head{
  padding:7px 11px;background:var(--paper-2);border-bottom:1px solid var(--rule-2);
  font-size:10px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3)
}


/* ══════════════ buttons ══════════════ */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  height:var(--tap);padding:0 15px;
  background:var(--sheet);color:var(--ink);
  border:1px solid var(--ink);border-radius:var(--r);
  font-size:13.5px;font-weight:600;letter-spacing:-.005em;
  cursor:pointer;white-space:nowrap;
  transition:transform .1s,box-shadow .1s,background .12s
}
.btn:hover{box-shadow:var(--press);transform:translate(-1px,-1px)}
.btn:active{box-shadow:none;transform:translate(1px,1px)}
.btn.primary{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.btn.primary:hover{box-shadow:var(--press-a)}
.btn.ghost{border-color:var(--rule);background:transparent}
.btn.ghost:hover{border-color:var(--ink)}
.btn.sm{height:30px;padding:0 11px;font-size:12.5px}
.btn.lg{height:46px;padding:0 22px;font-size:15px}
.btn.wide{width:100%}
.btn[disabled],.btn.off{opacity:.42;pointer-events:none}
.btn svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

/* ══════════════ panels & rules ══════════════ */
.panel{
  background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r);
}
.panel-hd{
  display:flex;align-items:center;gap:10px;
  padding:11px 14px;border-bottom:1px solid var(--rule);
  background:var(--pink)
}
:root[data-theme="dark"] .panel-hd{background:var(--paper-2)}
.panel-hd h3{font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase}
.panel-hd .sp{flex:1}
.panel-bd{padding:14px}

.hr{height:1px;background:var(--rule);border:0;margin:0}

/* ══════════════ pills ══════════════ */
.pill{
  display:inline-flex;align-items:center;gap:5px;
  height:21px;padding:0 8px;border-radius:2px;
  font-size:10.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  background:var(--paper-2);color:var(--ink-2);border:1px solid var(--rule-2);
  white-space:nowrap
}
.pill.up{background:var(--up-bg);color:var(--up);border-color:transparent}
.pill.down{background:var(--down-bg);color:var(--down);border-color:transparent}
.pill.gold{background:var(--gold-bg);color:var(--gold);border-color:transparent}
.pill.hot{background:var(--accent);color:var(--on-accent);border-color:transparent}
.pill.tier{font-family:var(--mono);letter-spacing:.02em}

/* ══════════════ token avatar ══════════════
   No image uploads in a static preview, so the art is generated: two ink
   colours derived from the mint plus the first letter. Deterministic, so a
   token looks the same on every page it appears. */
.av{
  display:grid;place-items:center;flex:none;
  border:1px solid var(--rule);border-radius:2px;
  font-weight:800;color:#fff;text-transform:uppercase;
  overflow:hidden;position:relative;line-height:1
}
.av::after{
  content:'';position:absolute;inset:0;
  background:linear-gradient(150deg,rgba(255,255,255,.28),transparent 60%)
}
.av span{position:relative;z-index:1;letter-spacing:-.03em}

/* An uploaded image is the creator's, not a surface to gloss over. */
.av-img{background:var(--paper-2)}
.av-img::after{display:none}
.av-img img{width:100%;height:100%;object-fit:cover;display:block}

/* No image uploaded. A flat lettered tile, deliberately plain — nothing is
   generated to dress up the absence. */
.av-blank{background:var(--paper-2);color:var(--ink-4);border-style:dashed}
.av-blank::after{display:none}

/* ══════════════ segmented control ══════════════ */
.seg{
  display:inline-flex;background:var(--paper-2);border:1px solid var(--rule);
  border-radius:var(--r);padding:2px;gap:2px
}
.seg button{
  background:none;border:0;cursor:pointer;padding:0 11px;height:28px;
  font-size:12.5px;font-weight:600;color:var(--ink-3);border-radius:2px;white-space:nowrap
}
.seg button:hover{color:var(--ink)}
.seg button[aria-selected="true"]{background:var(--sheet);color:var(--ink);box-shadow:0 1px 0 var(--rule)}

/* ══════════════ tabs (ruled, not pilled) ══════════════ */
.tabs{display:flex;gap:2px;align-items:flex-end}
.tabs button{
  background:none;border:0;border-bottom:2px solid transparent;cursor:pointer;
  padding:8px 12px;font-size:13.5px;font-weight:600;color:var(--ink-3);white-space:nowrap
}
.tabs button:hover{color:var(--ink)}
.tabs button[aria-selected="true"]{color:var(--ink);border-bottom-color:var(--accent)}
.tabs button .cnt{
  font-family:var(--mono);font-size:11px;color:var(--ink-4);margin-left:5px
}

/* ══════════════ tables ══════════════ */
.tbl{width:100%;border-collapse:collapse;font-size:13.5px}
.tbl th{
  text-align:left;padding:8px 12px;
  font-size:10px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-3);border-bottom:1px solid var(--rule);white-space:nowrap;
  background:var(--sheet);position:sticky;top:0;z-index:2
}
.tbl th.r,.tbl td.r{text-align:right}
.tbl td{padding:10px 12px;border-bottom:1px solid var(--rule-2);vertical-align:middle}
.tbl tbody tr:hover td{background:var(--pink)}
:root[data-theme="dark"] .tbl tbody tr:hover td{background:var(--paper-2)}
.tbl tbody tr{cursor:pointer}
.tbl th.sortable{cursor:pointer;user-select:none}
.tbl th.sortable:hover{color:var(--ink)}
.tbl th .arw{opacity:0;margin-left:4px}
.tbl th.sorted .arw{opacity:1}

/* ══════════════ forms ══════════════ */
.field{display:block;margin-bottom:16px}
.field > label{display:block;margin-bottom:6px;font-size:12.5px;font-weight:600}
.field .hint{display:block;margin-top:6px;font-size:12px;color:var(--ink-3);line-height:1.45}
.field .err{display:block;margin-top:6px;font-size:12px;color:var(--down);font-weight:500}
.inp{
  width:100%;height:42px;padding:0 12px;
  background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r);
  font-size:14.5px;-webkit-appearance:none
}
textarea.inp{height:auto;padding:11px 12px;resize:vertical;min-height:84px;line-height:1.55}
.inp::placeholder{color:var(--ink-4)}
.inp:focus{outline:none;border-color:var(--ink);box-shadow:var(--press)}
.inp.bad{border-color:var(--down)}
.inp[readonly]{background:var(--paper-2);color:var(--ink-2)}

.cnt-box{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:6px}
.cnt-box .c{font-family:var(--mono);font-size:11.5px;color:var(--ink-4)}

/* ══════════════ sparkline ══════════════ */
.spark{display:block;width:100%;height:100%;overflow:visible}
.spark path{fill:none;stroke-width:1.5;vector-effect:non-scaling-stroke}
.spark .fill{stroke:none;opacity:.13}

/* ══════════════ progress ══════════════ */
.prog{height:6px;background:var(--paper-2);border:1px solid var(--rule-2);border-radius:99px;overflow:hidden}
.prog i{display:block;height:100%;background:var(--accent);border-radius:99px;transition:width .5s}
.prog.done i{background:var(--up)}

/* ══════════════ empty & loading ══════════════ */
.empty{
  padding:56px 24px;text-align:center;color:var(--ink-3);
  border:1px dashed var(--rule);border-radius:var(--r);background:var(--sheet)
}
.empty h3{font-size:17px;color:var(--ink);margin-bottom:7px}
.empty p{max-width:46ch;margin:0 auto 16px;font-size:14px;line-height:1.6}
/* The sheet's own empty state carries the page rather than apologising in a
   corner of it, so it gets the room a listing table would have taken. */
.empty-lg{padding:76px 24px}
.empty-lg h3{font-size:22px;letter-spacing:-.025em;margin-bottom:10px}
.empty-lg p{max-width:52ch;font-size:15px}
.empty-cta{display:flex;gap:10px;justify-content:center;flex-wrap:wrap}

/* ══════════════ notice ══════════════
   Says what is not true yet, inline where it matters, instead of a banner
   nailed across the top of every page. */
.notice{
  margin-top:20px;padding:14px 16px;
  border:1px solid var(--ink);border-radius:var(--r);background:var(--pink);box-shadow:var(--press)
}
:root[data-theme="dark"] .notice{background:var(--paper-2)}
.notice b{
  display:block;font-size:11px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--accent);margin-bottom:6px
}
.notice p{font-size:13.5px;line-height:1.6;color:var(--ink-2);margin:0}

/* ══════════════ breadcrumb ══════════════ */
.crumb{
  display:inline-flex;align-items:center;gap:6px;margin-bottom:14px;
  font-size:12.5px;font-weight:600;color:var(--ink-3)
}
.crumb:hover{color:var(--accent)}

/* ══════════════ key/value rows ══════════════ */
.pb-rows{border-top:1px solid var(--rule-2)}
.pb-row{display:flex;gap:10px;padding:8px 14px;font-size:12.5px;border-bottom:1px solid var(--rule-2)}
.pb-row:last-child{border-bottom:0}
.pb-row .k{color:var(--ink-3);flex:1}
.pb-row .v{font-family:var(--mono);font-variant-numeric:tabular-nums}

.skel{
  background:linear-gradient(90deg,var(--paper-2) 25%,var(--pink) 50%,var(--paper-2) 75%);
  background-size:200% 100%;animation:sk 1.3s linear infinite;border-radius:2px;color:transparent
}
@keyframes sk{to{background-position:-200% 0}}
@media (prefers-reduced-motion:reduce){.skel{animation:none}}

/* ══════════════ view routing ══════════════ */
.view{display:none}
.view.on{display:block;animation:in .22s ease-out}
@keyframes in{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.view.on{animation:none}}

/* ══════════════ footer ══════════════ */
.ft{margin-top:64px;border-top:1px solid var(--rule-hard);background:var(--sheet)}
.ft-in{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:32px;padding-top:40px;padding-bottom:32px}
.ft-brand .mk{display:inline-block;vertical-align:-4px;margin-right:7px}
.ft-brand .wordmark{font-size:18px}
.ft-brand p{margin-top:11px;max-width:34ch;font-size:13.5px;color:var(--ink-3);line-height:1.6}
.ft-col{display:flex;flex-direction:column;gap:8px}
.ft-col h4{
  font-size:10px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink-4);margin-bottom:3px
}
.ft-col a{font-size:13.5px;color:var(--ink-2)}
.ft-col a:hover{color:var(--accent)}

/* ══════════════ responsive ══════════════ */
@media (max-width:1180px){
  .mh-search{max-width:230px}
  .ft-in{grid-template-columns:1.6fr 1fr 1fr 1fr;gap:22px}
}
@media (max-width:1000px){
  :root{--gut:18px}
  .mh-nav,.mh-actions .btn:not(#walletBtn){display:none}
  .burger{display:grid}
  .mh-search{max-width:none;order:5;flex-basis:100%;margin:0 0 12px}
  .mh-main-in{flex-wrap:wrap;padding-top:10px}
  .masthead.open .mh-nav{
    display:flex;order:6;flex-basis:100%;flex-direction:column;align-items:stretch;
    gap:0;border-top:1px solid var(--rule);padding:8px 0 12px;margin-top:2px
  }
  .masthead.open .mh-nav a{padding:11px 8px;font-size:15px;border-radius:0}
  .masthead.open .mh-nav a.on{box-shadow:inset 2px 0 0 var(--accent)}
  .masthead.open .mh-actions{order:7;flex-basis:100%;padding-bottom:12px}
  .masthead.open .mh-actions .btn{display:inline-flex;flex:1}
  .ft-in{grid-template-columns:1fr 1fr;gap:26px}
}
@media (max-width:560px){
  body{font-size:14.5px}
  .ft-in{grid-template-columns:1fr}
  .wordmark{font-size:19px}
}
