/* ==========================================================================
   WTH — Live dashboard (local only, not deployed)
   Leans on styles.css for tokens, fonts and the ambient background.
   ========================================================================== */

/* pure black, no ambient washes or dots — the data reads better flat */
body { background: #000; }
body::before { display: none; }

/* desktop reads 10% bigger; phones keep their own tuned sizes */
@media (min-width: 901px) {
  body { zoom: 1.1; }
}

/* ── signs of life ─────────────────────────────────────────────────────── */

/* a very slow pink drift behind the panels — felt more than seen */
body::after {
  content: ''; position: fixed; inset: -25%; z-index: -1; pointer-events: none;
  background:
    radial-gradient(38% 34% at 22% 28%, color-mix(in srgb, var(--pink) 8%, transparent), transparent 70%),
    radial-gradient(34% 30% at 78% 68%, color-mix(in srgb, var(--pink) 9%, transparent), transparent 70%),
    radial-gradient(40% 30% at 55% 96%, color-mix(in srgb, var(--pink) 6%, transparent), transparent 72%);
  animation: bgdrift 52s ease-in-out infinite;
}
@keyframes bgdrift {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); opacity: .8; }
  50%      { transform: translate3d(2.5%, -2%, 0) scale(1.07); opacity: 1; }
}

/* the refresh heartbeat: fills over the twenty seconds between snapshots */
.beat {
  position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 70;
  pointer-events: none;
}
.beat i {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--pink) 70%, transparent), var(--pink));
}
.beat.run i { animation: beatfill 20s linear 1 forwards; }
@keyframes beatfill { from { width: 0; } to { width: 100%; } }

/* a payout landing breathes light along the top edge of the page */
.edge {
  position: fixed; top: 0; left: 0; right: 0; height: 130px; z-index: 65;
  pointer-events: none; opacity: 0;
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--pink) 20%, transparent), transparent 72%);
}
.edge.on { animation: edgeglow 1.8s var(--ease) 1; }
@keyframes edgeglow {
  0%   { opacity: 0; }
  18%  { opacity: 1; }
  100% { opacity: 0; }
}

/* ── the circuit: etched routes, travelling sparks, pool nodes ─────────────
   Sits with the pink drift behind everything; the solid cards mask it, so
   it lives only in the dark gaps the layout breathes through. */
.circuit {
  position: fixed; inset: 0; z-index: -1;
  pointer-events: none;
}
.circuit svg { width: 100%; height: 100%; }
/* a fine dot matrix under everything: the texture the glass gets to blur */
.circuit::before {
  content: ''; position: absolute; inset: 0;
  background-image: radial-gradient(circle,
    color-mix(in srgb, var(--pink) 9%, transparent) 1px, transparent 1.5px);
  background-size: 26px 26px;
  -webkit-mask-image: radial-gradient(120% 90% at 50% 40%, #000 30%, transparent 78%);
          mask-image: radial-gradient(120% 90% at 50% 40%, #000 30%, transparent 78%);
}
/* etched traces — visible the way a hairline engraving is visible;
   alternating depth so the board reads dimensional, not flat */
.circuit .tr path {
  fill: none;
  stroke: color-mix(in srgb, var(--pink) 24%, transparent);
  stroke-width: 1;
}
.circuit .tr path:nth-child(even) {
  stroke: color-mix(in srgb, var(--pink) 15%, transparent);
}
/* a spark is the lit tail of an invisible copy of the route. One life per
   cycle: it runs the route (0–82% of the timeline), slides into the node,
   vanishes, and rests dark until the next cycle — no teleporting back */
.circuit .sp path {
  fill: none;
  stroke: color-mix(in srgb, var(--pink) 75%, #fff);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-dasharray: .012 .988;
  stroke-dashoffset: 1;
  filter: drop-shadow(0 0 4px color-mix(in srgb, var(--pink) 60%, transparent));
  animation: spark-travel var(--t, 17s) linear infinite;
  animation-delay: var(--dl, 0s);
}
@keyframes spark-travel {
  0%     { stroke-dashoffset: 1; opacity: 1; }
  82%    { stroke-dashoffset: 0; opacity: 1; }   /* contact */
  82.6%  { stroke-dashoffset: 0; opacity: 0; }   /* absorbed by the node */
  99.4%  { stroke-dashoffset: 1; opacity: 0; }   /* rewound in the dark */
  100%   { stroke-dashoffset: 1; opacity: 1; }
}
/* nodes rest dim; the five at spark-route ends share their spark's clock
   and ignite AT contact — light strictly means a spark just arrived */
.circuit .nd circle {
  fill: var(--pink);
  opacity: .24;
  transform-box: fill-box; transform-origin: center;
}
.circuit .nd .hit {
  animation: node-hit var(--t, 17s) linear infinite;
  animation-delay: var(--dl, 0s);
}
@keyframes node-hit {
  0%, 81.5% { opacity: .24; transform: scale(1);
              filter: drop-shadow(0 0 0 transparent); }
  83.5%     { opacity: 1; transform: scale(2.1);
              filter: drop-shadow(0 0 7px color-mix(in srgb, var(--pink) 70%, transparent)); }
  90%, 100% { opacity: .24; transform: scale(1);
              filter: drop-shadow(0 0 0 transparent); }
}

@media (prefers-reduced-motion: reduce) {
  body::after, .beat.run i, .edge.on { animation: none; }
  .circuit .sp { display: none; }   /* a frozen spark reads as a dead pixel */
  .circuit .nd .hit { animation: none; }
}

/* ── frame ─────────────────────────────────────────────────────────────── */

.dhead {
  position: relative;   /* the sync status centres against this box */
  display: flex; align-items: center; gap: var(--s3);
  max-width: 1240px; margin: 0 auto;
  padding: var(--s3) var(--s4);
}
.dback {
  flex: none;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border: 1px solid var(--rule-2); border-radius: 50%;
  color: var(--ink-2); text-decoration: none;
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.dback:hover { border-color: var(--pink); color: var(--pink); }
.dback svg {
  width: 15px; height: 15px;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.dtitle { display: flex; flex-direction: column; gap: 2px; }
.dt-label { font-size: .78rem; font-weight: 700; letter-spacing: .18em; color: var(--ink); }
.dt-sub { font-size: .58rem; letter-spacing: .14em; color: var(--ink-3); }
.dstatus {
  /* centred in the free run between the title and the header buttons */
  margin-left: auto; margin-right: auto;
  display: flex; align-items: center; gap: .5rem;
  font-size: .62rem; letter-spacing: .1em; color: var(--ink-3);
}
/* wide screens: dead centre of the header. Narrower than this the true
   centre runs into the title, so the free-run centring above takes over */
@media (min-width: 980px) {
  .dstatus {
    position: absolute; left: 50%; top: 50%;
    transform: translate(-50%, -50%);
    margin: 0;
  }
  /* The status no longer holds the flex row open, so the trailing group has
     to push itself right. Only its FIRST visible member may take the free
     space — give every button `auto` and they share it, opening a gap in
     the middle of the group. Either RECORDS or CALCULATOR can be hidden, so
     the auto walks down the row to whoever is showing. */
  .dhead > .byot { margin-left: auto; }
  .dhead > .trec:not([hidden]) { margin-left: auto; }
  .dhead > .trec:not([hidden]) ~ .trec,
  .dhead > .trec:not([hidden]) ~ .byot { margin-left: 0; }
}
/* (livepulse stays: the payout bar's dot still breathes with it) */
@keyframes livepulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--pink) 55%, transparent); }
  60%      { box-shadow: 0 0 0 7px transparent; }
}

.dash {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 var(--s4) var(--s6);
  display: flex; flex-direction: column; gap: var(--s3);
}

/* ── cards ─────────────────────────────────────────────────────────────── */

/* One lighting model for the whole page, graded by rank: the headline
   total wears the warmest hairline (pink 22%), its two legs 14%, and the
   working cards here catch the faintest trace of the same light (7%) with
   the same specular line inside the top edge. Without this bottom step the
   strip read as jewellery on old furniture — the grade makes it one room. */
.dcard {
  background: var(--paper-2);
  border: 1px solid color-mix(in srgb, var(--pink) 7%, var(--rule));
  border-radius: var(--r-lg);
  padding: var(--s3);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .04);
}

/* liquid glass, desktop only: the surfaces go translucent and frost what
   lives behind them — the circuit shimmers through every card. Phones keep
   solid paper: backdrop-filter across a page of cards is a battery bill. */
@media (min-width: 901px) {
  .dcard, .dstat, .dpool, .pulse {
    background: color-mix(in srgb, var(--paper-2) 65%, transparent);
    -webkit-backdrop-filter: blur(16px) saturate(1.15);
            backdrop-filter: blur(16px) saturate(1.15);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06);
  }
  .pulse { background: color-mix(in srgb, var(--pink) 9%, rgba(13, 9, 12, .58)); }
  .pmodal-card {
    background: color-mix(in srgb, var(--paper-2) 82%, transparent);
    -webkit-backdrop-filter: blur(22px) saturate(1.2);
            backdrop-filter: blur(22px) saturate(1.2);
  }
}
.dcard-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s2);
  margin-bottom: var(--s2);
}
.dcard-head h2 {
  font-family: var(--display);
  font-size: 1.05rem; font-weight: 600; letter-spacing: -.01em;
  margin: 0;
  white-space: nowrap;   /* a card title never breaks in two */
}
.hint { font-size: .58rem; letter-spacing: .1em; color: var(--ink-3); text-align: right; }

/* the copyable hook address inside a hint — deliberately quiet */
.hook-copy {
  background: none; border: 0; padding: 0;
  font: inherit; letter-spacing: inherit; color: inherit;
  border-bottom: 1px dotted var(--rule-2);
  cursor: pointer;
  transition: color var(--dur) var(--ease), border-bottom-color var(--dur) var(--ease);
}
.hook-copy:hover { color: var(--pink); border-bottom-color: var(--pink); }
.hook-copy.ok { color: var(--berry); border-bottom-color: transparent; }

