/* PONTIMUS — application chrome and the /pools surfaces. */

/* ------------------------------------------------------------------ base */

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  -webkit-font-smoothing: antialiased;
  background: var(--bg);
  color-scheme: dark;
}

body {
  color: var(--text);
  font-family: var(--f-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

a {
  color: var(--green);
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}
::selection {
  background: var(--green);
  color: var(--on-green);
}
:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 2px;
}
h1,
h2,
h3,
h4 {
  font-family: var(--f-sans);
  font-weight: 600;
}
h3 {
  font-size: var(--fs-h3);
  letter-spacing: -0.01em;
}
button {
  font-family: inherit;
}
img {
  max-width: 100%;
}

/* One weight for every icon, so a stroke-width typo in one SVG cannot make a
   single icon look bolder than its neighbours. */
svg[class*='lucide'] {
  stroke-width: 1.75;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ------------------------------------------------------------ background */

.bg-wash,
.bg-field {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}
.bg-field {
  width: 100%;
  height: 100%;
}
.bg-wash {
  background:
    radial-gradient(120% 120% at 100% 0, rgba(103, 213, 75, 0.09) 0, transparent 46%),
    radial-gradient(120% 120% at 0 100%, rgba(238, 247, 239, 0.04) 0, transparent 50%);
}
.bg-wash::after {
  content: '';
  position: absolute;
  inset: -25%;
  background:
    radial-gradient(34% 40% at 72% 18%, rgba(103, 213, 75, 0.05), transparent 60%),
    radial-gradient(30% 38% at 22% 76%, rgba(135, 233, 94, 0.04), transparent 58%);
  filter: blur(40px);
}
/* ----------------------------------------------------------------- shell */

.shell-main {
  width: min(1280px, 100% - 2rem);
  margin: 0 auto;
  padding: 1.1rem 0 4rem;
  flex: 1 1;
  position: relative;
}
.shell-main::before {
  content: '';
  position: absolute;
  top: -3rem;
  left: 0;
  right: 0;
  height: 460px;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(46% 62% at 24% 18%, rgba(103, 213, 75, 0.09), transparent 62%),
    radial-gradient(42% 58% at 78% 8%, rgba(135, 233, 94, 0.07), transparent 60%);
}
.app-rail-shift {
  padding-left: var(--rail-w);
}

/* ---------------------------------------------------------------- topbar */

.topbar {
  position: sticky;
  top: 0;
  z-index: 70;
  background: rgba(5, 11, 7, 0.92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
.topbar::after {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 8%;
  right: 8%;
  height: 1px;
  pointer-events: none;
  background: linear-gradient(
    90deg,
    transparent 0,
    var(--edge-glow) 35%,
    var(--edge-glow) 65%,
    transparent 100%
  );
}

/*
  Grid, not absolute positioning.

  TRAP: the brand used to be `position: absolute` so the search could be centred
  over the content column independently of it. But an absolutely positioned
  element reserves no space, so the search's centring maths could put it
  underneath the brand - and it did, by 3px, across every width from 1024 to
  1280. Three separate media queries existed to paper over it.

  Four grid tracks make the overlap impossible to express: the brand owns its
  column, the search owns the middle, the live chip and the actions own the
  right. TRAP: the chip was added as a fourth child of a three-track grid and
  fell into an implicit second row, pushing the actions under the brand.
*/
.topbar-inner {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  height: calc(var(--topbar-h) - 1px);
  width: 100%;
  margin: 0;
  padding: 0 1.25rem 0 16px;
  column-gap: 1.1rem;
}

.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.34em;
  white-space: nowrap;
}
.brand,
.brand:hover {
  text-decoration: none;
}
/* The mark is a raster of the logo, not a drawn glyph, so it is rounded here
   rather than shipped pre-cut: one asset serves the topbar, the docs and the
   favicon set. */
.brand-mark {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  display: block;
  flex: 0 0 auto;
  transition: filter var(--dur) var(--ease);
}
.topbar .brand:hover .brand-mark {
  filter: drop-shadow(0 0 6px rgba(103, 213, 75, 0.55));
}
.brand-word {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.3em;
  color: var(--ink-bright);
}
.brand .net-tag {
  font-size: 9px;
  letter-spacing: var(--track);
  color: var(--ink-2);
  border: 1px solid var(--line-2);
  padding: 1px 5px;
  text-transform: uppercase;
}

.topbar-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  justify-self: end;
}
/*
  TRAP: a flex row shrinks its children by default. At 1024px the wallet button
  wrapped onto two lines and the stats strip clipped "$2,471" to "$2,47" -
  nothing overlapped, so no test saw it. Nothing here may shrink or wrap; the
  breakpoints further down remove whole items instead, widest first.
*/
.topbar-actions > * {
  flex: 0 0 auto;
}
.topbar-actions .btn {
  white-space: nowrap;
}


.g-search {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  max-width: 560px;
  margin: 0;
  justify-self: center;
  background: var(--panel);
  border: 1px solid var(--line);
  padding: 8px 14px;
  color: var(--text-3);
  border-radius: var(--r-full);
  font-family: var(--f-mono);
  transition: border-color var(--dur) var(--ease);
}
.g-search:focus-within {
  border-color: var(--green);
}
.g-search input {
  background: none;
  border: 0;
  outline: none;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  width: 100%;
  font-family: var(--f-mono);
}
.g-search input::placeholder {
  color: var(--text-3);
}

/* search dropdown */
.tok-search-drop {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  right: 0;
  z-index: 80;
  background: var(--panel);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  box-shadow: var(--glass-shadow);
  overflow: hidden;
  max-height: 60vh;
  overflow-y: auto;
}
.g-group {
  font-family: var(--f-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-3);
  padding: 8px 12px 4px;
}
.tok-search-hit {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 7px 12px;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  color: var(--text);
}
.tok-search-hit:hover,
.tok-search-hit.sel {
  background: var(--raised);
}
.tok-search-hit .tok-sym {
  font-family: var(--f-mono);
  font-size: 12px;
  font-weight: 700;
}
.tok-search-hit .tok-name {
  font-size: 11.5px;
  color: var(--ink-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tok-search-hit .tok-addr {
  margin-left: auto;
  font-family: var(--f-mono);
  font-size: 10px;
  color: var(--ink-3);
}
.tok-search-note {
  padding: 12px;
  font-size: 12px;
  color: var(--ink-2);
}

/* header stats */
.header-stats {
  display: flex;
  align-items: stretch;
  gap: 0;
  margin-right: 0.6rem;
  background-color: var(--panel);
  background-image: var(--card-wash);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.035);
  overflow: hidden;
}
.header-stats .hstat {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 13px;
  border-left: 1px solid var(--line);
}
.header-stats .hstat:first-child {
  border-left: 0;
}
.header-stats .hstat-ico {
  color: var(--green);
  flex: 0 0 auto;
}
.header-stats .hstat-body {
  display: flex;
  flex-direction: column;
  gap: 1px;
  line-height: 1.1;
}
.header-stats .hstat-label {
  font-family: var(--f-mono);
  font-size: 8.5px;
  font-weight: 500;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-2);
  white-space: nowrap;
}
.header-stats .hstat-value {
  font-family: var(--f-mono);
  font-size: 12.5px;
  font-weight: 700;
  font-feature-settings: 'tnum';
  font-variant-numeric: tabular-nums;
  color: var(--ink-bright);
  white-space: nowrap;
}

/* ------------------------------------------------------------ token pill */

/*
  Two controls in one shell: the left half opens the launchpad, the right half
  copies the address. They are separate elements on purpose, because a single
  control that both navigates and copies cannot say which it is about to do.
*/
.tokpill {
  display: flex;
  align-items: stretch;
  flex: 0 0 auto;
  border: 1px solid var(--green-line);
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--green-tint);
  white-space: nowrap;
}
.tokpill-buy,
.tokpill-ca {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  height: 30px;
  font-family: var(--f-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  background: none;
  border: 0;
  color: var(--green);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
/*
  The buy half is FILLED, not outlined.

  Green text on the app's own ground is fine for a state marker but not for
  the one control here that exists to be found. Filling it puts --on-green on
  --green instead, which clears 7:1.
*/
.tokpill-buy {
  background: var(--green);
  color: var(--on-green);
}
.tokpill-buy:hover {
  background: var(--green-bright);
  color: var(--on-green);
  text-decoration: none;
}
.tokpill-ico {
  flex: 0 0 auto;
}
.tokpill-word {
  padding-left: 6px;
  margin-left: 2px;
  border-left: 1px solid currentColor;
  opacity: 0.75;
  text-transform: uppercase;
  letter-spacing: var(--track);
  font-size: 9.5px;
}
/* Stands in for the address once the address no longer fits. */
.tokpill-ca-word {
  display: none;
  letter-spacing: var(--track);
  font-size: 9.5px;
  text-transform: uppercase;
}
.tokpill-ca {
  cursor: pointer;
  border-left: 1px solid var(--green-line);
  color: var(--ink-2);
  font-weight: 500;
}
.tokpill-ca:hover {
  background: var(--green-tint);
  color: var(--ink-bright);
}
.tokpill-ca.copied {
  background: var(--green);
  color: var(--on-green);
}

/* ------------------------------------------------------------- live chip */

/*
  One chip, three truths. LIVE with a block number when the keys contract is
  answering, TERMINAL LIVE when the pools index answers but the keys contract
  is not deployed, OFFLINE when nothing answers. The cyan dot is reserved for
  the first state: a dot that is always lit tells you nothing.
*/
.live-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 30px;
  padding: 0 11px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-full);
  background: var(--panel);
  font-family: var(--f-mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-2);
  white-space: nowrap;
  flex: 0 0 auto;
}
.live-chip .dot {
  width: 7px;
  height: 7px;
  border-radius: var(--r-full);
  background: var(--ink-3);
  flex: 0 0 auto;
}
.live-chip.is-live {
  color: var(--ink-bright);
  border-color: var(--green-line);
}
.live-chip.is-live .dot {
  background: var(--stripe);
  box-shadow: 0 0 0 3px rgba(98, 217, 255, 0.18);
}
.live-chip.is-offline {
  color: var(--neg);
  border-color: color-mix(in srgb, var(--neg) 45%, var(--line));
}
.live-chip.is-offline .dot {
  background: var(--neg);
}
.live-chip .chip-block {
  color: var(--ink-2);
  font-weight: 500;
}

/* The "How it works" opener: a labelled ghost button on desktop, an icon on a
   phone where the row has no room for the words. */
.how-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 34px;
  padding: 0 12px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: transparent;
  color: var(--ink-2);
  font-family: var(--f-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  flex: 0 0 auto;
  white-space: nowrap;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.how-btn:hover {
  color: var(--ink-bright);
  border-color: var(--line-3);
}

/* ---------------------------------------------------------------- buttons */

.btn {
  font-family: var(--f-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 9px 16px;
  border-radius: var(--r-md);
  cursor: pointer;
  border: 1px solid color-mix(in srgb, var(--green) 45%, var(--line));
  background: color-mix(in srgb, var(--green) 12%, var(--panel));
  color: var(--green);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
  transition:
    background var(--dur) var(--ease),
    border-color var(--dur) var(--ease),
    color var(--dur) var(--ease);
}
/* A hex address inside an uppercase button keeps its case: "0X12AB…9F3C" is
   not an address anyone recognises. */
.btn .addr-case {
  text-transform: none;
}
.btn:hover:not(:disabled) {
  background: color-mix(in srgb, var(--green) 22%, var(--panel));
  border-color: var(--green);
  color: var(--ink-bright);
}
.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.btn.btn-ghost {
  border-color: var(--line-2);
  background: var(--panel);
  color: var(--ink-bright);
}
.btn.btn-ghost:hover:not(:disabled) {
  border-color: var(--green);
  color: var(--green);
}
/* The primary action is the one place the green is used as a fill, so it reads
   as the single strongest element on the page. */
.btn.btn-primary {
  background: var(--green);
  border-color: var(--green);
  color: var(--on-green);
}
.btn.btn-primary:hover:not(:disabled) {
  background: var(--green-bright);
  border-color: var(--green-bright);
  color: var(--on-green);
}

.net-warn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--neg);
  background: none;
  border: 1px solid var(--neg);
  padding: 6px 10px;
  cursor: pointer;
  border-radius: var(--r-full);
}
.net-warn:hover {
  background: rgba(255, 107, 94, 0.12);
}

/* -------------------------------------------------------------- siderail */

.siderail {
  position: fixed;
  top: var(--topbar-h);
  left: 0;
  bottom: 0;
  width: var(--rail-w);
  z-index: 60;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  padding: 10px 0;
  gap: 2px;
  overflow: hidden;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.025) 0, transparent 42%),
    var(--bg);
  border-right: 1px solid var(--line);
  transition: width var(--dur) var(--ease);
}
.siderail:hover,
.siderail:focus-within {
  width: var(--rail-w-open);
  box-shadow: var(--glass-shadow);
}
.rail-group {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.rail-group--end {
  margin-top: auto;
}
/* Group labels (TERMINAL, CLANS) only exist in the expanded state; collapsed,
   the separator line carries the boundary on its own. */
.rail-glabel {
  height: 0;
  overflow: hidden;
  padding-left: 19px;
  font-family: var(--f-mono);
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-3);
  white-space: nowrap;
  opacity: 0;
  transition: opacity var(--dur) var(--ease), height var(--dur) var(--ease);
}
.siderail:hover .rail-glabel,
.siderail:focus-within .rail-glabel {
  height: 22px;
  line-height: 22px;
  opacity: 1;
}
.rail-sep {
  height: 1px;
  margin: 8px 12px;
  background: var(--line);
}
.rail-item {
  display: flex;
  align-items: center;
  gap: 14px;
  height: 40px;
  padding: 0 0 0 19px;
  color: var(--ink-2);
  white-space: nowrap;
  position: relative;
  transition: color var(--dur) var(--ease);
}
.rail-item:hover {
  color: var(--ink-bright);
  text-decoration: none;
  background: var(--green-tint);
}
.rail-item.active {
  color: var(--green);
}
/* An active-state marker that does not rely on colour alone. */
.rail-item.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 8px;
  bottom: 8px;
  width: 2px;
  background: var(--green);
}
.rail-ico {
  flex: 0 0 auto;
  display: inline-flex;
  width: 18px;
  justify-content: center;
}
.rail-label {
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: var(--track);
  text-transform: uppercase;
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.siderail:hover .rail-label,
.siderail:focus-within .rail-label {
  opacity: 1;
}
.rail-social {
  display: flex;
  align-items: center;
  gap: 14px;
  height: 34px;
  padding-left: 19px;
  color: var(--ink-3);
}
.rail-social:hover {
  color: var(--ink-bright);
}
/* The one green item in the rail. Nothing else in here competes with it. */
.rail-buy {
  color: var(--green);
}
.rail-buy:hover {
  color: var(--green);
  background: var(--green-tint);
}
.rail-ca {
  width: 100%;
  background: none;
  border: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

/* ---------------------------------------------------------------- tabbar */

/*
  The phone navigation is its OWN element, not the rail restyled.

  The rail carries eleven items and the phone bar carries exactly five, and
  they are not the same five in the same order (Stakes folds into Pools,
  Activity becomes a sheet, Buy is never in the bar). Hiding six rail items
  with CSS worked until someone added a seventh; a separate list cannot drift.
*/
.tabbar {
  display: none;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  height: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px));
  padding: 0 0 env(safe-area-inset-bottom, 0px);
  background: var(--bg);
  border-top: 1px solid var(--line);
}
.tab-item {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  height: 100%;
  min-height: 44px;
  color: var(--ink-2);
  position: relative;
}
.tab-item:hover {
  text-decoration: none;
  color: var(--ink-bright);
}
.tab-item.active {
  color: var(--green);
}
.tab-item.active::before {
  content: '';
  position: absolute;
  top: 0;
  left: 20%;
  right: 20%;
  height: 2px;
  background: var(--green);
}
.tab-label {
  font-family: var(--f-mono);
  /* 8.5px read as a smudge on a phone; --fs-micro is the floor for any label
     that carries meaning. */
  font-size: var(--fs-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* ------------------------------------------------------------------ sheet */

/*
  A sheet is the one modal surface: How it works, Activity on a phone, Found a
  clan. It docks to the right on a wide screen and to the bottom on a phone,
  and the panel scrolls inside itself so the page behind never has to.
*/
.sheet-backdrop {
  position: fixed;
  inset: 0;
  z-index: 85;
  background: rgba(5, 11, 7, 0.72);
  backdrop-filter: blur(4px);
  display: flex;
  justify-content: flex-end;
  align-items: stretch;
}
.sheet {
  width: min(460px, 100%);
  max-height: 100%;
  display: flex;
  flex-direction: column;
  background-color: var(--panel);
  background-image: var(--card-wash);
  border-left: 1px solid var(--line-2);
  box-shadow: var(--glass-shadow);
  animation: sheet-in-right 0.22s var(--ease) both;
}
.sheet-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
}
.sheet-head h2 {
  font-family: var(--f-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-2);
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sheet-close {
  width: 44px;
  height: 44px;
  margin: -7px -10px -7px 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  border-radius: var(--r-full);
}
.sheet-close:hover {
  color: var(--ink-bright);
  background: var(--raised);
}
.sheet-body {
  padding: 16px;
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-2);
}
@keyframes sheet-in-right {
  from {
    transform: translateX(24px);
    opacity: 0;
  }
  to {
    transform: none;
    opacity: 1;
  }
}
@keyframes sheet-in-up {
  from {
    transform: translateY(24px);
    opacity: 0;
  }
  to {
    transform: none;
    opacity: 1;
  }
}

/* The three-step list the How it works sheet and the landing share. */
.steps {
  display: flex;
  flex-direction: column;
  gap: 14px;
  list-style: none;
  counter-reset: step;
}
.steps > li {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 12px;
  counter-increment: step;
}
.steps > li::before {
  content: counter(step);
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-full);
  border: 1px solid var(--green-line);
  background: var(--green-tint);
  color: var(--green);
  font-family: var(--f-mono);
  font-size: 13px;
  font-weight: 700;
}
.steps h3,
.steps h4 {
  font-family: var(--f-sans);
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-bright);
  letter-spacing: 0;
  margin-bottom: 3px;
}
.steps p {
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-2);
}
.steps-note {
  margin-top: 16px;
  padding: 11px 13px;
  border-left: 2px solid var(--green-line);
  background: var(--green-tint);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--ink-2);
}

