/* The colour tokens (both themes) live in palette.css so the pages that do
   NOT load this file - token.html, index.html, matrix.html, the dark-only
   originals - share the same palette and the same theme toggle. */
@import url("palette.css");
/* The header's tab row and its menus (2026-09-25): shared with token.html
   and index.html, which do not load this file but <link> nav.css. */
@import url("nav.css");

/* Shared site styling - extracted from tokens.html's original inline
   <style> block so every page in the split (jungle.html, favorites.html,
   etc.) looks consistent without copy-pasting ~400 lines of CSS per file.
   #quicknav is new (the page-split nav, replacing the old JS-driven
   sidebar tabs) - everything else here is unchanged from the original. */


* { box-sizing: border-box; }
html, body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Noto Sans Symbols 2", "Noto Sans KR";
  -webkit-font-smoothing: antialiased;
}
body { padding: 28px 32px 64px; }

.num { font-family: "IBM Plex Mono", ui-monospace, monospace; font-variant-numeric: tabular-nums; }

/* THE HEADER IS TWO ROWS (per user 2026-09-11: "dexdenom at top, then under
   it we have our group tabs"). Row one: the wordmark and tagline on the
   left, the search box / Connect / theme toggle pushed to the right. Row
   two: the group tabs (#quicknav) on their own full-width line under a
   rule. Done in CSS alone - flex order and a 100% basis on the nav - so
   the sixteen page headers keep their markup and nav.js keeps mounting the
   search box and wallet button where it always did. */
header {
  display: flex;
  align-items: center;
  gap: 12px 18px;
  flex-wrap: wrap;
  margin-bottom: 18px;
  max-width: 1800px;
  margin-left: auto;
  margin-right: auto;
}
.searchwidget { margin-left: auto; }
/* THE WORDMARK IS CENTRED AT THE TOP (2026-09-19, per user: "the logo
   should be center middle as well at the top" - above the bolt, like the
   logo itself). Absolutely centred over row one, so the search box and
   the theme button keep their places on the right and the tabs their own
   row; row one is given the wordmark's height. Under 1000 px the two
   would overlap, so the wordmark takes a full row of its own there. */
header { position: relative; }
header > .searchwidget { min-height: 80px; }   /* the theme button keeps its 30 px; the row takes its height from the search widget */
header > .searchwidget { display: flex; align-items: center; }
.wordmark {
  font-family: "Fraunces", Georgia, serif;
  font-weight: 600;
  font-size: 30px;
  letter-spacing: -0.01em;
  display: flex;
  align-items: center;
  gap: 9px;
  text-decoration: none;
  color: var(--text);
  position: absolute;
  left: 50%;
  top: 0;
  height: 80px;
  transform: translateX(-50%);
}
/* With the image mounted (nav.js mountLogo) the text and the ✧ go, the
   image takes the slot at the row's height; a missing file drops the
   class and the text comes back. */
.wordmark.haslogo { font-size: 0; gap: 0; }
.wordmark.haslogo .mark { display: none; }
.wordmark img { height: 76px; width: auto; display: block; }
/* The bolt in the image sits 40% across it ("Denom" is the longer word); the
   IMAGE stays centred (per user) and the BACKGROUND bolt is shifted under
   it instead - palette.css, calc(50% - 19px). */
@media (max-width: 999px) {
  .wordmark { position: static; transform: none; flex-basis: 100%; justify-content: center; }
}
.wordmark .mark { color: var(--accent); font-size: 20px; }
.tagline { color: var(--text-muted); font-size: 13px; }
nav a {
  color: var(--link);
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
}
nav a:hover { text-decoration: underline; }

/* The tab row (#quicknav), its forks and the Token Groups menu live in
   css/nav.css since 2026-09-25 (imported above). */

.controls { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-left: auto; }

#searchBox {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 10px;
  font-size: 13px;
  width: 200px;
  box-shadow: var(--shadow);
}
#searchBox:focus { outline: none; border-color: var(--accent); }

.pillgroup {
  display: inline-flex;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 2px;
  box-shadow: var(--shadow);
}
.pillgroup button {
  all: unset;
  cursor: pointer;
  padding: 5px 9px;
  font-size: 12px;
  font-weight: 500;
  border-radius: 6px;
  color: var(--text-muted);
  transition: background 0.12s ease, color 0.12s ease;
}
.pillgroup button:hover { color: var(--text); }
.pillgroup button.active { background: var(--accent); color: var(--accent-text); }

.iconbtn:focus-visible, .pillgroup button:focus-visible, #searchBox:focus-visible, tbody tr:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.updated {
  font-size: 11.5px;
  color: var(--text-muted);
  font-family: "IBM Plex Mono", monospace;
}

#status { padding: 16px 0; color: var(--text-muted); }
.dirresult-addr { color: var(--text-muted); font-size: 11.5px; font-family: "IBM Plex Mono", ui-monospace, monospace; }
.dimtext { color: var(--text-muted); font-size: 12px; }
.dir-add-btn {
  background: var(--accent); color: var(--accent-text); border: none; border-radius: 6px;
  padding: 6px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.dir-add-btn:disabled { opacity: 0.6; cursor: default; }
.dir-watched-note { color: var(--text-muted); font-size: 12px; }

.dirtable { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 13px; }
.dirtable th {
  text-align: left; color: var(--text-muted); font-weight: 600; font-size: 11px;
  text-transform: uppercase; letter-spacing: 0.02em; padding: 6px 10px;
  border-bottom: 1px solid var(--border); white-space: nowrap;
}
.dirtable td { padding: 9px 10px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.dirtable tr:last-child td { border-bottom: none; }
.dirpairname { font-weight: 600; }
.dircopybtn {
  background: none; border: none; color: var(--text-muted); cursor: pointer;
  padding: 0 0 0 4px; font-size: 12px; vertical-align: middle;
}
.dircopybtn:hover { color: var(--accent); }

/* Shared "Copied" confirmation - see js/copy.js. One toast element,
   reused by every copy button on the page. */
.copy-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%) translateY(8px);
  background: var(--text);
  color: var(--surface);
  padding: 8px 16px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
  z-index: 1000;
  box-shadow: var(--shadow);
}
.copy-toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

.legend {
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 11px;
  color: var(--text-muted);
  padding: 10px 4px;
}
.legend .sw { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 5px; vertical-align: middle; }

.favfilterwrap {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  color: var(--text-muted);
  padding: 10px 4px 0;
}
.favfilterwrap select {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 8px;
  font-size: 12.5px;
}