.loading, .err { padding: var(--s2) 0; font-size: .66rem; letter-spacing: .1em; color: var(--ink-3); }
.err { color: var(--berry); }

/* ── live pulse ────────────────────────────────────────────────────────── */

.pulse {
  display: flex; align-items: stretch; flex-wrap: wrap;
  background: color-mix(in srgb, var(--pink) 10%, var(--paper-2));
  border: 1px solid color-mix(in srgb, var(--pink) 28%, var(--rule));
  border-radius: 100px;
  font-size: .66rem; color: var(--ink-2);
  overflow: hidden;
}
.pulse[hidden] { display: none; }
.pulse-seg {
  flex: 1; min-width: 0;
  display: flex; align-items: baseline; justify-content: center; gap: .7rem;
  padding: .55rem .9rem;
  color: inherit; text-decoration: none;
  transition: background var(--dur) var(--ease);
}
.pulse-seg .pulse-dot, .pulse-seg .pulse-lx { align-self: center; }
/* the line reads as one sentence, centred — no gap between text and age */
.pulse-seg .pulse-body { flex: 0 1 auto; }
.pulse-seg[hidden] { display: none; }
.pulse-dot {
  flex: none; width: 7px; height: 7px; border-radius: 50%;
  background: var(--pink);
  animation: livepulse 2s var(--ease) infinite;
}
.pulse-lead { flex: none; font-size: .52rem; letter-spacing: .16em; color: var(--ink-3); font-weight: 700; }
.pulse-body { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pulse-body b { color: var(--ink); font-weight: 700; }
.pulse-body b.amt { color: var(--pink); }
.pulse-lp { color: var(--ink-3); font-size: .92em; }
.pulse-age { flex: none; font-size: .56rem; letter-spacing: .1em; color: var(--ink-3); }
.pulse-lx { flex: none; font-size: .6rem; color: var(--ink-3); }
@media (hover: hover) and (pointer: fine) {
  .pulse-seg:hover { background: color-mix(in srgb, var(--pink) 8%, transparent); }
  .pulse-seg:hover .pulse-lx { color: var(--pink); }
}

/* a genuinely new payout slides in and glows once */
.pulse-seg.fresh { animation: pulsein .5s var(--ease) 1, pulseglow 2.2s var(--ease) 1; }
@keyframes pulsein {
  from { transform: translateY(-6px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
@keyframes pulseglow {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--pink) 45%, transparent); border-color: var(--pink); }
  70%  { box-shadow: 0 0 0 10px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* ── headline stats ────────────────────────────────────────────────────── */

.dstats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--s2);
}
.dstat {
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  padding: 1.05rem 1rem;
  display: flex; flex-direction: column; gap: .38rem;
  align-items: center; text-align: center;   /* the strip reads centred */
  justify-content: center;
}
.dstat .k {
  font-size: .63rem; font-weight: 500; letter-spacing: .15em;
  color: color-mix(in srgb, var(--pink) 12%, var(--ink-2));
}
.dstat .v { font-size: 1.28rem; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.dstat .v.up { color: var(--berry); }
/* a live change: the tile lights up softly while the number rolls in */
.dstat .v.roll { color: var(--berry); }
.dstat.live { animation: statlive 1.9s var(--ease) 1; }
@keyframes statlive {
  0%   { border-color: color-mix(in srgb, var(--pink) 60%, var(--rule));
         box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06),
                     0 0 16px 0 color-mix(in srgb, var(--pink) 22%, transparent),
                     inset 0 0 14px 0 color-mix(in srgb, var(--pink) 7%, transparent); }
  100% { border-color: var(--rule);
         box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06); }
}
@media (prefers-reduced-motion: reduce) {
  .dstat.live { animation: none; }
}

/* one tile, two stacked amounts (pooled WTH / pooled WETH), each with its
   live USD equivalent on the right */
.dstat .v.v-split { display: flex; flex-direction: column; gap: .3rem; font-size: .74rem; }
.v-split .sr { display: flex; align-items: baseline; gap: .32rem; white-space: nowrap; }
.v-split .sk { flex: 1; font-size: .48rem; letter-spacing: .1em; color: var(--ink-3); font-weight: 500; }
.v-split .su { color: var(--ink-3); font-weight: 500; font-size: .66em; text-align: right; }

/* ── divergence hero ───────────────────────────────────────────────────── */

.hero-div { padding-bottom: var(--s4); }
.div-big {
  display: flex; align-items: baseline; gap: var(--s3);
  margin: var(--s2) 0 var(--s4);
  flex-wrap: wrap;
}
.div-big > .mono:first-child {
  font-size: clamp(2.6rem, 7vw, 4.4rem);
  font-weight: 700;
  color: var(--pink);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.div-note { font-size: .6rem; letter-spacing: .14em; color: var(--ink-3); }

.div-scale {
  position: relative;
  height: 96px;
  border-top: 1px dashed var(--rule-2);
  border-bottom: 1px dashed var(--rule-2);
  margin: 1.4rem var(--s2) 0;
}
.div-band {
  position: absolute; top: 0; bottom: 0;
  background: color-mix(in srgb, var(--pink) 9%, transparent);
  border-left: 1px solid var(--pink);
  border-right: 1px solid var(--pink);
  transition: left .8s var(--ease), width .8s var(--ease);
}
.div-dot {
  position: absolute; top: 50%;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--pink);
  border: 2px solid var(--paper);
  transform: translate(-50%, -50%);
  transition: left .8s var(--ease);
}
.div-dot .tag {
  position: absolute; left: 50%; transform: translateX(-50%);
  white-space: nowrap;
  font-size: .56rem; letter-spacing: .08em; color: var(--ink-2);
}
/* one lane per label: alternating above/below, stepping further out */
.div-dot.lane-0 .tag { top: -26px; }
.div-dot.lane-1 .tag { bottom: -26px; }
.div-dot.lane-2 .tag { top: -46px; }
.div-dot.lane-3 .tag { bottom: -46px; }
.div-dot.lane-4 .tag { top: -66px; }
.div-dot.lane-5 .tag { bottom: -66px; }
.div-dot .tag b { color: var(--ink); font-weight: 700; }

/* when the deep lanes are in use, give the scale more breathing room */
.hero-div.dense .div-scale { margin-top: 4.6rem; }
.hero-div.dense .div-legend { margin-top: 4.4rem; }

.div-legend {
  display: flex; justify-content: space-between;
  margin: 2.6rem var(--s2) 0;
  font-size: .58rem; letter-spacing: .1em; color: var(--ink-3);
}

/* ── arbitrage turnover: the climb ─────────────────────────────────────── */

.engine { padding-bottom: var(--s2); }
.eng-top {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--s3); flex-wrap: wrap;
  margin-bottom: var(--s2);
}
/* the card title reads like every other card's, with the range trailing quietly */
.eng-h2 {
  font-family: var(--display);
  font-size: 1.05rem; font-weight: 600; letter-spacing: -.01em;
  color: var(--ink); margin: 0;
}
.eng-h2 span {
  font-size: .54rem; font-weight: 400; letter-spacing: .16em;
  color: var(--ink-3); vertical-align: middle; margin-left: .4em;
}
.eng-big {
  font-size: clamp(1.8rem, 4vw, 2.6rem); font-weight: 700; line-height: 1.1;
  color: var(--ink); font-variant-numeric: tabular-nums;
  margin-top: .2rem;
}
.eng-sub { font-size: .68rem; font-weight: 700; color: var(--berry); margin-top: .15rem; }
.eng-side { display: flex; flex-direction: column; align-items: flex-end; gap: .5rem; }
.eng-range { display: flex; gap: .3rem; }
.eng-range .tf { padding: .35em .75em; font-size: .54rem; }
.eng-note { font-size: .58rem; letter-spacing: .08em; color: var(--ink-3); text-align: right; }