/* ------------------------------------------------------------ segmented */

/* Explore | Fee APR on a phone. Hidden above 720px because the two views have
   their own rail items there. */
.seg {
  display: none;
  align-items: stretch;
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 3px;
  gap: 3px;
}
.seg-btn {
  flex: 1 1 0;
  min-height: 38px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--ink-2);
  font-family: var(--f-mono);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.seg-btn[aria-selected='true'] {
  background: var(--green);
  color: var(--on-green);
}
.pools-fold {
  display: none;
}

/* ----------------------------------------------------------------- footer */

/* One footer, two pages (/ and /docs), rendered by footerHtml() in app.js. */
.site-footer {
  border-top: 1px solid var(--line);
  padding: 22px 0 28px;
}
.site-footer-inner {
  width: min(1180px, 100% - 2rem);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 18px;
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--ink-3);
}
.site-footer-right {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 6px;
}
.site-footer-right a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 8px;
  color: var(--ink-2);
}
.site-footer-right a:hover {
  color: var(--ink-bright);
  text-decoration: none;
}

/* ---------------------------------------------------------------- landing */

/* On the landing the rail and the header stats go: the page is its own
   navigation, and the stats repeat in the live strip under the hero. */
body.is-landing .siderail,
body.is-landing .tabbar,
body.is-landing .header-stats {
  display: none;
}
body.is-landing .shell-main {
  width: 100%;
  padding: 0;
}
body.is-landing .shell-main::before {
  display: none;
}

