/*
 * Launch board.
 *
 * Two earlier decisions are reversed here, both on purpose.
 *
 * Density. The first pass followed gmgn: 8px corners, chips everywhere, rows
 * packed as tight as they would go. That optimises for a trader watching two
 * hundred launches at once, which is not what this board is for. Following
 * pons instead - large radii, real padding, one idea per line - costs maybe
 * two rows per screen and makes the thing readable.
 *
 * Type. Inter Tight was a placeholder. The mark is a monoline tube with fully
 * rounded caps, so the type is Outfit: a geometric monoline sans built the
 * same way the letter is. Figures are DM Mono, because a market-cap column
 * that does not align on the decimal is not a column. Neither is pons's pair
 * (they run Inter and Instrument Serif) - the shell is borrowed, the voice is
 * not.
 */

:root {
  /* ground — from the brand mark's own plate */
  --page: #1b1c1f;
  --surface: #232427;
  --surface-2: #292a2e;   /* the brand ground token */
  --raised: #303236;
  --line: #303237;
  --line-soft: #2a2c30;

  /* cobalt ramp — sampled from the chosen render */
  --cobalt-1: #5386dd;
  --cobalt-2: #3367cf;
  --cobalt-3: #2446a3;
  --cobalt-4: #132155;
  --accent: var(--cobalt-2);
  --accent-hi: var(--cobalt-1);
  --accent-soft: #16233f;

  --text: #edeff3;
  --text-2: #9aa1ad;
  --text-3: #6d7481;

  /* semantic — kept clear of the accent so state never reads as branding */
  --up: #30d158;
  --down: #ff453a;
  --warn: #ffb020;

  --r-card: 16px;
  --r-chip: 999px;
  --r-pill: 999px;

  --mono: "DM Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --sans: "Outfit", "Segoe UI", system-ui, -apple-system, "Noto Sans CJK SC",
          "Microsoft YaHei", sans-serif;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  display: flex; flex-direction: column; min-height: 100vh;
  background: var(--page);
  color: var(--text);
  font: 400 14px/1.5 var(--sans);
  -webkit-font-smoothing: antialiased;
}
:focus-visible { outline: 2px solid var(--accent-hi); outline-offset: 2px; }

/* ---------------------------------------------------------------- chrome */
/* Everything in the bar is one line. Without this the brand and the connect
   button both wrapped the moment the search hint appeared. */
.topbar {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 22px; border-bottom: 1px solid var(--line);
  background: var(--surface); flex: none; flex-wrap: nowrap; white-space: nowrap;
}
.brand { display: flex; align-items: center; gap: 10px; flex: none; }
.brand img { width: 30px; height: 30px; border-radius: 9px; display: block; }
.brand b { font-size: 16px; font-weight: 600; letter-spacing: -.015em; }
.brand span { color: var(--text-3); font-size: 13px; white-space: nowrap; }

.net {
  display: flex; align-items: center; gap: 10px; flex: none;
  font-family: var(--mono); font-size: 12px; color: var(--text-2); white-space: nowrap;
}
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--up); flex: none; }
.dot.stale { background: var(--warn); }
.dot.err { background: var(--down); }

select, button.ghost {
  background: var(--surface-2); color: var(--text); border: 1px solid var(--line);
  border-radius: var(--r-pill); padding: 7px 14px; font: 400 12px var(--mono); cursor: pointer;
}
button.ghost:hover, select:hover { border-color: var(--accent); }

/* --------------------------------------------------------- graduated grid
   Large square artwork, the way pons presents its graduated set. It earns the
   space here in a way it would not on a live curve: a graduated launch has a
   settled identity, and the picture is most of what identifies it. */
.top { border-bottom: 1px solid var(--line); background: var(--surface); flex: none; }
.top-head { display: flex; align-items: baseline; gap: 10px; padding: 16px 22px 12px; }
.top-head h2 { margin: 0; font-size: 17px; font-weight: 600; letter-spacing: -.015em; }
.top-head .col-note { margin-left: auto; }
/* A shelf, not a wall. Stacked rows would either clip the second one through
   the middle of its artwork — which reads as a rendering fault rather than as
   "scroll for more" — or eat the vertical space the four live columns need.
   Scrolling sideways keeps every card whole. */
.top-wrap { overflow-x: auto; overflow-y: hidden; padding: 0 20px 18px; }
.top-wrap::-webkit-scrollbar { height: 9px; }
.top-wrap::-webkit-scrollbar-thumb { background: var(--raised); border-radius: 5px; }
.top-wrap::-webkit-scrollbar-track { background: var(--surface-2); border-radius: 5px; }

.grid {
  display: grid; gap: 14px;
  grid-auto-flow: column; grid-auto-columns: 194px;
}
.gcard {
  background: var(--surface-2); border: 1px solid var(--line-soft);
  border-radius: var(--r-card); padding: 11px; cursor: pointer;
  transition: border-color .13s, background .13s;
}
.gcard:hover { border-color: var(--accent); background: var(--raised); }

.art {
  position: relative; aspect-ratio: 1; border-radius: 12px; overflow: hidden;
  background-size: cover; background-position: center; margin-bottom: 11px;
}
.art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.badge {
  position: absolute; top: 8px; left: 8px;
  font-family: var(--mono); font-size: 10px; letter-spacing: .02em;
  padding: 3px 8px; border-radius: var(--r-pill);
  /* The artwork underneath is arbitrary — anything from white to neon — so the
     badge carries its own dark ground rather than trusting the image. */
  background: rgba(12,13,15,.78); color: #e6e8ec; backdrop-filter: blur(6px);
}
.badge.pairbadge { left: auto; right: 8px; color: var(--cobalt-1); }

.gcard h3 {
  margin: 0; font-size: 14.5px; font-weight: 600; letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gcard .tick { font-family: var(--mono); font-size: 11.5px; color: var(--text-3); margin-top: 2px; }
.gcard .caps { margin-top: 8px; font-family: var(--mono); font-size: 13px; font-variant-numeric: tabular-nums; }
.gcard .caps b { color: var(--text); font-weight: 500; }
.gcard .caps em { font-style: normal; font-size: 10px; color: var(--text-3); }
.gcard .caps .fdv { color: var(--text-3); font-size: 11.5px; }
.gcard .gfoot {
  display: flex; justify-content: space-between; gap: 8px;
  margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--line-soft);
  font-family: var(--mono); font-size: 10.5px; color: var(--text-3);
}