.eng-chart { position: relative; height: 240px; }
.eng-chart svg { width: 100%; height: 100%; display: block; overflow: visible; }
.eng-fill { fill: url(#engFade); }
.eng-line {
  fill: none;
  stroke: var(--pink);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;   /* stays 1.5px through the stretch */
  stroke-linejoin: round; stroke-linecap: round;
  filter: drop-shadow(0 0 5px color-mix(in srgb, var(--pink) 45%, transparent));
}
/* two faint rules, labels riding on them — no axes, no frame, no legend */
.eng-rules { position: absolute; inset: 0; pointer-events: none; }
.eng-rule {
  position: absolute; left: 0; right: 0;
  border-top: 1px dashed var(--rule);
}
.eng-rule span {
  position: absolute; right: 0; top: -1.05em;
  font-size: .52rem; letter-spacing: .1em; color: var(--ink-3);
}
/* "now" — the head of the curve, breathing like a pool node */
.eng-now {
  position: absolute; width: 9px; height: 9px; border-radius: 50%;
  background: var(--pink);
  transform: translate(-50%, -50%);
  box-shadow: 0 0 10px color-mix(in srgb, var(--pink) 70%, transparent);
  animation: livepulse 2.6s var(--ease) infinite;
}
.eng-now[hidden] { display: none; }
.eng-now.tick { animation: engtick 1.5s var(--ease) 1, livepulse 2.6s var(--ease) infinite 1.5s; }
@keyframes engtick {
  0%   { transform: translate(-50%, -50%) scale(2.4); box-shadow: 0 0 20px var(--pink); }
  100% { transform: translate(-50%, -50%) scale(1); }
}
/* its own row under the chart — never overlapping the card's bottom edge */
.eng-axis {
  position: relative; height: 1.2em;
  margin-top: .55rem;
  font-size: .52rem; letter-spacing: .12em; color: var(--ink-3);
}
.eng-axis span {
  position: absolute; top: 0;
  transform: translateX(-50%);
  white-space: nowrap;
}
.eng-axis .edge-l { left: 0; transform: none; }
.eng-axis .edge-r { right: 0; left: auto; transform: none; }
@media (max-width: 900px) {
  /* a phone fits far fewer stamps — thin them to every other one */
  .eng-axis span:not(.edge-l):not(.edge-r):nth-of-type(even) { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .eng-now, .eng-now.tick { animation: none; }
}

/* ── divergence, centred like everything above it ──────────────────────── */
/* the title takes the true centre of the card; the LIQUID tag steps out of
   the flow and sits on the right edge, so it cannot push the title off */
.hero-div .dcard-head { position: relative; justify-content: center; }
.hero-div .div-filter {
  position: absolute; right: 0; top: 50%;
  transform: translateY(-50%);
  margin: 0;
}
/* the number owns its line; the caption sits centred beneath it */
.div-big {
  flex-direction: column; align-items: center; justify-content: center;
  gap: .5rem; text-align: center;
}

/* ── pool cards ────────────────────────────────────────────────────────── */

.pool-bar {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  margin-bottom: calc(var(--s2) * -0.4);
}
.pool-filter { display: flex; gap: .35rem; }
.pool-filter[hidden] { display: none; }   /* `hidden` must beat the flex above */
.pf, .df, .tf {
  font-size: .58rem; letter-spacing: .12em; font-weight: 700;
  padding: .45em .9em;
  background: transparent;
  border: 1px solid var(--rule-2); border-radius: 100px;
  color: var(--ink-2); cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.pf.on, .df.on, .tf.on { background: var(--pink); border-color: var(--pink); color: var(--on-pink); }
/* the divergence panel only ever shows liquid pools — a label, not a choice */
.dtag {
  font-size: .58rem; letter-spacing: .12em; font-weight: 700;
  padding: .45em .9em;
  background: var(--pink); border: 1px solid var(--pink); border-radius: 100px;
  color: var(--on-pink);
}
.div-filter { margin-left: var(--s2); margin-right: auto; }
/* stands in for the ALL / HOOKED switch when there is nothing to filter */
.ptag {
  font-size: .56rem; letter-spacing: .12em; font-weight: 700;
  padding: .45em .9em;
  border: 1px solid color-mix(in srgb, var(--pink) 40%, transparent);
  border-radius: 100px;
  color: var(--pink);
}
.dpool-side { display: flex; align-items: center; gap: .45rem; }
.dpool-side .badge { justify-self: auto; font-size: .5rem; }

.dpools {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--s2);
}
.dpool {
  display: block;
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  padding: 1rem;
  color: inherit; text-decoration: none;
  transition: border-color var(--dur) var(--ease);
}
.dpool-lx { color: var(--ink-3); font-size: .68rem; margin-left: .4rem; }
@media (hover: hover) and (pointer: fine) {
  a.dpool:hover { border-color: color-mix(in srgb, var(--pink) 45%, var(--rule)); }
  a.dpool:hover .dpool-lx { color: var(--pink); }
}
.dpool-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: .6rem; }
.dpool-pair { font-family: var(--display); font-weight: 600; font-size: .92rem; }
.dpool-chg { font-size: .62rem; font-weight: 700; }
.dpool-chg.pos { color: var(--berry); }
.dpool-chg.neg { color: var(--ink-3); }
.dpool-price { font-size: 1.5rem; font-weight: 700; font-variant-numeric: tabular-nums; margin-bottom: .7rem; }
.dpool-rows { display: flex; flex-direction: column; }
.dpool-row {
  display: flex; justify-content: space-between; gap: var(--s2);
  padding: .34rem 0;
  border-top: 1px solid var(--rule);
  font-size: .68rem; color: var(--ink-2);
  font-family: var(--display); font-weight: 500;
}
.dpool-row .mono { color: var(--ink); font-weight: 700; font-size: .7rem; }

/* ── connected pools ───────────────────────────────────────────────────── */

.conn-sub {
  font-size: .56rem; letter-spacing: .14em; color: var(--ink-3);
  margin: var(--s2) 0 .3rem;
}
.conn-sub:first-child { margin-top: 0; }
.conn-row {
  display: grid;
  grid-template-columns: minmax(120px, 1.2fr) 56px minmax(90px, .9fr) minmax(80px, .8fr) minmax(150px, 1.2fr) 84px;
  gap: .6rem;
  align-items: center;
  padding: .5rem 0;
  border-top: 1px solid var(--rule);
  font-size: .7rem;
}
.conn-row .cpair { color: var(--ink); font-weight: 700; }
/* grouped third-party rows: the donation count sits centred between
   the pool count and the distributed total */
.conn-row .cmid { grid-column: 3 / 5; text-align: center; }
.conn-row .cfee { color: var(--ink-3); font-size: .62rem; }
.conn-row .csince { color: var(--ink-3); font-size: .62rem; }
.conn-row .cvol { color: var(--ink-2); font-size: .64rem; }
.conn-row .cdon { color: var(--ink-2); font-size: .64rem; }
.badge {
  justify-self: end;
  font-size: .54rem; letter-spacing: .1em; font-weight: 700;
  padding: .3em .55em; border-radius: 3px;
}
.badge.hook { background: var(--pink); color: var(--on-pink); }
.badge.nohook { background: var(--paper-3); color: var(--ink-3); border: 1px solid var(--rule-2); }
.conn-empty {
  padding: .6rem 0;
  font-size: .64rem; letter-spacing: .04em; line-height: 1.6;
  color: var(--ink-3);
}

/* grouped token rows open a pool list — the whole row is the target */
.tprow {
  cursor: pointer;
  border-radius: var(--r);
  transition: background var(--dur) var(--ease);
}
.tprow:focus-visible { outline: 1px solid var(--pink); outline-offset: -1px; }
.cpill {
  display: inline-flex; align-items: center; justify-content: center; gap: .35em;
  min-width: 8.2em;                      /* "1 pool" and "4 pools" match */
  padding: .26em .7em;
  border: 1px solid var(--rule-2); border-radius: 100px;
  font-size: .56rem; letter-spacing: .1em; color: var(--ink-2);
  white-space: nowrap;
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease),
              background var(--dur) var(--ease);
}
.cpill svg {
  width: 9px; height: 9px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 2.4;
  stroke-linecap: round; stroke-linejoin: round;
  transition: transform var(--dur) var(--ease);
}
/* the token name links out to its Dexscreener page */
.ctok { color: var(--ink); text-decoration: none; }
.ctok-lx {
  margin-left: .4em; font-size: .58em; color: var(--ink-3);
  transition: color var(--dur) var(--ease);
}
/* name and pool list are separate targets: each lights only when hovered */
@media (hover: hover) and (pointer: fine) {
  .tprow:hover { background: color-mix(in srgb, var(--pink) 5%, transparent); }
  .ctok:hover, .ctok:hover .ctok-lx { color: var(--pink); }
  .cpill:hover {
    border-color: color-mix(in srgb, var(--pink) 55%, transparent);
    background: var(--pink-soft); color: var(--pink);
  }
  .cpill:hover svg { transform: translateY(1px); }
}

/* ── pool list modal ───────────────────────────────────────────────────── */

.pmodal {
  /* above the live map (z 60): the stone's chips open this list too */
  position: fixed; inset: 0; z-index: 80;
  display: grid; place-items: center;
  padding: var(--s3);
  background: color-mix(in srgb, #000 74%, transparent);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  animation: pmfade .16s var(--ease);
}
.pmodal[hidden] { display: none; }
@keyframes pmfade { from { opacity: 0; } }
.pmodal-card {
  width: min(560px, 100%);
  max-height: min(70vh, 560px);
  display: flex; flex-direction: column;
  background: var(--paper-2);
  border: 1px solid color-mix(in srgb, var(--pink) 35%, var(--rule));
  border-radius: var(--r-lg);
  overflow: hidden;
}
.pmodal-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  padding: .85rem 1rem;
  border-bottom: 1px solid var(--rule);
}
#pmTitle, #pbTitle, #topTitle { font-size: .7rem; letter-spacing: .14em; font-weight: 700; color: var(--ink); }
.pmodal-x {
  font-size: .56rem; letter-spacing: .12em; font-weight: 700;
  padding: .45em .8em;
  background: transparent; border: 1px solid var(--rule-2); border-radius: 100px;
  color: var(--ink-3); cursor: pointer;
}
.pmodal-x:hover { border-color: var(--pink); color: var(--pink); }
.pmodal-list {
  flex: 1; min-height: 0; overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: var(--rule-2) transparent;
}
.pmodal-list::-webkit-scrollbar { width: 6px; }
.pmodal-list::-webkit-scrollbar-thumb { background: var(--rule-2); border-radius: 3px; }
.pm-row {
  display: grid;
  grid-template-columns: minmax(90px, 1.1fr) 54px minmax(120px, 1.3fr) auto 16px;
  gap: .6rem; align-items: center;
  padding: .7rem 1rem;
  border-top: 1px solid var(--rule);
  font-size: .68rem; color: inherit; text-decoration: none;
}
.pm-row:first-child { border-top: 0; }
.pm-pair { color: var(--ink); font-weight: 700; }
/* liquidity pulled out — quiet marker, clears itself if LPs return */
.pm-tag {
  margin-left: .5em;
  font-size: .48rem; letter-spacing: .1em; font-weight: 500;
  color: var(--ink-3);
  border: 1px solid var(--rule-2); border-radius: 3px;
  padding: .18em .4em;
  vertical-align: middle;
}
.pm-fee { color: var(--ink-3); font-size: .62rem; }
.pm-don { color: var(--ink-2); font-size: .62rem; text-align: right; }
.pm-lx { color: var(--ink-3); font-size: .62rem; text-align: right; }
/* the per-pool add-liquidity pill — its own target inside the row */
.pm-add {
  justify-self: end;
  display: inline-flex; align-items: center;
  font-size: .5rem; letter-spacing: .12em; font-weight: 700;
  padding: .34em .75em;
  border: 1px solid var(--rule-2); border-radius: 100px;
  color: var(--ink-2); text-decoration: none;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.pm-add:hover { color: var(--pink); border-color: var(--pink); }
/* an older snapshot without the pool params — placeholder keeps the grid */
.pm-add.na { opacity: .35; border-style: dashed; pointer-events: none; }
.pm-row[data-ds] { cursor: pointer; }
/* pools Dexscreener does not list: shown, but plainly not clickable */
.pm-row.off { cursor: default; }
.pm-row.off .pm-pair { color: var(--ink-2); }
.pm-row.off .pm-don, .pm-row.off .pm-fee { color: var(--ink-3); }
.pm-lx.off { opacity: .5; }
@media (hover: hover) and (pointer: fine) {
  .pm-row:hover { background: color-mix(in srgb, var(--pink) 8%, transparent); }
  .pm-row:hover .pm-lx { color: var(--pink); }
}
.pmodal-foot {
  padding: .6rem 1rem;
  border-top: 1px solid var(--rule);
  font-size: .54rem; letter-spacing: .1em; color: var(--ink-3); text-align: center;
}

/* ── record payouts (header button + popup leaderboard) ────────────────── */

/* the header button, next to HOOK YOUR TOKEN — quiet until hovered */
.trec {
  flex: none;
  display: inline-flex; align-items: center; gap: .5em;
  font-size: .58rem; letter-spacing: .12em; font-weight: 700;
  padding: .55em 1.05em;
  background: transparent;
  border: 1px solid var(--rule-2);
  border-radius: 100px;
  color: var(--ink-2); cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.trec:hover { border-color: var(--pink); color: var(--pink); }
.trec[hidden] { display: none; }
.trec svg {
  width: 11px; height: 11px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 2.4;
  stroke-linecap: round;
}
/* a new record landing while the popup is closed pings the button once */
.trec.fresh { animation: pulseglow 2.2s var(--ease) 1; }

/* the toggle row under the popup's title bar */
.top-bar {
  display: flex; gap: .35rem;
  padding: .8rem 1rem;
  border-bottom: 1px solid var(--rule);
}

.top-row {
  display: flex; align-items: center; gap: .7rem;
  padding: .55rem 1rem;
  border-top: 1px solid var(--rule);
  font-size: .68rem;
  color: inherit; text-decoration: none;
}
.top-row:first-child { border-top: 0; }
.top-row .rank {
  flex: none; width: 1.6em;
  font-size: .62rem; font-weight: 700; color: var(--ink-3);
  text-align: right; font-variant-numeric: tabular-nums;
}
.top-row .who { flex: none; width: 148px; color: var(--ink-2); font-size: .64rem; }
.top-row .who .plus {
  font-style: normal; color: var(--ink-3); font-size: .85em; margin-left: .35em;
}
/* the bar is proportional to the biggest row on the board — pure geometry */
.top-row .bar {
  flex: 1; height: 4px; border-radius: 2px;
  background: color-mix(in srgb, var(--ink) 6%, transparent);
  overflow: hidden;
}
.top-row .bar i {
  display: block; height: 100%; border-radius: 2px;
  background: color-mix(in srgb, var(--pink) 45%, transparent);
}
.top-row .amt {
  flex: none; min-width: 76px; text-align: right;
  color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums;
}
.top-row .t { flex: none; width: 58px; text-align: right; color: var(--ink-3); font-size: .6rem; }
.top-row .lx { flex: none; color: var(--ink-3); font-size: .6rem; opacity: .55; }
/* the record holder carries the full pink */
.top-row.first .rank { color: var(--pink); }
.top-row.first .bar i { background: var(--pink); }
@media (hover: hover) and (pointer: fine) {
  .top-row:hover { background: color-mix(in srgb, var(--ink) 4%, transparent); }
  .top-row:hover .lx { color: var(--pink); opacity: 1; }
}
/* a new entry on the board flashes once, like the event feed */
.top-row.fresh { animation: levfresh 2.4s var(--ease) 1; }

/* ── liquidity: two columns ────────────────────────────────────────────── */

.dcols {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: var(--s2);
  align-items: stretch;
}
/* both lists are paginated now — the cards size to their ten rows,
   stretched equal by the grid; nothing scrolls inside */
.dcols .dcard { display: flex; flex-direction: column; }
#lpEvents, .lp-scroll {
  flex: 1; min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;   /* inner scroll never drags the page along */
  -webkit-overflow-scrolling: touch;
  padding-right: .4rem;
  scrollbar-width: thin;
  scrollbar-color: var(--rule-2) transparent;
}
#lpEvents::-webkit-scrollbar, .lp-scroll::-webkit-scrollbar { width: 6px; }
#lpEvents::-webkit-scrollbar-thumb, .lp-scroll::-webkit-scrollbar-thumb {
  background: var(--rule-2); border-radius: 3px;
}
/* just the wallet list and its pager — the totals live in the strip */
.lp-block {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
}

/* pager under the event list — stays put while the list scrolls */
.lev-pager {
  flex: none;
  display: flex; flex-wrap: wrap; justify-content: center; gap: .25rem;
  padding-top: .7rem; margin-top: .3rem;
  border-top: 1px solid var(--rule);
}
.lev-pager:empty { display: none; }
.pgb {
  min-width: 22px; height: 22px;
  padding: 0 .35em;
  background: transparent;
  border: 1px solid transparent; border-radius: 5px;
  color: var(--ink-3); font-family: var(--mono); font-size: .58rem; font-weight: 700;
  cursor: pointer;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease),
              background var(--dur) var(--ease);
}
.pgb.on { background: var(--pink); border-color: var(--pink); color: var(--on-pink); }
.pgb.arrow { color: var(--ink-2); font-size: .72rem; line-height: 1; }
.pgb[disabled] { opacity: .3; cursor: default; }
@media (hover: hover) and (pointer: fine) {
  .pgb:not(.on):not([disabled]):hover { color: var(--pink); border-color: color-mix(in srgb, var(--pink) 45%, transparent); }
}