/* --------------------------------------------------------------- panels */

.xpanel,
.panel {
  background-color: var(--panel);
  background-image: var(--card-wash);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  position: relative;
}
.xpanel--green {
  box-shadow: var(--glow-green);
}
.panel-head,
.ap-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
}
.panel-head h3,
.ap-head h3,
.ap-title {
  font-family: var(--f-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-2);
}
.panel-pad {
  padding: 14px 16px;
}

/* ---------------------------------------------------------- explore grid */

.explore-page {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.mband {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.mband-side {
  display: grid;
  grid-template-rows: 1fr 1fr;
  gap: 14px;
}
.explore-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

/* market spot cards */
.mspot {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 14px 16px;
  background-color: var(--panel);
  background-image: var(--card-wash);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  color: inherit;
}
.mspot:hover {
  text-decoration: none;
  border-color: var(--line-2);
}
.mspot--hero {
  min-height: 232px;
}
.mspot--sm {
  min-height: 109px;
}
.mspot-art {
  position: absolute;
  inset: auto 0 0 0;
  height: 70%;
  pointer-events: none;
  opacity: 0.55;
}
.mspot--hero .mspot-art {
  height: 58%;
}
.mspot-k {
  font-family: var(--f-mono);
  font-size: 8.5px;
  font-weight: 500;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-3);
}
.mspot-id {
  display: flex;
  align-items: center;
  gap: 10px;
  position: relative;
  z-index: 1;
}
.mspot-sym {
  font-family: var(--f-display);
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
}
.mspot--hero .mspot-sym {
  font-size: 42px;
}
.mspot-v {
  font-family: var(--f-mono);
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.mspot-mc {
  font-family: var(--f-mono);
  font-size: 11px;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.mspot-foot {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.mspot-hero-stats {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px 18px;
  margin-top: auto;
}
.mspot-hero-stats .k {
  font-family: var(--f-mono);
  font-size: 8.5px;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-3);
  display: block;
}
.mspot-hero-stats .v {
  font-family: var(--f-mono);
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink-bright);
}
.mspot--green .mspot-v,
.mspot--vol .mspot-v {
  color: var(--green);
}

/* sparklines */
.spark {
  display: block;
  overflow: visible;
}
.spark-fill {
  opacity: 0.9;
}
.spark-dot {
  fill: currentColor;
}
.spark-wide {
  width: 68px;
  height: 22px;
}

/* ---------------------------------------------------------------- tables */

.ftable {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}
.ftable thead th {
  font-family: var(--f-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-2);
  text-align: right;
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
  background: var(--panel);
}
.ftable thead th:first-child {
  text-align: left;
  padding-left: 16px;
}
.ftable thead th.sortable {
  cursor: pointer;
  user-select: none;
}
.ftable thead th.sortable:hover {
  color: var(--ink-bright);
}
.ftable thead th[aria-sort='ascending']::after {
  content: ' ▲';
  font-size: 7px;
}
.ftable thead th[aria-sort='descending']::after {
  content: ' ▼';
  font-size: 7px;
}
.ftable tbody td {
  padding: 9px 10px;
  text-align: right;
  border-bottom: 1px solid var(--line);
  font-family: var(--f-mono);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
}
.ftable tbody td:first-child {
  text-align: left;
  padding-left: 16px;
}
.ftable tbody tr:last-child td {
  border-bottom: 0;
}
.ftable tbody tr:hover td {
  background: var(--green-tint);
}

.tok-link {
  display: flex;
  align-items: center;
  gap: 9px;
  color: inherit;
  min-width: 0;
  overflow: hidden;
}
.tok-link:hover {
  text-decoration: none;
}
.tok-ico {
  width: 22px;
  height: 22px;
  border-radius: var(--r-full);
  flex: 0 0 auto;
  background: var(--raised-2);
  object-fit: cover;
  display: block;
}
.tok-ico-fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--f-mono);
  font-size: 9px;
  font-weight: 700;
  color: var(--ink-2);
  letter-spacing: 0;
}
.tok-text {
  display: flex;
  align-items: baseline;
  gap: 7px;
  min-width: 0;
  overflow: hidden;
}
/*
  The symbol truncates too, not just the name.

  TRAP: `.ftable` is `table-layout: fixed` with `white-space: nowrap`, so a cell
  that runs out of room does not wrap or scroll - it silently overprints its
  neighbour. A long symbol like STONKBROKER rendered straight through the market
  cap column. Only the name had an ellipsis, which is no help when it is the
  symbol that is long.
*/
.tok-sym {
  font-family: var(--f-mono);
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink-bright);
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tok-name {
  font-size: 11.5px;
  color: var(--ink-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--f-sans);
}