/* ---------------------------------------------------------------- board */
.board {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px; background: var(--line-soft);
  flex: 1; min-height: 0; overflow: hidden;
}
.col { background: var(--page); display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.col-head {
  display: flex; align-items: baseline; gap: 10px;
  padding: 15px 20px 12px; border-bottom: 1px solid var(--line); background: var(--page);
}
.col-head h2 { margin: 0; font-size: 15px; font-weight: 600; letter-spacing: -.01em; }
.count {
  font-family: var(--mono); font-size: 11px; color: var(--text-2);
  background: var(--surface-2); padding: 2px 9px; border-radius: var(--r-pill);
}
.col-note { margin-left: auto; font-family: var(--mono); font-size: 11px; color: var(--text-3); }
.col-body {
  flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden;
  padding: 12px; display: flex; flex-direction: column; gap: 8px;
}
.col-body::-webkit-scrollbar { width: 9px; }
.col-body::-webkit-scrollbar-thumb { background: var(--raised); border-radius: 5px; }

/* ---------------------------------------------------------------- row
   The card is a four-area grid: artwork, identity, rail on the first line,
   then description and links spanning underneath. Launches carry real logos
   on chain — 98% of them — so the artwork is sized to actually show one
   rather than to save a row of vertical space. */
.row {
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr) auto;
  grid-template-areas:
    "ava mid right"
    "desc desc desc"
    "links links links";
  gap: 10px 14px; align-items: center;
  background: var(--surface); border: 1px solid transparent;
  border-radius: var(--r-card); padding: 14px;
  cursor: pointer; transition: border-color .13s, background .13s;
}
.row:hover { border-color: var(--accent); background: var(--surface-2); }
.row.settling { background: #241f14; }
.row.rescued  { background: #241416; }

/* The identicon is the element's background; the real logo is an <img> on top
   of it. If the logo 404s or never resolves, the tile stays instead of the
   browser's broken-image glyph — no error handler, nothing for a CSP to
   block, and no flash of empty box while IPFS thinks about it. */
.ava {
  grid-area: ava; width: 52px; height: 52px; border-radius: 14px;
  background-size: cover; background-position: center; overflow: hidden; flex: none;
}
.ava img { width: 100%; height: 100%; object-fit: cover; display: block; }

.mid { grid-area: mid; min-width: 0; }
.line1 { display: flex; align-items: baseline; gap: 7px; min-width: 0; }
.sym { font-weight: 600; font-size: 16px; letter-spacing: -.01em; white-space: nowrap; }
.nm { color: var(--text-3); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
/* One line of metadata, not four chips. Age, what it is quoted in, and a tax
   only when there is one — a "tax 0.00%" chip on every row is pure noise. */
.line2 {
  margin-top: 5px; display: flex; align-items: center; gap: 4px 8px; flex-wrap: wrap;
  font-family: var(--mono); font-size: 11.5px; color: var(--text-3);
}
/* Four columns leave each card narrow enough that this line wraps; wrap it
   between facts, never through the middle of one. */
.line2 > span { white-space: nowrap; }
.line2 .pair { color: var(--accent-hi); }
.line2 .tax { color: var(--warn); }
.line2 .st { color: var(--warn); }
.line2 .st.rescued { color: var(--down); }
.sep { color: var(--line); }

/* Creators write these; two lines is enough to tell a project from a joke,
   and clamping means one long paragraph cannot push a whole column around. */
.desc {
  grid-area: desc; margin: 0; color: var(--text-2); font-size: 13px; line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; text-overflow: ellipsis;
}

.links {
  grid-area: links; display: flex; align-items: center; gap: 6px;
  padding-top: 11px; border-top: 1px solid var(--line-soft);
}
.ic {
  width: 28px; height: 28px; border-radius: 9px; display: grid; place-items: center;
  color: var(--text-3); background: var(--surface-2); transition: color .12s, background .12s;
}
.ic:hover { color: var(--text); background: var(--raised); }
.ic svg { width: 14px; height: 14px; fill: currentColor; display: block; }
.addr { margin-left: auto; font-family: var(--mono); font-size: 11px; color: var(--text-3); }

/* Right rail. gmgn puts a price sparkline here; a curve three minutes old has
   no price history worth drawing, but it does have an exact number — reserve
   over threshold, the very ratio it graduates on. In the volume column the
   rail carries dollars traded instead, which is the ordering of that column. */
.right { grid-area: right; display: flex; flex-direction: column; align-items: flex-end; gap: 7px; }
.pct { font-family: var(--mono); font-size: 15px; font-variant-numeric: tabular-nums; color: var(--accent-hi); }
.pct.zero { color: var(--text-3); }
.pct small { color: var(--text-3); font-size: 11px; }
.bar { width: 84px; height: 5px; border-radius: 3px; background: var(--raised); overflow: hidden; }
.bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--cobalt-3), var(--cobalt-1)); }
.bar.done i { background: var(--up); }
.bar.settling i { background: var(--warn); }
.vol { font-family: var(--mono); font-size: 14px; color: var(--text); font-variant-numeric: tabular-nums; }
.vol.buy { color: var(--up); }
.trades { font-family: var(--mono); font-size: 11px; color: var(--text-3); }
.waiting { font-family: var(--mono); font-size: 11.5px; color: var(--warn); }

.empty { padding: 40px 16px; color: var(--text-3); font-size: 13px; text-align: center; }
.banner {
  margin: 12px 12px 0; padding: 12px 14px; border-radius: var(--r-card);
  background: #241f14; color: #e8c98a; font-size: 12.5px; line-height: 1.5;
}
.banner b { color: var(--warn); }