.lev-row {
  display: flex; align-items: center; gap: .7rem;
  padding: .48rem 0;
  border-top: 1px solid var(--rule);
  font-size: .68rem;
}
.lev-row:first-child { border-top: 0; }
.lev-row .t { color: var(--ink-3); font-size: .6rem; width: 58px; flex: none; }
.lev-row .pool { color: var(--ink-2); font-size: .62rem; width: 92px; flex: none; }
.lev-badge {
  font-size: .54rem; font-weight: 700; letter-spacing: .08em;
  padding: .24em .55em; border-radius: 3px; flex: none;
}
/* quiet badges: outline for adds/removes, soft tint for donations —
   the hot pink stays reserved for the hero number and the live dot */
.lev-badge.add { background: transparent; color: var(--ink-2); border: 1px solid var(--rule-2); }
.lev-badge.remove { background: transparent; color: var(--ink-3); border: 1px solid var(--rule); }
.lev-badge.donate {
  background: var(--pink-soft); color: var(--berry);
  border: 1px solid color-mix(in srgb, var(--pink) 40%, transparent);
}
.lev-row .det { margin-left: auto; color: var(--ink-2); font-size: .62rem; text-align: right; }

/* every event row is one transaction — click opens it on the explorer */
a.lev-row { text-decoration: none; color: inherit; cursor: pointer; }
.lev-row .lx { flex: none; color: var(--ink-3); font-size: .6rem; opacity: .55; }
a.lev-row:hover .lx { color: var(--pink); opacity: 1; }

/* gentle life: hover trace (mouse only), fresh-event flash, stat blink */
@media (hover: hover) and (pointer: fine) {
  .lev-row:hover, .lp-row:hover, .conn-row:hover {
    background: color-mix(in srgb, var(--ink) 4%, transparent);
  }
}
.lev-row.fresh { animation: levfresh 2.4s var(--ease) 1; }
@keyframes levfresh {
  0%   { background: var(--pink-soft); }
  100% { background: transparent; }
}
.dstat .v, #divPct { display: inline-block; }
.dstat .v.v-split { display: flex; }
.dstat .v.bump, #divPct.bump, .v-split span.bump { animation: statbump 1s var(--ease) 1; }
@keyframes statbump {
  0%   { color: var(--berry); transform: scale(1.06); }
  100% { color: inherit; transform: scale(1); }
}

/* each pool dot breathes a soft ring, out of phase — the scale feels lit */
.div-dot { animation: dotping 3.8s var(--ease) infinite; animation-delay: calc(var(--di, 0) * .55s); }
@keyframes dotping {
  0%, 28% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--pink) 50%, transparent); }
  70%     { box-shadow: 0 0 0 8px transparent; }
  100%    { box-shadow: 0 0 0 0 transparent; }
}

/* ── liquidity ─────────────────────────────────────────────────────────── */

.lp-row {
  display: flex; align-items: center; gap: .7rem;
  padding: .45rem 0;
  border-top: 1px solid var(--rule);
  font-size: .7rem;
}
.lp-row .addr { color: var(--ink-2); }
.lp-row .meta { margin-left: auto; color: var(--ink-3); font-size: .6rem; letter-spacing: .06em; }
a.lp-row { color: inherit; text-decoration: none; }
.lp-row .lx { flex: none; color: var(--ink-3); font-size: .6rem; opacity: .55; }
a.lp-row:hover .addr { color: var(--pink); }
a.lp-row:hover .lx { color: var(--pink); opacity: 1; }

.dfoot {
  margin: var(--s2) 0 0;
  font-size: .56rem; letter-spacing: .12em; color: var(--ink-3);
  text-align: center;
}

/* ── phone ─────────────────────────────────────────────────────────────── */