.chg.up {
  color: var(--pos);
}
.chg.down {
  color: var(--neg);
}
.chg.up::before {
  content: '▲ ';
  font-size: 7px;
}
.chg.down::before {
  content: '▼ ';
  font-size: 7px;
}
.cell-age.fresh {
  color: var(--green);
}

/*
  The explore tables are table-layout:fixed, so seven equal columns give the
  token cell a seventh of the panel - about 45px of text next to its icon at
  1280px, which truncated every symbol to one letter. The two ends are pinned
  and the numeric middle divides the rest, the same fix the stakes table uses.
*/
.explore-grid .ftable :is(th, td):first-child {
  width: auto;
}
.explore-grid .ftable :is(th, td):nth-child(2),
.explore-grid .ftable :is(th, td):nth-child(4),
.explore-grid .ftable :is(th, td):nth-child(5) {
  width: 12%;
}
/* The change column is the widest numeric one: "▲ +909.8K%" is a real value. */
.explore-grid .ftable :is(th, td):nth-child(3) {
  width: 14%;
}
.explore-grid .ftable :is(th, td):nth-child(6) {
  width: 8%;
}
.explore-grid .ftable :is(th, td):last-child {
  width: 80px;
}
.explore-grid .ftable :is(thead th, tbody td) {
  padding-left: 6px;
  padding-right: 6px;
}
.explore-grid .ftable :is(thead th, tbody td):first-child {
  padding-left: 14px;
}