@media (max-width: 1500px) { .board { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 980px) {
  .board { grid-template-columns: 1fr; flex: none; overflow: visible; }
  .col { min-height: auto; }
  .col-body { flex: none; max-height: 60vh; }
  .top-wrap { max-height: 220px; }
  table.mc .hide-s { display: none; }
}

/* ================================================================= app shell
   The board is one view; launch, profile and docs are pages. Pages get a
   measured column and real reading width — the board's density is right for
   scanning two hundred launches and wrong for a form or a paragraph. */
/* The nav does the pushing, so what follows stays right-aligned whether or
   not the board's own controls are on screen. */
.nav { display: flex; gap: 4px; margin-left: 8px; margin-right: auto; }
.nav a {
  padding: 7px 14px; border-radius: var(--r-pill); text-decoration: none;
  color: var(--text-3); font-size: 13.5px; font-weight: 500; transition: color .12s, background .12s;
}
.nav a:hover { color: var(--text-2); background: var(--surface-2); }
.nav a.on { color: var(--text); background: var(--surface-2); }

.wallet { display: flex; align-items: center; gap: 8px; position: relative; flex: none; }
.acct {
  font-family: var(--mono); font-size: 12px; color: var(--text);
  background: var(--surface-2); padding: 7px 12px; border-radius: var(--r-pill);
}
button.cta {
  background: var(--accent); color: #fff; border: 0; border-radius: var(--r-pill);
  padding: 8px 16px; font: 500 13px var(--sans); cursor: pointer; transition: background .12s;
  white-space: nowrap; flex: none;
}
button.cta:hover { background: var(--cobalt-1); }
button.cta:disabled { background: var(--raised); color: var(--text-3); cursor: not-allowed; }
button.cta.big { padding: 12px 26px; font-size: 15px; margin-top: 22px; }
.warn-pill {
  background: #3a2a10; color: var(--warn); border: 1px solid #5a4418;
  border-radius: var(--r-pill); padding: 6px 12px; font: 400 12px var(--mono); cursor: pointer;
}
.picker { position: relative; }
.picker .menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 40; min-width: 190px;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 12px; padding: 5px; display: flex; flex-direction: column; gap: 2px;
}
.picker .menu button {
  display: flex; align-items: center; gap: 9px; width: 100%;
  background: none; border: 0; border-radius: 9px; padding: 9px 11px;
  color: var(--text); font: 400 13px var(--sans); cursor: pointer; text-align: left;
}
.picker .menu button:hover { background: var(--raised); }
.picker .menu img { width: 18px; height: 18px; border-radius: 5px; }

#toast {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: 26px; z-index: 100;
  max-width: 560px; padding: 12px 18px; border-radius: 12px;
  background: #2a1618; border: 1px solid #4a2226; color: #ffb4ae;
  font-size: 13px; line-height: 1.45;
}

/* ------------------------------------------------------------------- pages */
.page { max-width: 780px; margin: 0 auto; padding: 34px 24px 80px; }
.page h1 { margin: 0 0 8px; font-size: 27px; font-weight: 600; letter-spacing: -.02em; }
.lede { margin: 0 0 22px; color: var(--text-2); font-size: 15px; line-height: 1.55; max-width: 62ch; }