.tablewrap {
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: var(--shadow);
  overflow-x: auto;
}
table { border-collapse: collapse; width: 100%; min-width: 880px; }
thead th {
  text-align: right;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 12px 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
#mainTableWrap thead th:first-child, #mainTableWrap thead th:nth-child(3) { text-align: left; }
#pcopyTableWrap thead th:first-child, #pcopyTableWrap thead th:nth-child(2),
#ecopyTableWrap thead th:first-child, #ecopyTableWrap thead th:nth-child(2) { text-align: left; }
tbody td {
  padding: 11px 16px;
  text-align: right;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  font-size: 13.5px;
}
tbody tr { background: var(--surface); cursor: pointer; }

/* MANY-COLUMN TABLES.
   16px of horizontal padding a side is 32px per column. Comfortable at cores'
   eleven columns; at copies' fourteen it is 448px of pure whitespace, which is
   most of why that table ran off the right-hand edge while cores fit. Density
   is the honest lever here - dropping a real column would be hiding data to
   make the layout work. */
/* THE TWO PRICE COLUMNS ON COPIES.
   Purple is the PulseChain side, green the Ethereum side. They sit next to each
   other because the comparison IS the page. The colour is on the HEADERS only:
   the text colour on a number already means something everywhere else on this
   site (green up, red down), so the digits stay plain. The cells used to carry
   an outline too - dropped 2026-09-11 per user, the headers carry it.
   Fixed widths on Token / the two prices / Parity so the table's slack does
   not pile up as a gap between the token and its price - an auto-width table
   at 100% spread every spare pixel across those columns. */
thead th.px-pls { color: #a9a9e4; }
thead th.px-eth { color: #7fcfa6; }
/* The floating horizontal scrollbar (js/hscroll.js): pinned to the bottom
   of the viewport while a table wider than the window is in view, so the
   table can be moved without scrolling down to its own scrollbar first. */
.hscroll {
  position: fixed; bottom: 0; height: 14px; display: none;
  overflow-x: auto; overflow-y: hidden; z-index: 900;
  background: var(--surface); border-top: 1px solid var(--border);
  box-shadow: 0 -2px 8px rgba(0,0,0,0.15);
}
.hscroll > div { height: 1px; }

}

/* Share / Import on the Favorites page. */
.sharepanel { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin: 0 0 14px; }
@media (max-width: 800px) { .sharepanel { grid-template-columns: 1fr; } }
.sharecol { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 12px 14px; box-shadow: var(--shadow); }
.sharehead { display: flex; align-items: center; gap: 10px; font-weight: 600; font-size: 13px; margin-bottom: 8px; }
.sharecol textarea {
  width: 100%; height: 72px; resize: vertical; margin-bottom: 8px;
  font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 11.5px; line-height: 1.4;
  background: var(--bg); color: var(--text); border: 1px solid var(--border); border-radius: 8px; padding: 8px;
  word-break: break-all;
}
.sharecol textarea:focus { outline: none; border-color: var(--accent); }

/* The "it lives in your browser" note on the Favorites page. */
.storage-note { max-width: 720px; margin: 28px 0 0; font-size: 13px; line-height: 1.55; color: var(--text-muted); }

/* The write-up under the cores table (web/cores.html). Reads like a note,
   not a table: measured width, quiet heading, body-sized text. */
.about { max-width: 720px; margin: 36px 0 12px; color: var(--text); }
.about h2 { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 22px; margin: 0 0 10px; }
.about p { font-size: 14.5px; line-height: 1.6; margin: 0 0 12px; color: var(--text); }
.about p:last-child { color: var(--text-muted); }

/* Parity carries the same two colours: which side is dearer. */
.pct.parity-pls { color: #a9a9e4; }
.pct.parity-eth { color: #7fcfa6; }
table.dense th[data-sort="symbol"] { width: 230px; }
table.dense th.px-pls, table.dense th.px-eth { width: 120px; }
table.dense th[data-sort="parity_multiplier"] { width: 120px; }

table.dense thead th { padding: 12px 9px; }
table.dense tbody td { padding: 11px 9px; font-size: 13px; }


tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: var(--surface-hover); }

.rank { color: var(--text-muted); font-size: 12px; width: 28px; }

.tokencell { display: flex; align-items: center; gap: 10px; text-align: left; }
.dot {
  width: 11px; height: 11px; border-radius: 50%; flex: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--dot) 18%, transparent);
}
.tokenicon {
  width: 22px; height: 22px; border-radius: 50%; flex: none;
  object-fit: cover;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--dot) 18%, transparent);
}
/* The LP-token placeholder (plp.html, per user 2026-09-12): a circle with
   "PLP" in it where a logo would sit. Same footprint as .tokenicon so the
   rows line up with every other page's. */
.lpicon {
  width: 22px; height: 22px; border-radius: 50%; flex: none;
  display: inline-grid; place-items: center;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 7px; font-weight: 700; letter-spacing: 0.02em;
  color: var(--text-muted); background: var(--surface-hover);
  border: 1px solid var(--border);
}
.symbol { font-weight: 600; font-size: 13.5px; }
.mostactive { font-size: 10.5px; color: var(--text-muted); white-space: nowrap; }
/* A NAME CANNOT WIDEN THE TABLE (2026-09-21, per user on the V3 page:
   "shift parent to the left a bit so we can get address in there"). The
   Address column was there - a 160-character token name, rendered on one
   line, had pushed it 365 px past the card's edge, where overflow-x: auto
   hides it behind a scrollbar nobody sees. A symbol or name is whatever
   the deployer's contract returns, so the token cell clips both with an
   ellipsis; the pages that show a name put the full one in its title. The
   symbol line is NOT clipped - on Jungle it carries badges and links that
   must stay whole - it may break anywhere instead, so a spaceless 80-char
   symbol wraps rather than widens. */
.tokencell > div { min-width: 0; }
.tokencell .symbol { overflow-wrap: anywhere; }
.tokencell .mostactive { max-width: 220px; overflow: hidden; text-overflow: ellipsis; }   /* 320 -> 220 same day, per user: "shorter... to give room to the rest of the metrics" */
/* The V3/V4 Parent cell: the parent's symbol and tags over its address.
   The NAME is capped (a long parent name cannot widen the column) and the
   tags sit after it uncapped - a cap on the whole line clipped the tag
   off a long name, and the tag is the point. */
td.parentcell .symbol { display: flex; align-items: center; gap: 4px; white-space: nowrap; flex-wrap: wrap; max-width: 260px; }   /* several tags wrap under the name rather than widen the column */
td.parentcell .pname { max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
td.parentcell .mostactive { max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
td.parentcell .symbol .groupbadge { margin-right: 0; }
.mostactive .pct { font-weight: 500; }
.poolpair { font-size: 10.5px; color: var(--text-muted); white-space: nowrap; }

.leadbadge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 42px;
  padding: 3px 7px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
}
.lead-full { background: var(--good-soft); color: var(--good); }
.lead-half { background: var(--accent-soft); color: var(--accent); }
.lead-low  { background: var(--bad-soft); color: var(--bad); }

.pct { font-weight: 600; }
.pct.pos { color: var(--good); }
.pct.neg { color: var(--bad); }
.pct.flat { color: var(--text-muted); }

.tvlcell { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; }
.tvlbar {
  width: 64px;
  height: 4px;
  border-radius: 2px;
  background: var(--border);
  overflow: hidden;
  display: flex;
}
.tvlbar .seg-bridge { background: #5aa7a3; }
.tvlbar .seg-wpls { background: var(--accent); }

.volcell { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; }
.volbar {
  width: 64px;
  height: 4px;
  border-radius: 2px;
  background: var(--border);
  overflow: hidden;
  display: flex;
}
.volbar .seg-buy { background: var(--good); }
.volbar .seg-sell { background: var(--bad); }

.layout { display: flex; gap: 20px; align-items: flex-start; max-width: 1800px; margin: 0 auto; }
#sidebar {
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: 140px;
  flex: none;
}
#sidebar button {
  all: unset;
  cursor: pointer;
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
}
#sidebar button:hover { background: var(--surface-hover); color: var(--text); }
#sidebar button.active { background: var(--accent); color: var(--accent-text); }
main { flex: 1; min-width: 0; }