/* filters */
.quote-switch,
.win-filter {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  padding: 2px;
}
.qs-btn,
.win-btn {
  font-family: var(--f-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
  background: none;
  border: 0;
  border-radius: var(--r-full);
  padding: 4px 10px;
  cursor: pointer;
  transition:
    background var(--dur) var(--ease),
    color var(--dur) var(--ease);
}
.qs-btn:hover,
.win-btn:hover {
  color: var(--ink-bright);
}
.qs-btn.on,
.win-btn.on {
  background: var(--green);
  color: var(--on-green);
}
.table-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

/* A timeframe change dims the body rather than blanking it, so the table does
   not jump while the new window loads. */
.tbl-swap tbody {
  opacity: 0.45;
  transition: opacity 0.18s ease;
}

/*
  Entrance animation on the PANEL, never on the rows.

  TRAP: `animation: row-in .42s both` on tbody tr looks fine until the table is
  driven by a live feed. Every repaint replaces the rows, which restarts the
  animation from opacity 0 - and when ticks arrive faster than 0.42s the rows
  never finish fading in and the table renders permanently blank. The panel is
  not re-created per tick, so animating it is safe.
*/
@media (prefers-reduced-motion: no-preference) {
  .explore-grid .panel,
  .app-page .panel,
  .mband .mspot {
    animation: panel-in 0.36s var(--ease) both;
  }
}
@keyframes panel-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* ------------------------------------------------------------- empty/misc */

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 6px;
  padding: 3rem 1.5rem;
  color: var(--text-2);
}
.empty .e-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-3);
}
.subnote {
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink-2);
}
.subnote strong {
  color: var(--ink);
  font-weight: 700;
}
.mlabel {
  font-family: var(--f-mono);
  /* Same floor as .tab-label: these name the live-strip numbers. */
  font-size: var(--fs-micro);
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-3);
}
.stat .k {
  font-family: var(--f-mono);
  font-size: 8.5px;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-3);
  display: block;
}
.stat .v {
  font-family: var(--f-mono);
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.stat .v .unit {
  font-size: 10px;
  font-weight: 400;
  color: var(--text-3);
}

/* ---------------------------------------------------------------- toasts */

.toasts {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 90;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: min(420px, calc(100vw - 32px));
}
.toast {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 13px;
  background: var(--panel);
  border: 1px solid var(--line-2);
  border-left-width: 3px;
  border-radius: var(--r-md);
  box-shadow: var(--glass-shadow);
  font-size: 12.5px;
  line-height: 1.45;
  animation: toast-in 0.22s var(--ease) both;
}
.toast.ok {
  border-left-color: var(--pos);
}
.toast.err {
  border-left-color: var(--neg);
}
.toast.info {
  border-left-color: var(--green);
}
.toast-body {
  min-width: 0;
  overflow-wrap: anywhere;
}
.toast-title {
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-3);
  display: block;
  margin-bottom: 2px;
}
.toast a {
  color: var(--green);
}
.toast-close {
  margin-left: auto;
  background: none;
  border: 0;
  color: var(--ink-3);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
}
@keyframes toast-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* --------------------------------------------------------------- notices */