.ctx {
  font-family: var(--mono); font-size: 11.5px; color: var(--text-2);
  background: var(--surface); border-radius: 10px; padding: 11px 14px; margin-bottom: 24px;
}
.ctx.bad { color: var(--warn); background: #241f14; }

.form { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field.wide { grid-column: 1 / -1; }
.field label {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 13px; font-weight: 500; color: var(--text-2);
}
.field .count { margin-left: auto; font-family: var(--mono); font-size: 10.5px; color: var(--text-3); }
.field .count.over { color: var(--down); }
.field input, .field textarea, .field select {
  background: var(--surface); border: 1px solid var(--line); border-radius: 11px;
  padding: 11px 13px; color: var(--text); font: 400 14px var(--sans); width: 100%;
  transition: border-color .12s;
}
.field textarea { resize: vertical; line-height: 1.5; }
.field input:focus, .field textarea:focus, .field select:focus { border-color: var(--accent); outline: none; }
.field.bad input, .field.bad textarea { border-color: var(--down); }
.field .hint { font-size: 12px; color: var(--text-3); line-height: 1.45; }
.field .err { font-size: 12px; color: var(--down); min-height: 0; }
.field.check label { font-weight: 400; color: var(--text); gap: 10px; align-items: center; }
.field.check input { width: auto; }

.result {
  margin-top: 20px; padding: 14px 16px; border-radius: 12px;
  background: var(--surface); font-size: 13.5px; line-height: 1.6; word-break: break-word;
}
.result.good { background: #10240f; color: #b6efb0; }
.result.bad { background: #241416; color: #ffb4ae; }
.result code { font-family: var(--mono); font-size: 12px; }
.result a { color: var(--accent-hi); }

/* ----------------------------------------------------------------- profile */
.pstats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px;
  margin-bottom: 24px;
}
.pstats div { background: var(--surface); border-radius: 12px; padding: 14px 16px; }
.pstats span { display: block; font-size: 12px; color: var(--text-3); margin-bottom: 4px; }
.pstats b { font-size: 16px; font-weight: 600; }
.plist { display: flex; flex-direction: column; gap: 8px; }
.prow {
  display: grid; grid-template-columns: minmax(0,1fr) auto auto; gap: 16px; align-items: center;
  background: var(--surface); border-radius: 12px; padding: 14px 16px;
}
.prow b { font-size: 14.5px; }
.prow span { color: var(--text-3); font-size: 13px; }
.prow .mono { font-family: var(--mono); font-size: 12px; color: var(--text-2); }
.prow .addr { color: var(--text-3); }
.prow a { color: var(--accent-hi); text-decoration: none; }

/* -------------------------------------------------------------------- docs */
.docs { display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 42px; max-width: 1020px; margin: 0 auto; padding: 34px 24px 90px; }
.toc { position: sticky; top: 84px; align-self: start; display: flex; flex-direction: column; gap: 1px; }
.toc a {
  padding: 8px 12px; border-radius: 9px; color: var(--text-3);
  text-decoration: none; font-size: 13px; transition: color .12s, background .12s;
}
.toc a:hover { color: var(--text); background: var(--surface); }
.docs article { min-width: 0; }
.docs h1 { margin: 0 0 8px; font-size: 30px; font-weight: 600; letter-spacing: -.02em; }
.docs h2 { margin: 38px 0 12px; font-size: 19px; font-weight: 600; letter-spacing: -.01em; }
.docs p, .docs li { color: var(--text-2); font-size: 15px; line-height: 1.68; max-width: 66ch; }
.docs p { margin: 0 0 14px; }
.docs ul { margin: 0 0 14px; padding-left: 20px; }
.docs li { margin-bottom: 6px; }
.docs b { color: var(--text); font-weight: 600; }
.docs em { color: var(--text); font-style: italic; }
.docs code {
  font-family: var(--mono); font-size: 13px; color: var(--accent-hi);
  background: var(--surface); padding: 2px 6px; border-radius: 6px;
}
.docs a { color: var(--accent-hi); }

@media (max-width: 900px) {
  .form { grid-template-columns: 1fr; }
  .docs { grid-template-columns: 1fr; gap: 20px; }
  .toc { position: static; flex-direction: row; flex-wrap: wrap; }
}

/* The hidden attribute must beat the layout rules above it; `display: flex` on
   a class otherwise wins over the UA's `[hidden] { display: none }`. */
[hidden] { display: none !important; }

/* ------------------------------------------------------------ copy button
   Every address on the page is one. The confirmation lands on the element you
   clicked, not in a corner — with a hundred addresses on screen, a toast does
   not tell you which one you got. */
.copy {
  display: inline-flex; align-items: center; gap: 6px;
  background: none; border: 0; padding: 2px 6px; border-radius: 7px;
  color: var(--text-3); font-family: var(--mono); font-size: 10.5px;
  cursor: pointer; transition: color .12s, background .12s;
}
.copy:hover { color: var(--text-2); background: var(--surface-2); }
.copy svg { width: 11px; height: 11px; fill: currentColor; opacity: .55; flex: none; }
.copy.copied { color: var(--up); background: #0f2416; }
.copy.copied svg { opacity: 1; }
.copy.copyfail { color: var(--warn); }
.copy.wide { font-size: 12px; padding: 8px 10px; background: var(--surface); width: 100%; justify-content: space-between; }
.links .copy { margin-left: auto; }
.gfoot .copy { padding: 0; }

/* ---------------------------------------------------------------- search */
.search {
  display: flex; align-items: center; gap: 8px; margin-left: 14px; flex: 0 1 auto;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-pill); padding: 0 12px; height: 36px; min-width: 290px;
  transition: border-color .12s;
}
.search:focus-within { border-color: var(--accent); }
.search svg { width: 14px; height: 14px; fill: var(--text-3); flex: none; }
.search input {
  flex: 1; min-width: 0; background: none; border: 0; outline: none;
  color: var(--text); font: 400 13px var(--sans);
}
.search input::placeholder { color: var(--text-3); }
.search kbd {
  font-family: var(--mono); font-size: 10px; color: var(--text-3);
  border: 1px solid var(--line); border-radius: 5px; padding: 2px 5px;
}
#search-hint { font-family: var(--mono); font-size: 10.5px; color: var(--accent-hi); white-space: nowrap; }

/* ----------------------------------------------------------- token panel */
#panel { position: fixed; inset: 0; z-index: 60; display: flex; justify-content: flex-end; }
.panel-scrim { position: absolute; inset: 0; background: rgba(8,9,11,.6); backdrop-filter: blur(2px); }
/* A token page, not a sidebar. The chart, the trade list, the holders and the
   buy box all want to be visible at once — stacking them into a 520px column
   meant scrolling past the chart to reach the thing you came to do. */
.panel-card {
  position: relative; width: min(1180px, 100%); height: 100%; overflow-y: auto;
  background: var(--page); border-left: 1px solid var(--line); padding: 26px 30px 40px;
}
.panel-card::-webkit-scrollbar { width: 9px; }
.panel-card::-webkit-scrollbar-thumb { background: var(--raised); border-radius: 5px; }

.phead { display: grid; grid-template-columns: 76px minmax(0,1fr) auto; gap: 16px; align-items: center; }
.pava { width: 76px; height: 76px; border-radius: 20px; background-size: cover; background-position: center; overflow: hidden; }
.pava img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pid h2 { margin: 0; font-size: 26px; font-weight: 600; letter-spacing: -.02em; }
.ptick { margin-top: 4px; font-family: var(--mono); font-size: 12px; color: var(--text-3); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pphase { padding: 2px 8px; border-radius: var(--r-pill); font-size: 10.5px; }
.pphase.ph0 { background: var(--accent-soft); color: var(--accent-hi); }
.pphase.ph1 { background: #241f14; color: var(--warn); }
.pphase.ph2 { background: #0f2416; color: var(--up); }
.pphase.ph3 { background: #241416; color: var(--down); }
.pdesc { margin: 14px 0 0; color: var(--text-2); font-size: 14.5px; line-height: 1.6; max-width: 74ch; }

/* Chart and activity on the left, everything you act on pinned right. */
.pgrid { display: grid; grid-template-columns: minmax(0, 1fr) 372px; gap: 22px; margin-top: 20px; align-items: start; }
.pmain { min-width: 0; }
.pside { min-width: 0; display: flex; flex-direction: column; gap: 12px; position: sticky; top: 0; }
.pside .pbar, .pside .pstats, .pside .pca, .pside .plinks, .pside .trade, .pside .pnote { margin-top: 0; }

.pca { margin-top: 12px; }
.pca > span { display: block; font-size: 11px; color: var(--text-3); margin-bottom: 5px; }
.plinks { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.plinks a {
  font-size: 12px; color: var(--accent-hi); text-decoration: none;
  background: var(--surface); padding: 7px 13px; border-radius: var(--r-pill);
}
.plinks a:hover { background: var(--surface-2); }

.pbar { margin-top: 20px; background: var(--surface); border-radius: 12px; padding: 14px 16px; }
.pbar-top { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 8px; }
.pbar-top span { font-size: 12px; color: var(--text-3); }
.pbar-top b { font-family: var(--mono); font-size: 15px; color: var(--accent-hi); }
.pbar .bar { width: 100%; height: 6px; }
.pbar-note { margin-top: 8px; font-family: var(--mono); font-size: 11px; color: var(--text-3); }

#panel .pstats { grid-template-columns: repeat(2, minmax(0,1fr)); margin-top: 14px; gap: 10px; }
#panel .pstats div { padding: 11px 13px; }
#panel .pstats b { font-size: 14px; font-family: var(--mono); }
#panel .pstats b.warn { color: var(--warn); }
.pnote { margin-top: 18px; background: #241f14; color: #e8c98a; border-radius: 12px; padding: 13px 15px; font-size: 13px; line-height: 1.55; }

/* ------------------------------------------------------------------ trade */
.trade { margin-top: 20px; background: var(--surface); border-radius: 14px; padding: 16px; }
.tabs { display: flex; gap: 4px; background: var(--surface-2); padding: 4px; border-radius: var(--r-pill); margin-bottom: 14px; }
.tab {
  flex: 1; background: none; border: 0; border-radius: var(--r-pill); padding: 8px;
  color: var(--text-3); font: 500 13px var(--sans); cursor: pointer;
}
.tab.on { background: var(--raised); color: var(--text); }
.tin { display: flex; align-items: center; gap: 10px; background: var(--surface-2); border-radius: 12px; padding: 12px 14px; }
.tin input { flex: 1; min-width: 0; background: none; border: 0; outline: none; color: var(--text); font: 500 20px var(--mono); }
.tin span { font-family: var(--mono); font-size: 13px; color: var(--text-3); }
.tpresets { display: flex; gap: 6px; margin-top: 9px; }
.tpresets button {
  flex: 1; background: var(--surface-2); border: 0; border-radius: 9px; padding: 7px;
  color: var(--text-2); font: 400 12px var(--mono); cursor: pointer;
}
.tpresets button:hover { background: var(--raised); color: var(--text); }
.tquote { margin-top: 12px; font-size: 13px; color: var(--text-2); line-height: 1.5; }
.tquote b { color: var(--text); font-family: var(--mono); }
.tquote span { color: var(--text-3); font-size: 12px; }
.tquote.bad { color: var(--warn); }
.tslip { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.tslip label { font-size: 12px; color: var(--text-3); }
.tslip select { padding: 6px 10px; font-size: 12px; }
.trade .cta.big { width: 100%; margin-top: 14px; }
.tresult { margin-top: 12px; font-size: 12.5px; line-height: 1.5; color: var(--text-2); word-break: break-word; }
.tresult code { font-family: var(--mono); font-size: 11px; }
.tresult.good { color: #b6efb0; }
.tresult.bad { color: #ffb4ae; }

@media (max-width: 1360px) { .brand span { display: none; } }
/* The bar is one line on a wide screen and two on a narrow one. Without
   re-allowing the wrap here, the nav kept its place in the flex order and
   simply slid off the right edge. */
@media (max-width: 980px) {
  .topbar { flex-wrap: wrap; white-space: normal; row-gap: 10px; }
  .nav { order: 3; width: 100%; margin: 0; margin-right: 0; overflow-x: auto; }
  .search { order: 2; flex: 1 1 100%; margin-left: 0; }
  #board-controls { display: none; }
}
@media (max-width: 1220px) { #board-controls select, #board-controls #reload { display: none; } }
@media (max-width: 1100px) {
  .search { min-width: 150px; }
  .search kbd { display: none; }
  .pgrid { grid-template-columns: 1fr; }
  /* Stacked, the buy box goes first — it is what someone opened the page for. */
  .pside { position: static; order: -1; }
  .panel-card { padding: 20px; }
}
.pacts { display: flex; gap: 6px; }
.pacts .ghost { padding: 6px 11px; font-size: 11px; }
.pmiss { padding: 40px 8px; }
.pmiss h2 { margin: 0 0 10px; font-size: 18px; font-weight: 600; }
.pmiss p { margin: 0 0 18px; color: var(--text-2); font-size: 13.5px; line-height: 1.6; }

/* ------------------------------------------------------------------ X link */
.xlink {
  display: grid; place-items: center; width: 34px; height: 34px;
  border-radius: var(--r-pill); color: var(--text-3);
  transition: color .12s, background .12s;
}
.xlink:hover { color: var(--text); background: var(--surface-2); }
.xlink svg { width: 15px; height: 15px; fill: currentColor; }

/* Each view fills what the topbar leaves, so the footer is pushed to the
   bottom instead of floating directly under short content with dead space
   below it. #view-board is a column because .board inside it still wants to
   claim the leftover height for its scrolling columns. */
#view-board, #view-launch, #view-profile, #view-docs { flex: 1 1 auto; min-height: 0; }
#view-board { display: flex; flex-direction: column; }
#view-launch, #view-profile, #view-docs { display: flex; flex-direction: column; }
#view-launch > .page, #view-profile > .page { flex: 1 1 auto; }

/* ------------------------------------------------------------------ footer */
.foot {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  padding: 20px 24px; border-top: 1px solid var(--line);
  background: var(--surface); color: var(--text-3); font-size: 12.5px;
  flex: none;              /* never absorbs slack; the view above it does */
  margin-top: auto;        /* and it sits at the bottom on any view */
}
.foot-brand { color: var(--text-2); font-weight: 500; }
/* The links read as links and match the nav's hover, rather than being three
   differently-treated pieces of grey text. */
.foot a {
  color: var(--text-3); text-decoration: none;
  padding: 4px 8px; border-radius: var(--r-pill); transition: color .12s, background .12s;
}
.foot a:hover { color: var(--text); background: var(--surface-2); }
.foot-sep { color: var(--line); }
.foot-note { margin-left: auto; color: var(--text-3); max-width: 46ch; text-align: right; }

/* --------------------------------------------------------------- dropzone
   The preview is the point: a creator has a picture, not a URL, and should
   see their own artwork land before anything is uploaded. */
.drop {
  display: grid; grid-template-columns: auto minmax(0,1fr) auto; gap: 14px; align-items: center;
  border: 1px dashed var(--line); border-radius: 14px; padding: 18px;
  background: var(--surface); cursor: pointer;
  transition: border-color .13s, background .13s;
}
.drop:hover, .drop:focus-visible { border-color: var(--accent); }
.drop.over { border-color: var(--accent-hi); background: var(--accent-soft); }
.drop.has { border-style: solid; }
.drop-preview { width: 64px; height: 64px; border-radius: 15px; overflow: hidden; background: var(--surface-2); }
.drop-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.drop-copy { min-width: 0; }
.drop-copy b { display: block; font-size: 14px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.drop-copy span { display: block; margin-top: 3px; font-size: 12px; color: var(--text-3); }
.drop:not(.has) .drop-copy { grid-column: 1 / -1; text-align: center; }
.drop-state {
  margin-top: 8px; font-family: var(--mono); font-size: 11px; color: var(--text-3);
  word-break: break-all; line-height: 1.5;
}
.drop-state.ok { color: var(--up); }
.drop-state.bad { color: var(--down); }

details.pin { margin-top: 10px; }
details.pin summary {
  cursor: pointer; font-size: 12px; color: var(--text-3); list-style: none;
  display: flex; align-items: center; gap: 8px;
}
details.pin summary::-webkit-details-marker { display: none; }
details.pin summary::before { content: '›'; transition: transform .12s; display: inline-block; }
details.pin[open] summary::before { transform: rotate(90deg); }
#pin-badge { font-family: var(--mono); font-size: 10.5px; color: var(--accent-hi); }
.pin-body { margin-top: 10px; padding: 14px; background: var(--surface); border-radius: 12px; }
.pin-row { display: flex; gap: 8px; flex-wrap: wrap; }
.pin-row select, .pin-row input { flex: 1; min-width: 130px; padding: 9px 11px; font-size: 13px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px; color: var(--text); }
.pin-body .hint { margin: 10px 0 0; }

/* ------------------------------------------------------------------ polish
   Small, consistent motion and focus behaviour across the app, rather than
   each control inventing its own. */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
.row, .gcard, .gcard .art img, .ic, .copy { will-change: auto; }
.gcard:hover .art img { transform: scale(1.03); }
.gcard .art img { transition: transform .2s ease; }
.col-head { backdrop-filter: blur(6px); }
button, select, input, textarea, a { -webkit-tap-highlight-color: transparent; }

/* ------------------------------------------------------- token page: price */
.pprice { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 0; }
.pquote { background: var(--surface); border-radius: 12px; padding: 13px 15px; min-width: 0; }
.pquote span { display: block; font-size: 11px; color: var(--text-3); }
.pquote b {
  display: block; margin-top: 4px; font-family: var(--mono); font-size: 22px;
  font-weight: 500; letter-spacing: -.01em; overflow: hidden; text-overflow: ellipsis;
}
.pquote em { display: block; margin-top: 3px; font-style: normal; font-family: var(--mono); font-size: 11px; color: var(--text-3); }
.pquote em.up { color: var(--up); }
.pquote em.down { color: var(--down); }
.pquote em span { display: inline; color: var(--text-3); }

/* The chart is drawn from the launch's own trades, on a log axis — a launch
   routinely moves three orders of magnitude and a linear axis would flatten
   every early trade into the baseline. */
.pchart { margin-top: 10px; background: var(--surface); border-radius: 12px; padding: 12px; }
.pchart svg { display: block; width: 100%; height: 220px; }
.chart-note {
  display: flex; justify-content: space-between; margin-top: 6px;
  font-family: var(--mono); font-size: 10.5px; color: var(--text-3);
}
.chart-empty { height: 220px; display: grid; place-items: center; color: var(--text-3); font-size: 12.5px; }

#panel .pstats.flow { grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 10px; }
#panel .pstats.flow div { padding: 10px 11px; }
#panel .pstats.flow b { font-size: 15px; }
#panel .pstats.flow b.up { color: var(--up); }
#panel .pstats.flow b.down { color: var(--down); }

/* --------------------------------------------------- token page: trades */
.ptrades { margin-top: 22px; }
.ptrades h3 { margin: 0 0 10px; font-size: 14px; font-weight: 600; }
#p-trades { max-height: 400px; overflow-y: auto; }
#p-trades::-webkit-scrollbar { width: 8px; }
#p-trades::-webkit-scrollbar-thumb { background: var(--raised); border-radius: 4px; }
.trow {
  display: grid; grid-template-columns: 42px minmax(0,1fr) auto auto auto;
  gap: 10px; align-items: center; padding: 8px 10px; border-radius: 9px;
  font-family: var(--mono); font-size: 11.5px; color: var(--text-2);
}
.trow:nth-child(odd) { background: var(--surface); }
.tside { font-size: 10px; text-transform: uppercase; letter-spacing: .04em; }
.trow.b .tside { color: var(--up); }
.trow.s .tside { color: var(--down); }
.tamt { color: var(--text); overflow: hidden; text-overflow: ellipsis; }
.tamt em { font-style: normal; color: var(--text-3); font-size: 10.5px; }
.tpx { color: var(--text-3); }
.tago { color: var(--text-3); font-size: 10.5px; min-width: 30px; text-align: right; }

/* -------------------------------------------------- token page: tab strip */
.ptabs { display: flex; gap: 4px; background: var(--surface-2); padding: 4px; border-radius: var(--r-pill); margin-bottom: 12px; }
.ptab {
  flex: 1; background: none; border: 0; border-radius: var(--r-pill); padding: 8px;
  color: var(--text-3); font: 500 12.5px var(--sans); cursor: pointer;
}
.ptab.on { background: var(--raised); color: var(--text); }

/* ----------------------------------------------------------------- holders
   The pool and the curve are labelled rather than hidden: on a graduated
   launch the pool is usually the largest holder, and an unlabelled 40% at the
   top of a holder list is how a rumour starts. */
#p-holders { max-height: 400px; overflow-y: auto; }
#p-holders::-webkit-scrollbar, #p-comments::-webkit-scrollbar { width: 8px; }
#p-holders::-webkit-scrollbar-thumb, #p-comments::-webkit-scrollbar-thumb { background: var(--raised); border-radius: 4px; }
.hsum {
  display: flex; gap: 16px; flex-wrap: wrap; padding: 10px 12px; margin-bottom: 8px;
  background: var(--surface); border-radius: 10px;
  font-family: var(--mono); font-size: 11px; color: var(--text-3);
}
.hsum b { color: var(--text); font-weight: 500; }
.hwarn { padding: 10px 12px; margin-bottom: 8px; border-radius: 10px; background: #241f14; color: #e8c98a; font-size: 12px; }
.hrow {
  display: grid; grid-template-columns: 22px auto minmax(0,1fr) auto auto;
  gap: 10px; align-items: center; padding: 8px 10px; border-radius: 9px;
  font-family: var(--mono); font-size: 11.5px; color: var(--text-2);
}
.hrow:nth-child(odd) { background: var(--surface); }
.hrow.sys { color: var(--text-3); }
.hrow.you { outline: 1px solid var(--accent); }
.hrank { color: var(--text-3); font-size: 10.5px; }
.hlabel { font-size: 10.5px; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hlabel.you { color: var(--accent-hi); }
.hbal { color: var(--text); }
.hshare { color: var(--accent-hi); min-width: 52px; text-align: right; }

/* ---------------------------------------------------------------- comments
   On chain, so the author is an address the holder list can vouch for. */
#p-comments { max-height: 460px; overflow-y: auto; }
.cbox { background: var(--surface); border-radius: 12px; padding: 12px; margin-bottom: 12px; }
.cbox textarea {
  width: 100%; background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px;
  padding: 10px 12px; color: var(--text); font: 400 13.5px var(--sans); resize: vertical; outline: none;
}
.cbox textarea:focus { border-color: var(--accent); }
.crow { display: flex; align-items: center; gap: 10px; margin-top: 9px; }
.ccount { font-family: var(--mono); font-size: 10.5px; color: var(--text-3); }
.ccount.over { color: var(--down); }
.crow .cta { margin-left: auto; padding: 7px 14px; font-size: 12.5px; }
.cnote { margin-top: 8px; font-size: 12px; color: var(--text-3); line-height: 1.5; word-break: break-word; }
.cnote.bad { color: var(--down); }
.crow-item { padding: 11px 12px; border-radius: 10px; }
.crow-item:nth-child(even) { background: var(--surface); }
.chead { display: flex; align-items: center; gap: 8px; }
.cbadge {
  font-family: var(--mono); font-size: 10px; color: var(--accent-hi);
  background: var(--accent-soft); padding: 2px 7px; border-radius: var(--r-pill);
}
.cago { margin-left: auto; font-family: var(--mono); font-size: 10.5px; color: var(--text-3); }
.crow-item p { margin: 7px 0 0; font-size: 13.5px; line-height: 1.55; color: var(--text-2); white-space: pre-wrap; word-break: break-word; }
.pmiss .pca { margin: 16px 0; }
.pmiss a { color: var(--accent-hi); }

/* -------------------------------------------------------------------- fees */
.fees { background: var(--surface); border-radius: 14px; padding: 16px; margin-bottom: 22px; }
.fees.none { color: var(--text-3); font-size: 13px; line-height: 1.55; }
.fees-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 12px; }
.fees-head h3 { margin: 0; font-size: 15px; font-weight: 600; }
.fees-head span { margin-left: auto; font-family: var(--mono); font-size: 10.5px; color: var(--text-3); }
.fee-row {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 0; border-top: 1px solid var(--line-soft);
}
.fee-row b { display: block; font-family: var(--mono); font-size: 16px; font-weight: 500; }
.fee-row span { display: block; margin-top: 3px; font-size: 12px; color: var(--text-3); }
.fee-row button { margin-left: auto; flex: none; }

/* ------------------------------------------------------------ zap + warning */
.tvia {
  margin-bottom: 12px; padding: 9px 12px; border-radius: 10px;
  background: var(--accent-soft); color: #bcd0f2; font-size: 12.5px; line-height: 1.5;
}
.tvia b { color: var(--cobalt-1); }
/* The audit's finding 2: a stalled launch bills the next buyer ~15x, and that
   has to be visible before signing rather than after. */
.twarn {
  margin-bottom: 12px; padding: 11px 13px; border-radius: 10px;
  background: #241f14; color: #e8c98a; font-size: 12.5px; line-height: 1.55;
}
.twarn b { display: block; color: var(--warn); margin-bottom: 3px; }

/* ===================================================================== mobile
   Everything below is the phone. It is written as one block at the end rather
   than scattered through the file because the desktop rules above are the
   default and this is the deliberate departure from them.

   The bug that motivated most of it: `.panel-card` is a flex item, and a flex
   item's default `min-width: auto` means it cannot be narrower than its own
   content. A full 42-character contract address inside set that floor, so the
   token page was wider than the phone and `width: min(1180px, 100%)` never got
   a say. Capping the width is not enough; the floor has to be removed too. */
@media (max-width: 720px) {
  /* ---- the token page ---- */
  #panel { justify-content: stretch; }
  .panel-card {
    width: 100%; max-width: 100vw; min-width: 0;
    border-left: 0; padding: 16px 14px 40px;
  }
  .phead { grid-template-columns: 52px minmax(0,1fr); gap: 12px; }
  .pava { width: 52px; height: 52px; border-radius: 14px; }
  .pid h2 { font-size: 21px; }
  /* The buttons drop to their own row rather than squeezing the name. */
  .pacts { grid-column: 1 / -1; }
  .pdesc { font-size: 14px; }
  /* Stacked, the two columns interleave rather than following one another:
     `display: contents` drops .pmain and .pside out of the box tree so their
     children order against each other directly.

     The order matters. With .pside simply hoisted, the Buy button arrived
     before the price and the chart — asking someone to buy before showing them
     what it costs. Price and chart come first now; the button follows them. */
  .pgrid { display: flex; flex-direction: column; gap: 14px; margin-top: 16px; }
  .pmain, .pside { display: contents; }
  .pprice        { order: 1; }
  .pchart        { order: 2; }
  .trade, .pnote { order: 3; }
  .pstats.flow   { order: 4; }
  .pbar          { order: 5; }
  #panel .pstats:not(.flow) { order: 6; }
  .pca           { order: 7; }
  .plinks        { order: 8; }
  .ptrades       { order: 9; }
  .pprice { grid-template-columns: 1fr 1fr; gap: 8px; }
  .pquote { padding: 11px 12px; }
  .pquote b { font-size: 18px; }
  .pchart { padding: 10px; }
  .pchart svg, .chart-empty { height: 160px; }
  #panel .pstats.flow { grid-template-columns: repeat(2, 1fr); }

  /* An address is 42 characters and a phone is not. Truncate rather than
     letting it set the width of the whole page. */
  .copy.wide { font-size: 11px; }
  .copy.wide span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

  /* ---- trades, holders, comments ---- */
  .ptab { font-size: 12px; padding: 9px 4px; }
  .trow { grid-template-columns: 38px minmax(0,1fr) auto auto; gap: 8px; padding: 8px; font-size: 11px; }
  /* The per-trade price is the first thing to go: size, who and when are what
     someone reads a trade list for on a phone. */
  .trow .tpx { display: none; }
  .hrow { grid-template-columns: 20px minmax(0,1fr) auto; gap: 8px; padding: 8px; }
  .hrow .hlabel { display: none; }
  .hrow.sys { color: var(--warn); }
  .hsum { gap: 10px; font-size: 10.5px; }
  #p-trades, #p-holders, #p-comments { max-height: none; }

  /* ---- the board ---- */
  /* Stacked columns: an empty one should cost a header, not two thirds of a
     screen. */
  .col-body { max-height: none; }
  .col-body:empty { display: none; }
  .board { gap: 0; }
  .col { border-bottom: 1px solid var(--line); }
  .row { grid-template-columns: 44px minmax(0,1fr) auto; padding: 12px; gap: 8px 11px; }
  .ava { width: 44px; height: 44px; }
  .top-wrap { padding: 0 14px 14px; }
  .top-head, .col-head { padding-left: 14px; padding-right: 14px; }

  /* ---- pages ---- */
  .page { padding: 24px 16px 60px; }
  .page h1 { font-size: 23px; }
  .lede { font-size: 14.5px; }
  .docs { padding: 24px 16px 60px; }
  .docs h1 { font-size: 26px; }
  .docs p, .docs li { font-size: 15px; }
  .prow { grid-template-columns: minmax(0,1fr); gap: 6px; }
  .pstats { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .fee-row { flex-wrap: wrap; }
  .fee-row button { margin-left: 0; width: 100%; }
  .foot { gap: 12px; padding: 16px; font-size: 12px; }
  .foot-note { margin-left: 0; flex: 1 1 100%; }

  /* ---- the launch form ---- */
  .drop { grid-template-columns: 56px minmax(0,1fr); gap: 12px; padding: 14px; }
  .drop-preview { width: 56px; height: 56px; }
  .drop-clear, #drop-clear { grid-column: 1 / -1; }
  .pin-row { flex-direction: column; }
  .pin-row select, .pin-row input, .pin-row button { width: 100%; }
}

/* Tap targets. A 28px icon is fine with a mouse and small with a thumb. */
@media (hover: none) and (pointer: coarse) {
  .ic { width: 36px; height: 36px; }
  .copy { padding: 6px 8px; }
  .tab, .ptab { padding: 11px 8px; }
  .tpresets button { padding: 11px 6px; }
}

/* -------------------------------------------------------- activity feed
   Sits between the graduated shelf and the columns, because it answers a
   different question from either: not "what is worth looking at" but "what is
   happening right now". It scrolls sideways so it costs one row of height
   however busy the chain is. */
#activity { border-bottom: 1px solid var(--line); background: var(--surface); flex: none; }
.act-head { display: flex; align-items: baseline; gap: 10px; padding: 13px 22px 9px; }
.act-head h2 { margin: 0; font-size: 14px; font-weight: 600; letter-spacing: -.01em; }
.act-head .col-note { margin-left: auto; }
.act-strip {
  display: flex; gap: 8px; overflow-x: auto; padding: 0 22px 14px;
  scroll-snap-type: x proximity;
}
.act-strip::-webkit-scrollbar { height: 8px; }
.act-strip::-webkit-scrollbar-thumb { background: var(--raised); border-radius: 4px; }

.act {
  display: grid; grid-template-columns: 30px minmax(0,1fr) auto; gap: 9px; align-items: center;
  flex: none; width: 208px; scroll-snap-align: start;
  background: var(--surface-2); border: 1px solid transparent;
  border-radius: 11px; padding: 9px 11px; cursor: pointer;
  transition: border-color .12s, background .12s;
}
.act:hover { border-color: var(--accent); background: var(--raised); }
/* The side of the trade is the first thing to read, so it is a colour before
   it is a word. */
.act.buy  { border-left: 2px solid var(--up); }
.act.sell { border-left: 2px solid var(--down); }
.act.created { border-left: 2px solid var(--cobalt-1); }

.act-ava { width: 30px; height: 30px; border-radius: 9px; background-size: cover; background-position: center; overflow: hidden; }
.act-ava img { width: 100%; height: 100%; object-fit: cover; display: block; }
.act-mid { min-width: 0; }
.act-top { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.act-top b { font-size: 12.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.act-verb { font-family: var(--mono); font-size: 10px; color: var(--text-3); }
.act.buy .act-verb { color: var(--up); }
.act.sell .act-verb { color: var(--down); }
.act.created .act-verb { color: var(--cobalt-1); }
.act-sub { margin-top: 2px; font-family: var(--mono); font-size: 11px; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.act-ago { font-family: var(--mono); font-size: 10px; color: var(--text-3); align-self: flex-start; }

@media (max-width: 720px) {
  .act-head { padding: 11px 14px 8px; }
  .act-strip { padding: 0 14px 12px; }
  .act { width: 178px; }
}