.sidebar-divider {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 14px 12px 4px;
}
.favrow {
  display: flex;
  align-items: center;
  border-radius: 8px;
}
.favrow.active { background: var(--accent); }
.favrow.active .favname, .favrow.active .favaction { color: var(--accent-text); }
/* #sidebar button (ID+type) outranks a bare class selector, so these
   need the #sidebar ancestor too or their all:unset/display would lose
   to that rule's own all:unset despite coming later in the file. */
#sidebar button.favname {
  all: unset;
  cursor: pointer;
  flex: 1;
  min-width: 0;
  padding: 8px 4px 8px 12px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 6px;
}
.favrow:not(.active) .favname:hover { color: var(--text); }
.favcount { font-size: 10.5px; opacity: 0.7; }
#sidebar button.favaction {
  all: unset;
  cursor: pointer;
  padding: 6px;
  font-size: 11px;
  color: var(--text-muted);
  flex: none;
}
.favaction:hover { color: var(--text); }
#newFavListBtn { width: 100%; text-align: left; color: var(--text-muted); }

/* The star's HIT AREA is the whole cell, not the glyph. Per user, clicking
   just outside the star fell through to the row's click handler and navigated
   to the token page instead of toggling.
   Paired with the `td:has(> .favstar) { padding: 0 }` rule further down: the
   cell contributes no padding of its own, and the button supplies all of it,
   so every pixel of that column's WIDTH belongs to the button. Shrinking the
   dead zone was not enough - it had to be removed.
   The remaining few pixels of HEIGHT (a cell is as tall as its row, a button
   as tall as its own text, and `height: 100%` does not resolve inside a table
   cell) are closed in js/format.js, which forwards a click anywhere in a
   star's cell to the star. See DEAD SPACE there before changing these
   numbers. */
.favstar {
  all: unset;
  cursor: pointer;
  font-size: 19px;
  line-height: 1;
  color: var(--border);
  display: block;
  width: 100%;
  min-width: 48px;          /* the invisible box: wider than the glyph (per user 2026-09-19) */
  box-sizing: border-box;
  padding: 12px 14px;
  text-align: center;
}
.favstar:hover { color: var(--accent); }
.favstar.active { color: var(--accent); }

th[data-sort] { cursor: pointer; user-select: none; }
th[data-sort]:hover { color: var(--text); }
th .sort-arrow { color: var(--accent); margin-left: 3px; }

/* Local list filter - narrows the already-loaded rows on a group page
   (Cores/Jungle/666/Atropa/Copies/Federal Minter), separate from the
   global header search widget which hits the whole on-chain directory. */
.listfilter {
  width: 240px;
  margin-bottom: 10px;
  padding: 6px 10px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: 13px;
  display: block;
}
.listfilter:focus { outline: none; border-color: var(--accent); }

.searchwrap { position: relative; display: flex; align-items: center; }
/* js/emoji.js wraps a search input and its 😀 button in this; the picker
   hangs under it. z-index above the header search dropdown (.searchdrop),
   which sits under the same box. */
.emojiwrap { position: relative; display: inline-flex; align-items: center; gap: 4px; }
.emojibtn { font-size: 15px; flex: none; }
.emojipicker {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 1100;
  width: 280px; max-height: 220px; overflow-y: auto;
  background: var(--bg-elevated, var(--bg)); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px; box-shadow: 0 8px 24px rgba(0,0,0,0.35);
  display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px;
}
.emojipicker button {
  background: none; border: none; font-size: 18px; line-height: 1;
  padding: 6px 0; cursor: pointer; border-radius: 6px;
}
.emojipicker button:hover { background: var(--border); }

/* Group badges (cores/666/prc20/erc20/maria-v2/...) - the unified tag
   system's visual form, shown on Jungle rows and token detail pages. */