.notice {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 13px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--raised);
  font-size: 12.5px;
  color: var(--text-2);
}
.notice.warn {
  border-color: color-mix(in srgb, var(--warn) 50%, var(--line));
  color: var(--warn);
}
.notice.err {
  border-color: color-mix(in srgb, var(--neg) 50%, var(--line));
  color: var(--neg);
}

.skel {
  background: linear-gradient(90deg, var(--raised) 25%, var(--raised-2) 37%, var(--raised) 63%);
  background-size: 400% 100%;
  animation: skel 1.4s ease infinite;
  border-radius: var(--r-sm);
  color: transparent;
}
@keyframes skel {
  from {
    background-position: 100% 50%;
  }
  to {
    background-position: 0 50%;
  }
}

/* ----------------------------------------------------------- responsive */

@media (max-width: 1100px) {
  .explore-grid,
  .mband {
    grid-template-columns: 1fr;
  }
}

/*
  The topbar sheds items widest-first as the viewport narrows, so the search
  always keeps at least ~130px. The numbers repeat on the pages themselves
  (Stakes strip, landing strip), so nothing is lost, only moved.
*/
@media (max-width: 1620px) {
  .header-stats .hstat.hstat-wide {
    display: none;
  }
}
@media (max-width: 1100px) {
  .how-btn .how-word {
    display: none;
  }
  .how-btn {
    width: 34px;
    padding: 0;
    justify-content: center;
  }
}
/*
  The stats give way to the token pill, not the other way round: Live pools, TVL,
  Fees 24h and ETH are all repeated on the pages themselves (the landing strip,
  the Stakes strip), while the buy link and the copyable address exist nowhere
  else at a readable size - the rail collapses them to bare icons. So the pill
  keeps the row from 1001px up and the stats return only when there is room for
  both: two of them at 1360, all four at 1620.
*/
@media (max-width: 1359px) {
  .header-stats {
    display: none;
  }
}

/*
  The token pill is 257px with a ticker, a BUY word and an address, and it only
  exists once a token address is set - so it appeared in the topbar for the
  first time on launch day, into a row that had been measured without it, and
  pushed /pools 117px wide at 1024. It sheds the same way everything else in
  this row does, widest part first.
*/
@media (max-width: 1180px) {
  /* The green fill and the ticker already say "buy"; the word is the widest
     part of the pill and the least load-bearing. */
  .tokpill-word {
    display: none;
  }
}

/*
  Between 720 and 1000 the row cannot hold the pill at all: brand, chip and the
  wallet button alone leave it about 117px. The side rail is on screen at these
  widths and carries both Buy $PONTIMUS and Copy CA with their labels, so
  nothing is lost. Below 720 the rail is replaced by the tab bar and the pill
  comes back in its compact form. A range query rather than an override, so this
  cannot depend on which block the cascade reaches last. It goes entirely, and comes back below 720 where the
  rail is replaced by the tab bar. A range query rather than an override, so
  this cannot depend on which block the cascade reaches last.
*/
@media (max-width: 1000px) and (min-width: 721px) {
  .tokpill {
    display: none;
  }
}

@media (max-width: 900px) {
  /* The address is the first thing to go: it is the least readable part and
     the copy icon still carries the action. */
  .tokpill-addr {
    display: none;
  }
  .tokpill-ca {
    padding: 0 8px;
  }
}

/*
  Phone widths. The topbar row is brand + actions, and at 390px and below the
  actions column overflowed its grid track and painted over the brand. Every
  control in the row therefore has a narrower form: the wallet button drops the
  word "wallet" (the DOM keeps it), the How-it-works button drops to its icon,
  and the token pill drops its buy half - the phone has no rail to spell BUY
  out, and a buy link nobody can read is not a buy link, so it goes rather than
  shrinks. The docs page still carries the launchpad link.
*/
@media (max-width: 400px) {
  /* The wallet button is the widest thing in the row and the only one whose
     padding can go without losing a word. */
  .topbar-actions .btn {
    padding-left: 8px;
    padding-right: 8px;
  }
}

@media (max-width: 460px) {
  .tokpill {
    display: none;
  }
  .hide-narrow {
    display: none;
  }
}