@media (max-width: 900px) {
  /* phones keep two sparks and lose the watermark — battery and clarity */
  .circuit .sp path:nth-of-type(n+3) { display: none; }

  .dhead { padding: var(--s2) var(--s3); }
  .dash { padding: 0 var(--s3) var(--s5); gap: var(--s2); }

  /* pulse: the payout itself stays, the LP half is dropped for width */
  .pulse { font-size: .58rem; border-radius: var(--r-lg); }
  .pulse-seg { gap: .45rem; padding: .5rem .7rem; }
  .pulse-lead { font-size: .46rem; letter-spacing: .1em; }
  .pulse-lp { display: none; }
  .pulse-age { font-size: .5rem; }

  /* headline stats: tight 2x3 grid */
  .dstats { grid-template-columns: 1fr 1fr; gap: .5rem; }
  .dstat { padding: .6rem .7rem; }
  .dstat .k { font-size: .54rem; }
  .dstats.split .k::before,
  .dstats.split .k::after { width: 9px; }
  .dstats.split > .total .k::before,
  .dstats.split > .total .k::after { width: 12px; }
  .dstat .v { font-size: .92rem; }
  .dstat .v.v-split { font-size: .66rem; }
  .v-split .sk { font-size: .42rem; letter-spacing: .08em; }
  .dback { width: 32px; height: 32px; }

  .dcard { padding: var(--s2); }
  .dpool { padding: .85rem; }

  /* divergence: smaller tags, tighter legend */
  .div-dot .tag { font-size: .5rem; }
  .div-big { margin-bottom: var(--s3); }
  .div-legend { margin-top: 2.2rem; font-size: .52rem; }

  /* the two lists stack, each at its natural ten-row height */
  .dcols { grid-template-columns: 1fr; }

  /* pager: thumb-sized targets */
  .pgb { min-width: 28px; height: 28px; font-size: .56rem; }
  .lev-pager { gap: .2rem; }

  /* record rows: tighter fixed columns, the bar keeps flexing */
  .top-row { gap: .45rem; padding: .65rem .7rem; }
  .top-row .who { width: 104px; font-size: .56rem; }
  .top-row .amt { min-width: 58px; font-size: .62rem; }
  .top-row .t { width: 42px; font-size: .52rem; }
  .top-bar { padding: .7rem .7rem; }

  /* event rows: slimmer fixed columns */
  .lev-row { gap: .5rem; }
  .lev-row .t { width: 44px; font-size: .54rem; }
  .lev-row .pool { width: 74px; font-size: .56rem; }
  .lev-row .det { font-size: .56rem; }
  .lev-badge { font-size: .5rem; padding: .2em .45em; }

  .conn-row { display: flex; flex-wrap: wrap; align-items: center; gap: .25rem .8rem; }
  .conn-row .cpair { flex: 1 1 auto; order: 0; }
  .conn-row .badge { order: 1; margin-left: auto; justify-self: auto; }
  .conn-row .cfee, .conn-row .csince, .conn-row .cvol, .conn-row .cdon { order: 2; }
  .conn-row .cmid { text-align: left; }

  /* pool modal: full-width card, roomier rows for thumbs */
  .pmodal { padding: var(--s2); }
  .pmodal-card { max-height: 78vh; }
  .pm-row { grid-template-columns: minmax(72px, 1fr) 40px minmax(74px, 1fr) auto 12px; padding: .8rem .7rem; font-size: .62rem; min-height: 46px; gap: .45rem; }
  .pm-don { font-size: .56rem; }
  .pm-add { min-height: 30px; }
  .pmodal-x { padding: .55em 1em; min-height: 38px; }
}

/* notched phones: keep content clear of the safe-area insets */
@supports (padding: max(0px)) {
  @media (max-width: 900px) {
    .dhead, .dash {
      padding-left: max(var(--s3), env(safe-area-inset-left));
      padding-right: max(var(--s3), env(safe-area-inset-right));
    }
  }
}

/* ── hook your token: pool link builder ────────────────────────────────── */

/* the header button that opens the builder */
.byot {
  flex: none;
  display: inline-flex; align-items: center;
  font-size: .58rem; letter-spacing: .12em; font-weight: 700;
  padding: .55em 1.05em;
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--pink) 45%, transparent);
  border-radius: 100px;
  color: var(--pink); cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.byot:hover { background: var(--pink); border-color: var(--pink); color: var(--on-pink); }
.byot .byot-s { display: none; }

/* electrified like the landing page's dashboard pill: the same spark of
   current orbits this rim (property + keyframes come from styles.css) */