.groupbadge {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 600;
  margin-right: 4px;
  background: var(--surface-hover);
  color: var(--text-muted);
}
.groupbadge.prc20 { background: color-mix(in srgb, #9b6fd6 18%, transparent); color: #9b6fd6; }
.groupbadge.erc20 { background: var(--good-soft); color: var(--good); }
.groupbadge.cores { background: var(--accent-soft); color: var(--accent); }
.groupbadge.atropa { background: color-mix(in srgb, #c9598f 18%, transparent); color: #c9598f; }
.groupbadge.\36 66 { background: var(--bad-soft); color: var(--bad); }
.groupbadge.maria-v2 { background: color-mix(in srgb, #4a7fc9 18%, transparent); color: #4a7fc9; }
.groupbadge.lau { background: color-mix(in srgb, #3fa5a0 18%, transparent); color: #3fa5a0; }
/* PumpTires - the launchpad. Orange, off every other run on purpose: a
   promoted launch is neither a minter product nor a curated set. */
.groupbadge.pumptires { background: color-mix(in srgb, #d9822b 18%, transparent); color: #d9822b; }
/* pDev - a token claimed by its dev (the category badge, and the "Dev" tag
   on pdev.html). Gold, near the accent: a claim is the one group a token's
   own people put it in. "Community" is the same claim made on their behalf,
   muted so the two read as one family. */
.groupbadge.pdev { background: color-mix(in srgb, #c9a227 20%, transparent); color: #b8921f; }
.groupbadge.community { background: var(--surface-hover); color: var(--text-muted); }
/* IndexMinter V3. Deliberately close to maria-v2's blue (same TT contract
   family, shown as sibling products) but shifted violet so the two are
   still tellable apart at a glance in search results. */
.groupbadge.treasuryminter { background: color-mix(in srgb, #3f63c9 18%, transparent); color: #3f63c9; }
.groupbadge.indexminter { background: color-mix(in srgb, #7a6fd6 18%, transparent); color: #7a6fd6; }
/* PersonalMinter V4 - next step along the same violet run as maria-v2 ->
   indexminter, so the four minter generations read as one family. */
.groupbadge.personalminter { background: color-mix(in srgb, #a86fc9 18%, transparent); color: #a86fc9; }
/* Dysnomia - deliberately off the minter violet run, this is a curated
   set rather than a factory product. */
.groupbadge.dysnomia { background: color-mix(in srgb, #5f8fa8 18%, transparent); color: #5f8fa8; }
/* Token+ - green, for the one group whose defining property is that
   holding it pays you. Doubles as the "Reward" tag on tokenplus.html: the
   group badge elsewhere and the per-row mechanic tag there are the same
   thing seen at two zoom levels, so they share a colour on purpose. */
.groupbadge.tokenplus { background: color-mix(in srgb, #4f9e72 18%, transparent); color: #4f9e72; }
/* VIEWS INSIDE A DEV CARD (2026-09-24): the tab row under the header -
   All / Dysnomia / PumpTires / Token+ / pDev with a count each, quiet
   underline tabs like the Dev Favorites pair, sized to their words. */
.devviewtabs { display: flex; gap: 14px; flex-wrap: wrap; margin: 2px 4px 10px; border-bottom: 1px solid var(--border); }
.devviewtab { background: none; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; padding: 6px 2px 7px; font: inherit; font-size: 13px; font-weight: 600; color: var(--text-muted); cursor: pointer; }
.devviewtab:hover { color: var(--text); }
.devviewtab.on { color: var(--accent); border-bottom-color: var(--accent); }
.devviewtab .cnt { font-weight: 500; font-size: 11px; color: var(--text-muted); margin-left: 3px; }
/* The four tags a pDev card's rows carry (2026-09-24): Dysnomia, PumpTires
   and Token+ link to their pages, pDev is a plain badge. */
.groupbadge.devtag { text-decoration: none; }
.groupbadge.devtag:hover { filter: brightness(1.15); }
/* The other Token+ mechanic. Distinct hue because the two are genuinely
   different contracts with different guarantees (see contracts/README.md) -
   a reader scanning the column needs to tell them apart at a glance, not
   read the word. */
.groupbadge.reflection { background: color-mix(in srgb, #c08a3e 18%, transparent); color: #c08a3e; }
/* An LP payout on tokenplus.html - a pair handed out as the reward. Its own
   hue because it is a different KIND of thing from the ecosystem badges
   beside it (ERC20/PRC20/Atropa/Core name where a token came from; this one
   says the payout isn't a plain token at all). */
.groupbadge.lp { background: color-mix(in srgb, #7f8da3 20%, transparent); color: #7f8da3; }
/* The `plp` CATEGORY badge - an LP token that trades against PLS, filed by
   scripts/classify-plp.js. Shares the LP hue on purpose: wherever a group
   badge appears, "this is an LP token" should read the same as the LP tag
   on tokenplus.html rather than looking like an unrelated group. */
.groupbadge.plp { background: color-mix(in srgb, #7f8da3 20%, transparent); color: #7f8da3; }

/* DEX-source badge (see js/format.js's dexBadge()) - which AMM a pool was
   created on. Every pool is PulseX today; shown explicitly anyway since
   this is the only thing that'll tell two pools apart once a second DEX
   gets indexed. */
.dexbadge {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 6px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 600;
  margin-right: 4px;
  background: var(--surface-hover);
  color: var(--text-muted);
}

/* Global search widget - lives in every page's header (see js/search.js).
   A plain text input that opens a live dropdown of matching LPs; Enter (or
   the "see all results" row) goes to search.html for the fuller table. */
.searchwidget { position: relative; }
.searchwidget input {
  width: 260px;
  padding: 7px 10px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: 13px;
}
.searchwidget input:focus { outline: none; border-color: var(--accent); }
.searchdrop {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  width: 420px;
  max-height: 420px;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
  z-index: 1000;
  display: none;
}
.searchdrop.show { display: block; }
.searchdrop-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 12px;
  cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.searchdrop-row:last-child { border-bottom: none; }
.searchdrop-row:hover { background: var(--surface-hover); }
/* The two sections (2026-09-21): Tokens, then Pools - a small caps label
   over each, so a row's click target (token page or chart) is never a guess. */
.searchdrop-head { padding: 6px 12px 3px; font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); background: var(--bg); border-bottom: 1px solid var(--border); }
.searchdrop-pair { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; }
.searchdrop-sub { font-size: 11px; color: var(--text-muted); font-weight: 400; }
.searchdrop-metrics { text-align: right; font-size: 12px; }
.searchdrop-empty, .searchdrop-more {
  padding: 10px 12px;
  font-size: 12px;
  color: var(--text-muted);
}
.searchdrop-more { cursor: pointer; text-align: center; border-top: 1px solid var(--border); }
.searchdrop-more:hover { background: var(--surface-hover); }

/* Wallet connect button - top right, next to the theme toggle. Injected by
   nav.js into the header (not into #quicknav's link list) so it reads as a
   control rather than another page link, and does not get lost as the nav
   grows. */
.walletbtn {
  font: inherit;
  font-size: 12px;
  margin-left: 8px;
  padding: 4px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
  white-space: nowrap;
}
.walletbtn:hover:not(:disabled) { border-color: var(--accent); color: var(--text); }
.walletbtn:disabled { opacity: .5; cursor: default; }
.walletbtn.connected { color: var(--accent); border-color: var(--accent); }
/* Connected but on the wrong chain - visibly different from both states,
   because "connected" and "connected but useless for contract reads" are
   not the same thing. */
.walletbtn.wrongchain { color: #d29922; border-color: #d29922; }

/* Active-favorites-list picker - header, left of the wallet button. Only
   rendered when more than one list exists (nav.js), so it never shows a
   pointless one-option dropdown. */
.favlistpicker {
  font: inherit;
  font-size: 12px;
  margin-left: 8px;
  padding: 4px 8px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
  max-width: 190px;
}
.favlistpicker:hover { border-color: var(--accent); color: var(--text); }

/* Row holding the active-list picker beside a page's own filter box.
   Built by nav.js only when a second favorites list exists - .listfilter is
   display:block, so without this the two controls stack instead of sitting
   side by side. */
.listcontrols { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.listcontrols .listfilter { margin-bottom: 0; }
.listcontrols .favlistpicker { margin-left: 0; }

/* Zero padding on the star's cell so the button - which is width:100% with
   its own padding - covers it entirely. Any padding left here would be a
   strip owned by the ROW handler, which is exactly the dead zone being fixed.
   Row height is preserved because the button's padding replaces the cell's. */
td:has(> .favstar) { padding: 0; }

/* ---- New Pairs (newpairs.html) ---- */
/* Kind pills, the window picker and the quiet toggle on one line. */
.newpairs-controls { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 4px; }
.newpairs-controls .pillgroup { margin: 0; }
.newpairs-toggle { font-size: 12px; color: var(--text-muted); display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.newpairs-toggle input { accent-color: var(--accent); }
/* What kind of row this is - the page's whole point, so it gets its own
   column rather than a badge lost among the group badges. */
.kindpill {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  font-size: 10.5px; font-weight: 600; white-space: nowrap;
  background: var(--surface-hover); color: var(--text-muted);
}
.kindpill.new_token { background: var(--good-soft); color: var(--good); }
.kindpill.new_pool { background: color-mix(in srgb, #4a7fc9 18%, transparent); color: #4a7fc9; }
.kindpill.both_new { background: var(--bad-soft); color: var(--bad); }
/* The NEW tag on the side that has never had a pool before. */
.newside {
  display: inline-block; margin: 0 4px 0 5px; padding: 1px 5px; border-radius: 4px;
  font-size: 9px; font-weight: 700; letter-spacing: .04em; vertical-align: middle;
  background: var(--good-soft); color: var(--good);
}
.pairsep { color: var(--text-muted); margin: 0 5px; font-weight: 400; }
.tokencell .symbol a.tokenlink { color: inherit; text-decoration: none; }
.tokencell .symbol a.tokenlink:hover { color: var(--accent); }
.tokencell .symbol a.tokenlink.quote { color: var(--text-muted); font-weight: 500; }
.tokencell .symbol a.tokenlink.quote:hover { color: var(--accent); }

/* Links inside a page's write-up read in the accent, not browser blue. */
.about a { color: var(--accent); text-decoration: none; }
.about a:hover { text-decoration: underline; }

/* ---- Scan (scan.html) ---- */
.scanform { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.scanform .listfilter { margin-bottom: 0; max-width: 520px; font-family: "IBM Plex Mono", ui-monospace, monospace; }
.scanbtn {
  font: inherit; font-size: 13px; font-weight: 600; padding: 7px 16px; border-radius: 999px;
  border: 1px solid var(--accent); background: var(--accent); color: var(--accent-text); cursor: pointer;
}
.scanbtn:hover { filter: brightness(1.08); }
.scannote { max-width: 1100px; margin-bottom: 18px; line-height: 1.5; }
/* The in-flight line beside the Scan button reads in the accent colour so
   "still running" is visible without reading. */
#scanStatus:not(:empty) { color: var(--accent); font-weight: 500; }
.scanh { font-size: 13px; letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted); margin: 22px 0 8px; }
#report { border: 1px solid var(--border); border-radius: 12px; padding: 16px 18px; margin-bottom: 26px; background: var(--surface); }
.scanhead { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.scanhead-token { font-size: 20px; font-weight: 600; }
.scanhead-token .num { font-size: 12px; font-weight: 400; }
.verdict {
  display: inline-block; padding: 4px 12px; border-radius: 999px; font-size: 12px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; background: var(--surface-hover); color: var(--text-muted);
}
/* 'clean' is GREY, not green: nothing found is not a green light for an
   unknown token (per user 2026-09-12). Green is reserved for the group
   rule to come. */
.verdict.clean { background: var(--surface-hover); color: var(--text-muted); }
.verdict.caution { background: color-mix(in srgb, #d9822b 18%, transparent); color: #d9822b; }
.verdict.flagged { background: var(--bad-soft); color: var(--bad); }
.verdictnote { margin: 4px 0 12px; font-size: 13px; }
.proxynote { margin: 0 0 12px; font-size: 13px; padding: 8px 10px; border-radius: 8px; background: var(--surface-hover); }
.scanmeta { display: flex; flex-wrap: wrap; gap: 6px 18px; font-size: 12px; color: var(--text-muted); margin: 8px 0; }
.scanmeta-title { width: 100%; font-weight: 600; color: var(--text); }
.findings { list-style: none; padding: 0; margin: 0; }
.findings li { padding: 8px 10px; border-left: 3px solid var(--border); margin-bottom: 6px; border-radius: 0 8px 8px 0; background: var(--surface-hover); font-size: 13px; }
.findings li.f-high { border-left-color: var(--bad); }
.findings li.f-medium { border-left-color: #d9822b; }
.findings li .fdetail { margin-top: 3px; color: var(--text-muted); font-size: 12px; line-height: 1.45; }
.sev { display: inline-block; padding: 1px 6px; border-radius: 4px; font-size: 9.5px; font-weight: 700; letter-spacing: .05em; margin-right: 4px; background: var(--surface-hover); color: var(--text-muted); }
.sev.high { background: var(--bad-soft); color: var(--bad); }
.sev.medium { background: color-mix(in srgb, #d9822b 18%, transparent); color: #d9822b; }
.fndetails { margin-top: 12px; }
.fndetails summary { cursor: pointer; font-size: 13px; color: var(--text-muted); }
.fndetails summary:hover { color: var(--text); }
.fntable { font-size: 12px; margin-top: 8px; }
.scanfoot { margin-top: 14px; line-height: 1.5; max-width: 1100px; }
/* "NOT THAT THE TOKEN IS SAFE" on the Scan page (2026-09-18, per user:
   "capitalize, bold and underline, maybe make it a font or two bigger
   cause it's important"). */
.notsafe { font-weight: 800; text-decoration: underline; text-underline-offset: 2px; font-size: 1.15em; color: var(--text); }
/* Address links inside a report: the page's own text colour with a quiet
   dotted underline, not the browser's blue ("hard on the eyes", per user). */
#report a.tokenlink, .dettable a.tokenlink {
  color: var(--text); text-decoration: underline dotted; text-underline-offset: 3px;
  font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 12px;
}
#report a.tokenlink:hover, .dettable a.tokenlink:hover { color: var(--accent); }
.verdict.pending { background: var(--surface-hover); color: var(--text-muted); }
.verdict.known { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); }
/* The small verdict badge on lists and the token page - a LINK to the
   report, coloured like the big pill. */
.scanbadge {
  display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 10px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; text-decoration: none;
  background: var(--surface-hover); color: var(--text-muted); vertical-align: middle;
}
.scanbadge:hover { filter: brightness(1.12); text-decoration: none; }
.scanbadge.clean { background: var(--surface-hover); color: var(--text-muted); }
.scanbadge.caution { background: color-mix(in srgb, #d9822b 18%, transparent); color: #d9822b; }
.scanbadge.flagged { background: var(--bad-soft); color: var(--bad); }
.scanbadge.none, .scanbadge.pending { font-weight: 500; text-transform: none; }
/* Made by one of our factories - not scanned, filed under its group. */
.scanbadge.known { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); font-weight: 600; text-transform: none; }
#symbolHeading .scanbadge { margin-left: 10px; font-size: 11px; }
/* The scan log's controls, and the detective's section. */
.scanlog-controls { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.scanlog-controls .pillgroup { margin: 0; }
.dettable { font-size: 12px; margin-top: 6px; }
.detgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 8px 18px; margin: 8px 0 12px; }
.detgrid .k { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; }
.detgrid .v { font-size: 15px; font-weight: 600; }
.detgrid .v small { font-size: 11px; font-weight: 400; color: var(--text-muted); }
.reasons { margin: 6px 0 12px; padding-left: 18px; font-size: 13px; line-height: 1.5; }
.source { font-size: 10px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .05em; }

/* Slur mask (js/mask.js, mounted from format.js on every page): a slur in
   a chain-supplied symbol/name is shown as N***** until clicked. Dotted
   underline says "there is something here", the cursor says it is a
   control; revealed keeps the underline so it can be hidden again. */
.slurmask { cursor: pointer; border-bottom: 1px dotted var(--text-muted); letter-spacing: 0.04em; }
.slurmask:hover { color: var(--accent); }
.slurmask.revealed { letter-spacing: normal; border-bottom-style: solid; }

/* Dev cards (js/devcards.js) - pDev and Token+. One card per dev, their
   tokens in the shared metric table inside; top N with a Show-all button;
   ⋮⋮ drag handle and ▲▼ to reorder, remembered per viewer. Moved here
   from pdev.html's <style> when Token+ started using the same cards. */
.devgrid { display: grid; grid-template-columns: 1fr; gap: 14px; }
/* min-width: 0 at every width: a grid item's 1fr track is minmax(auto, 1fr),
   so without it a card grows to its header's min-content width (the fixed
   stats block plus a long name) and the page scrolls sideways instead of
   the name being cut. */
.devcard { border: 1px solid var(--border); border-radius: 12px; background: var(--surface); padding: 14px 18px; min-width: 0; }
.devhead { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; cursor: pointer; }
.devident { display: flex; align-items: baseline; gap: 10px; }
/* THE DISPLAY PHOTO (2026-09-23, per user: "id like it on the Left of the
   name... just leave the same size since we may include other things like
   disclaimer about contract stuff, so then we have a nice rectangular
   layout"): a fixed 56 px round picture before the name, the SAME size
   whether the card is collapsed or expanded - a click opens it full size
   through js/logobox.js (data-logobox) instead of growing the header. */
.devphoto { width: 56px; height: 56px; border-radius: 50%; object-fit: cover; flex: 0 0 56px; align-self: center; border: 1px solid var(--border); box-shadow: 0 0 0 2px var(--surface), 0 0 0 3px var(--border); cursor: zoom-in; background: var(--bg); }
.devident:has(> .devphoto) { align-items: center; }
/* The card's own line under the name - Token+ uses it for the contract
   disclaimer ("fees are read from the contract where it exposes them...").
   Part of the header rectangle, so it reads collapsed or expanded. */
.devnote { font-size: 12px; color: var(--text-muted); margin-top: 3px; max-width: 720px; line-height: 1.4; }
.devnote a { color: var(--accent); }
/* Token+ cells: a value read off the contract carries the tick; one the
   dev typed on the form is marked as reported. */
.chainok { color: var(--good); font-weight: 600; cursor: help; }
/* A SMALL R IN A CIRCLE (2026-09-24, per user: "doesnt need to be reported
   beside it... like a small R in a circle and a description when hovered
   that its not verified"): the description is the title. */
.reported { display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; font-size: 9px; font-weight: 700; line-height: 1; color: var(--text-muted); border: 1px solid var(--text-muted); border-radius: 50%; margin-left: 4px; cursor: help; vertical-align: middle; font-family: "Public Sans", sans-serif; }
/* MORE THAN ONE REWARD TOKEN (2026-09-23): the second and later reward
   tokens the dev listed, each under the first in the Pays cell */
.extrareward { margin-top: 4px; padding-top: 4px; border-top: 1px dashed var(--border); }
.devname { font-family: "Fraunces", serif; font-size: 22px; font-weight: 600; }
.devname .groupbadge { vertical-align: middle; margin-left: 8px; font-family: "Public Sans", sans-serif; }
/* THE STATS ARE A FIXED-COLUMN GRID (2026-09-26, per user, on the folded
   cards: "not all metrics are lined up... everything should be lined up
   left to right and up and down type thing so it looks clean"). They were a
   flex row packed to the right, so "TVL" on one card sat 300 px from "TVL"
   on the next. Every card now draws the same nine cells (devcards.js draws
   an empty one where a card has no hidden tokens, no date or no flag), each
   in a column of a fixed width, and the block is pushed to the card's right
   edge (margin-left: auto) even when a long name wraps it onto its own line
   - so every column is at one x on every card. Under 1000 px it is the
   wrapping row again. */
.devstats { display: grid; grid-template-columns: 84px 70px 124px 160px 134px 100px 96px 48px 24px; column-gap: 12px; align-items: baseline; font-size: 12px; color: var(--text-muted); margin-left: auto; white-space: nowrap; }
.devstats > * { min-width: 0; }
.devstats .empty { border: 0; padding: 0; background: none; }
/* The header never wraps on a wide screen: a long name is cut with an
   ellipsis (the full name in its title) so the stats stay on the name's
   line, at the same height on every card. */
.devhead { flex-wrap: nowrap; }
.devident { min-width: 0; flex: 1 1 auto; }
.devident > div { min-width: 0; }
.devname { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.devstats .devmove, .devstats .devhidebtn, .devstats .devunhidebtn { justify-self: end; }
.devstats .devflag { justify-self: start; }
@media (max-width: 1000px) {
  .devstats { display: flex; gap: 14px 22px; flex-wrap: wrap; margin-left: 0; white-space: normal; }
  .devstats .empty { display: none; }
  .devhead { flex-wrap: wrap; }
  .devname { white-space: normal; }
}
.devstats b { color: var(--text); font-family: "IBM Plex Mono", ui-monospace, monospace; font-weight: 600; }
.devtokens { margin-top: 10px; }
.devtokens .tablewrap { margin: 0; }
.devowner { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 11px; color: var(--text-muted); }
.devowner .devlink { color: var(--accent); text-decoration: none; font-family: "Public Sans", sans-serif; font-weight: 600; }
.devowner .devlink:hover { text-decoration: underline; }
.devcard.collapsed .devtokens { display: none; }
.devtoggle { font-size: 12px; color: var(--text-muted); }
.devgrip { cursor: grab; color: var(--text-muted); font-size: 16px; letter-spacing: -3px; user-select: none; padding: 0 2px; align-self: center; }
.devgrip:hover { color: var(--accent); }
.devcard.dragging { opacity: 0.45; }
.devcard.dropbefore { box-shadow: 0 -3px 0 0 var(--accent); }
.devcard.dropafter { box-shadow: 0 3px 0 0 var(--accent); }
.devmove { display: inline-flex; gap: 2px; }
/* HIDE A DEV (2026-09-23) - the × at the right of the header, the ↩ on a
   hidden card, and the line above the cards that brings them back. */
.devhidebtn, .devunhidebtn { background: none; border: 1px solid var(--border); color: var(--text-muted); border-radius: 6px; width: 24px; height: 24px; line-height: 1; font-size: 15px; cursor: pointer; padding: 0; }
.devhidebtn:hover { color: var(--bad); border-color: var(--bad); }
.devunhidebtn:hover { color: var(--accent); border-color: var(--accent); }
.devhiddennote { font-size: 12px; color: var(--text-muted); padding: 2px 4px 6px; }
.devhiddennote b { color: var(--text); font-family: "IBM Plex Mono", ui-monospace, monospace; }
.devhiddennote .notelink { background: none; border: none; padding: 0; color: var(--accent); cursor: pointer; font: inherit; text-decoration: underline; }
.devhiddennote[hidden] { display: none; }
.devhiddennote .organize { font-weight: 700; text-decoration: none; border: 1px solid var(--accent); border-radius: 999px; padding: 1px 10px; }
.devhiddennote .organize:hover { background: var(--accent); color: var(--accent-text); }
.devcard.markedhide { opacity: 0.45; }
.devhidebtn.marked { color: var(--accent); border-color: var(--accent); }
.devpage { margin-top: 4px; }
/* DEV FAVOURITES (2026-09-23) - the ★ at the left of the header (one list,
   no name) and the All / Favorites pills above the cards. */
.devstar { background: none; border: none; color: var(--text-muted); font-size: 18px; cursor: pointer; padding: 0 4px; line-height: 1; align-self: center; }
.devstar:hover { color: var(--accent); }
.devstar.active { color: var(--accent); }
/* Two quiet underline tabs, sized to their words - not the site's boxed
   pill group, which the card grid stretched across the whole width (per
   user 2026-09-23: "get rid of that look and that long line... make it
   look more professional"). .pillgroup stays on the element only for its
   button reset; everything visible is set here. */
.devview.pillgroup { justify-self: start; display: inline-flex; gap: 4px; background: none; border: none; border-radius: 0; box-shadow: none; padding: 0; margin: 0 0 12px; border-bottom: 1px solid var(--border); }
.devview.pillgroup button { padding: 7px 14px 8px; font-size: 13px; font-weight: 600; letter-spacing: 0.01em; border-radius: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; color: var(--text-muted); background: none; }
.devview.pillgroup button:hover { color: var(--text); }
.devview.pillgroup button.active { background: none; color: var(--text); border-bottom-color: var(--accent); }
/* A tab that is a LINK - pDev's Manage Card (pdev-manage.html), and the
   two tabs back from that page - drawn exactly like the button tabs. */
.devview.pillgroup a { display: inline-block; text-decoration: none; padding: 7px 14px 8px; font-size: 13px; font-weight: 600; letter-spacing: 0.01em; border-bottom: 2px solid transparent; margin-bottom: -1px; color: var(--text-muted); }
.devview.pillgroup a:hover { color: var(--text); }
.devview.pillgroup a.active { color: var(--text); border-bottom-color: var(--accent); }
#pdevTabs { margin: 8px 0 4px; }
.devfavempty { color: var(--text-muted); font-size: 13px; padding: 12px 4px; }
/* The scanner's verdict on a dev card: the badge beside the symbol, the
   count in the header. */
.devscan { display: inline-block; vertical-align: middle; margin-left: 6px; }
/* HIDDEN BY THE DEV (2026-09-25): tokens taken off the card through Dev
   Updates, counted in the header - they are still on every other page. */
.devhidden { border: 1px dashed var(--border); border-radius: 999px; padding: 2px 8px; }
.devflag { font-size: 11px; font-weight: 600; border-radius: 999px; padding: 2px 8px; }
.devflag.flagged { color: var(--bad); border: 1px solid var(--bad); }
.devflag.caution { color: #d9a52a; border: 1px solid #d9a52a; }
.devmovebtn { background: none; border: 1px solid var(--border); border-radius: 5px; color: var(--text-muted); font-size: 9px; line-height: 1; padding: 4px 5px; cursor: pointer; }
.devmovebtn:hover:not(:disabled) { color: var(--accent); border-color: var(--accent); }
.devmovebtn:disabled { opacity: 0.3; cursor: default; }
.devmore { display: block; width: 100%; margin-top: 6px; padding: 7px; background: none; border: 1px dashed var(--border); border-radius: 8px; color: var(--text-muted); font-size: 12.5px; cursor: pointer; }
.devmore:hover { color: var(--accent); border-color: var(--accent); }

/* Plain-words layer on the scan report (js/scanglossary.js): one line
   under each finding and each detective reason, and a short "in plain
   words" box under the verdict. */
.fmeaning { margin-top: 5px; font-size: 12.5px; line-height: 1.5; color: var(--text); }
.fmeaning b { color: var(--text-muted); font-weight: 600; margin-right: 4px; }
.fmeaning .innocent { color: var(--text-muted); }
.plainwords { margin: 8px 0 14px; padding: 10px 14px; border-left: 3px solid var(--accent); background: var(--surface); border-radius: 0 8px 8px 0; font-size: 13.5px; line-height: 1.55; }
.plainwords .k { color: var(--text-muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 4px; }

/* The contract-family section on a scan report (js/scanglossary.js is
   the words; fates.js is the counting). */
.fam { display: grid; gap: 6px; font-size: 13.5px; line-height: 1.5; margin: 6px 0 12px; }
.fam-own { margin-top: 4px; }

/* NO WRITING ON THE GROUP PAGES (2026-09-19, per user: "get rid of all the
   writing on each group... we will figure it out later"). Every page's
   header tagline (the line beside the wordmark) is hidden, not deleted,
   so the copy is still in each page for when the wording is decided. ONLY
   the tagline: the user meant the header lines ("I was only talking about
   the headers"), so the Cores welcome block and pDev's blurb stay. (An
   earlier cut hid the .about class and took the Advertisement page's
   forms with it - they use that class - never hide by that class.) */
.tagline { display: none; }

/* ============================================================
   THE LEGAL PAGES AND THE SITE FOOTER (2026-09-19)

   Four documents - terms, privacy, disclaimer, listing terms - and the
   footer that reaches them from every page. The footer is mounted by
   js/legal.js from format.js, so no page opts in; a fixed-height app page
   (the pool chart, the matrix) carries data-nofooter and is skipped.
   ============================================================ */
.legalpage {
  max-width: 760px;
  margin: 0 auto;
  padding: 8px 20px 40px;
  font-size: 15px;
  line-height: 1.65;
  color: var(--text);
}
.legalpage h1 { font-size: 28px; margin: 12px 0 4px; }
.legalpage h2 {
  font-size: 17px;
  margin: 30px 0 8px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
.legalpage p { margin: 0 0 12px; }
.legalpage ul { margin: 0 0 14px; padding-left: 22px; }
.legalpage li { margin: 0 0 6px; }
.legalpage a { color: var(--link); }
.legalmeta { color: var(--text-muted); font-size: 13px; margin-bottom: 20px; }
/* The lead paragraph is the answer, said once, before the clauses. */
.legallead {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  padding: 14px 16px;
  font-size: 15.5px;
  margin-bottom: 22px;
}
.legalwarn { border-left-color: var(--bad); }

#sitefooter {
  margin: 48px 0 0;
  padding: 22px 20px 30px;
  border-top: 1px solid var(--border);
  background: color-mix(in srgb, var(--surface) 60%, transparent);
}
.footinner { max-width: 1800px; margin: 0 auto; text-align: center; }
/* The links read as one line separated by dots, the way most sites' footers
   do - a ::after on each but the last, so the separator is decoration and
   never lands in the link text or in a link count. */
.footlinks { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; margin-bottom: 10px; }
.footlinks a { color: var(--text-muted); text-decoration: none; font-size: 13px; font-weight: 600; position: relative; }
.footlinks a:not(:last-child)::after {
  content: "\00b7";
  position: absolute;
  right: -9px;
  color: var(--border);
  font-weight: 400;
}
.footlinks a:hover { color: var(--accent); text-decoration: underline; }
.footnote { color: var(--text-muted); font-size: 12px; line-height: 1.6; max-width: 720px; margin: 0 auto; }

/* PHONES (2026-09-25, js/mobiletable.js - read its header). AT THE END OF
   THE FILE ON PURPOSE: it overrides same-specificity rules above (.favstar's
   48 px box, the cell padding), and a later rule wins. The table
   drops its 880 px floor and scrolls inside the card; the star and the
   Token column are stuck to the left (the offsets are written per table by
   the script, since they depend on the star cell's real width); the #
   column is gone; the cells are tighter; and the column picker above the
   table (.colpick) shows only here - a desktop always shows every column.
   border-collapse: separate, because a collapsed border scrolls away from a
   sticky cell in Chromium and leaves it borderless. The floating scrollbar
   (hscroll.js) is a desktop thing: a thumb is what a phone swipes. */
.colpick { display: none; }
/* THE CARD VIEW (2026-09-26, js/mobilecards.js; per user, from a
   whiteboard: "see everything in one shot instead of scrolling
   left/right", then "lets try it and ill see if it looks good" for the
   desktop). Cards | Compact | Table above every page-one list at EVERY
   width, a Sort pull-down for the two card views (no headers to tap),
   the table and its column picker hidden while a card view is on. A
   phone opens on Cards, a desktop on Table (the choice, once made, wins
   at any width); on a desktop the cards sit in one centred column (the
   rule under this block) - a card's middle grows with the width and
   reads empty past ~700 px, and the column leaves the sides free for a
   later gutter. */
.mviewbar { display: flex; align-items: center; gap: 6px 8px; margin: 0 0 10px; flex-wrap: wrap; }
.mviewbar[hidden] { display: none; }
.mcseg { display: inline-flex; border: 1px solid var(--border); border-radius: 999px; overflow: hidden; background: var(--surface); }
.mcseg button { font: inherit; font-size: 12.5px; padding: 6px 12px; border: 0; background: none; color: var(--text-muted); cursor: pointer; }
.mcseg button.on { background: var(--accent); color: var(--accent-text); font-weight: 600; }
.mcsortwrap { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; }
.mcsort { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); padding: 4px 6px 4px 12px; }
.mcsortsel { font: inherit; font-size: 12.5px; border: 0; background: transparent; color: var(--text); max-width: 130px; }
.mcflip { font: inherit; font-size: 14px; width: 30px; height: 30px; border-radius: 50%; border: 1px solid var(--border); background: var(--surface); color: var(--text); cursor: pointer; }
.colpick.mc-off, .tablewrap.mc-hidetable { display: none !important; }
.mcards { display: flex; flex-direction: column; gap: 10px; }
.mcards[hidden] { display: none; }
.mcard { position: relative; background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 12px 12px 10px; box-shadow: var(--shadow); cursor: pointer; }
.mcard .favstar { display: inline-block; width: auto; min-width: 0; padding: 2px 4px; font-size: 20px; }
.mcicon { display: inline-flex; }
.mcard .mcicon .tokenicon, .mcard .mcicon .lpicon { width: 40px; height: 40px; }
.mcard .mcicon .lpicon { font-size: 11px; }
.mcard .mcicon .dot { width: 34px; height: 34px; }
.mchead { display: flex; gap: 10px; align-items: flex-start; }
.mcleft { display: flex; flex-direction: column; align-items: center; gap: 6px; flex: none; }
.mcmid { flex: 1 1 auto; min-width: 0; }
.mcsym { font-weight: 700; font-size: 16px; line-height: 1.25; overflow-wrap: anywhere; }
.mcsym .groupbadge { vertical-align: middle; }
.mcname { font-size: 11.5px; color: var(--text-muted); margin-top: 3px; overflow-wrap: anywhere; }
.mclbl { font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); white-space: nowrap; }
.mcval { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 12.5px; font-variant-numeric: tabular-nums; margin-top: 1px; }
.mcaddr { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 11px; color: var(--text-muted); display: inline-flex; align-items: center; gap: 6px; }
.mcard .dircopybtn.mccopy { all: unset; font-size: 10px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--accent); border: 1px solid var(--accent); border-radius: 6px; padding: 1px 6px; cursor: pointer; }
.mcbox { flex: none; width: 150px; border-left: 1px solid var(--border); padding-left: 10px; display: grid; grid-template-columns: 1fr 1fr; row-gap: 4px; column-gap: 8px; }
.mcbox .full { grid-column: 1 / -1; }
.mcband { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 6px; margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--border); }
.mcband .mcval { font-size: 13px; }
.mcextra { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 8px; padding-top: 6px; border-top: 1px dashed var(--border); font-size: 12px; }
.mcx .mclbl { margin-right: 4px; }
.mc-compact { padding: 10px 12px; }
.mc-compact .mchead { align-items: center; }
.mc-compact .mcicon .tokenicon, .mc-compact .mcicon .lpicon { width: 30px; height: 30px; }
.mc-compact .mcicon .dot { width: 26px; height: 26px; }
.mc-compact .mcsym { font-size: 15px; }
.mcright { margin-left: auto; text-align: right; flex: none; }
.mcright .mcprice { font-size: 14px; font-weight: 600; }
.mcstrip { display: grid; grid-template-columns: repeat(5, 1fr); gap: 4px; margin-top: 8px; padding-top: 6px; border-top: 1px dashed var(--border); }
.mcstrip .mcval { font-size: 11.5px; }
.mcstrip .pctcell { text-align: right; }

/* The desktop column: one centred column of cards, whatever the screen. */
@media (min-width: 761px) {
  .mviewbar, .mcards { max-width: 720px; margin-left: auto; margin-right: auto; }
  .mviewbar { margin-bottom: 12px; }
}

@media (max-width: 760px) {
  body { padding: 16px 12px 48px; }
  table { min-width: 0; border-collapse: separate; border-spacing: 0; }
  .tablewrap th { width: auto !important; }
  thead th { padding: 10px 9px; font-size: 10px; }
  tbody td { padding: 9px 9px; font-size: 12.5px; }
  table.dense thead th { padding: 10px 7px; }
  table.dense tbody td { padding: 9px 7px; font-size: 12px; }
  /* A sticky cell needs a background of its own to cover what slides under
     it - the row's, so the hover colour follows. Headers keep theirs. */
  .tablewrap > table > tbody > tr > td { background: inherit; }
  .tablewrap > table > thead th { z-index: 3; }
  .favstar { min-width: 0; padding: 8px 4px; font-size: 16px; }
  td:has(> .favstar) { width: 30px; }
  .tokencell { width: 140px; gap: 8px; }
  .tokencell .mostactive { max-width: 110px; }
  /* tokens.html's sidebar stacks above its list; a dev card is a grid item
     and must be allowed to shrink under its own scrolling table; the view
     tabs wrap. */
  .layout { flex-direction: column; }
  #sidebar { width: auto; flex-direction: row; flex-wrap: wrap; }
  .devcard { min-width: 0; padding: 12px 12px; }
  .devview.pillgroup { flex-wrap: wrap; }
  .hscroll { display: none !important; }
  .colpick { display: block; margin: 0 0 10px; font-size: 12px; color: var(--text-muted); }
  .colpick[hidden] { display: none; }
  /* THE PICKER IS FOLDED (later 2026-09-25, per user: "dont present them
     openly have them in a tab... organize what ones we want to see 1-X"):
     one Columns button; open, the chips - a lit chip carries its number,
     the order the columns show in. */
  .colpicktoggle {
    font: inherit; font-size: 12px; font-weight: 500; cursor: pointer;
    display: inline-flex; align-items: center; gap: 6px;
    padding: 5px 12px; border-radius: 999px;
    border: 1px solid var(--border); background: var(--surface); color: var(--text);
  }
  .colpick.open .colpicktoggle { border-color: var(--accent); }
  .colpickcount { font-size: 11px; color: var(--text-muted); }
  .colpickpanel { display: none; margin-top: 8px; padding: 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
  .colpick.open .colpickpanel { display: block; }
  .colpickhint { font-size: 11.5px; color: var(--text-muted); margin-bottom: 8px; }
  .colpickchips { display: flex; flex-wrap: wrap; gap: 6px; }
  .colpickbtn {
    font: inherit; font-size: 12px; font-weight: 500; cursor: pointer;
    display: inline-flex; align-items: center;
    padding: 4px 10px; border-radius: 999px;
    border: 1px solid var(--accent); background: var(--accent); color: var(--accent-text);
  }
  .colpickbtn .colnum {
    display: inline-block; min-width: 16px; height: 16px; line-height: 16px; margin-right: 5px;
    border-radius: 50%; background: var(--accent-text); color: var(--accent);
    font-size: 10.5px; font-weight: 700; text-align: center;
  }
  .colpickbtn.off { background: var(--surface); color: var(--text-muted); border-color: var(--border); }
  .colpickreset { margin-top: 8px; padding: 0; font: inherit; font-size: 11.5px; background: none; border: none; color: var(--accent); cursor: pointer; text-decoration: underline; }
}