@media (max-width: 720px) {
  /* Brand and actions share the top row, search and the live chip take the one
     below. Named areas rather than wrapping, so the order cannot depend on
     source order. */
  .topbar-inner {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      'brand actions'
      'search chip';
    height: auto;
    row-gap: 8px;
    column-gap: 8px;
    padding: 10px 16px 12px;
  }
  .topbar-inner .brand {
    grid-area: brand;
    min-width: 0;
    gap: 6px;
  }
  .brand-word {
    font-size: 13px;
    letter-spacing: 0.18em;
  }
  .brand .net-tag {
    display: none;
  }
  .topbar-inner .topbar-actions {
    grid-area: actions;
  }
  .topbar-inner .g-search {
    grid-area: search;
    max-width: none;
    min-width: 0;
  }
  .topbar-inner .live-chip {
    grid-area: chip;
    justify-self: end;
  }
  .header-stats {
    display: none;
  }
  /* 44px tap targets on touch: the two topbar controls, the segmented control. */
  .how-btn {
    width: 44px;
    height: 44px;
    padding: 0;
    justify-content: center;
  }
  .topbar-actions .btn {
    min-height: 44px;
  }
  .seg-btn {
    min-height: 44px;
  }
  .tokpill-word {
    display: none;
  }
  .tokpill-buy {
    display: none;
  }
  .tokpill-ca {
    border-left: 0;
    color: var(--green);
    font-weight: 700;
  }
  .tokpill-addr {
    display: none;
  }
  .tokpill-ca-word {
    display: inline;
  }

  /* The rail goes; the five-tab bar takes over. */
  .siderail {
    display: none;
  }
  .tabbar {
    display: flex;
  }

  /* Sheets dock to the bottom on a phone and cap their height so the close
     button is always within thumb reach. */
  .sheet-backdrop {
    align-items: flex-end;
  }
  .sheet {
    width: 100%;
    max-height: 88vh;
    border-left: 0;
    border-top: 1px solid var(--line-2);
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    padding-bottom: env(safe-area-inset-bottom, 0px);
    animation-name: sheet-in-up;
  }

  /* Stakes folds into Pools through the segmented control. */
  .seg {
    display: flex;
  }
  .pools-seg {
    margin-bottom: 14px;
  }
  .pools-fold[data-view='stakes'] {
    display: block;
  }
  .pools-fold[data-view='stakes'] ~ .explore-page,
  .pools-fold[data-view='stakes'] ~ #explore {
    display: none;
  }

  /*
    Clearance for the bottom tab bar, plus a real gap.

    TRAP: padding-bottom exactly equal to the bar height leaves zero room, so at
    full scroll the last panel's border sits under the bar. It also replaces
    .shell-main's own 4rem bottom padding, which made the page end TIGHTER than
    it did on desktop. The bar is 58px; this reserves that plus a gap.
  */
  .app-rail-shift {
    padding-left: 0;
    padding-bottom: calc(58px + env(safe-area-inset-bottom, 0px) + 2rem);
  }
  body.is-landing .shell-main {
    padding-bottom: 0;
  }
  .shell-main {
    width: min(1280px, 100% - 1.5rem);
  }
  .mspot--hero .mspot-sym {
    font-size: 32px;
  }
  .mspot-hero-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  /* Drop the two least load-bearing columns rather than letting the table
     scroll sideways off the page. */
  .ftable :is(th, td):nth-child(4),
  .ftable :is(th, td):nth-child(5) {
    display: none;
  }
  /* TRAP: table-layout:fixed + nowrap overprints, it never wraps. Five columns
     at 320px left the 24h cell 64px, and "+909.8K%" painted into the age
     column. The sparkline carries the least, so it goes too, and the four
     that remain get widths sized to their longest real value at 11px. */
  .explore-grid .ftable :is(th, td):nth-child(7) {
    display: none;
  }
  .explore-grid .ftable :is(th, td):nth-child(2) {
    width: 22%;
  }
  .explore-grid .ftable :is(th, td):nth-child(3) {
    width: 26%;
  }
  .explore-grid .ftable :is(th, td):nth-child(6) {
    width: 16%;
  }
  .explore-grid .ftable :is(thead th, tbody td) {
    font-size: 11px;
  }
  .explore-grid .ftable :is(thead th, tbody td):first-child {
    padding-left: 10px;
  }
}

@media (max-width: 430px) {
  /* The token name is the first thing an explorer can do without; the symbol
     is the identity and at 320px it was truncating to two letters. */
  .explore-grid .ftable .tok-name {
    display: none;
  }
}

@media (max-width: 430px) {
  /* The block number is the first thing to go from the chip: the state word
     carries the meaning and the number is in the footer of every page. */
  .live-chip .chip-block {
    display: none;
  }
}

/* ================================================================ /stakes */
/* Appended for the Stakes surface. Everything above is untouched.          */