.byot { position: relative; animation: dlarc 3.6s linear infinite; }
.byot::before {
  content: ''; position: absolute; inset: -1px;
  border-radius: 100px; padding: 1.5px;
  background: conic-gradient(from var(--dl-arc),
    transparent 0 74%,
    color-mix(in srgb, var(--pink) 40%, transparent) 84%,
    var(--pink) 91%,
    color-mix(in srgb, var(--pink) 55%, #fff) 95%,
    var(--pink) 97%,
    transparent 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .byot { animation: none; }
  .byot::before { content: none; }
}

/* the form, living inside a pmodal card */
.pb-card { max-height: min(84vh, 640px); }
.pb-form {
  display: flex; flex-direction: column; gap: var(--s2);
  padding: var(--s3);
  overflow-y: auto; min-height: 0;
  overscroll-behavior: contain;
}
.pb-field { display: flex; flex-direction: column; gap: .45rem; }
.pb-lab { font-size: .56rem; letter-spacing: .12em; font-weight: 700; color: var(--ink-3); }
.pb-in {
  width: 100%;
  padding: .7em .95em;
  font-size: .78rem; letter-spacing: .03em;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--rule-2); border-radius: var(--r);
  transition: border-color var(--dur) var(--ease);
}
.pb-in:focus { outline: none; border-color: var(--pink); }
.pb-in::placeholder { color: var(--ink-3); opacity: .7; }

.pb-opts { display: flex; gap: var(--s3); flex-wrap: wrap; }
.pb-group { display: flex; flex-direction: column; gap: .45rem; }
.pb-btns { display: flex; gap: .35rem; }
.pb {
  font-size: .58rem; letter-spacing: .12em; font-weight: 700;
  padding: .45em .9em;
  background: transparent;
  border: 1px solid var(--rule-2); border-radius: 100px;
  color: var(--ink-2); cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.pb.on { background: var(--pink); border-color: var(--pink); color: var(--on-pink); }

.pb-status { min-height: 1.1em; font-size: .62rem; letter-spacing: .08em; color: var(--ink-3); overflow-wrap: anywhere; }
.pb-status.err { color: var(--berry); }
.pb-status.ok { color: var(--ink-2); }
.pb-status.ok b { color: var(--berry); font-weight: 700; }

.pb-act { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
/* shown only after the first OPEN — Uniswap's create page drops the chain
   on a cold load and needs a second pass */
.pb-note {
  font-size: .58rem; letter-spacing: .06em; line-height: 1.6;
  color: var(--ink-3);
}
.pb-note b { color: var(--berry); font-weight: 700; }
.pb-note[hidden] { display: none; }
.pb-go {
  display: inline-flex; align-items: center; gap: .55em;
  padding: .85em 1.5em;
  font-size: .62rem; letter-spacing: .14em; font-weight: 700;
  background: var(--pink); color: var(--on-pink);
  border-radius: 100px; text-decoration: none;
  transition: background var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.pb-go:hover { background: var(--pink-2); }
.pb-go[aria-disabled="true"] { opacity: .35; pointer-events: none; }
.pb-copy {
  font-size: .58rem; letter-spacing: .12em; font-weight: 700;
  padding: .8em 1.2em;
  background: transparent;
  border: 1px solid var(--rule-2); border-radius: 100px;
  color: var(--ink-2); cursor: pointer;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.pb-copy:hover:not(:disabled) { color: var(--pink); border-color: var(--pink); }
.pb-copy:disabled { opacity: .35; cursor: default; }
.pb-copy.ok { color: var(--berry); border-color: var(--berry); }

@media (max-width: 900px) {
  .pb-opts { gap: var(--s2); }
  .pb, .pb-copy { min-height: 34px; }
  .pb-go { width: 100%; justify-content: center; min-height: 40px; }
  .pb-copy { flex: 1; }
  .pb-form { padding: var(--s2); }
}

/* narrow phones: the header button collapses to a round + */
@media (max-width: 640px) {
  .dhead { gap: .7rem; }
  .byot {
    width: 32px; height: 32px; padding: 0;
    justify-content: center; border-radius: 50%;
    font-size: 1.05rem; font-weight: 500; line-height: 1;
  }
  .byot .byot-l { display: none; }
  .byot .byot-s { display: inline; }
  /* records collapses the same way: just the podium glyph */
  .trec {
    width: 32px; height: 32px; padding: 0;
    justify-content: center; border-radius: 50%;
  }
  .trec .trec-l { display: none; }
  .trec svg { width: 13px; height: 13px; }
}

/* ── The distributed-per-volume projection ───────────────────────────────
   The strip carries what the hook has handed out and the engine card what
   it turned over to do it. Their quotient is the one number that says what
   a dollar of arbitrage is worth to the people in the pools, and the only
   one that can be carried to a volume nobody has traded yet — the
   CALCULATOR button in the header opens it. */

.rt-card { width: min(520px, 100%); max-height: min(88vh, 720px); }

/* observed → observed = ratio, the three numbers the projection rests on */
.rt-now {
  display: flex; align-items: stretch; gap: .5rem;
  padding: var(--s3) var(--s3) 0;
}
.rt-obs {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: .3rem; align-items: center;
  padding: .7rem .5rem;
  background: var(--paper-3);
  border: 1px solid var(--rule);
  border-radius: var(--r);
}
.rt-obs.hot { background: var(--pink-soft); border-color: color-mix(in srgb, var(--pink) 42%, transparent); }
.rt-k { font-size: .5rem; font-weight: 500; letter-spacing: .12em; color: color-mix(in srgb, var(--pink) 10%, var(--ink-2)); text-align: center; }
.rt-v { font-size: .82rem; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
.rt-obs.hot .rt-v { color: var(--berry); }
.rt-op { align-self: center; color: var(--ink-3); font-size: .8rem; flex: none; }

.rt-form { padding: var(--s3); }
.rt-lab { display: block; font-size: .54rem; letter-spacing: .14em; color: var(--ink-3); margin-bottom: .5rem; }
.rt-input {
  display: flex; align-items: center; gap: .4rem;
  padding: .6rem .8rem;
  background: var(--paper-3);
  border: 1px solid var(--rule-2); border-radius: var(--r);
  transition: border-color var(--dur) var(--ease);
}
.rt-input:focus-within { border-color: color-mix(in srgb, var(--pink) 55%, transparent); }
.rt-cur { color: var(--ink-3); font-size: 1rem; flex: none; }
.rt-in {
  flex: 1; min-width: 0;
  background: none; border: 0; outline: none; padding: 0;
  font-family: var(--mono); font-size: 1.15rem; font-weight: 700;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
.rt-presets { display: flex; gap: .4rem; margin-top: .6rem; flex-wrap: wrap; }
.rt-p {
  flex: 1; min-width: 4rem;
  font-family: var(--mono); font-size: .6rem; letter-spacing: .08em; font-weight: 700;
  padding: .5em .2em;
  background: transparent; color: var(--ink-3);
  border: 1px solid var(--rule-2); border-radius: 100px;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.rt-p:hover { border-color: var(--ink-3); color: var(--ink-2); }
.rt-p.on { border-color: var(--pink); color: var(--pink); }

.rt-out {
  margin: 0 var(--s3) var(--s3);
  padding: var(--s3);
  background: var(--pink-soft);
  border: 1px solid color-mix(in srgb, var(--pink) 38%, transparent);
  border-radius: var(--r-lg);
}
.rt-big { display: flex; flex-direction: column; align-items: center; gap: .35rem; }
.rt-total {
  font-size: clamp(1.7rem, 8vw, 2.3rem); font-weight: 700;
  color: var(--ink); letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; line-height: 1;
}
.rt-split {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--s2);
  margin-top: var(--s3); padding-top: var(--s3);
  border-top: 1px solid color-mix(in srgb, var(--pink) 25%, transparent);
}
.rt-leg { display: flex; flex-direction: column; align-items: center; gap: .3rem; }

@media (max-width: 560px) {
  .rt-now { flex-direction: column; }
  /* the arrow turns with the stack; the equals sign must not — rotated, it
     reads as a pause bar */
  .rt-now .rt-op:first-of-type { transform: rotate(90deg); }
}

/* ── Liquidity-events filter ─────────────────────────────────────────────
   The feed mixes three kinds of event that people read for different
   reasons — who added liquidity, who pulled it, and what the hook paid in.
   The chips carry their own counts so the mix is legible before you click
   anything, and the counts are of the window the feed actually holds. */

.lev-filter {
  display: flex; gap: .35rem; flex-wrap: wrap;
  margin-bottom: var(--s2);
}
.lev-filter .tf { padding: .4em .8em; }
.lev-filter .tf .n {
  font-weight: 400; color: var(--ink-3);
  margin-left: .5em;
  font-variant-numeric: tabular-nums;
}
.lev-filter .tf.on .n { color: color-mix(in srgb, var(--on-pink) 65%, transparent); }
.lev-filter .tf:disabled { opacity: .4; cursor: default; }
.lev-filter .tf:disabled:hover { border-color: var(--rule-2); }

/* ── the split strip: the total above, its two legs below, wired ─────────
   The same identity the numbers already obey — rebates + LP = total —
   drawn as one circuit. No travelling sparks here: the page already runs
   those in the background, and more of them would read as clutter. The
   wire breathes slowly at rest, and CONDUCTS — the whole trace surging
   bright at once — in the same instant the numbers change, which is the
   moment a payout has actually landed. Life strictly means news.
   The svg stretches to the strip (preserveAspectRatio none), so strokes
   pin their width with vector-effect and the pads are CSS dots — an svg
   circle would pull into an ellipse with the stretch. */

.dstats.split { grid-template-columns: 1fr 1fr; gap: 0 var(--s2); }

/* the three boxes wear a finer frame than the working cards below them:
   a hairline warmed with a trace of pink, a specular line inside the top
   edge, and a faint bloom pooling underneath — jewellery, kept quiet */
.dstats.split > .dstat {
  border-color: color-mix(in srgb, var(--pink) 14%, var(--rule-2));
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--pink) 5%, transparent), transparent 58%),
    var(--paper-2);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .07),
    0 22px 44px -34px color-mix(in srgb, var(--pink) 45%, transparent);
}
.dstats.split > .total { grid-column: 1 / -1; }
.dstats.split > .total .v { font-size: 1.55rem; }
/* the flagship box catches a little more light than its legs */
.dstats.split > .total {
  border-color: color-mix(in srgb, var(--pink) 22%, var(--rule-2));
  background:
    radial-gradient(56% 130% at 50% 0%,
      color-mix(in srgb, var(--pink) 7%, transparent), transparent 72%),
    var(--paper-2);
}
/* the labels are engraved to match: pink-warmed silver flanked by hairline
   leads that pick up the wire's current, fading outward — and the flagship's
   leads burn brighter, the same ladder the frames climb */
.dstats.split .k {
  --lead: color-mix(in srgb, var(--pink) 45%, transparent);
  display: inline-flex; align-items: center; gap: .6rem;
}
.dstats.split .k::before,
.dstats.split .k::after {
  content: ""; flex: none; width: 14px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--lead));
}
.dstats.split .k::after {
  transform: scaleX(-1);
  margin-left: -.15em;   /* swallow the tracking after the last letter */
}
.dstats.split > .total .k {
  --lead: color-mix(in srgb, var(--pink) 62%, transparent);
  color: color-mix(in srgb, var(--pink) 12%, color-mix(in srgb, var(--ink) 28%, var(--ink-2)));
}
.dstats.split > .total .k::before,
.dstats.split > .total .k::after { width: 18px; }

/* On glass desktops the strip must stay glass: these overrides outrank the
   .dstat glass rule, so they carry the same translucent paper themselves —
   the pink is a tint OVER the frost, never a solid poured across it. The
   circuit shimmers through the jewellery exactly as through the furniture. */
@media (min-width: 901px) {
  .dstats.split > .dstat {
    background:
      linear-gradient(180deg, color-mix(in srgb, var(--pink) 5%, transparent), transparent 58%),
      color-mix(in srgb, var(--paper-2) 65%, transparent);
  }
  .dstats.split > .total {
    background:
      radial-gradient(56% 130% at 50% 0%,
        color-mix(in srgb, var(--pink) 7%, transparent), transparent 72%),
      color-mix(in srgb, var(--paper-2) 65%, transparent);
  }
}

.dwire { grid-column: 1 / -1; position: relative; height: 58px; }
.dwire svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* the etched pair underneath — the wire itself, always there */
.dwire .wt path {
  fill: none;
  stroke: color-mix(in srgb, var(--pink) 28%, transparent);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

/* the current: glowing capsules gliding from the total into the legs —
   each one drawn twice on the same dash grid, a blurred wide halo under a
   bright core, so a link reads as a soft body of light rather than a tick
   of a dashed line. Deliberately not the circuit's sparks: one bright dot
   reads as a creature, a stately procession reads as flow. The two paths
   share the stem at offset phases, so the trunk runs denser than either
   branch — which is what it carries. */
.dwire .wh path, .dwire .wf path {
  fill: none;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: .05 .11;              /* one capsule every .16 of the path */
  animation: wireflow 1.6s linear infinite;
  animation-delay: var(--dl, 0s);
}
.dwire .wh path {
  stroke: color-mix(in srgb, var(--pink) 48%, transparent);
  stroke-width: 5;
  opacity: .45;
  filter: blur(3px);
}
.dwire .wf path {
  stroke: color-mix(in srgb, var(--pink) 68%, #fff);
  stroke-width: 1.5;
  filter: drop-shadow(0 0 3px color-mix(in srgb, var(--pink) 55%, transparent));
}
/* one dash period per loop — the pattern lands exactly on itself, so the
   glide never stutters */
@keyframes wireflow {
  from { stroke-dashoffset: .16; }
  to   { stroke-dashoffset: 0; }
}

/* the pads keep a slow breath, in time with nothing — a resting pulse */
.dwire .wp { animation: wirebreath 6s ease-in-out infinite; }
@keyframes wirebreath {
  0%, 100% { opacity: .55; }
  50%      { opacity: 1; }
}

/* the conduction layer: dark until a payout lands, then the full trace
   lights and decays — cued from flashCell, the same beat as the cells */
.dwire .wg path {
  fill: none;
  stroke: color-mix(in srgb, var(--pink) 80%, #fff);
  stroke-width: 1.6;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  opacity: 0;
  filter: drop-shadow(0 0 5px color-mix(in srgb, var(--pink) 55%, transparent));
}
.dwire.surge .wg path { animation: wiresurge 1.6s var(--ease) 1; }
@keyframes wiresurge {
  0%   { opacity: 0; }
  12%  { opacity: 1; }
  100% { opacity: 0; }
}

/* solder pads where the wire meets the boxes */
.dwire .wp {
  position: absolute; width: 5px; height: 5px; border-radius: 50%;
  background: var(--pink);
  box-shadow: 0 0 8px color-mix(in srgb, var(--pink) 55%, transparent);
  transform: translate(-50%, -50%);
}
.dwire .wp.c { left: 50%; top: 3px; }
.dwire .wp.l { left: 25%; top: calc(100% - 3px); }
.dwire .wp.r { left: 75%; top: calc(100% - 3px); }

@media (max-width: 560px) {
  .dwire { height: 46px; }
  .dstats.split > .total .v { font-size: 1.4rem; }
}
@media (prefers-reduced-motion: reduce) {
  /* the current freezes into an ordinary dashed trace — a legitimate way
     to draw a wire, unlike one stranded spark — and the pads hold still.
     The surge stays: a brief fade tied to a real event, not ambient motion */
  .dwire .wf path, .dwire .wh path, .dwire .wp { animation: none; }
}

/* ── WATCH LIVE: the diamond ────────────────────────────────────────────────
   A cut stone. The medallion in the centre is WTH; the chips on the
   perimeter are little siblings of the headline boxes — same paper, same
   pink-warmed hairline, same specular glint — and one fine ray ties each
   of them straight to the centre. A single drop of light slides down every
   ray the whole time: quiet, inevitable pull toward the router. Wallets
   dock at ports; one card shows the latest transaction and nothing else. */

/* while the map is open the page behind it is frozen: no scrolling under
   the overlay on a phone, no phantom scrollbar beside it on a desktop */
html.lv-lock, html.lv-lock body { overflow: hidden; }

/* TEMPORARY, for filming — one line up, one line out. A 50% lift on the
   whole overlay: brighter and a touch more saturated so the pink survives
   video compression. Delete this rule to restore the shipped look. */
.lmap { filter: brightness(1.28) saturate(1.12); }

/* display:flex would silently beat the hidden attribute — say it out loud */
.lmap[hidden] { display: none; }
.lmap {
  position: fixed; inset: 0; z-index: 60;
  overscroll-behavior: contain;
  touch-action: manipulation;
  /* the page's own fabric, carried into the overlay: the etched dot grid
     and a few soft blooms — the stone floats on cloth, not on a void */
  background:
    radial-gradient(90% 70% at 54% 50%,
      color-mix(in srgb, var(--pink) 7%, transparent), transparent 68%),
    radial-gradient(420px 320px at 88% 8%, color-mix(in srgb, var(--pink) 9%, transparent), transparent 70%),
    radial-gradient(360px 280px at 8% 86%, color-mix(in srgb, var(--pink) 7%, transparent), transparent 70%),
    radial-gradient(color-mix(in srgb, var(--pink) 9%, transparent) 1px, transparent 1.4px),
    var(--paper);
  background-size: auto, auto, auto, 30px 30px, auto;
  display: flex; flex-direction: column;
  animation: lmapin .35s var(--ease) 1;
}
@keyframes lmapin { from { opacity: 0; } to { opacity: 1; } }

.lmap-head .dback { background: transparent; cursor: pointer; padding: 0; }
.lmap-head {
  display: flex; align-items: center; gap: .7rem;
  padding: .85rem var(--s3);
  border-bottom: 1px solid color-mix(in srgb, var(--pink) 12%, var(--rule));
  background: color-mix(in srgb, var(--paper-2) 72%, transparent);
  backdrop-filter: blur(10px);
}
.lmap-title { font-size: .72rem; font-weight: 700; letter-spacing: .22em; color: var(--ink); }
.lmap-sub { font-size: .58rem; letter-spacing: .12em; color: var(--ink-3); flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* the live dot — a slow heartbeat, never frantic */
.lv-dot {
  width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: var(--pink);
  box-shadow: 0 0 8px color-mix(in srgb, var(--pink) 60%, transparent);
  animation: lvbeat 2.2s var(--ease) infinite;
}
.lv-dot.big { width: 9px; height: 9px; }
@keyframes lvbeat {
  0%, 100% { opacity: .55; transform: scale(.85); }
  50%      { opacity: 1;   transform: scale(1); }
}
.trec .lv-dot { margin-right: .1rem; }

#lmapSvg { flex: 1; width: 100%; height: 100%; display: block; }

/* ── the stone: facets etched into the dark ── */
.lm-facet {
  fill: none;
  stroke: color-mix(in srgb, var(--pink) 22%, transparent);
  stroke-width: 1;
}
.lm-facet.in { stroke: color-mix(in srgb, var(--pink) 13%, transparent); }
.lm-vertex { fill: color-mix(in srgb, var(--pink) 45%, var(--paper-2)); }
/* the gate: the one inlet on the rim, where every order enters the stone */
.lm-gate {
  fill: color-mix(in srgb, var(--pink) 26%, var(--paper-2));
  stroke: color-mix(in srgb, var(--pink) 72%, transparent);
  stroke-width: 1;
}
.lm-gate.ping {
  fill: var(--pink);
  filter: drop-shadow(0 0 10px color-mix(in srgb, var(--pink) 65%, transparent));
  transition: fill .12s, filter .12s;
}

/* ── the medallion: WTH cut into the centre ── */
.lm-medal-box {
  fill: color-mix(in srgb, var(--pink) 8%, var(--paper-2));
  stroke: color-mix(in srgb, var(--pink) 62%, var(--rule-2));
  stroke-width: 1.2;
  filter: drop-shadow(0 0 30px color-mix(in srgb, var(--pink) 38%, transparent));
}
.lm-medal-in {
  fill: none;
  stroke: color-mix(in srgb, var(--pink) 32%, transparent);
  stroke-width: 1;
}
.lm-medal-lab {
  font-family: var(--mono); font-weight: 700; letter-spacing: .2em;
  fill: var(--ink);
}
.lm-medal-sub {
  font-family: var(--mono); font-weight: 500; letter-spacing: .24em;
  fill: color-mix(in srgb, var(--pink) 20%, var(--ink-2));
}
.lm-medal { animation: lmmedal 6s var(--ease) infinite; }
@keyframes lmmedal {
  0%, 100% { opacity: .94; }
  50%      { opacity: 1; }
}
.lm-medal.hit .lm-medal-box {
  fill: color-mix(in srgb, var(--pink) 22%, var(--paper-2));
  stroke: var(--pink);
  filter: drop-shadow(0 0 34px color-mix(in srgb, var(--pink) 55%, transparent));
  transition: fill .15s, stroke .15s, filter .15s;
}

/* ── chips: the strip boxes in miniature ── */
.lm-box {
  fill: color-mix(in srgb, var(--pink) 4%, var(--paper-2));
  stroke: color-mix(in srgb, var(--pink) 34%, var(--rule-2));
  stroke-width: 1;
}
.lm-glint { fill: rgba(255, 255, 255, .07); }
.lm-lab { font-family: var(--mono); fill: color-mix(in srgb, var(--pink) 10%, var(--ink)); letter-spacing: .14em; font-weight: 500; }
.lm-sum { font-family: var(--mono); fill: color-mix(in srgb, var(--pink) 8%, var(--ink-2)); letter-spacing: .08em; }
.lm-pad { fill: color-mix(in srgb, var(--pink) 60%, var(--paper-2)); }
.lm-chip { animation: lmbreathe 6s var(--ease) infinite; }
@keyframes lmbreathe {
  0%, 100% { opacity: .92; }
  50%      { opacity: 1; }
}
/* seats change hands: the newcomer fades in, the quiet one bows out */
.lm-chip.in, .lm-rayg.in { animation: lmseat .5s var(--ease) 1; }
@keyframes lmseat { from { opacity: 0; } to { opacity: 1; } }
.lm-chip.out, .lm-rayg.out { animation: none; opacity: 0; transition: opacity .5s; }

.lm-chip.hit .lm-box {
  stroke: color-mix(in srgb, var(--pink) 75%, transparent);
  fill: color-mix(in srgb, var(--pink) 16%, var(--paper-2));
  filter: drop-shadow(0 0 16px color-mix(in srgb, var(--pink) 50%, transparent));
  transition: fill .15s, stroke .15s, filter .15s;
}

/* ── rays: one filament per chip, one drop of light each ── */
.lm-ray {
  fill: none;
  stroke: color-mix(in srgb, var(--pink) 28%, transparent);
  stroke-width: 1;
}
/* the surge: the hook running the stone — in to the medallion, then back out */
.lm-raysurge {
  fill: none;
  stroke: var(--pink);
  stroke-width: 1.8;
  stroke-linecap: round;
  opacity: 0;
  filter: drop-shadow(0 0 7px color-mix(in srgb, var(--pink) 65%, transparent));
}
.lm-rayg.surge .lm-raysurge { animation: lmsurgein 1.2s var(--ease) 1; }
@keyframes lmsurgein {
  0%   { opacity: 0; stroke-dashoffset: 0; }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { opacity: 0; stroke-dashoffset: calc((var(--len) + 22) * -1px); }
}
.lm-rayg.surge-out .lm-raysurge { animation: lmsurgeout 1.2s var(--ease) 1; }
@keyframes lmsurgeout {
  0%   { opacity: 0; stroke-dashoffset: calc((var(--len) + 22) * -1px); }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { opacity: 0; stroke-dashoffset: 0; }
}

/* the trader's beam, alive only while their transaction plays */
.lm-beam {
  fill: none;
  stroke: color-mix(in srgb, var(--pink) 34%, transparent);
  stroke-width: 1;
  opacity: 0;
  transition: opacity .5s;
}
.lm-beam.on { opacity: 1; transition: opacity .15s; }

.lm-ghost { fill: none; stroke: none; }
.lm-spark {
  fill: var(--pink);
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--pink) 70%, transparent));
}
.lm-spark.back { fill: #ffd6ea; }

/* ── ports: where wallets dock, the last six resident ── */
.lm-port { fill: color-mix(in srgb, var(--pink) 45%, var(--paper-2));
  stroke: color-mix(in srgb, var(--pink) 55%, transparent); stroke-width: 1; }
.lm-port-ring { fill: none; stroke: color-mix(in srgb, var(--pink) 25%, transparent); stroke-width: 1; }
/* the addresses are doors to the explorer — a hairline says so quietly */
.lm-wlab {
  font-family: var(--mono); fill: var(--ink-2); letter-spacing: .06em;
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--pink) 26%, transparent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3.5px;
  transition: text-decoration-color .2s;
}
.lm-portg:hover .lm-wlab,
.lm-portg.on .lm-wlab,
.lm-portg.last .lm-wlab { text-decoration-color: color-mix(in srgb, var(--pink) 60%, transparent); }
.lm-portg { animation: lmbreathe 5s var(--ease) infinite; }
/* the entrance fades ONLY. It used to animate transform too, and a CSS
   animation outranks the style attribute — so for its whole half second
   the ports rendered at their creation slots instead of the ranked ones
   lvReflow had written inline, painting the dock upside down and then
   snapping. Opacity cannot collide with the inline translateY. */
.lm-portg.in { animation: lmdock .5s var(--ease) 1; }
@keyframes lmdock {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.lm-portg.out { opacity: 0; transform: translateX(-14px); transition: opacity .5s, transform .5s; }
.lm-portg.on .lm-port {
  fill: var(--pink);
  filter: drop-shadow(0 0 8px color-mix(in srgb, var(--pink) 65%, transparent));
}
.lm-portg.on .lm-wlab { fill: var(--ink-2); }
/* the newest trader says so in writing, above their address */
.lm-ptag {
  font-family: var(--mono); font-weight: 700; letter-spacing: .18em;
  fill: var(--berry); opacity: 0; transition: opacity .3s;
}
.lm-portg.last .lm-ptag { opacity: 1; }
/* ports are doors now — say so on approach */
.lm-portg:hover .lm-port { fill: var(--pink); }
.lm-portg:hover .lm-wlab { fill: var(--ink-2); }
.lm-portg.last .lm-port { fill: var(--pink); }
.lm-portg.last .lm-port-ring { stroke: color-mix(in srgb, var(--pink) 55%, transparent); }
.lm-portg.last .lm-wlab { fill: var(--ink-2); }
.lm-portg.paid .lm-port-ring {
  stroke: var(--pink);
  animation: lmpaid 1.2s var(--ease) 1;
}
@keyframes lmpaid {
  0%   { stroke-opacity: 1; transform: scale(1); }
  100% { stroke-opacity: 0; transform: scale(2.2); }
}
.lm-portg .lm-port-ring { transform-box: fill-box; transform-origin: center; }

/* money floating off the board */
.lm-float {
  font-family: var(--mono); font-weight: 700; letter-spacing: .04em;
  animation: lmfloat 4s var(--ease) 1 forwards;
}
.lm-float.cash { fill: var(--berry); }
.lm-float.lp { fill: color-mix(in srgb, var(--pink) 45%, var(--ink-2)); }
/* the figure holds long enough to be read twice — and is gone before the
   next act lights anything */
@keyframes lmfloat {
  0%   { opacity: 0; transform: translateY(6px); }
  6%   { opacity: 1; transform: translateY(0); }
  82%  { opacity: 1; transform: translateY(-6px); }
  100% { opacity: 0; transform: translateY(-18px); }
}

/* the machine's odometer, held above the latest card — always readable */
.lmap-vol[hidden] { display: none; }
.lmap-vol {
  position: absolute; left: 54%; bottom: calc(var(--s3) + 58px);
  transform: translateX(-50%);
  display: flex; align-items: baseline; gap: .6rem;
  white-space: nowrap;
}
.lvv-k {
  font-size: .54rem; font-weight: 500; letter-spacing: .2em;
  color: color-mix(in srgb, var(--pink) 14%, var(--ink-2));
}
.lmap-vol b {
  font-size: 1.02rem; font-weight: 700; color: var(--ink);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 18px color-mix(in srgb, var(--pink) 30%, transparent);
}
@media (max-width: 900px) {
  .lmap-vol { bottom: calc(var(--s3) + 92px); }
  .lvv-k { font-size: .48rem; }
  .lmap-vol b { font-size: .9rem; }
}

/* the latest transaction — one card, centred under the stone */
.lmap-cards {
  position: absolute; left: 54%; bottom: var(--s3); transform: translateX(-50%);
  width: auto; max-width: min(600px, calc(100vw - 2 * var(--s3)));
  pointer-events: none;
  display: flex;
}
.lm-card {
  pointer-events: auto;
  display: flex; align-items: center; gap: .6rem;
  padding: .62rem .85rem;
  font-family: var(--mono); font-size: .62rem; letter-spacing: .04em;
  color: var(--ink-2); text-decoration: none; white-space: nowrap;
  background: color-mix(in srgb, var(--paper-2) 82%, transparent);
  border: 1px solid color-mix(in srgb, var(--pink) 26%, var(--rule-2));
  border-radius: var(--r-lg);
  backdrop-filter: blur(8px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .06),
    0 18px 36px -26px color-mix(in srgb, var(--pink) 55%, transparent);
  animation: lmcard .4s var(--ease) 1;
}
@keyframes lmcard {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
.lm-tag {
  font-size: .5rem; letter-spacing: .16em; color: var(--berry);
  border: 1px solid color-mix(in srgb, var(--pink) 40%, transparent);
  border-radius: 99px; padding: .16rem .45rem; flex: none;
}
.lm-card b { color: var(--ink); font-weight: 700; }
.lm-card .amt { color: var(--berry); }
.lm-card .lm-when { color: var(--ink-3); flex: none; margin-left: .2rem; }
.lm-card .lm-lx { color: var(--ink-3); flex: none; }
.lm-card:hover { border-color: color-mix(in srgb, var(--pink) 45%, var(--rule-2)); }

.lmap-hint {
  position: absolute; left: 54%; bottom: calc(var(--s3) + .2rem); transform: translateX(-50%);
  font-size: .58rem; letter-spacing: .14em; color: var(--ink-3);
  animation: lmbreathe 4s var(--ease) infinite;
}

@media (max-width: 900px) {
  .lmap-head { padding: .7rem var(--s3); }
  .lmap-title { font-size: .62rem; }
  /* one line, and it shrinks to fit rather than growing into a tower */
  .lm-card { font-size: .54rem; padding: .45rem .6rem; gap: .4rem; white-space: nowrap; }
  .lmap-cards { max-width: calc(100vw - 2 * var(--s3)); }
  .lm-card .lm-when { margin-left: .1rem; }
}
@media (max-width: 640px) {
  /* the addresses stay put on a phone too — hiding them once the act ended
     read as the wallet vanishing. A half-point smaller, so the middle one
     clears the gate on a 375px screen */
  .lm-wlab { font-size: 7.5px; }
  .lm-tag { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .lmap, .lm-card, .lv-dot, .lm-chip, .lm-medal, .lm-portg, .lmap-hint { animation: none; }
  /* flights resolve instantly in the script; what remains is the flash,
     the floats and the card — events acknowledged, not ambient motion */
}

/* ── the narrator: the animation captions itself ── */
/* display:flex would beat the hidden attribute here too — the empty pill bug */
.lmap-cap[hidden] { display: none; }
.lmap-cap {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--s3) + 58px);
  display: flex; align-items: center; gap: .55rem;
  padding: .42rem .75rem;
  font-size: .6rem; letter-spacing: .08em; color: var(--ink-2);
  background: color-mix(in srgb, var(--paper-2) 62%, transparent);
  border: 1px solid color-mix(in srgb, var(--pink) 14%, var(--rule));
  border-radius: 99px;
  backdrop-filter: blur(6px);
  white-space: nowrap;
  animation: lmcap .3s var(--ease) 1;
}
.lmap-cap.off { opacity: 0; transition: opacity .6s; }
@keyframes lmcap {
  from { opacity: 0; transform: translate(-50%, 5px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}
.lc-tag { font-size: .5rem; letter-spacing: .18em; color: var(--berry); flex: none; }

/* ── the key: who is who, kept out of the way ── */
.lmap-key {
  position: absolute; left: var(--s3); bottom: var(--s3);
  display: flex; flex-direction: column; gap: .45rem;
  font-size: .54rem; letter-spacing: .1em; color: var(--ink-2);
}
.lmap-key span { display: flex; align-items: center; gap: .5rem; }
.lmap-key i { flex: none; display: inline-block; }
.k-port {
  width: 7px; height: 7px; border-radius: 50%;
  background: color-mix(in srgb, var(--pink) 45%, var(--paper-2));
  border: 1px solid color-mix(in srgb, var(--pink) 55%, transparent);
}
.k-chip {
  width: 14px; height: 9px; border-radius: 3px;
  background: color-mix(in srgb, var(--paper-2) 92%, transparent);
  border: 1px solid color-mix(in srgb, var(--pink) 30%, var(--rule-2));
}
.k-med {
  width: 8px; height: 8px; border-radius: 2px;
  transform: rotate(45deg);
  background: color-mix(in srgb, var(--pink) 12%, var(--paper-2));
  border: 1px solid color-mix(in srgb, var(--pink) 55%, transparent);
}
.k-drop {
  width: 10px; height: 2px; border-radius: 2px;
  background: color-mix(in srgb, var(--pink) 70%, transparent);
  box-shadow: 0 0 4px color-mix(in srgb, var(--pink) 45%, transparent);
}

/* the Connected-pools masthead holds three things; the grid keeps the
   doorway on the row's TRUE centre, whatever its neighbours weigh */
.conn-head { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; }
.conn-head h2 { justify-self: start; }
.conn-head .hint { justify-self: end; }
@media (max-width: 900px) {
  .conn-head { grid-template-columns: auto auto; row-gap: .55rem; }
  .conn-head .lv-cta { justify-self: end; }
  .conn-head .hint { grid-column: 1 / -1; }
}

/* the doorway to the live map, set into the Connected-pools masthead —
   solid enough to be found, quiet enough to belong */
.lv-cta[hidden] { display: none; }
.lv-cta {
  display: inline-flex; align-items: center; gap: .55rem;
  align-self: center;
  padding: .6rem 1.1rem;
  font-family: var(--mono); font-size: .66rem; font-weight: 700; letter-spacing: .18em;
  color: var(--ink);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--pink) 16%, transparent),
      color-mix(in srgb, var(--pink) 6%, transparent)),
    var(--paper-2);
  border: 1px solid color-mix(in srgb, var(--pink) 45%, var(--rule-2));
  border-radius: 999px;
  cursor: pointer;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .08),
    0 10px 26px -18px color-mix(in srgb, var(--pink) 60%, transparent);
  transition: border-color .2s, box-shadow .2s, transform .15s;
}
.lv-cta:hover {
  border-color: var(--pink);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .1),
    0 12px 30px -16px color-mix(in srgb, var(--pink) 75%, transparent);
  transform: translateY(-1px);
}
@media (max-width: 900px) {
  /* one line always — the pill must not fold in two on a phone */
  .lv-cta { font-size: .52rem; padding: .45rem .7rem; letter-spacing: .12em; white-space: nowrap; }
}

/* the board's own name, engraved above the stone */
.lm-boardtitle {
  font-family: var(--mono); font-weight: 700; letter-spacing: .34em;
  fill: color-mix(in srgb, var(--pink) 14%, var(--ink));
}

/* the dock wears its name the way the strip labels do */
.lm-kick {
  font-family: var(--mono); font-weight: 500;
  fill: color-mix(in srgb, var(--pink) 12%, var(--ink-2));
  letter-spacing: .2em;
}

@media (max-width: 640px) {
  .lmap-cap {
    bottom: calc(var(--s3) + 66px);
    white-space: normal; text-align: center;
    max-width: calc(100vw - 2 * var(--s3));
    border-radius: var(--r-lg);
    font-size: .52rem;
  }
  /* the captions teach on a phone; the key would crowd the stone */
  .lmap-key { display: none; }
}