.stakes-page {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
/* The APR caveat is prose, not a table cell, so it gets a measure. */
.stakes-lede {
  max-width: 86ch;
}

/* The four totals above the table. One bordered block with hairlines between
   the cells rather than four floating cards, so it reads as a single strip and
   does not compete with the panel below it. auto-fit lets it fold to two rows
   on a narrow screen without a second breakpoint. */
.stats-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  background-color: var(--panel);
  background-image: var(--card-wash);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.stats-strip .cell {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 12px 16px;
  border-right: 1px solid var(--line);
}
.stats-strip .cell:last-child {
  border-right: 0;
}
/* How much of the index a total actually covers, when it is not all of it. */
.stats-strip .cell .tnote {
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.03em;
  color: var(--ink-3);
}

/* .ftable is table-layout:fixed, so eight equal columns would truncate the
   pair symbols. The two ends are pinned and the numeric middle divides up
   whatever is left. */
.stakes-table th:first-child,
.stakes-table td:first-child {
  width: 26%;
}
.stakes-table th:last-child,
.stakes-table td:last-child {
  width: 104px;
}
.cell-tier {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 7px;
}

/* The pair's two discs overlap by a third, ringed in the panel colour so the
   back one reads as behind rather than merged. */
.pair-art {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
}
.pair-art .tok-ico + .tok-ico {
  margin-left: -8px;
  box-shadow: 0 0 0 2px var(--panel);
}

.cell-apr {
  color: var(--green);
  font-weight: 700;
}
/* An APR we cannot measure is an em dash, and an em dash should not be green. */
.cell-apr.unknown {
  color: var(--ink-3);
  font-weight: 400;
}

.provide-link {
  display: inline-block;
  font-family: var(--f-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
  border: 1px solid var(--line-2);
  border-radius: var(--r-full);
  padding: 4px 11px;
  transition:
    background var(--dur) var(--ease),
    border-color var(--dur) var(--ease),
    color var(--dur) var(--ease);
}
.provide-link:hover {
  text-decoration: none;
  background: var(--green);
  border-color: var(--green);
  color: var(--on-green);
}

@media (max-width: 720px) {
  /* The title and the two filter groups cannot share a line at this width. */
  .stakes-page .panel-head {
    flex-wrap: wrap;
  }
  .stakes-page .table-toolbar {
    margin-left: 0;
    width: 100%;
  }

  /* TRAP: .ftable is table-layout:fixed with white-space:nowrap, so a column
     that runs out of room does not wrap or scroll - it silently overprints its
     neighbour. Eight columns will never fit 350px, so four of them go: tier and
     the two raw fee figures are the detail behind Fee APR, and Provide is
     redundant because the pair cell already links to the same pool page. The
     four that remain get explicit widths wide enough for their longest real
     value ("$149.46K", "181.18K%"). */
  .stakes-table :is(th, td):nth-child(2),
  .stakes-table :is(th, td):nth-child(4),
  .stakes-table :is(th, td):nth-child(5),
  .stakes-table :is(th, td):nth-child(8) {
    display: none;
  }
  .stakes-table th:first-child,
  .stakes-table td:first-child {
    width: 42%;
    padding-left: 12px;
  }
  .stakes-table :is(th, td):nth-child(3) {
    width: 24%;
  }
  .stakes-table :is(th, td):nth-child(6) {
    width: 22%;
  }
  .stakes-table :is(th, td):nth-child(7) {
    width: 12%;
  }
  .stakes-table :is(thead th, tbody td) {
    padding-left: 8px;
    padding-right: 8px;
    font-size: 11px;
  }
  /* The pair needs every pixel for the symbols; the long token name is the
     first thing an LP can do without. */
  .stakes-table .tok-name {
    display: none;
  }
}

/* Between the phone table above and the full desktop table the eight columns
   get 66px each at 768 (rail + panel + 26% pair + 104px Provide leave 400px
   for six), and "LIQUIDITY" needs 80. Tier is the detail behind Fee APR and
   volume is the input to the fees column, so they are the two that fold;
   the four left get 100px at 768 and 91px at 721. */
@media (min-width: 721px) and (max-width: 1000px) {
  .stakes-table :is(th, td):nth-child(2),
  .stakes-table :is(th, td):nth-child(4) {
    display: none;
  }
}

@media (max-width: 400px) {
  /* TRAP: a nowrap <th> has no overflow:hidden, so a header that runs out of
     room paints into the next cell while the two cell boxes never overlap -
     the box check stays green. At 320px the 24% column is 71px and
     "LIQUIDITY" at 10.5px with .14em tracking needs 81; "FEE APR" was 76 in
     65. Tighter tracking and a smaller size bring the longest header under
     its column at 320 and 360. */
  .stakes-table thead th {
    font-size: 9.5px;
    letter-spacing: 0.06em;
    padding-left: 6px;
    padding-right: 6px;
  }
}

/* A trailing APR from a near-empty pool is noise wearing a yield's clothes.
   It still renders - hiding real data is worse - but in the muted tier with a
   marker, so it cannot be mistaken for the headline rates above it. */
.cell-apr.thin {
  color: var(--ink-2);
}
/* Scoped to nothing in particular on purpose: the same marker appears in the
   lede, where it is the legend for this column. Both have to look alike or the
   sentence explaining the asterisk does not visibly refer to the asterisk. */
.thin-flag {
  color: var(--warn);
  margin-left: 2px;
  font-weight: 700;
}

/* ------------------------------------------------ $PONTIMUS in the hero band */

/*
  The token's own card sits beside the movers. It is a div rather than an anchor
  because it carries its own outbound links, and an anchor inside an anchor is
  not something a browser will render the way it reads in the source.
*/
.mspot--own {
  display: flex;
  flex-direction: column;
  background-image:
    radial-gradient(circle at 14% 0%, rgba(103, 213, 75, 0.16), rgba(0, 0, 0, 0) 52%),
    linear-gradient(145deg, #0b1a0f, #08120b 64%);
  box-shadow:
    inset 0 1px 0 rgba(135, 233, 94, 0.14),
    0 0 0 1px rgba(103, 213, 75, 0.08);
}
.mspot-own-link {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1 1 auto;
  color: inherit;
  min-width: 0;
}
.mspot-own-link:hover {
  text-decoration: none;
}
.mspot-links {
  display: flex;
  gap: 8px;
  margin-top: 10px;
}
.mspot-out {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--green-line);
  border-radius: var(--r-sm);
  color: var(--green);
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: var(--track);
  text-transform: uppercase;
  padding: 7px 10px;
  min-height: 34px;
}
.mspot-out:hover {
  background: var(--green-dim);
  text-decoration: none;
}
@media (max-width: 720px) {
  /* 44px targets once a finger is doing the tapping. */
  .mspot-out {
    min-height: 44px;
    padding: 0 14px;
  }
}

/* -------------------------------------------- the position watcher on /positions */

/* Loud when a range has stopped earning, quiet when nothing is wrong. */
.pos-watch {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: 1rem;
}
.pos-watch svg {
  flex: 0 0 auto;
  margin-top: 3px;
}
.pos-watch.ok {
  color: var(--ink-2);
  border-color: var(--line-2);
}
.pos-rebuild {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
@media (max-width: 720px) {
  .pos-rebuild .btn {
    min-height: 44px;
  }
}
