/* ===== $Send design system — cypherpunk synthwave =====
 * Identity hues (green/gold/diamond) are unchanged: they ARE the brand.
 * Everything else moved from blue-black to a violet-black ramp, which is what
 * makes neon read as neon rather than as "bright colour on grey".
 *
 * SILENT-FAILURE WARNINGS for future edits:
 *  - Restoring `body { background: var(--ink) }` deletes the horizon grid and
 *    scanlines with no error, because both are body pseudo-elements.
 *  - Any ancestor of body gaining transform/filter/will-change/contain breaks
 *    `position: fixed` on those two layers.
 *  - --ink-4 is DECORATIVE ONLY. Interactive borders use --edge-ctl, which is
 *    the only value that clears WCAG 1.4.11 (3:1) against our surfaces.
 *  - --focus is deliberately NOT accent-derived. prefs.js lets a user set the
 *    accent to anything, including something invisible; the focus ring must
 *    survive that, so it is pinned to --text.
 */
:root {
  /* ---------- IDENTITY (prefs.js live-overrides the first three) ---------- */
  /* The acid green the brand art is built on. It was #b4ff2b — already a yellow-green, and close — but
     the mark sits on a field that is a shade deeper and more saturated, and "close" is what makes a logo
     look like it was dropped onto somebody else's site. prefs.js live-overrides these three per reader,
     so this is the DEFAULT accent, not a fixed value anything may assume.

     --green-dark is NOT free to follow the hue down. Seventeen rules paint a button as
     `linear-gradient(180deg, var(--green-bright), var(--green-dark))` with a fixed --on-green label, and
     the label spans the whole button — so the contrast that matters is against the gradient's BOTTOM.
     A first pass took it to #5e7a00, which is the right hue and a 39% luminance drop, and put that
     label at 3.44:1: a real WCAG failure on every primary button on the site, introduced by the
     rebrand and invisible to any check that only measures tokens against the page background.
     #7e9a00 keeps the new hue at the old luminance — 5.26:1 on the label, 6.05:1 as a hairline. */
  --green: #a8ce00; --green-bright: #c6f000; --green-dark: #7e9a00;
  --rh-green: #00C805; --gold: #ffb340; --gold-deep: #e07b00;
  --diamond: #9fe0ff; --diamond-deep: #2a7fb0; --red: #ff5d5d;

  /* ---------- ATMOSPHERE (decoration only — never text, never state) ---------- */
  --neon-magenta: #ff3ba7; --neon-violet: #a45cff; --neon-cyan: #45e5ff;

  /* ---------- SURFACE RAMP ----------
     Was a VIOLET-black ramp, chosen (see the note at the top of this file) because violet is what made
     the old neon read as neon rather than as bright colour on grey. The brand's marks are MATTE NEUTRAL
     black, so that violet cast was the one thing on the page actively disagreeing with the logo.

     Not a pure neutral grey either — a ramp with no bias at all reads as unconsidered, and grey under an
     acid-green accent reads as cold. The bias is a few points toward the accent's own hue, so the dark
     belongs to the same family as the mark sitting on it. Every step keeps or improves the contrast it
     had: --text-dim went 9.59 → 10.18, --text-mute 6.58 → 6.86. */
  --void:  #000000;
  --ink:   #050604;
  --ink-1: #020301; /* darkest ink — high-contrast text ON bright green/gold highlights */
  --ink-2: #0c0e09;
  --ink-3: #14170f;
  --ink-4: #22261b; /* DECORATIVE separator ONLY — not a control boundary */
  --ink-5: #3a4032;

  /* ---------- TEXT ----------
     The blue cast went with the violet ramp; on a green-biased dark it read as a second accent nobody
     asked for. Warmed to a near-white that belongs to the same family, at the same contrast. */
  --text: #f2f6ec; --text-dim: #b6beac; --text-mute: #949c8a;

  /* ---------- FOCUS (never accent-derived — prefs.js must not be able to hide it) ---------- */
  --focus: #f2f6ec;
  /* How much of the bottom of the VIEWPORT the two pinned controls own — #music-player (bottom 1rem,
     ~61px tall, z 250) and #compose-fab (bottom 1rem, ~51px, z 240). Anything that puts a control near
     the bottom of the screen has to clear this or the pinned ones sit on top of it: they are pinned to
     the viewport, not to the column, so it happens at every width, not just on a phone. Declared once
     because it was already being re-derived in two places. */
  --fab-clear: calc(5.5rem + env(safe-area-inset-bottom, 0px));
  --focus-halo: rgba(5,3,14,0.92);

  /* ---------- INK-ON-ACCENT ---------- */
  --on-green: var(--ink-1); --on-gold: var(--ink-1); --on-diamond: #04121c; --on-red: #140606;

  /* ---------- CONTROL FILLS ----------
     Every button on the site carries BLACK type (--on-green / --on-gold / --ctl-ink). A control that is
     not a brand-gradient primary therefore needs a LIGHT fill under it — a transparent or ink-coloured
     pill with black type is invisible. The ladder: rest → hover lightens toward --text → selected takes
     the green (or gold) fill → disabled drops to a muted mix that still clears 4.5:1 for --ink-1.
     Mixes of tokens only, so prefs.js's re-solved --text / --green families carry straight through. */
  /* Every control fill is the brand green — never a white wash. Black type sits on all of them, and
     --green-dark is the floor: prefs.js lifts a user-chosen accent until --ink-1 clears 4.5:1 on it. */
  --ctl-fill: var(--green);
  --ctl-fill-hi: var(--green-bright);
  --ctl-fill-lo: var(--green-dark);
  --ctl-fill-mute: var(--green-dark);
  --ctl-fill-dis: color-mix(in srgb, var(--green-dark) 75%, var(--ink-4) 25%);
  /* the matrix grid every control wears: dark cells on the green, lit cells around the pointer */
  --mx-line: color-mix(in srgb, var(--ink-1) 26%, transparent);
  --mx-cell: var(--green-bright);
  --mx-glow: color-mix(in srgb, var(--green-bright) 55%, transparent);
  --mx-size: 7px;
  --ctl-ink: var(--ink-1);

  /* ---------- CONTROL BOUNDARY (WCAG 1.4.11 >= 3:1) ---------- */
  --edge-ctl: #7e8a6e;
  --edge-ctl-lit: var(--green);

  /* ---------- ACCENT TINTS (follow the user's accent automatically) ---------- */
  --g-wash: color-mix(in srgb, var(--green) 7%,  transparent);
  --g-tint: color-mix(in srgb, var(--green) 13%, transparent);
  --g-veil: color-mix(in srgb, var(--green) 22%, transparent);
  --g-edge: color-mix(in srgb, var(--green) 33%, transparent);
  --g-lit:  color-mix(in srgb, var(--green) 45%, transparent);
  --g-hot:  color-mix(in srgb, var(--green) 62%, transparent);
  --o-wash: color-mix(in srgb, var(--gold) 7%,  transparent);
  --o-tint: color-mix(in srgb, var(--gold) 13%, transparent);
  --o-veil: color-mix(in srgb, var(--gold) 22%, transparent);
  --o-edge: color-mix(in srgb, var(--gold) 35%, transparent);
  --o-lit:  color-mix(in srgb, var(--gold) 45%, transparent);
  --o-hot:  color-mix(in srgb, var(--gold) 62%, transparent);
  --r-wash: color-mix(in srgb, var(--red) 8%,  transparent);
  --r-tint: color-mix(in srgb, var(--red) 15%, transparent);
  --r-edge: color-mix(in srgb, var(--red) 40%, transparent);
  --d-tint: color-mix(in srgb, var(--diamond) 12%, transparent);
  --d-edge: color-mix(in srgb, var(--diamond) 40%, transparent);

  /* ---------- GLASS ---------- */
  /* These are the ramp again, as rgba so they can sit translucently over content — and being rgba they
     are INVISIBLE to any search for hex colours, which is how they stayed violet while every token
     around them moved. They paint the nav, the mobile menu, modal scrims and card surfaces, i.e. the
     most-seen chrome on every page. Same alphas, new ramp. */
  --glass-nav:   rgba(5, 6, 4, 0.86);     /* --ink   */
  --glass-menu:  rgba(5, 6, 4, 0.975);    /* mobile dropdown sits over scrolling content — stays near-opaque */
  --glass-scrim: rgba(0, 0, 0, 0.80);       /* --void  */
  --glass-hi:    rgba(20, 23, 15, 0.82);    /* --ink-3 */
  --glass-lo:    rgba(12, 14, 9, 0.86);    /* --ink-2 */
  --glass-well:  rgba(2, 3, 1, 0.55);       /* --ink-1 */
  --glass-sheen: color-mix(in srgb, var(--green) 9%, transparent);    /* green, not a white wash — the world layer is one colour */
  --glass-edge:  color-mix(in srgb, var(--green) 20%, transparent);
  --hair:        color-mix(in srgb, var(--green) 14%, transparent);
  --blur: 18px; --blur-sm: 10px; --blur-scrim: 8px; --sat: 1.35;

  /* ---------- GLOW ---------- */
  --glow-g: color-mix(in srgb, var(--green) 55%, transparent);
  --glow-o: color-mix(in srgb, var(--gold) 50%, transparent);
  --glow-d: rgba(159,224,255,0.50);
  --glow-m: rgba(255,59,167,0.45);
  --glow-r: rgba(255,93,93,0.45);
  --glow-1: 8px; --glow-2: 20px; --glow-3: 44px;
  --shadow-1: 0 2px 10px rgba(3,2,10,0.45);
  --shadow-2: 0 12px 30px rgba(3,2,10,0.50);
  --shadow-3: 0 24px 56px rgba(3,2,10,0.60);

  /* ---------- GRID / SCANLINE ---------- */
  --grid-line: color-mix(in srgb, var(--green) 9%, transparent);   /* was magenta — the last of the old identity in the world layer */
  --grid-line-2: color-mix(in srgb, var(--green) 15%, transparent);
  --grid-gap: 48px; --grid-tilt: 58deg; --grid-persp: 340px;
  /* referenced by components but never defined — they resolved to their fallbacks (an old blue-black) or inherited */
  --bg-1: var(--ink-2); --mono: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace); --muted: var(--text-dim);
  --red-soft: #ffb4b4;   /* loss text on dark wells; was the same literal in seven places */
  --scan: rgba(255,255,255,0.026); --scan-period: 3px;

  /* ---------- GEOMETRY / MOTION / TYPE ---------- */
  --r-1: 10px; --r-2: 14px; --r-3: 18px; --r-4: 22px; --r-pill: 999px;
  --dur-1: 120ms; --dur-2: 180ms; --dur-3: 320ms; --dur-4: 600ms;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-pop: cubic-bezier(0.2, 2.2, 0.4, 1);
  --ease-xp:  cubic-bezier(0.2, 0.8, 0.3, 1);
  --font-body: 'Rubik', system-ui, -apple-system, sans-serif;
  --font-disp: 'Luckiest Guy', 'Rubik', cursive;
  /* ---------- TEXT SIZE: a fluid scale with a floor ----------
     Every font-size in every stylesheet, inline style and script-built style is max(var(--text-floor), <its size>)
     (tests/textsize.mjs holds the line), and the rem scale hangs off --text-base on <html>. Both grow with the
     viewport: on a phone (375px) the base is the reader's own 1rem (16px by default — the text a phone always had)
     and nothing is smaller than 14px, the accessibility floor for the smallest captions; from there both rise
     linearly with the width to a 1.25rem base and a 19pt (25.3px) floor at 1280px and wider. rem on <html> means a
     reader's browser font-size preference still scales the whole site; browser zoom scales all of it too. */
  --text-floor: clamp(14px, calc(14px + (100vw - 375px) * 0.01252), 19pt);
  --text-base: clamp(1rem, calc(1rem + (100vw - 375px) * 0.00442), 1.25rem);
  /* ---------- THE NAV'S OWN SCALE ----------
     A bar has one row to spend, so its text does not follow the page floor: links and the wordmark use --nav-fs
     (15px on a phone, 17px from 1500px up), the pills' labels and figures --nav-fs-s (13px to 15px) — never
     under 13px, the floor for a control label. Every pill and button in the bar is --nav-ctl tall (44px where a
     finger does the pointing). tests/textsize.mjs allows exactly these tokens outside the page floor. */
  --nav-fs: clamp(15px, calc(15px + (100vw - 375px) * 0.00178), 17px);
  --nav-fs-s: clamp(13px, calc(13px + (100vw - 375px) * 0.00178), 15px);
  --nav-ctl: 40px;
  /* the notification count: a circle sized with the bell (20px on a phone, 22px from 1500px up) and digits at 58%
     of it — about 12–13px bold, so "9+" sits inside the red circle at every width instead of spilling out of it */
  --notif-badge: clamp(20px, calc(20px + (100vw - 375px) * 0.00178), 22px);
  --nav-fs-badge: calc(var(--notif-badge) * 0.58);
  /* ---------- TEXT DRAWN INSIDE A GRAPHIC ----------
     A label painted into a ring or a medal has to fit the graphic's geometry, so it is sized in the graphic's own
     units and grows with the graphic — the page floor would push it into its neighbours (the level ring's "LEVEL"
     sat on its number). The dashboard ring itself grows with the text scale: 148px on a phone to 188px. */
  --gfx-ring: clamp(148px, calc(var(--text-floor) * 7), 188px);
  --gfx-ring-num: 30px;     /* SVG user units in a 120-unit viewBox: 37px on a phone, 44–47px on a desktop */
  --gfx-ring-lbl: 11px;     /* 13.6px on a phone, 16–17px on a desktop */
  --gfx-relic-lv: 13px;     /* the diamond medal's "LV n", in its own 120-unit viewBox */
  --fs-micro: 0.75rem; --fs-xs: 0.8125rem; --fs-s: 0.875rem; --fs-base: 1rem;
  --fs-m: 1.125rem; --fs-l: 1.375rem;
  --fs-xl: clamp(1.5rem, 3.4vw, 2rem);
  --fs-2xl: clamp(1.9rem, 4.6vw, 3rem);
  --fs-3xl: clamp(2.4rem, 7vw, 4.6rem);
  --lh-tight: 1.08; --lh-snug: 1.35; --lh-body: 1.6; --lh-loose: 1.72;
  --tr-display: 0.02em; --tr-caps: 0.08em;
}

/* Static fallbacks for engines without color-mix(). Values are the same mixes
   pre-computed against the default accent, so the site degrades in shade only. */
@supports not (color: color-mix(in srgb, red 50%, transparent)) {
  :root {
    /* rgba of --green, so it must move with it. These were still 142,224,0 — the retired #8ee000 — which
       meant every green wash on the site rendered in the OLD brand on any engine without color-mix().
       An rgba fallback for a token is a second copy of that token, and a second copy is what gets left
       behind by a rebrand. */
    --g-wash: rgba(168,206,0,0.07);  --g-tint: rgba(168,206,0,0.13);
    --g-veil: rgba(168,206,0,0.22);  --g-edge: rgba(168,206,0,0.33);
    --g-lit:  rgba(168,206,0,0.45);  --g-hot:  rgba(168,206,0,0.62);
    --o-wash: rgba(255,179,64,0.07); --o-tint: rgba(255,179,64,0.13);
    --o-veil: rgba(255,179,64,0.22); --o-edge: rgba(255,179,64,0.35);
    --o-lit:  rgba(255,179,64,0.45); --o-hot:  rgba(255,179,64,0.62);
    --r-wash: rgba(255,93,93,0.08);  --r-tint: rgba(255,93,93,0.15);
    --r-edge: rgba(255,93,93,0.40);
    --d-tint: rgba(159,224,255,0.12); --d-edge: rgba(159,224,255,0.40);
    --ctl-fill: #a8ce00; --ctl-fill-dis: #6d8318;
    --mx-line: rgba(2,3,1,0.26); --mx-glow: rgba(198,240,0,0.55);
    --glass-sheen: rgba(168,206,0,0.09); --glass-edge: rgba(168,206,0,0.20); --hair: rgba(168,206,0,0.14);
    --glow-g: rgba(168,206,0,0.55);   --glow-o: rgba(255,179,64,0.50);
    --grid-line-2: rgba(168,206,0,0.15);
  }
}

* { margin: 0; padding: 0; box-sizing: border-box; }
[hidden] { display: none !important; }
html { scroll-behavior: smooth; font-size: var(--text-base); }
/* a contract address or a hash is one unbreakable string: it may break anywhere rather than run off a phone's screen */
code, .mono, .addr { overflow-wrap: anywhere; }
/* ...except where an address is drawn to fit its box on ONE line: as much of it as fits, then …, then always its last
   4 characters (0x1234…abcd at the narrowest). Markup: <code class="addr-fit"><span class="addr-head">all but the
   last 4</span><span class="addr-tail">last 4</span></code>, the two halves aria-hidden beside an sr-only copy of the
   whole address — a reader hears it once, in one piece. */
.addr-fit { display: inline-flex; max-width: 100%; min-width: 0; white-space: nowrap; overflow-wrap: normal; word-break: normal; vertical-align: bottom; }
.addr-fit .addr-head { min-width: 7ch; overflow: hidden; text-overflow: ellipsis; }
.addr-fit .addr-tail { flex: none; }

body {
  background: var(--ink);
  color: var(--text);
  font-family: 'Rubik', system-ui, -apple-system, sans-serif;
  font-size: max(var(--text-floor), 1rem);   /* what every element with no size of its own inherits: never under the floor */
  line-height: 1.5;                          /* body copy at the spacing WCAG 1.4.12 expects; headings and controls set their own */
  overflow-x: hidden;
}

.display { font-family: 'Luckiest Guy', 'Rubik', cursive; font-weight: 400; letter-spacing: 0.02em; }

a { color: var(--gold); }

/* ===== Nav ===== */
.nav {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; gap: 0.75rem; flex-wrap: nowrap; min-height: 60px;
  padding: 0.5rem 1rem;
  background: color-mix(in srgb, var(--ink) calc(0.86 * 100%), transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--hair);
}
.nav-logo { display: flex; align-items: center; justify-content: center; gap: 0.55rem; min-width: var(--nav-ctl); min-height: var(--nav-ctl); text-decoration: none; }   /* a control like the rest of the bar: the 42px mark was 2px short of the 44px a finger gets */
.nav-logo img { width: 42px; height: 42px; filter: drop-shadow(0 0 10px color-mix(in srgb, var(--green) 50%, transparent)); }
.nav-logo span { font-family: 'Luckiest Guy', cursive; font-size: calc(var(--nav-fs) * 1.35); color: var(--green-bright); }
.nav-menu { display: flex; align-items: center; gap: 0.1rem; margin-left: auto; flex-wrap: wrap; min-width: 0; }   /* wraps only while nav.js measures; a row that would wrap becomes the pop-down */
.nav-menu a {
  color: var(--text-mute); text-decoration: none; font-weight: 600; font-size: var(--nav-fs); letter-spacing: 0.01em; white-space: nowrap;
  display: inline-flex; align-items: center; min-height: var(--nav-ctl); padding: 0 0.5rem; border-radius: 999px; transition: color 0.15s ease, background 0.15s ease;
}
/* the balances pill never rides in the bar: one row to spend, and the balances live on the profile and the connected-wallet card */
.nav .nav-bal { display: none !important; }
/* while nav.js measures the bar, the pop-down's open/close transitions are off — or every measurement (page load,
   resize, sign-in) would briefly fade the closed menu in and out */
.nav.is-measuring .nav-menu, .nav.is-measuring .nav-menu * { transition: none !important; }
/* nothing in the row is ever squashed — a pill, the bell or the logo mark at the wrong width is a broken graphic. When
   the row cannot fit, nav.js steps down through measured tiers instead: .is-tight drops the live count and the
   Send Power figures; .is-tighter the wordmark and the @name (the avatar stays); .is-tightest the level pill; .is-bare,
   the last, the OG badge in the name pill (an OG member's bar was still 29px past a 320px phone without it). */
.nav > *:not(.nav-menu), #nav-auth.nav-persist > *, .nav-profile > * { flex-shrink: 0; }
.nav-logo img { flex: 0 0 auto; }
.profile-link .pl-name { display: inline-block; white-space: nowrap; vertical-align: bottom; }   /* shown whole or not at all: nav.js hides it (.is-tighter) when the bar has no room */
.nav.is-tight .nav-live, .nav.is-tight .nav-xp-sep, .nav.is-tight .nav-xp-pts, .nav.is-tight .nav-xp-boost { display: none; }
.nav.is-tighter .nav-logo span, .nav.is-tighter .profile-link .pl-name { display: none; }
.nav.is-tighter .profile-link .pl-ava { margin-right: 0; }   /* with the name hidden, the gap it kept sat on one side and pushed the avatar 3px off the pill's middle */
.nav.is-tighter { gap: 0.45rem; }   /* the 3px this saves keeps a one-digit level pill on a 360px phone now that the logo and the pill are a full --nav-ctl */
.nav.is-tightest .nav-xp { display: none; }
.nav.is-tightest { gap: 0.35rem; padding-left: 0.6rem; padding-right: 0.6rem; }
.nav.is-bare .profile-link .og-badge { display: none; }
.nav-menu a:hover { color: var(--green-bright); background: color-mix(in srgb, var(--green) 10%, transparent); }
.nav-menu a.active { color: var(--on-green); background: var(--green); }

/* persistent right-side cluster: Send Level + account button — always visible, even collapsed */
#nav-auth.nav-persist { display: inline-flex; align-items: center; gap: 0.35rem; }
.profile-link {
  color: var(--on-gold); text-decoration: none; font-weight: 800; font-size: var(--nav-fs); font-family: inherit;
  padding: 0 0.9rem; border-radius: 999px; white-space: nowrap; border: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 0.3rem; min-height: var(--nav-ctl);
  background: linear-gradient(180deg, var(--gold), var(--gold-deep));
  transition: transform 0.15s ease;
}
.profile-link:hover { transform: translateY(-1px); }
.profile-link:focus-visible { outline: 3px solid var(--green-bright); outline-offset: 2px; }
.pl-ava { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; margin-right: 0.4rem; border-radius: 50%; overflow: hidden; }
.pl-ava-emo { font-size: var(--nav-fs-s); line-height: 1; }   /* inside a 24px circle: the nav's scale, not the page floor */
.pl-img { width: 24px; height: 24px; border-radius: 50%; object-fit: cover; display: block; }
.pl-name { min-width: 0; white-space: nowrap; }   /* whole or hidden, never cut (see .profile-link .pl-name) */
.np-caret { flex: 0 0 auto; font-size: max(var(--text-floor), 0.7rem); line-height: 1; transition: transform 0.15s ease; }
.profile-link .og-badge { flex: 0 0 auto; }
.nav-profile.open .np-caret { transform: rotate(180deg); }

/* ===== Nav account menu (hover on desktop · click/keyboard everywhere) ===== */
.nav-profile { position: relative; display: inline-flex; }
.nav-profile-menu {
  position: absolute; top: calc(100% + 0.5rem); right: 0; z-index: 60; min-width: 224px;
  background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 14px; padding: 0.4rem;
  box-shadow: 0 14px 40px rgba(0,0,0,0.5), 0 0 0 1px color-mix(in srgb, var(--green) 6%, transparent); display: grid; gap: 0.12rem;
}
.npm-item {
  display: flex; align-items: center; gap: 0.55rem; width: 100%; text-align: left;
  padding: 0.6rem 0.7rem; border-radius: 10px; border: none; background: var(--ctl-fill-lo); cursor: pointer;
  color: var(--ctl-ink); font-family: 'Rubik', sans-serif; font-weight: 700; font-size: max(var(--text-floor), 0.9rem);
  text-decoration: none; transition: background 0.12s ease, color 0.12s ease;
}
.npm-item:hover, .npm-item:focus-visible { background: var(--green); color: var(--on-green); }
.npm-ico { flex: 0 0 auto; width: 1.2em; text-align: center; }
.npm-sep { height: 1px; background: var(--ink-4); margin: 0.25rem 0.2rem; }
.npm-danger { background: var(--ctl-fill-mute); color: var(--ctl-ink); }
.npm-danger:hover, .npm-danger:focus-visible { background: var(--red); color: var(--on-red); }
.npm-item.armed { background: var(--red-soft); color: var(--ctl-ink); }
@media (prefers-reduced-motion: reduce) { .np-caret, .profile-link { transition: none; } }

/* ===== Auth modal: log in / sign up segmented choice (login-first) ===== */
.auth-segment {
  display: grid; grid-template-columns: 1fr 1fr; gap: 0.3rem; margin: 0 0 1rem;
  background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 999px; padding: 0.28rem;
}
.auth-seg {
  display: inline-flex; align-items: center; justify-content: center; min-height: 40px;
  border: none; background: none; border-radius: 999px; cursor: pointer;
  color: var(--ctl-ink); font-family: 'Rubik', sans-serif; font-weight: 800; font-size: max(var(--text-floor), 0.95rem);
  transition: background 0.14s ease, color 0.14s ease;
}
.auth-seg.active { background: linear-gradient(180deg, var(--green-bright), var(--green-dark)); color: var(--on-green); }
.auth-seg:focus-visible { outline: 3px solid var(--ctl-ink); outline-offset: 2px; }   /* the ring now sits on a light track, so it is the ink */
@media (prefers-reduced-motion: reduce) { .auth-seg { transition: none; } }
/* sign-up extras: a quiet hint beside a label, the optional email+password fold, and the opt-in boxes */
.f-hint { font-weight: 500; color: var(--text-dim); }
.w-extra { margin: 0.4rem 0 0.2rem; border: 1px solid var(--ink-4); border-radius: var(--r-2, 12px); padding: 0.5rem 0.75rem; }
.w-extra > summary { cursor: pointer; font-weight: 700; font-size: max(var(--text-floor), 0.88rem); list-style: none; }
.w-extra > summary::-webkit-details-marker { display: none; }
.w-extra > summary:focus-visible { outline: 3px solid var(--focus, var(--green-bright)); outline-offset: 2px; border-radius: 6px; }
.w-extra[open] > summary { margin-bottom: 0.2rem; }
.w-opt { display: flex; align-items: center; gap: 0.5rem; margin: 0.7rem 0 0.4rem; font-size: max(var(--text-floor), 0.88rem); font-weight: 600; cursor: pointer; }
.w-opt input { width: 1.05rem; height: 1.05rem; accent-color: var(--green-bright); flex: none; }
/* the confirm pane is about the account in hand: no "or continue with Google" under it */
#auth-modal.is-confirm #oauth-row { display: none; }
#pane-confirm #cf-go { margin-top: 0.8rem; }
/* Security card: the unlock state, and the note a brand-new account lands on */
.sudo-bar { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; margin: 0 0 0.9rem;
  padding: 0.55rem 0.75rem; border-radius: var(--r-2, 12px); border: 1px solid var(--ink-4); background: var(--ctl-fill-lo); font-size: max(var(--text-floor), 0.85rem); font-weight: 600; }
.sudo-bar.is-open { border-color: color-mix(in srgb, var(--green) 45%, transparent); background: color-mix(in srgb, var(--green) 10%, transparent); }
.setup-2fa-note { padding: 0.6rem 0.75rem; border-radius: var(--r-2, 12px); background: color-mix(in srgb, var(--gold) 10%, transparent); border: 1px solid color-mix(in srgb, var(--gold) 40%, transparent); }

/* hamburger toggle — hidden on desktop, revealed when the nav collapses (≤1280px: 8 links + search + bell + account need ~1280 to sit on one line) */
.nav-toggle {
  display: none; width: var(--nav-ctl); height: var(--nav-ctl); flex: 0 0 auto;
  align-items: center; justify-content: center;
  border: none; background: var(--ctl-fill-lo); cursor: pointer; border-radius: 12px;
  -webkit-tap-highlight-color: transparent;
}
.nav-toggle:hover { background: var(--ctl-fill-hi); }
.nav-toggle:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--green-bright); }
.nav-toggle-bars, .nav-toggle-bars::before, .nav-toggle-bars::after {
  content: ''; display: block; width: 22px; height: 2.5px; border-radius: 2px;
  background: var(--ctl-ink); transition: transform 0.25s ease, opacity 0.2s ease;
}
.nav-toggle-bars { position: relative; }
.nav-toggle-bars::before { position: absolute; top: -7px; left: 0; }
.nav-toggle-bars::after  { position: absolute; top: 7px;  left: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars { background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::before { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::after  { transform: translateY(-7px) rotate(-45deg); }

/* ===== Collapsible mobile nav (pop-down panel) ===== */
/* The pop-down form of the menu. nav.js puts .is-compact on the bar whenever the row of links would wrap or
   overflow — measured, not guessed by width, because the signed-in cluster (bell, level, live count, balances,
   account) is hundreds of px wider than the signed-out one. The pages ship the class on, so nothing flashes. */
.nav.is-compact .nav-toggle { display: inline-flex; order: 3; }
.nav.is-compact #nav-auth.nav-persist { margin-left: auto; order: 2; }
.nav.is-compact .nav-menu {
    order: 4;
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 0.15rem;
    margin: 0; padding: 0.5rem 1rem calc(0.7rem + env(safe-area-inset-bottom, 0px));
    background: color-mix(in srgb, var(--ink) calc(0.98 * 100%), transparent); backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--g-veil);
    box-shadow: 0 22px 44px rgba(0,0,0,0.55);
    max-height: 0; overflow: hidden; opacity: 0; visibility: hidden;
    transition: max-height 0.28s ease, opacity 0.24s ease, visibility 0.28s; }
.nav.is-compact .nav-menu.open { max-height: var(--menu-room, min(80vh, 560px)); overflow-y: auto; overscroll-behavior: contain; opacity: 1; visibility: visible;
  scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--green) 60%, transparent) transparent; }
/* Owner, 2026-10-15: "make sure there is no scroll if there doesn't have to be on the page menu if you have to have a scroll on
   smaller screens make sure users know they need to scroll". The pop-down is as tall as its links need, up to the room under the
   bar (--menu-room, set by nav.js — it was capped at 560px, under the ~580px the links take, so it scrolled on every screen).
   When one column would not fit there the links go into columns as wide as the widest link (--menu-col, measured); only when
   even that is too tall does it scroll, and then the "Scroll for more ↓" button (nav.js) sits at the bottom until the end, with a
   shade along the top once it has moved. The button is a real target: a tap on it scrolls, never lands on a link under it. */
.nav.is-compact .nav-menu.is-cols { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--menu-col, 8em)), 1fr)); align-content: start; gap: 0.15rem 0.3rem; }
.nav.is-compact .nav-menu.is-cols > #nav-search-slot { grid-column: 1 / -1; }
.nav.is-compact .nav-menu.is-cols a { justify-content: center; text-align: center; padding-inline: 0.5rem; }
.nav-more { display: none; }
.nav.is-compact .nav-menu.open.has-more > .nav-more {
  display: block; position: sticky; bottom: 0; z-index: 1; grid-column: 1 / -1; flex: none; width: 100%; min-height: 44px;
  margin: 0.3rem 0 0; padding: 0.4rem 0.5rem; border: 0; border-radius: 12px; cursor: pointer;
  font: inherit; font-size: max(var(--text-floor), 0.85rem); font-weight: 800; letter-spacing: 0.02em; line-height: 1.2; text-align: center;
  color: var(--green-bright); background: var(--ink); box-shadow: 0 -18px 14px -4px var(--ink); }   /* the shadow is the fade above it */
.nav.is-compact .nav-menu.open.has-more > .nav-more:hover, .nav.is-compact .nav-menu.open.has-more > .nav-more:focus-visible { background: var(--ink-2); outline: 2px solid var(--green); outline-offset: -2px; }
.nav.is-compact .nav-menu.open.has-more { scroll-padding-bottom: 3.6rem; }   /* a link reached with Tab scrolls clear of the button */
.nav.is-compact .nav-menu.open.is-scrolled { box-shadow: inset 0 12px 10px -10px rgba(0,0,0,0.75), 0 22px 44px rgba(0,0,0,0.55); }
@media (forced-colors: active) { .nav.is-compact .nav-menu.open.has-more > .nav-more { background: ButtonFace; color: ButtonText; border: 1px solid ButtonText; box-shadow: none; } }
/* the pop-down sits under the menu button on the right, so its links line up on the right edge too, and the sender
   search comes first (it is first in each page's markup, so the tab order agrees) */
.nav.is-compact .nav-menu a { font-size: calc(var(--nav-fs) * 1.06); padding: 0.6rem 1rem; min-height: 44px; border-radius: 12px; white-space: normal; justify-content: flex-end; text-align: right; }
.nav.is-compact #nav-search-slot { width: 100%; margin: 0 0 0.35rem; }
/* in the wide bar the search keeps its place at the end of the row of links */
.nav:not(.is-compact) #nav-search-slot { order: 1; }
.nav.is-compact #nav-search-slot.nav-search input, .nav.is-compact .nav-menu .nav-search input:focus { width: 100% !important; }
.nav.is-compact .nav-bal { display: none !important; }
.nav.is-compact #nav-auth.nav-persist, .nav.is-compact .nav-profile { min-width: 0; }
.nav.is-compact .profile-link { white-space: nowrap; }
@media (prefers-reduced-motion: reduce) {
  .nav-menu { transition: none; }
  .nav-toggle-bars, .nav-toggle-bars::before, .nav-toggle-bars::after { transition: none; }
}

/* ===== Ticker ===== */
.ticker {
  background: linear-gradient(90deg, var(--green-dark), var(--green), var(--green-dark));
  color: #08130a; font-weight: 800; font-size: max(var(--text-floor), 0.95rem); padding: 0.45rem 0;
  white-space: nowrap; overflow: hidden; position: relative; z-index: 20;
}
.ticker-track { display: inline-block; animation: ticker 22s linear infinite; }
.ticker-track span { margin: 0 1.4rem; }
@keyframes ticker { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ===== Hero ===== */
.hero {
  position: relative; min-height: 88vh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 3rem 1.25rem 4.5rem;
  /* overflow was written to crop the background video. The video is gone and this stays: it is now the only
     thing clipping the .float-emoji spans, which travel 26px past these edges. Not a leftover to sweep. */
  overflow: hidden;
  background: radial-gradient(ellipse 90% 60% at 50% 110%, color-mix(in srgb, var(--green) 18%, transparent), transparent 60%),
              radial-gradient(ellipse 60% 40% at 80% -10%, rgba(255,179,64,0.12), transparent 60%),
              var(--ink);
}
.hero::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(ellipse 70% 60% at 50% 45%, transparent 30%, var(--ink) 100%);
  pointer-events: none;
}
.hero > .hero-content { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: center; }
.hero-logo {
  width: min(340px, 68vw); height: auto; cursor: pointer;
  filter: drop-shadow(0 0 45px var(--glow-g)) drop-shadow(0 12px 30px rgba(0,0,0,0.6));
  animation: bob 4s ease-in-out infinite;
  transition: transform 0.2s ease;
}
.hero-logo:hover { animation-play-state: paused; transform: scale(1.04) rotate(1deg); }   /* bob owns transform otherwise */
@keyframes bob {
  0%, 100% { transform: translateY(0) rotate(-1.5deg); }
  50% { transform: translateY(-14px) rotate(1.5deg); }
}
.hero h1 {
  font-size: max(var(--text-floor), clamp(2.4rem, 7vw, 4.6rem)); line-height: 1.05; margin-top: 1.4rem;
  color: var(--green-bright);
  text-shadow: 0 3px 0 var(--green-dark), 0 8px 24px rgba(0,0,0,0.8);
  transform: rotate(-2deg);
}
.hero h1 .rocket { display: inline-block; animation: rocket-wiggle 1.6s ease-in-out infinite; }
@keyframes rocket-wiggle {
  0%, 100% { transform: translate(0,0) rotate(0deg); }
  25% { transform: translate(2px,-4px) rotate(8deg); }
  75% { transform: translate(-2px,2px) rotate(-6deg); }
}
.hero .tag { margin-top: 1rem; font-size: max(var(--text-floor), clamp(1rem, 2.4vw, 1.3rem)); font-weight: 600; color: var(--text-dim); max-width: 40ch; }
/* what the site is, in one plain sentence: for a first-time visitor, and for the search engines and AI crawlers that read the
   HTML without running scripts (the H1 is a slogan) */
.hero .hero-lede { margin: 0.6rem auto 0; max-width: 52ch; font-size: max(var(--text-floor), 0.95rem); line-height: 1.55; color: var(--text-dim); text-align: center; text-wrap: balance; }
.hero .tag strong { color: var(--gold); }

.rh-badge {
  display: inline-flex; align-items: center; gap: 0.5rem; margin-top: 1.3rem;
  padding: 0.5rem 1.1rem; border-radius: 999px;
  border: 1.5px solid var(--rh-green);
  background: rgba(0,200,5,0.1); color: var(--rh-green);
  font-weight: 800; font-size: max(var(--text-floor), 0.92rem); letter-spacing: 0.03em;
  box-shadow: 0 0 24px rgba(0,200,5,0.25);
}
.rh-badge .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--rh-green); animation: pulse 1.6s ease-in-out infinite; }
@keyframes pulse { 0%,100% { opacity: 1; transform: scale(1);} 50% { opacity: 0.4; transform: scale(0.7);} }

.cta-row { display: flex; gap: 1rem; flex-wrap: wrap; justify-content: center; margin-top: 2rem; }

/* ===== Buttons ===== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.4em; line-height: 1.15;
  padding: 0.9rem 2rem; border-radius: 999px; border: none; cursor: pointer;
  font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.15rem); letter-spacing: 0.04em;
  text-decoration: none; text-align: center; box-sizing: border-box;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
  /* safe default: a variant-less .btn is a light pill with black type, never a bare label */
  background: var(--ctl-fill); color: var(--ctl-ink);
}
.btn:active { transform: scale(0.93) !important; }
.btn-primary {
  background: linear-gradient(180deg, var(--green-bright), var(--green-dark)); color: var(--on-green);
  box-shadow: 0 6px 0 var(--green-dark), 0 14px 34px color-mix(in srgb, var(--green) 35%, transparent);
}
.btn-primary:hover { transform: translateY(-3px) scale(1.03); box-shadow: 0 9px 0 var(--green-dark), 0 20px 44px var(--g-lit); }
.btn-gold {
  background: linear-gradient(180deg, var(--gold), var(--gold-deep)); color: var(--on-gold);
  box-shadow: 0 6px 0 var(--gold-deep), 0 14px 34px rgba(255,179,64,0.3);
}
.btn-gold:hover { transform: translateY(-3px) scale(1.03); box-shadow: 0 9px 0 var(--gold-deep), 0 20px 44px rgba(255,179,64,0.4); }
.btn-rh {
  background: var(--rh-green); color: var(--ctl-ink);
  box-shadow: 0 6px 0 color-mix(in srgb, var(--rh-green) 70%, var(--ink)), 0 14px 34px color-mix(in srgb, var(--rh-green) 30%, transparent);
}
.btn-rh:hover { transform: translateY(-3px) scale(1.03); }
.btn-ghost {
  background: var(--ctl-fill); color: var(--ctl-ink); border: 2px solid var(--ctl-fill);
  font-family: 'Rubik', sans-serif; font-weight: 700; font-size: max(var(--text-floor), 1rem);
}
.btn-ghost:hover { border-color: var(--green); background: var(--ctl-fill-hi); color: var(--ctl-ink); transform: translateY(-2px); }
.btn-sm { padding: 0.5rem 1.1rem; font-size: max(var(--text-floor), 0.95rem); min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
/* disabled: a muted fill, still black type (>= 4.5:1), no lift, no shadow — distinguishable from the live pill without an opacity wash */
.btn:disabled, .btn[aria-disabled="true"] {
  background: var(--ctl-fill-dis); color: var(--ctl-ink); border-color: transparent;
  box-shadow: none; text-shadow: none; cursor: not-allowed; opacity: 1;
}
.btn:disabled:hover, .btn[aria-disabled="true"]:hover { transform: none; }

/* ===== Sections ===== */
section { padding: 3.6rem 1.25rem; position: relative; }
.wrap { max-width: 1040px; margin: 0 auto; }
.section-title {
  text-align: center; font-size: max(var(--text-floor), clamp(1.9rem, 4.6vw, 3rem)); color: var(--gold);
  text-shadow: 0 3px 0 var(--gold-deep);
  margin-bottom: 0.6rem; transform: rotate(-1deg);
}
.section-title.green { color: var(--green-bright); text-shadow: 0 3px 0 var(--green-dark), 0 0 30px color-mix(in srgb, var(--green) 35%, transparent); }
.section-sub { text-align: center; color: var(--text-dim); font-size: max(var(--text-floor), 1.05rem); margin-bottom: 2.4rem; max-width: 60ch; margin-left: auto; margin-right: auto; }
/* A limit-of-the-data caveat sitting inside a section subtitle — present, readable, not shouting. */
.section-sub-note { display: block; margin-top: 0.35rem; font-size: max(var(--text-floor), 0.88rem); opacity: 0.8; }

.alt-bg { background: linear-gradient(180deg, var(--ink), var(--ink-2)); }
.alt-bg-2 { background: var(--ink-2); }

/* ===== Cards ===== */
.card {
  background: var(--ink-2);
  border: 1px solid var(--hair); border-radius: var(--r-3);
  padding: 1.5rem; box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text) 5%, transparent), 0 12px 32px rgba(0,0,0,0.35);
}
.card.gold-card { border-color: rgba(255,179,64,0.4); }

/* ===== Token cards ===== */
.token-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(330px, 100%), 1fr)); gap: 1.6rem; }
.token-head { display: flex; align-items: center; gap: 0.8rem; margin-bottom: 1rem; }
.token-emblem {
  width: 54px; height: 54px; border-radius: 50%; display: grid; place-items: center;
  font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.15rem); flex-shrink: 0;
}
.token-emblem.send { background: radial-gradient(circle at 30% 30%, var(--green-bright), var(--green-dark)); color: var(--on-green); box-shadow: 0 0 22px color-mix(in srgb, var(--green) 50%, transparent); }
.token-emblem.gwc { background: radial-gradient(circle at 30% 30%, var(--gold), var(--gold-deep)); color: var(--on-gold); box-shadow: 0 0 22px rgba(255,179,64,0.5); }
.token-head h3 { font-size: max(var(--text-floor), 1.35rem); }
.token-head .sub { color: var(--text-dim); font-size: max(var(--text-floor), 0.88rem); font-weight: 600; }
/* Dexscreener branding on the token cards (logo + banner), matching each token's listing */
.tok-banner { margin: -1.6rem -1.6rem 1.1rem; border-radius: 20px 20px 0 0; overflow: hidden; line-height: 0; }
.tok-banner-img { width: 100%; height: 130px; object-fit: cover; display: block; }
.token-emblem.has-logo { background: none; overflow: hidden; padding: 0; }
.token-emblem.send.has-logo { box-shadow: 0 0 22px color-mix(in srgb, var(--green) 35%, transparent); }
.token-emblem.gwc.has-logo { box-shadow: 0 0 22px rgba(255,179,64,0.35); }
.tok-logo-img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.price-row { display: flex; align-items: baseline; gap: 0.7rem; flex-wrap: wrap; margin-bottom: 0.9rem; }
.price-big { font-size: max(var(--text-floor), 1.7rem); font-weight: 800; color: var(--green-bright); }
.price-chip { font-size: max(var(--text-floor), 0.85rem); font-weight: 700; padding: 0.15rem 0.6rem; border-radius: 999px; }
.price-chip.up { background: color-mix(in srgb, var(--green) 16%, transparent); color: var(--green-bright); }
.price-chip.down { background: rgba(255,93,93,0.14); color: var(--red); }
.stat-mini { display: flex; gap: 1.2rem; flex-wrap: wrap; color: var(--text-dim); font-size: max(var(--text-floor), 0.85rem); font-weight: 600; margin-bottom: 1rem; }
.stat-mini b { color: var(--text); }

.contract-box {
  display: flex; align-items: center; gap: 0.6rem;
  background: var(--ink); border: 1.5px dashed color-mix(in srgb, var(--green) 40%, transparent); border-radius: 12px;
  padding: 0.65rem 0.85rem; margin-bottom: 1rem;
}
.contract-box code {
  font-size: max(var(--text-floor), 0.78rem); color: var(--green-bright); word-break: break-all;
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
}
.copy-btn {
  flex-shrink: 0; background: var(--ctl-fill-lo); color: var(--ctl-ink); border: none; border-radius: 9px;
  padding: 0.45rem 0.7rem; font-weight: 700; font-size: max(var(--text-floor), 0.8rem); cursor: pointer;
  transition: all 0.12s ease;
}
.copy-btn:hover { background: var(--green); color: var(--on-green); }
.copy-btn:active { transform: scale(0.88); }

.token-links { display: flex; gap: 0.6rem; flex-wrap: wrap; }


/* ===== Guide ===== */
.step-list { display: grid; gap: 1.3rem; max-width: 780px; margin: 0 auto; counter-reset: step; }
.step {
  display: flex; gap: 1.1rem; align-items: flex-start;
  background: linear-gradient(180deg, var(--ink-3), var(--ink-2));
  border: 2px solid var(--g-veil); border-radius: 18px; padding: 1.3rem 1.4rem;
  transition: transform 0.15s ease, border-color 0.15s ease;
}
.step:hover { transform: translateX(6px); border-color: var(--glow-g); }
.step-num {
  flex-shrink: 0; width: 46px; height: 46px; border-radius: 50%;
  display: grid; place-items: center;
  background: linear-gradient(180deg, var(--green-bright), var(--green-dark)); color: var(--on-green);
  font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.3rem);
  box-shadow: 0 4px 0 var(--green-dark);
}
.step h4, .step h3 { font-size: max(var(--text-floor), 1.15rem); margin-bottom: 0.35rem; }
.step p { color: var(--text-dim); font-size: max(var(--text-floor), 0.95rem); line-height: 1.55; }
.step p b, .step li b { color: var(--text); }
.step ul { margin: 0.5rem 0 0 1.1rem; color: var(--text-dim); font-size: max(var(--text-floor), 0.92rem); line-height: 1.6; }
.step .step-actions { margin-top: 0.75rem; display: flex; gap: 0.6rem; flex-wrap: wrap; }
.security-step { border-color: rgba(255,179,64,0.45); }
.security-step .step-num { background: linear-gradient(180deg, var(--gold), var(--gold-deep)); color: var(--on-diamond); box-shadow: 0 4px 0 var(--gold-deep); }

.warn-box {
  max-width: 780px; margin: 1.6rem auto 0;
  background: var(--r-wash); border: 1px solid var(--r-edge); border-radius: var(--r-2);
  padding: 1.1rem 1.3rem; font-size: max(var(--text-floor), 0.92rem); color: var(--text-dim); line-height: 1.6;
}
.warn-box b { color: var(--red); }

.chain-params {
  width: 100%; border-collapse: collapse; margin-top: 0.6rem; font-size: max(var(--text-floor), 0.85rem);
}
.chain-params td { padding: 0.35rem 0.5rem; border-bottom: 1px solid var(--ink-4); color: var(--text-dim); }
.chain-params td:first-child { font-weight: 700; color: var(--text); white-space: nowrap; }
.chain-params code { color: var(--green-bright); font-size: max(var(--text-floor), 0.8rem); word-break: break-all; }

/* ===== Swap ===== */
.swap-panel {
  max-width: 640px; margin: 0 auto;
  background: linear-gradient(180deg, var(--ink-3), var(--ink-2));
  border: 2px solid rgba(0,200,5,0.4); border-radius: 24px; padding: 2rem;
  box-shadow: 0 0 50px rgba(0,200,5,0.12), 0 24px 50px rgba(0,0,0,0.5);
}
.swap-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin: 1.2rem 0; }
.swap-choice {
  border: 2px solid var(--ink-4); border-radius: 16px; padding: 1.1rem; text-align: center;
  cursor: pointer; transition: all 0.15s ease; background: var(--ctl-fill-lo); color: var(--ctl-ink);
}
.swap-choice:hover { transform: translateY(-3px); }
.swap-choice.selected.send { border-color: var(--green); background: var(--green); color: var(--on-green); box-shadow: 0 0 24px color-mix(in srgb, var(--green) 30%, transparent); }
.swap-choice.selected.gwc { border-color: var(--gold); background: var(--gold); color: var(--on-gold); box-shadow: 0 0 24px rgba(255,179,64,0.3); }
.swap-choice .big { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.4rem); }
.swap-choice.send .big { color: inherit; }
.swap-choice.gwc .big { color: inherit; }
.swap-choice .sub { color: inherit; font-size: max(var(--text-floor), 0.82rem); font-weight: 600; margin-top: 0.2rem; }
.swap-note { color: var(--text-dim); font-size: max(var(--text-floor), 0.85rem); line-height: 1.55; margin-top: 1rem; }
.swap-note a { color: var(--rh-green); }

/* ===== Video sections ===== */
.feature-frame {
  position: relative; border-radius: 22px; overflow: hidden;
  border: 3px solid var(--glow-g);
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--green) 8%, transparent), 0 0 60px var(--g-veil), 0 30px 60px rgba(0,0,0,0.55);
  background: #000;
}
.feature-frame video { display: block; width: 100%; height: auto; }
.clip-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); gap: 1.6rem; max-width: 760px; margin: 0 auto; }
.clip-card {
  border-radius: 20px; overflow: hidden; border: 3px solid rgba(255,179,64,0.5);
  box-shadow: 0 0 40px rgba(255,179,64,0.14), 0 18px 40px rgba(0,0,0,0.5);
  background: #000; transform: rotate(-1.2deg); transition: transform 0.2s ease;
}
.clip-card:nth-child(2) { transform: rotate(1.2deg); }
.clip-card:hover { transform: rotate(0deg) scale(1.035); }
.clip-card video { display: block; width: 100%; height: auto; }
.clip-ctl { text-align: center; margin-top: 0.9rem; }

/* ===== GWC card ===== */
.gwc-hero {
  max-width: 620px; margin: 0 auto; text-align: center; padding: 2.6rem 2rem;
  border-radius: 26px; background: linear-gradient(180deg, var(--ink-3), var(--ink-2));
  border: 2px solid rgba(255,179,64,0.4);
  box-shadow: 0 0 50px rgba(255,179,64,0.12), 0 24px 50px rgba(0,0,0,0.5);
}
.gwc-hero .coins { font-size: max(var(--text-floor), 2.4rem); letter-spacing: 0.3rem; }
.gwc-hero h3 { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), clamp(1.5rem, 4vw, 2.1rem)); color: var(--gold); margin: 0.7rem 0 0.4rem; text-shadow: 0 2px 0 var(--gold-deep); }
.gwc-hero p { color: var(--text-dim); margin-bottom: 1.6rem; }
.gwc-hero p strong { color: var(--green-bright); }
.community-links { display: flex; gap: 0.6rem; justify-content: center; flex-wrap: wrap; margin-top: 0.4rem; }
/* The $GWC card and the OG $SEND site's card side by side where two fit, stacked on a phone and a tablet. Each card is a
   column, so the two button rows sit on the same line whatever the copy's length. */
.origin-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr)); gap: 1.4rem; max-width: 1240px; margin: 0 auto; }
.origin-pair > .gwc-hero { max-width: none; margin: 0; display: flex; flex-direction: column; align-items: center; min-width: 0; }
.origin-pair > .gwc-hero > p:not(.og-site-tag) { flex: 1 0 auto; max-width: 34em; }
.origin-pair > .gwc-hero > .community-links { margin-top: 0; }
@media (max-width: 1099px) { .origin-pair { max-width: 620px; } }
/* the OG site in the site's own green: $SEND's colour, where the $GWC card is gold */
.gwc-hero.og-site { border-color: color-mix(in srgb, var(--green-bright) 45%, transparent); box-shadow: 0 0 50px color-mix(in srgb, var(--green) 14%, transparent), 0 24px 50px rgba(0,0,0,0.5); }
.gwc-hero.og-site h3 { color: var(--green-bright); text-shadow: 0 2px 0 var(--green-dark); margin-top: 0.5rem; overflow-wrap: anywhere; }
.gwc-hero.og-site em { color: var(--text); font-style: normal; font-weight: 700; }
.gwc-hero .og-site-tag { display: inline-block; margin: 0.7rem 0 0; padding: 0.15em 0.8em; border-radius: 999px; font-size: max(var(--text-floor), 0.8rem); font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--on-gold); background: linear-gradient(180deg, var(--gold) 0%, var(--gold-deep) 100%); }

/* ===== Profile ===== */
.profile-hero { text-align: center; padding: 3rem 1.25rem 1.5rem; }
.my-wall-btn { display: inline-flex; margin-top: 1rem; }
.connect-panel { max-width: 560px; margin: 0 auto; text-align: center; }
.addr-input {
  width: 100%; background: var(--ink-1); color: var(--green-bright);
  border: 1px solid var(--edge-ctl); border-radius: var(--r-2); padding: 0.85rem 1rem;
  font-family: ui-monospace, Menlo, monospace; font-size: max(var(--text-floor), 1rem); margin-bottom: 0.8rem;
}
.addr-input:focus { border-color: var(--green); }
.addr-pill {
  display: inline-flex; align-items: center; gap: 0.5rem;
  background: var(--ink-3); border: 1.5px solid color-mix(in srgb, var(--green) 35%, transparent); border-radius: 999px;
  padding: 0.45rem 1rem; font-family: ui-monospace, Menlo, monospace; font-size: max(var(--text-floor), 0.85rem);
  color: var(--green-bright);
}
.holdings-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 1.4rem; margin-top: 1.8rem; }
.holding-stat { display: grid; grid-template-columns: 1fr 1fr; gap: 0.7rem; margin-top: 1rem; }
.hstat { background: var(--ink); border-radius: 12px; padding: 0.7rem 0.9rem; }
.hstat .lbl { font-size: max(var(--text-floor), 0.72rem); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-dim); }
.hstat .val { font-size: max(var(--text-floor), 1.05rem); font-weight: 800; margin-top: 0.15rem; }
.hstat .val.green { color: var(--green-bright); }
.hstat .val.gold { color: var(--gold); }
.hstat .val.red { color: var(--red); }
.pnl-note { color: var(--text-dim); font-size: max(var(--text-floor), 0.8rem); margin-top: 0.8rem; line-height: 1.5; }
.skeleton { position: relative; overflow: hidden; background: var(--ink-4); border-radius: 8px; color: transparent !important; }
.skeleton::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, var(--g-tint), transparent);   /* green sweep, not a white one */
  animation: shimmer 1.2s infinite;
}
@keyframes shimmer { from { transform: translateX(-100%);} to { transform: translateX(100%);} }

/* ===== Wall ===== */
.composer { max-width: 640px; margin: 0 auto 0.5rem; } /* tight below the composer — same 0.5rem rhythm as the Convicted-In chips */
.composer textarea {
  width: 100%; min-height: 90px; resize: vertical;
  background: var(--ink-1); color: var(--text); border: 1px solid var(--edge-ctl); border-radius: var(--r-2);
  padding: 0.9rem 1rem; font-family: 'Rubik', sans-serif; font-size: max(var(--text-floor), 16px);
}
.composer textarea:focus { border-color: var(--green); }
.composer-bar { display: flex; align-items: center; gap: 0.7rem; margin-top: 0.7rem; flex-wrap: wrap; }
.composer-bar .hint { color: var(--text-dim); font-size: max(var(--text-floor), 0.8rem); margin-left: auto; }
.file-label {
  cursor: pointer; background: var(--ctl-fill-lo); color: var(--ctl-ink); border-radius: 10px; padding: 0.5rem 0.9rem;
  font-weight: 700; font-size: max(var(--text-floor), 0.85rem); transition: all 0.12s ease;
  /* the 📷 control is a <label> and the 🎤 control beside it is a <button>: a button does not inherit the
     page font and brings the UA's outset border, so both are set here or the pair does not match */
  font-family: inherit; border: 0;
  display: inline-flex; align-items: center; justify-content: center; gap: 0.35em; text-align: center; min-height: 40px;
}
.file-label:hover { background: var(--ctl-fill-hi); color: var(--ctl-ink); }
.wall-feed { max-width: 640px; margin: 0 auto; display: grid; gap: 1.2rem; }
.post {
  background: linear-gradient(180deg, var(--ink-3), var(--ink-2));
  border: 2px solid color-mix(in srgb, var(--green) 20%, transparent); border-radius: 18px; padding: 1.1rem 1.2rem;
  animation: post-in 0.35s ease;
}
@keyframes post-in { from { opacity: 0; transform: translateY(14px) scale(0.97); } to { opacity: 1; transform: none; } }
.post-head { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.6rem; }
.post-avatar {
  width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center; font-size: max(var(--text-floor), 1.15rem);
  background: radial-gradient(circle at 30% 30%, var(--ink-4), var(--ink));
  border: 1.5px solid color-mix(in srgb, var(--green) 40%, transparent);
}
.post-head .who { font-weight: 800; font-size: max(var(--text-floor), 0.92rem); }
.post-head .who .handle { color: var(--green-bright); }
.post-head .when { color: var(--text-dim); font-size: max(var(--text-floor), 0.78rem); font-weight: 600; }
.post-body { font-size: max(var(--text-floor), 0.98rem); line-height: 1.55; white-space: pre-wrap; word-break: break-word; }
.post-img { margin-top: 0.8rem; border-radius: 12px; max-width: 100%; display: block; }
/* posted video (renders like an image — natural size capped to the column, height-capped, black bg) */
.post-video { max-height: 70vh; background: #000; outline: none; width: 100%; height: auto; } /* take the post's width, never the video's intrinsic width */
.wall-feed > .post, .post { min-width: 0; max-width: 100%; } /* a grid item defaults to min-width:auto, so an intrinsic-width video could inflate the post past a 320px viewport */
/* composer draft-media preview (image/gif/video) */
.media-preview { margin-top: 0.8rem; position: relative; display: inline-block; }
.media-preview-el { display: block; max-width: 100%; max-height: 220px; border-radius: 12px; background: #000; }
video.media-preview-el { width: auto; }
.media-preview-rm { position: absolute; top: 6px; right: 6px; width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--ctl-fill-hi); border: 1.5px solid var(--ctl-fill-hi); color: var(--ctl-ink); font-size: max(var(--text-floor), 0.9rem); cursor: pointer; line-height: 1; }
.media-preview-rm:hover { background: var(--red); border-color: var(--red); color: var(--on-red); }
.media-preview-rm:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--green-bright); }
/* keyboard focus on the (visually-hidden) file input shows on its label */
.file-label:focus-within { outline: 3px solid var(--green-bright); outline-offset: 2px; }
.post-actions { display: flex; align-items: center; gap: 0.4rem; margin-top: 0.85rem; flex-wrap: wrap; }
.react-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.25em; text-align: center;
  background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); color: var(--ctl-ink);
  border-radius: 999px; padding: 0.35rem 0.85rem; font-weight: 700; font-size: max(var(--text-floor), 0.85rem);
  cursor: pointer; transition: all 0.12s ease;
}
.react-btn:hover { border-color: var(--ctl-fill-hi); background: var(--ctl-fill-hi); color: var(--ctl-ink); transform: translateY(-1px); }
.react-btn:active { transform: scale(0.85); }
.react-btn.lit { border-color: var(--gold); color: var(--on-gold); background: var(--gold); }
/* armed delete ("Sure? 🗑") — the state is data-armed, set by wall.js / upage.js; the fill carries the warning, the type stays dark */
.react-btn.post-del[data-armed] { background: var(--red); border-color: var(--red); color: var(--on-red); }
.empty-wall { text-align: center; color: var(--text-dim); padding: 2rem 0; }

/* ===== Vote widget (Reddit-style, one segmented pill) — rank a send ===== */
.act-sep { width: 1px; align-self: stretch; margin: 0.15rem 0.2rem; background: var(--ink-4); flex: 0 0 auto; }
.post-del { margin-left: auto; }
.vote { display: inline-flex; align-items: center; gap: 0.1rem; flex: 0 0 auto; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 999px; padding: 0.1rem 0.15rem; }
.vote-btn { min-width: 40px; min-height: 40px; display: grid; place-items: center; background: none; border: 0; border-radius: 50%; cursor: pointer; color: var(--ctl-ink); transition: color 0.12s ease, background 0.12s ease, transform 0.12s ease; }
.vote-ico { width: 17px; height: 17px; fill: currentColor; display: block; }
.vote-btn:hover { color: var(--ctl-ink); background: var(--ctl-fill-hi); }
.vote-btn:active { transform: scale(0.82); }
.vote-up.on { color: var(--on-green); background: var(--green); }
.vote-down.on { color: var(--on-red); background: var(--red); }
.vote-btn:focus-visible { outline: 3px solid var(--ctl-ink); outline-offset: -3px; } /* drawn inside the arrow's circle, so the whole ring sits on the light track instead of spilling onto the dark post */
.vote-score { min-width: 2.2ch; padding: 0 0.15rem; text-align: center; font-weight: 800; font-size: max(var(--text-floor), 0.9rem); color: var(--ctl-ink); font-variant-numeric: tabular-nums; }
.vote-score.neg { color: var(--ctl-ink); } /* the − sign carries the meaning; a red numeral on the light track would not clear 4.5:1 */
/* your own post: read-only score, no self-vote arrows */
.vote-own { gap: 0.35rem; padding: 0.1rem 0.6rem; }
.vote-static { width: 15px; height: 15px; fill: var(--ink-4); }
.vote-btn.pop { animation: vote-pop 0.28s ease; }
@keyframes vote-pop { 0% { transform: scale(1); } 40% { transform: scale(1.32); } 100% { transform: scale(1); } }

/* ===== Send Wall sort control (Top / New) ===== */
.feed-sort { display: flex; align-items: center; justify-content: center; gap: 0.4rem; flex-wrap: wrap; margin: -0.6rem 0 1.2rem; }
.sort-btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.3em; text-align: center; min-height: 40px; padding: 0.45rem 1rem; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); color: var(--ctl-ink); border-radius: 999px; font-family: 'Rubik', sans-serif; font-weight: 800; font-size: max(var(--text-floor), 0.85rem); cursor: pointer; transition: all 0.12s ease; }
.sort-btn:hover { border-color: var(--ctl-fill-hi); background: var(--ctl-fill-hi); color: var(--ctl-ink); }
.sort-btn.is-on { border-color: var(--green); color: var(--on-green); background: var(--green); }
.sort-caption { width: 100%; text-align: center; font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); margin: 0.2rem auto 0; max-width: 46ch; }
.resort-nudge { text-align: center; margin: -0.5rem 0 1rem; }
@media (max-width: 560px) { .vote-btn { min-width: 44px; min-height: 44px; } .react-btn { min-height: 44px; } .sort-btn { min-height: 44px; } }
@media (prefers-reduced-motion: reduce) { .vote-btn.pop { animation: none; } .vote-btn:active { transform: none; } }

/* ===== Toast + fx ===== */
/* Toasts sit at the TOP, under the nav rather than over it — nav.js measures the real bar and publishes
   it as --nav-h (58px is the fallback for any page that does not load it). The bottom of the screen is
   already spoken for by #music-player and #compose-fab, and a toast landing there had to either cover
   them or dodge them; at the top it answers where the reader's attention already is after pressing
   something in the page chrome. z-index stays 200, above the nav's 50, so a toast is never clipped. */
#toast-zone { position: fixed; top: calc(var(--nav-h, 58px) + 0.75rem); left: 1rem; right: 1rem; z-index: 9200; display: grid; gap: 0.5rem; justify-items: center; pointer-events: none; }   /* both edges pinned: a left:50% box only ever had half the screen, so a toast wrapped into a narrow column */
.toast {
  background: linear-gradient(180deg, var(--green-bright), var(--green-dark)); color: var(--on-green);
  font-weight: 800; padding: 0.65rem 1.4rem; border-radius: 999px; border-radius: calc(0.65rem + 0.5lh); font-size: max(var(--text-floor), 0.95rem);
  max-width: 100%; text-align: center; text-wrap: balance;   /* a wrapped toast keeps its lines centred, and its corners (half a one-line toast's height) clear of them */
  box-shadow: 0 8px 30px rgba(0,0,0,0.5); animation: toast-in 0.25s ease, toast-out 0.3s ease 2.2s forwards;
}
/* Direction follows position: it drops in from above the fold and withdraws upward. */
@keyframes toast-in { from { opacity: 0; transform: translateY(-16px) scale(0.9); } }
@keyframes toast-out { to { opacity: 0; transform: translateY(-10px) scale(0.92); } }
#fx-canvas { position: fixed; inset: 0; pointer-events: none; z-index: 300; }

/* one wrapper so the whole field is a single aria-hidden and a span added later cannot forget it;
   .og-confetti below is the same shape for the same reason */
.hero-floats { position: absolute; inset: 0; pointer-events: none; }
/* the duration belongs in the shorthand. Without it the shorthand resets animation-duration to 0s, so a span
   written without an inline value rendered upright and perfectly still — indistinguishable from a deliberate
   placement, which is exactly how it would pass review. Every span still sets its own; this is the floor. */
.float-emoji { position: absolute; font-size: max(var(--text-floor), 1.9rem); opacity: 0.5; animation: floaty 6s ease-in-out infinite; pointer-events: none; z-index: 1; }
/* two planes: the inward rail sits back, so a dozen glyphs read as depth rather than wallpaper. New for this
   class — the original four were all one weight — and opacity rather than size, because opacity is what this
   repo already varies for depth (.og-confetti span) and it stays on the compositor. */
.float-emoji.faint { opacity: 0.3; }
@keyframes floaty {
  0%, 100% { transform: translateY(0) rotate(-8deg); }
  50% { transform: translateY(-26px) rotate(10deg); }
}
/* the global rule already stops these; naming them drops the animation outright rather than leaving a dozen
   zero-length cycles to start and end on every load */
@media (prefers-reduced-motion: reduce) {
  .float-emoji { animation: none; }
}
/* The float field stops here, not at 560px. .hero-logo is min(340px, 68vw): above a ~500px viewport it is a
   fixed 340px while the emoji rails, being percentages of the hero box, keep closing in — so between 561 and
   ~710px the top rail reaches the logo and the 45px glow around it. Hiding the field is the one-line fix, and
   561-700px is already this file's landscape-phone cohort. .float-emoji is shared with about.html, whose three
   spans are hidden across the same band; they are decoration, and that page loses nothing by it. */
/* …and with the larger text the content column spans nearly the whole hero up to a small laptop, so the field
   would drift over the market-cap cards and the buy button: it shows only where the page has side gutters */
@media (max-width: 1099px) {
  .float-emoji { display: none; }
}

/* visible by default. Parked at opacity 0 only once app.js has taken responsibility (it adds html.js
   before observing), so a script that fails to load leaves the page readable rather than blank. */
.reveal { transition: opacity 0.55s ease, transform 0.55s ease; }
html.js .reveal { opacity: 0; transform: translateY(26px); }
html.js .reveal.shown { opacity: 1; transform: none; }

/* ===== Footer ===== */
footer { padding: 2.6rem 1.25rem 3rem; text-align: center; background: var(--ink); border-top: 1px solid var(--hair); }
.disclaimer {
  display: inline-block; font-weight: 800; font-size: max(var(--text-floor), 1.02rem); color: var(--on-green);
  background: linear-gradient(180deg, var(--green-bright), var(--green));
  padding: 0.6rem 1.5rem; border-radius: 999px; transform: rotate(-1deg);
  box-shadow: 0 4px 0 var(--green-dark), 0 10px 26px color-mix(in srgb, var(--green) 30%, transparent);
}
.footer-tax { margin: 1.1rem auto 0; max-width: 62ch; color: var(--text); font-size: max(var(--text-floor), 0.82rem); line-height: 1.65; background: color-mix(in srgb, var(--green) 8%, transparent); border: 1px solid color-mix(in srgb, var(--green) 28%, transparent); border-radius: 12px; padding: 0.6rem 0.9rem; }
.footer-tax b { color: var(--green-bright); }
.footer-tax a { color: var(--green-bright); font-weight: 700; text-decoration: none; white-space: nowrap; }
.footer-tax a:hover { text-decoration: underline; }
footer .fine { margin-top: 1.4rem; color: var(--text-dim); font-size: max(var(--text-floor), 0.87rem); line-height: 1.7; max-width: 68ch; margin-left: auto; margin-right: auto; }
footer .fine a { color: var(--gold); text-decoration: none; font-weight: 600; }
footer .fine a:hover { text-decoration: underline; }
footer .nav-foot { margin-top: 1.2rem; display: flex; gap: 1.1rem; justify-content: center; flex-wrap: wrap; font-weight: 700; font-size: max(var(--text-floor), 0.9rem); }

/* ===== Auth modal ===== */
#auth-modal { position: fixed; inset: 0; z-index: 400; display: grid; place-items: center; padding: 1rem; }
/* The invite line under the sign-in modal: quiet, but the only signpost a person holding a code has. */
.auth-invite { margin: 1rem 0 0; padding-top: 0.9rem; border-top: 1px solid var(--hair);
  font-size: max(var(--text-floor), 0.83rem); line-height: 1.55; color: var(--text-dim); text-align: center; }
#auth-modal[hidden] { display: none; }
/* the title keeps clear of the ✕ in the corner (at 320px it ran under it and lost its last word), and breaks evenly when it wraps */
#auth-title { padding: 0 1.9rem; text-wrap: balance; overflow-wrap: anywhere; }
.modal-backdrop { position: absolute; inset: 0; background: rgba(4,6,10,0.78); backdrop-filter: blur(6px); }
.modal-card {
  position: relative; width: min(420px, 100%); max-height: 92vh; overflow-y: auto;
  background: linear-gradient(180deg, var(--ink-3), var(--ink-2));
  border: 2px solid color-mix(in srgb, var(--green) 40%, transparent); border-radius: 22px; padding: 1.8rem 1.6rem;
  box-shadow: 0 0 60px color-mix(in srgb, var(--green) 18%, transparent), 0 30px 60px rgba(0,0,0,0.6);
}
.modal-x {
  position: absolute; top: 0.8rem; right: 0.8rem; background: var(--ctl-fill-lo); border: none;
  color: var(--ctl-ink); width: 34px; height: 34px; border-radius: 50%; cursor: pointer; font-size: max(var(--text-floor), 0.95rem);
  display: inline-flex; align-items: center; justify-content: center; line-height: 1; padding: 0;
}
.modal-x:hover { background: var(--red); color: var(--on-red); }
.modal-sub { text-align: center; color: var(--text-dim); font-size: max(var(--text-floor), 0.9rem); margin: 0.4rem 0 1.2rem; }
.modal-note { color: var(--text-dim); font-size: max(var(--text-floor), 0.85rem); line-height: 1.5; margin: 0.7rem 0; }
/* the three ways in — Connect wallet, Burn Verification, Email — as one stacked menu: three labels this long never fit side by side at the text floor */
.auth-tabs { display: grid; grid-template-columns: 1fr; gap: 0.45rem; margin-bottom: 1.1rem; }
.auth-tab {
  background: var(--ctl-fill-lo); border: 2px solid var(--ctl-fill-lo); color: var(--ctl-ink);
  padding: 0.65rem; border-radius: 12px; font-weight: 800; font-size: max(var(--text-floor), 0.95rem); cursor: pointer;
  font-family: 'Rubik', sans-serif;
}
.auth-tab.active { border-color: var(--green); color: var(--on-green); background: var(--green); }
.f-label { display: block; font-weight: 700; font-size: max(var(--text-floor), 0.85rem); margin: 0.7rem 0 0.3rem; }
/* a button that used to look like a gold text link — now a small gold pill, so its black type has a ground */
.linklike { background: var(--gold); border: none; color: var(--on-gold); font-weight: 700; cursor: pointer; font-size: max(var(--text-floor), 0.85rem); font-family: 'Rubik', sans-serif; padding: 0.35rem 0.9rem; border-radius: var(--r-pill); text-decoration: none; }
.linklike:hover { text-decoration: none; background: var(--gold-deep); color: var(--ctl-ink); }
.or-line { display: flex; align-items: center; gap: 0.7rem; color: var(--text-dim); font-size: max(var(--text-floor), 0.8rem); margin: 1rem 0 0.7rem; }
.or-line::before, .or-line::after { content: ""; flex: 1; height: 1px; background: var(--ink-4); }
/* social sign-in buttons with brand logos */
.oauth-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
.oauth-btn {
  display: flex; align-items: center; justify-content: center; gap: 0.55rem;
  background: var(--ctl-fill-hi); border: 1.5px solid var(--ctl-fill-hi); border-radius: 12px;
  padding: 0.6rem 0.7rem; color: var(--ctl-ink); font-weight: 800; font-size: max(var(--text-floor), 0.9rem);
  text-decoration: none; cursor: pointer; transition: transform 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}
.oauth-btn:hover, .oauth-btn:focus-visible { transform: translateY(-2px); border-color: var(--green); background: var(--green-bright); color: var(--ctl-ink); }
.oauth-ico { display: inline-flex; width: 20px; height: 20px; align-items: center; justify-content: center; flex-shrink: 0; }
.oauth-x .oauth-ico { color: currentColor; } /* X mark uses currentColor — dark on the light pill */
.oauth-name { line-height: 1; }
@media (prefers-reduced-motion: reduce) { .oauth-btn:hover, .oauth-btn:focus-visible { transform: none; } }
@media (max-width: 380px) { .oauth-grid { grid-template-columns: 1fr; } }

/* ===== Comments ===== */
.comments { margin-top: 0.8rem; border-top: 1px solid var(--ink-4); padding-top: 0.7rem; display: grid; gap: 0.6rem; }
.comment { display: flex; gap: 0.5rem; font-size: max(var(--text-floor), 0.9rem); }
.comment .c-ava { flex-shrink: 0; }
.comment .c-who { font-weight: 800; color: var(--green-bright); }
.comment .c-text { color: var(--text); word-break: break-word; }
.comment-form { display: flex; gap: 0.5rem; }
.comment-form input { flex: 1; margin: 0; padding: 0.55rem 0.8rem; font-family: 'Rubik', sans-serif; font-size: max(var(--text-floor), 0.9rem); }

/* ===== Wallet tracker ===== */
.wallet-row {
  background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 14px;
  padding: 0.9rem 1rem; display: grid; gap: 0.5rem;
}
.wallet-row-head { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; }
.wallet-label { font-weight: 800; font-size: max(var(--text-floor), 1rem); }
.wallet-addr { font-family: ui-monospace, Menlo, monospace; font-size: max(var(--text-floor), 0.78rem); color: var(--text-dim); }
.wallet-actions { margin-left: auto; display: flex; gap: 0.4rem; }
.token-row { display: flex; align-items: center; gap: 0.7rem; padding: 0.5rem 0; border-bottom: 1px solid var(--ink-4); font-size: max(var(--text-floor), 0.9rem); flex-wrap: wrap; }
.token-row:last-child { border-bottom: none; }
.token-row .t-sym { font-weight: 800; min-width: 70px; }
.t-sym, .trk-token .t-sym { max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: inline-block; vertical-align: bottom; }
.token-row .t-bal { color: var(--text-dim); }
.token-row .t-val { margin-left: auto; font-weight: 800; }
.token-row .t-pnl { font-weight: 700; font-size: max(var(--text-floor), 0.82rem); }
.t-pnl.pos { color: var(--green-bright); }
.t-pnl.neg { color: var(--red); }
.privacy-chip {
  display: inline-flex; align-items: center; gap: 0.4rem; background: var(--o-wash);
  border: 1px solid var(--o-edge); color: var(--gold); border-radius: 999px;
  padding: 0.3rem 0.9rem; font-weight: 700; font-size: max(var(--text-floor), 0.8rem);
}

/* ===== Tracker ===== */
.trk-bar { display: flex; gap: 0.4rem; flex-wrap: wrap; margin: 0.7rem 0 0.9rem; }
.trk-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 0.6rem; margin-bottom: 0.8rem; }
.trk-grid-tight .hstat { padding: 0.5rem 0.7rem; }
.trk-h { font-family: 'Luckiest Guy', cursive; color: var(--green-bright); font-size: max(var(--text-floor), 1.05rem); margin: 1rem 0 0.5rem; letter-spacing: 0.03em; }
.trk-token { background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 12px; margin-bottom: 0.5rem; }
/* The summary is the row's button, so it sits on the green control ladder with black type like every other
   disclosure summary. The ± figure keeps its green / red, on an ink pill (the .g1-w-tag construction) so it
   stays legible at every step of the fill; the caret is its own ::before, so no matrix layers here. */
.trk-token summary {
  display: flex; align-items: center; gap: 0.8rem; padding: 0.65rem 0.9rem;
  cursor: pointer; list-style: none; flex-wrap: wrap;
  background: var(--ctl-fill-lo); color: var(--ctl-ink); transition: background 0.15s ease;
  border-radius: calc(12px - 1.5px);   /* the .trk-token radius less its border: `inherit` reads 0 through the <details> slot */
}
.trk-token summary::-webkit-details-marker { display: none; }
.trk-token summary::before { content: '▸'; color: var(--ctl-ink); transition: transform 0.15s; }
.trk-token[open] summary { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.trk-token[open] summary::before { transform: rotate(90deg); }
.trk-token summary:hover { background: var(--ctl-fill-hi); }
.trk-token summary .t-pnl.pos, .trk-token summary .t-pnl.neg { background: var(--ink-1); padding: 0.15rem 0.4rem; border-radius: var(--r-pill); white-space: nowrap; }
@media (prefers-reduced-motion: reduce) { .trk-token summary, .trk-token summary::before { transition: none; } }
html.motion-off .trk-token summary, html.motion-off .trk-token summary::before { transition: none; }
.trk-token-body { padding: 0.4rem 0.9rem 0.9rem; border-top: 1px solid var(--ink-4); }
.trk-table { width: 100%; border-collapse: collapse; font-size: max(var(--text-floor), 0.85rem); margin-top: 0.5rem; }
.trk-table th { text-align: left; color: var(--text-dim); font-size: max(var(--text-floor), 0.72rem); text-transform: uppercase; letter-spacing: 0.05em; padding: 0.35rem 0.5rem; border-bottom: 1px solid var(--ink-4); }
.trk-table td { padding: 0.4rem 0.5rem; border-bottom: 1px solid var(--hair); }
.trk-table a { color: var(--gold); text-decoration: none; }

/* ===== Wall themes ===== */
/* ===== Public profile wall — X-native header (banner + overlapping round avatar) ===== */
.wall-hero { position: relative; max-width: 640px; margin: 0 auto; padding: 0 0 1.5rem; text-align: left; overflow: visible; }
/* Banner: ALWAYS rendered — image fills it, else the branded gradient shows; clips only itself */
.wall-banner {
  position: relative; aspect-ratio: 3 / 1; max-height: 220px; border-radius: 0 0 18px 18px; overflow: hidden;
  background: radial-gradient(120% 140% at 50% -10%, color-mix(in srgb, var(--accent, var(--green)) 40%, transparent), transparent 60%), linear-gradient(135deg, var(--ink-3), var(--ink));
  border-bottom: 2px solid var(--accent, var(--green));
}
.wall-banner-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.wall-id { --ava: 96px; padding: 0 1.1rem; }
.wall-id-top { display: flex; align-items: flex-end; justify-content: space-between; gap: 0.7rem; margin-top: calc(var(--ava) / -2); }
.wall-id-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; justify-content: flex-end; padding-bottom: 0.35rem; }
/* The wall's buttons (Edit profile and Share on your own; Follow, Alerts, Share, Moderation on someone else's) sit clear of
   the banner with room around them (owner, 2026-10-15: "add some padding around the edit profile and share button"): beside
   the picture, just under the banner's edge, on a wide screen; on a row of their own under the picture on a phone. */
.wall-id-actions { align-self: flex-start; margin-top: calc(var(--ava) / 2 + 0.85rem); gap: 0.65rem; padding: 0 0.15rem 0.5rem; }
@media (max-width: 440px) {
  .wall-id-top { flex-wrap: wrap; }
  .wall-id-actions { flex: 1 1 100%; justify-content: flex-start; margin-top: 0.9rem; padding: 0 0 0.25rem; }
}
/* THE AVATAR — the wrap is the SOLE size/ring/clip authority; img + emoji stack in one grid cell */
.wall-avatar {
  width: var(--ava); height: var(--ava); flex: 0 0 auto; position: relative; z-index: 2;
  border-radius: 50%; overflow: hidden; display: grid; place-items: center; background: var(--ink-3);
  border: 4px solid var(--accent, var(--green)); box-shadow: 0 0 0 4px var(--ink), 0 8px 26px rgba(0,0,0,0.55);
}
.wall-avatar-img, .wall-avatar-emoji { grid-area: 1 / 1; width: 100%; height: 100%; }
.wall-avatar-img { object-fit: cover; object-position: center; display: block; }
.wall-avatar-emoji { display: grid; place-items: center; line-height: 1; font-size: calc(var(--ava) * 0.52); background: radial-gradient(circle at 30% 28%, var(--ink-4), var(--ink)); }
@media (min-width: 600px) { .wall-id { --ava: 116px; } }
.wall-name { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), clamp(1.5rem, 5vw, 2rem)); line-height: 1.1; margin: 0.6rem 0 0.15rem; color: var(--accent, var(--green-bright)); word-break: break-word; }
.wall-badges { display: flex; gap: 0.5rem; flex-wrap: wrap; margin: 0.35rem 0; }
.wall-bio { color: var(--text); font-size: max(var(--text-floor), 0.98rem); line-height: 1.5; margin: 0.4rem 0 0.2rem; max-width: 52ch; }
.wall-meta { color: var(--text-dim); font-size: max(var(--text-floor), 0.82rem); font-weight: 600; margin: 0.2rem 0 0.6rem; }
.composer-id { display: flex; gap: 0.6rem; align-items: center; margin-bottom: 0.7rem; }
.composer-ava { font-size: max(var(--text-floor), 1.6rem); line-height: 1; }
.composer-handle { font-weight: 800; }
.themed-page { background-size: cover; background-position: center; }
.color-swatches { display: flex; gap: 0.45rem; flex-wrap: wrap; }
.swatch {
  width: 34px; height: 34px; border-radius: 50%; cursor: pointer; border: 3px solid transparent;
  padding: 0; transition: transform 0.12s;
}
.swatch:hover { transform: scale(1.15); }
.swatch[aria-checked="true"] { border-color: var(--green-bright); box-shadow: 0 0 0 2px var(--ink), 0 0 14px var(--glow-g); }
/* your own colours (profile.js hexRow): a dashed ring marks a colour you typed, and every picker has a hex box under it */
.swatch.is-mine:not([aria-checked="true"]) { border-color: var(--ink-4); border-style: dashed; }
.hex-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.6rem; margin: 0.55rem 0 0.9rem; }
.hex-label { color: var(--text-dim); font-weight: 700; font-size: max(var(--text-floor), 0.88rem); }
.hex-field { display: inline-flex; align-items: center; gap: 0.45rem; flex-wrap: nowrap; min-width: 0; }
.hex-chip { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%; border: 2px solid var(--edge-ctl); background: var(--ink-1); }
.hex-chip.is-empty { background: repeating-linear-gradient(135deg, var(--ink-1) 0 4px, var(--ink-3) 4px 8px); }
.hex-input { width: 9.5ch; min-width: 0; min-height: 44px; padding: 0.4rem 0.6rem; border-radius: var(--r-2); border: 1px solid var(--edge-ctl); background: var(--ink-1); color: var(--green-bright);
  font-family: ui-monospace, Menlo, monospace; font-size: max(var(--text-floor), 1rem); letter-spacing: 0.03em; }
.hex-input:focus { border-color: var(--green); outline: 3px solid var(--focus, var(--green-bright)); outline-offset: 1px; }
.hex-use { flex: 0 0 auto; }
.hex-msg { flex: 1 1 100%; margin: 0; color: var(--text-dim); font-size: max(var(--text-floor), 0.85rem); line-height: 1.45; }
.hex-msg:empty { display: none; }
.hex-msg.is-err { color: var(--red-soft, var(--red)); }
.img-slot { display: flex; align-items: center; gap: 0.7rem; margin: 0.5rem 0; flex-wrap: wrap; }
.img-slot img { width: 72px; height: 44px; object-fit: cover; border-radius: 8px; border: 1.5px solid var(--ink-4); }
.img-slot .none { width: 72px; height: 44px; border-radius: 8px; border: 1.5px dashed var(--ink-4); display: grid; place-items: center; color: var(--text-dim); font-size: max(var(--text-floor), 0.7rem); }

/* ===== Music player ===== */
#music-player {
  position: fixed; bottom: 1rem; left: 1rem; z-index: 250;
  display: flex; align-items: center; gap: 0.55rem;
  background: color-mix(in srgb, var(--ink-2) calc(0.92 * 100%), transparent); backdrop-filter: blur(10px);
  border: 1.5px solid color-mix(in srgb, var(--green) 40%, transparent); border-radius: 999px;
  padding: 0.45rem 0.8rem; box-shadow: 0 10px 30px rgba(0,0,0,0.5);
}
#music-player .mp-btn {
  background: linear-gradient(180deg, var(--green-bright), var(--green-dark)); border: none;
  width: 38px; height: 38px; border-radius: 50%; cursor: pointer; font-size: max(var(--text-floor), 1rem);
  display: grid; place-items: center; color: var(--on-green);
  transition: transform 0.12s;
}
/* The play and pause marks are drawn, not typed: ▶ and ⏸ come from whatever symbol font the device falls back to, and
   sat about 2px off the circle's middle. Sized from the circle (--ava), centred by the grid. */
#music-player .mp-btn { --ava: 38px; }
@media (max-width: 560px) { #music-player .mp-btn { --ava: 48px; } }
#music-player .mp-ico { display: block; width: calc(var(--ava) * 0.34); height: calc(var(--ava) * 0.38); background: currentColor; clip-path: polygon(0 0, 100% 50%, 0 100%); }
#music-player .mp-btn.is-playing .mp-ico { width: calc(var(--ava) * 0.3); clip-path: none; background: linear-gradient(90deg, currentColor 0 34%, transparent 34% 66%, currentColor 66%); }
#music-player .mp-btn:active { transform: scale(0.88); }
/* The song's full title, at the site's text floor: the box is sized in em of that text (13em holds "Just $Send It"
   with its bars at any floor size), where it used to stop at 110px — about "Just" at the 19pt desktop floor. The
   three bars are drawn, not typed (a ▮ comes from whatever symbol font the device falls back to), and sit on the
   text's baseline at its cap height. */
#music-player .mp-title { display: inline-flex; align-items: center; gap: 0.4em; font-size: max(var(--text-floor), 0.8rem); line-height: 1.1; font-weight: 800; color: var(--text-dim); max-width: 13em; overflow: hidden; white-space: nowrap; }
#music-player .mp-title .eq { display: inline-flex; align-items: flex-end; gap: 0.12em; height: 0.72em; color: var(--green-bright); flex: 0 0 auto; }
#music-player .mp-title .eq span { display: block; width: 0.2em; height: 100%; background: currentColor; border-radius: 1px; transform-origin: 50% 100%; }
#music-player .mp-title .eq span:nth-child(2) { height: 70%; }
#music-player.playing .mp-title .eq span { animation: eq 0.8s ease-in-out infinite; }
#music-player.playing .mp-title .eq span:nth-child(2) { animation-delay: 0.2s; }
#music-player.playing .mp-title .eq span:nth-child(3) { animation-delay: 0.4s; }
@keyframes eq { 0%,100% { transform: scaleY(0.5); } 50% { transform: scaleY(1.2); } }
#music-player input[type=range] { width: 64px; accent-color: var(--green); }
/* ===== THE PLAYER KEEPS TO ITSELF ================================================================
   It is a FIXED overlay, so whatever is under it cannot be tapped — and a measured sweep of every page
   at nine widths from 320 to 1440 found that this one control was the ONLY thing on the site covering
   anything: community cards, the risk chip, the New Pairs filters, the sign-in button, links all
   through the white paper. Nothing else overlapped, nothing ran off-screen, nothing clipped.

   So it collapses. At rest it is one round button — the smallest thing that can still be pressed — and
   the title and volume unfold only while it is hovered, focused or being used. That takes its footprint
   from about 240px wide to 48, which is the difference between covering a card and covering nothing.
   Everything stays keyboard-reachable: :focus-within opens it, so tabbing to the volume slider expands
   the player first. */
#music-player .mp-title, #music-player input[type=range] {
  max-width: 0; opacity: 0; overflow: hidden; white-space: nowrap;
  transition: max-width var(--dur-3, 0.24s) var(--ease-out, ease), opacity var(--dur-2, 0.16s) ease;
}
#music-player:hover .mp-title, #music-player:focus-within .mp-title { max-width: 13em; opacity: 1; }
#music-player:hover input[type=range], #music-player:focus-within input[type=range] { max-width: 64px; opacity: 1; }
#music-player:not(:hover):not(:focus-within) { gap: 0; padding: 0.3rem; }
@media (prefers-reduced-motion: reduce) { #music-player .mp-title, #music-player input[type=range] { transition: none; } }
/* The nudge is the widest part of it — a 137px bubble floating over whatever is above the button. It
   stays reachable, but it gets out of the way on its own (player.js hides it after a while) and it can
   never be wider than the viewport it sits in. */
#music-player .mp-hint { max-width: min(74vw, 22rem); white-space: normal; text-align: center; line-height: 1.25; }   /* at the floor size the hint wraps rather than truncates */
/* A lane at the foot of every page, so content at the very END is never permanently trapped under the
   player — mid-page content scrolls out from under it, page-end content cannot. */
body { padding-bottom: 5.5rem; }
@media (max-width: 560px) { body { padding-bottom: 4.5rem; } }
@media (max-width: 560px) { #music-player .mp-title, #music-player input[type=range] { display: none; } #music-player { padding: 0.3rem; } #music-player .mp-btn { width: 48px; height: 48px; font-size: max(var(--text-floor), 1.15rem); } }

/* ===== Intro ===== */
#intro {
  position: fixed; inset: 0; z-index: 999; display: grid; place-items: center;
  background: radial-gradient(ellipse 80% 70% at 50% 40%, #16240a, var(--ink) 75%);
  transition: opacity 0.5s ease, visibility 0.5s;
}
#intro.gone { opacity: 0; visibility: hidden; pointer-events: none; }
.intro-stage { text-align: center; position: relative; }
.intro-logo {
  width: min(300px, 60vw);
  animation: intro-slam 0.7s cubic-bezier(0.2, 2.2, 0.4, 1) both;
  filter: drop-shadow(0 0 60px color-mix(in srgb, var(--green) 60%, transparent));
}
@keyframes intro-slam {
  0% { transform: scale(4) rotate(-14deg); opacity: 0; }
  60% { transform: scale(0.92) rotate(2deg); opacity: 1; }
  100% { transform: scale(1) rotate(-1deg); }
}
.intro-tag {
  font-family: 'Luckiest Guy', cursive; color: var(--green-bright);
  font-size: max(var(--text-floor), clamp(1.6rem, 5vw, 2.6rem)); margin-top: 0.8rem;
  text-shadow: 0 3px 0 var(--green-dark), 0 0 40px color-mix(in srgb, var(--green) 50%, transparent);
  animation: intro-pop 0.5s 0.55s ease both;
}
@keyframes intro-pop { from { transform: translateY(30px) scale(0.6); opacity: 0; } }
.intro-rocket {
  position: absolute; font-size: max(var(--text-floor), 3rem); left: -12%; bottom: -10%;
  animation: intro-fly 1.4s 0.7s cubic-bezier(0.4, 0, 0.7, 0.2) both;
}
@keyframes intro-fly {
  0% { transform: translate(0, 0) rotate(40deg); opacity: 1; }
  100% { transform: translate(130vw, -120vh) rotate(40deg); opacity: 1; }
}
.intro-skip {
  position: absolute; bottom: 2rem; left: 50%; transform: translateX(-50%);
  background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); color: var(--ctl-ink);
  border-radius: 999px; padding: 0.5rem 1.3rem; cursor: pointer; font-weight: 700; font-size: max(var(--text-floor), 0.85rem);
}
.intro-skip:hover { border-color: var(--green); background: var(--ctl-fill-hi); color: var(--ctl-ink); }

/* ===== Market cap hero ===== */
.mcap-panels { display: flex; flex-wrap: wrap; gap: 1rem; justify-content: center; margin-top: 1.4rem; }
/* The two live trackers in the hero are DATA panels, not calls to action: a dark well over the
   Dexscreener banner, so the readings can carry their own colours — the market cap in bright text, the
   24h move green when it is up and red when it is down (with ▲/▼ so colour is never the only signal),
   the label and the source line dimmer. They are deliberately not matrix tiles: the banner is the
   texture, and the tile's ::after would replace the scrim that keeps the numbers readable. */
.mcap-panel {
  position: relative; overflow: hidden; isolation: isolate;
  display: inline-flex; flex-direction: column; align-items: center; gap: 0.1rem;
  padding: 0.9rem 2rem; border-radius: 20px; flex: 1 1 260px; max-width: 360px; min-width: 240px;
  background: var(--ink-2); color: var(--text); border: 1px solid var(--green);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--green) 25%, transparent), 0 12px 32px color-mix(in srgb, var(--void) 55%, transparent);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.mcap-panel[data-mcap-jump="GWC"] { border-color: var(--gold); box-shadow: 0 0 0 1px color-mix(in srgb, var(--gold) 25%, transparent), 0 12px 32px color-mix(in srgb, var(--void) 55%, transparent); }
.mcap-panel:hover { transform: translateY(-2px); }
.mcap-panel:focus-visible { outline: 3px solid var(--focus, var(--green-bright)); outline-offset: 3px; }
/* Dexscreener banner behind each tracker (JS sets background-image), dimmed so the numbers stay readable */
.mcap-banner { position: absolute; inset: 0; z-index: 0; background-size: cover; background-position: center; opacity: 0.3; }
/* a DARK scrim over the banner: the ground every reading is measured against (--text on --ink-2 ≥ 15:1) */
.mcap-panel::after { content: ''; position: absolute; inset: 0; z-index: 1; background: linear-gradient(180deg, color-mix(in srgb, var(--ink-2) 72%, transparent), color-mix(in srgb, var(--ink-2) 94%, transparent)); pointer-events: none; }
.mcap-panel > .mcap-label, .mcap-panel > .mcap-value, .mcap-panel > .mcap-delta, .mcap-panel > .mcap-sub { position: relative; z-index: 2; }
.mcap-label { font-size: max(var(--text-floor), 0.78rem); font-weight: 800; letter-spacing: 0.1em; color: var(--text-dim); text-transform: uppercase; }
.mcap-value {
  font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), clamp(1.8rem, 5vw, 2.8rem));
  color: var(--text); text-shadow: 0 0 22px color-mix(in srgb, var(--green) 45%, transparent);
  font-variant-numeric: tabular-nums;
}
.mcap-value.pumping { animation: mcap-pump 0.35s ease infinite alternate; color: var(--green-bright); text-shadow: 0 2px 0 var(--green-dark), 0 0 40px color-mix(in srgb, var(--green) 70%, transparent); }
@keyframes mcap-pump { from { transform: scale(1); } to { transform: scale(1.06) rotate(0.5deg); } }
.mcap-sub { font-size: max(var(--text-floor), 0.8rem); color: var(--text-mute); font-weight: 600; }

/* ===== Sender search ===== */
.nav-search { position: relative; }
.nav-search input {
  background: var(--ink); border: 1.5px solid var(--edge-ctl); color: var(--text); /* ≥3:1 field boundary against the nav (WCAG 1.4.11) */
  border-radius: 999px; padding: 0 1rem 0 2.1rem; height: var(--nav-ctl); box-sizing: border-box; font-size: var(--nav-fs); width: 170px;
  font-family: 'Rubik', sans-serif; transition: width 0.2s ease, border-color 0.2s ease;
}
.nav-search input:focus { border-color: var(--green); width: 230px; }
.nav-search .s-icon { position: absolute; left: 0.75rem; top: calc(var(--nav-ctl) / 2); transform: translateY(-50%); pointer-events: none; opacity: 0.6; font-size: var(--nav-fs-s); }   /* the box's middle, not the slot's: on a phone the results flow inside the slot */
.search-drop {
  position: absolute; top: calc(100% + 0.5rem); right: 0; width: min(max(320px, 20em), calc(100vw - 2rem)); max-height: min(max(380px, 24em), 70vh); overflow-y: auto;
  background: var(--ink-2); border: 2px solid color-mix(in srgb, var(--green) 35%, transparent); border-radius: 16px;
  box-shadow: 0 20px 50px rgba(0,0,0,0.6); z-index: 60; padding: 0.4rem;
}
.search-hit {
  display: flex; align-items: center; gap: 0.7rem; padding: 0.55rem 0.7rem; border-radius: 12px;
  text-decoration: none; color: var(--text); transition: background 0.12s;
}
.search-hit:hover, .search-hit:focus { background: color-mix(in srgb, var(--green) 10%, transparent); }
.search-hit .h-ava { width: 36px; height: 36px; border-radius: 50%; display: grid; place-items: center; font-size: max(var(--text-floor), 1.1rem); background: var(--ink-3); border: 1.5px solid var(--ink-4); flex-shrink: 0; object-fit: cover; }
.search-hit .h-name { font-weight: 800; font-size: max(var(--text-floor), 0.92rem); }
.search-hit .h-sub { color: var(--text-dim); font-size: max(var(--text-floor), 0.75rem); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.search-empty { padding: 0.8rem; color: var(--text-dim); font-size: max(var(--text-floor), 0.85rem); text-align: center; overflow-wrap: anywhere; }
/* a result is a row of the panel, not a link of the bar: the bar's pill, underline and (on a phone) right alignment stay out */
.nav .nav-menu .search-drop a.search-hit { display: flex; justify-content: flex-start; text-align: left; white-space: normal; min-height: 44px; padding: 0.55rem 0.7rem; border-radius: 12px; color: var(--text); }
.nav .nav-menu .search-drop a.search-hit::after { content: none; }
.search-hit > div { flex: 1 1 auto; min-width: 0; }
.search-hit .h-name { overflow-wrap: anywhere; }   /* a name with no spaces (a memecoin's, a long @handle) wraps inside the row */
.search-hit .h-addr { display: flex; min-width: 0; color: var(--text-dim); font-size: max(var(--text-floor), 0.75rem); }
.search-hit .h-addr code { font-variant-numeric: tabular-nums; }
/* tokens by name, under the senders: a heading, rows whose figures wrap rather than being cut, and a line on where they come from */
.search-sec { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; margin: 0.5rem 0.7rem 0.2rem; padding-top: 0.45rem; border-top: 1px solid var(--ink-4); color: var(--text-dim); font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; font-size: max(var(--text-floor), 0.72rem); }
.search-drop > .search-toks:first-child .search-sec { border-top: 0; margin-top: 0.2rem; }
.search-sec-n { font-variant-numeric: tabular-nums; text-transform: none; letter-spacing: 0; }
.search-hit .h-stats { white-space: normal; overflow: visible; text-overflow: clip; font-variant-numeric: tabular-nums; }
.search-hit img.h-logo { object-fit: cover; padding: 0; }
.search-wait { font-style: italic; }
.search-note { margin: 0.3rem 0.7rem 0.4rem; color: var(--text-dim); font-size: max(var(--text-floor), 0.72rem); line-height: 1.45; }
/* in the phone pop-down the results flow under the box, full width, instead of floating over the links */
.nav.is-compact .search-drop { position: static; width: auto; max-height: none; margin-top: 0.4rem; box-shadow: none; }

/* ===== Follow + wall stats ===== */
.btn-follow {
  border-radius: 999px; border: 2px solid var(--accent, var(--green)); background: var(--green);
  color: var(--on-green); font-family: 'Rubik', sans-serif; font-weight: 800;   /* --accent (a wall owner's pick) is never the label colour or the fill under it */
  padding: 0.55rem 1.6rem; font-size: max(var(--text-floor), 0.95rem); cursor: pointer; transition: all 0.15s ease;
}
.btn-follow:hover { transform: translateY(-2px); }
.btn-follow.on { background: var(--ctl-fill-lo); border-color: var(--ctl-fill-lo); color: var(--ctl-ink); }
.wall-stats { display: flex; gap: 1.4rem; justify-content: flex-start; flex-wrap: wrap; margin: 0.3rem 0 0; }
.wall-stat { display: flex; align-items: baseline; gap: 0.35rem; text-decoration: none; color: inherit; }
.wall-stat .n { font-weight: 800; font-size: max(var(--text-floor), 1.05rem); color: var(--accent, var(--green-bright)); font-variant-numeric: tabular-nums; }
.wall-stat .l { font-size: max(var(--text-floor), 0.74rem); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-dim); }
a.wall-stat:hover .l { color: var(--text); }

/* ===== Feed tabs ===== */
.feed-tabs { display: flex; gap: 0.5rem; justify-content: center; margin-bottom: 1.4rem; }
.feed-tab {
  background: var(--ctl-fill-lo); border: 2px solid var(--ctl-fill-lo); color: var(--ctl-ink);
  border-radius: 999px; padding: 0.5rem 1.4rem; font-weight: 800; font-size: max(var(--text-floor), 0.9rem); cursor: pointer;
  font-family: 'Rubik', sans-serif;
}
.feed-tab[aria-selected="true"] { border-color: var(--green); color: var(--on-green); background: var(--green); }

/* ===== Collapsible settings ===== */
/* ---------- dashboard tabs ----------
   Sticky under the nav so the section switch is always one tap away on a long panel; the bar scrolls
   sideways on a phone instead of wrapping into two rows. The selected tab is a filled pill — an
   aria-selected styling, not a hover one, so it reads the same on touch. --nav-h is published by nav.js. */
.dtabs { position: sticky; top: calc(var(--nav-h, 58px) + 0.35rem); z-index: 15; display: flex; gap: 0.35rem; margin: 0 0 1.2rem; padding: 0.35rem; overflow-x: auto; scrollbar-width: none; background: var(--ctl-fill-lo); border: 1px solid var(--hair); border-radius: 999px; backdrop-filter: blur(var(--blur)); -webkit-backdrop-filter: blur(var(--blur)); }
.dtabs::-webkit-scrollbar { display: none; }
@media (max-width: 900px) { .dtabs .dtab { padding-inline: 0.75rem; } }   /* a tablet holds all five without scrolling (it ran 30px past at 768) */
/* A strip that scrolls sideways says so (window.scrollCue in app.js sets .cue-start / .cue-end): a fade and a ›/‹ at the edge
   that has more, drawn as sticky end items so they ride the visible edge and take no room (the negative margin, the strip's own
   gap included). A tap on one scrolls the strip that way. --cue-bg is what the fade fades into; --cue-pad the strip's padding. */
[data-scroll-cue] { scroll-padding-inline: 2.8rem; }   /* a tab or chip scrolled into view (keyboard focus) lands clear of the cue */
[data-scroll-cue]::before, [data-scroll-cue]::after {
  content: none; position: sticky; z-index: 2; flex: none; align-self: stretch; box-sizing: border-box; width: 2.6rem; display: grid; align-items: center;
  cursor: pointer; font-size: max(var(--text-floor), 1.3rem); font-weight: 800; line-height: 1; color: var(--green-bright); }   /* a tap on the cue scrolls the strip (app.js), never lands on a tab under it */
[data-scroll-cue].cue-start::before { content: "‹"; content: "‹" / ""; left: calc(0px - var(--cue-pad, 0px)); margin-right: calc(-2.6rem - var(--cue-gap, 0.4rem)); justify-items: start; padding-left: 0.2rem;
  background: linear-gradient(to left, transparent, var(--cue-bg, var(--ink)) 55%); }
[data-scroll-cue].cue-end::after { content: "›"; content: "›" / ""; right: calc(0px - var(--cue-pad, 0px)); margin-left: calc(-2.6rem - var(--cue-gap, 0.4rem)); justify-items: end; padding-right: 0.2rem;
  background: linear-gradient(to right, transparent, var(--cue-bg, var(--ink)) 55%); }
.dtabs[data-scroll-cue] { --cue-gap: 0.35rem; --cue-pad: 0.35rem; --cue-bg: var(--ctl-fill-lo); }   /* --cue-pad: the strip's own padding, which the content scrolls under too */
.dtabs[data-scroll-cue]::before, .dtabs[data-scroll-cue]::after { border-radius: 999px; color: var(--ctl-ink); }   /* the bar is the light control fill: its own colour to fade into, and its own ink for the arrow */
.np-chips[data-scroll-cue] { --cue-gap: 0.4rem; --cue-pad: 0.1rem; }
.snap-tabs[data-scroll-cue] { --cue-gap: 0.4rem; --cue-bg: var(--ink-3); }   /* the card it sits on (glass over ink) */
@media (forced-colors: active) { [data-scroll-cue].cue-start::before, [data-scroll-cue].cue-end::after { background: Canvas; color: CanvasText; } }
.dpanel [id] { scroll-margin-top: calc(var(--nav-h, 58px) + var(--dtabs-h, 64px) + 0.9rem); }   /* lands below the nav and the sticky tab bar (dashtabs.js publishes its height) */
.dtab { flex: 0 0 auto; min-height: 44px; padding: 0.55rem 1rem; border: 0; border-radius: 999px; background: transparent; color: var(--ctl-ink); font: inherit; font-weight: 800; font-size: max(var(--text-floor), 0.92rem); white-space: nowrap; cursor: pointer; transition: background var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out); }
.dtab:hover { color: var(--ctl-ink); background: var(--ctl-fill-hi); }
.dtab[aria-selected="true"] { color: var(--on-green); background: linear-gradient(180deg, var(--green-bright), var(--green-dark)); box-shadow: 0 4px 0 var(--green-dark), 0 8px 22px var(--glow-g); }
.dtab:focus-visible { outline: 3px solid var(--ctl-ink); outline-offset: 2px; }   /* on the light track --focus (near-white) would vanish */
.dpanel:focus-visible { outline: 3px solid var(--focus); outline-offset: 4px; border-radius: 12px; }
@media (prefers-reduced-motion: reduce) { .dtab { transition: none; } }

.settings-group { display: grid; gap: 0.8rem; }
details.setting-card {
  background: linear-gradient(180deg, var(--ink-3), var(--ink-2));
  border: 2px solid var(--g-veil); border-radius: 18px;
}
/* The summary IS the card's button, so it is the green tile every other control is, with black type.
   Its caret is its own ::after, so the matrix layers cannot ride on it — fill and ink still match. */
details.setting-card > summary {
  display: flex; align-items: center; gap: 0.7rem; padding: 1rem 1.3rem;
  cursor: pointer; list-style: none; font-family: 'Luckiest Guy', cursive;
  font-size: max(var(--text-floor), 1.15rem); color: var(--ctl-ink); letter-spacing: 0.03em;
  background: var(--ctl-fill-lo); border-radius: inherit; transition: background 0.15s ease;
}
details.setting-card > summary:hover { background: var(--ctl-fill-hi); }
details.setting-card[open] > summary { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
details.setting-card > summary::-webkit-details-marker { display: none; }
details.setting-card > summary::after { content: '▾'; margin-left: auto; color: var(--ctl-ink); transition: transform 0.2s; }
details.setting-card[open] > summary::after { transform: rotate(180deg); }
details.setting-card > .setting-body { padding: 0 1.3rem 1.3rem; }
.pref-row { display: flex; align-items: center; gap: 0.8rem; justify-content: space-between; padding: 0.55rem 0; border-bottom: 1px solid var(--ink-4); flex-wrap: wrap; }
.pref-row:last-child { border-bottom: none; }
.pref-row .p-label { font-weight: 700; font-size: max(var(--text-floor), 0.92rem); }
.pref-row .p-sub { color: var(--text-dim); font-size: max(var(--text-floor), 0.78rem); }
.switch {
  position: relative; width: 48px; height: 26px; border-radius: 999px; border: none; cursor: pointer;
  background: var(--ctl-fill-lo); transition: background 0.2s;
}
.switch::after {
  content: ''; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%;
  background: var(--ctl-ink); transition: transform 0.2s;
}
.switch[aria-checked="true"] { background: var(--green); }
.switch[aria-checked="true"]::after { transform: translateX(22px); }

/* ===== sr-only ===== */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ===== Music unmute hint ===== */
#music-player .mp-hint {
  position: absolute; bottom: calc(100% + 0.5rem); left: 0;
  background: var(--green); color: var(--on-green);
  border: 1.5px solid var(--green); border-radius: 999px;
  padding: 0.35rem 0.7rem; font: 800 max(var(--text-floor), 0.72rem) 'Rubik', sans-serif; white-space: nowrap; cursor: pointer;
  /* the 44px tap height is taller than the words: centre them in it (a block put them at the top), and restate the line
     height the font shorthand just reset to 'normal' */
  display: inline-flex; align-items: center; justify-content: center; line-height: 1.25;
}
#music-player .mp-hint::after { content: ''; position: absolute; top: 100%; left: 18px; border: 6px solid transparent; border-top-color: var(--green); }
#music-player .mp-btn.wants { animation: mp-pulse 1.4s ease-out infinite; }
@keyframes mp-pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--green-bright) 55%, transparent); } 100% { box-shadow: 0 0 0 12px transparent; } }
@media (prefers-reduced-motion: reduce) { #music-player .mp-btn.wants { animation: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--green-bright) 50%, transparent); } }

/* ===== Entry market-cap tease ===== */
.intro-mcap {
  font-family: 'Luckiest Guy', cursive; color: var(--gold); font-size: max(var(--text-floor), clamp(1.1rem, 3.5vw, 1.6rem));
  margin-top: 0.5rem; font-variant-numeric: tabular-nums; text-shadow: 0 0 20px rgba(255,179,64,0.4);
  animation: intro-mcap-in 0.4s 0.85s ease both;
}
@keyframes intro-mcap-in { from { opacity: 0; } }

/* ===== Global compose FAB ===== */
#compose-fab {
  position: fixed; right: 1rem; bottom: calc(1rem + env(safe-area-inset-bottom, 0px)); z-index: 240;
  display: inline-flex; align-items: center; gap: 0.5rem; border: none; cursor: pointer;
  background: linear-gradient(180deg, var(--green-bright), var(--green-dark)); color: var(--on-green);
  border-radius: 999px; padding: 0.75rem 1.3rem;
  font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.05rem); letter-spacing: 0.03em;
  box-shadow: 0 6px 0 var(--green-dark), 0 12px 30px color-mix(in srgb, var(--green) 35%, transparent);
  transition: transform 0.14s ease, box-shadow 0.14s ease;
}
#compose-fab .fab-ico { font-size: max(var(--text-floor), 1.15rem); display: inline-block; transition: transform 0.14s ease; }
#compose-fab:hover, #compose-fab:active { animation-play-state: paused; }   /* sw-breathe owns transform; pause it so the press can show */
#compose-fab:hover { transform: translateY(-3px); box-shadow: 0 9px 0 var(--green-dark), 0 18px 40px var(--g-lit); }
#compose-fab:hover .fab-ico { transform: rotate(-8deg); }
#compose-fab:active { transform: scale(0.92); }
#compose-fab.nudge { animation: fab-nudge 1.4s ease; }
@keyframes fab-nudge { 0%,100% { transform: none; } 20% { transform: translateY(-6px) rotate(-6deg); } 40% { transform: translateY(0) rotate(4deg); } 60% { transform: translateY(-3px) rotate(-3deg); } }
@media (prefers-reduced-motion: reduce) { #compose-fab, #compose-fab .fab-ico { transition: none; } #compose-fab:hover { transform: none; } #compose-fab.nudge { animation: none; } }
@media (max-width: 560px) {
  #compose-fab { padding: 0; width: 54px; height: 54px; justify-content: center; border-radius: 50%; }
  #compose-fab .fab-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  #compose-fab .fab-ico { font-size: max(var(--text-floor), 1.4rem); }
}

/* ===== Compose modal (reuses .modal-* classes) ===== */
#compose-modal { position: fixed; inset: 0; z-index: 430; display: grid; place-items: center; padding: 1rem; }
#compose-modal[hidden] { display: none; }
#compose-modal textarea {
  width: 100%; min-height: 90px; resize: vertical; background: var(--ink); color: var(--text);
  border: 2px solid var(--ink-4); border-radius: 14px; padding: 0.9rem 1rem;
  font-family: 'Rubik', sans-serif; font-size: max(var(--text-floor), 16px); margin-top: 0.4rem;
}
#compose-modal textarea:focus { border-color: var(--green); }

/* ===== Onboarding tour ===== */
.tour-welcome-wrap { position: fixed; inset: 0; z-index: 360; display: grid; place-items: center; padding: 1rem; }
.tour-welcome-backdrop { position: absolute; inset: 0; background: rgba(4,6,10,0.82); backdrop-filter: blur(6px); }
.tour-welcome {
  position: relative; width: min(440px, 100%); text-align: center;
  max-height: 92vh; overflow-y: auto;
  background: linear-gradient(180deg, var(--ink-3), var(--ink-2));
  border: 2px solid color-mix(in srgb, var(--green) 40%, transparent); border-radius: 22px; padding: 2rem 1.6rem;
  box-shadow: 0 0 60px color-mix(in srgb, var(--green) 18%, transparent), 0 30px 60px rgba(0,0,0,0.6);
}
.tour-spot {
  position: fixed; z-index: 351; border-radius: 12px; pointer-events: none;
  box-shadow: 0 0 0 4px var(--green-bright), 0 0 0 100vmax rgba(4,6,10,0.8);
  transition: left 0.2s ease, top 0.2s ease, width 0.2s ease, height 0.2s ease;
}
.tour-tip {
  position: fixed; z-index: 352; width: min(340px, calc(100vw - 24px));
  max-height: 80vh; overflow-y: auto;
  background: linear-gradient(180deg, var(--ink-3), var(--ink-2));
  border: 2px solid color-mix(in srgb, var(--green) 50%, transparent); border-radius: 16px; padding: 1.1rem 1.2rem;
  box-shadow: 0 20px 50px rgba(0,0,0,0.6);
}
.tour-count { color: var(--text-dim); font-size: max(var(--text-floor), 0.72rem); font-weight: 800; text-transform: uppercase; letter-spacing: 0.08em; margin: 0; }
.tour-title { font-family: 'Luckiest Guy', cursive; color: var(--green-bright); font-size: max(var(--text-floor), 1.2rem); margin: 0.3rem 0; }
.tour-body { color: var(--text); font-size: max(var(--text-floor), 0.92rem); line-height: 1.5; margin: 0 0 0.9rem; }
.tour-controls { display: flex; align-items: center; gap: 0.5rem; }
@media (prefers-reduced-motion: reduce) { .tour-spot { transition: none; } }

/* ===== Homepage max-up: reassurance, risk chip, do-grid, mcap delta, gwc tax ===== */
[id] { scroll-margin-top: 72px; }
.risk-chip {
  display: inline-flex; align-items: center; gap: 0.4rem; margin-top: 0.8rem;
  background: var(--gold); border: 1.5px solid var(--gold); color: var(--on-gold);   /* a clickable chip is a control: gold FILL, black type, no wash */
  border-radius: 999px; padding: 0.35rem 0.9rem; font-weight: 800; font-size: max(var(--text-floor), 0.8rem); text-decoration: none;
}
.risk-chip:hover, .risk-chip:focus-visible { background: var(--gold-deep); border-color: var(--gold-deep); color: var(--ctl-ink); }
.reassure { max-width: 620px; margin: 1.4rem auto 0; text-align: left; background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 16px; }
.reassure > summary { cursor: pointer; padding: 0.9rem 1.2rem; font-weight: 800; color: var(--ctl-ink); background: var(--ctl-fill-lo); border-radius: inherit; list-style: none; transition: background 0.15s ease; }
.reassure > summary:hover { background: var(--ctl-fill-hi); }
.reassure[open] > summary { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.reassure > summary::-webkit-details-marker { display: none; }
.reassure > summary::after { content: ' ▾'; color: var(--ctl-ink); }
.reassure[open] > summary::after { content: ' ▴'; }
.reassure-body { padding: 0 1.2rem 1.1rem; color: var(--text-dim); font-size: max(var(--text-floor), 0.9rem); line-height: 1.6; }
.reassure-body ul { margin: 0.5rem 0 0 1.1rem; display: grid; gap: 0.4rem; }
.do-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); gap: 1rem; max-width: 900px; margin: 2rem auto 0; }
.do-card { display: block; text-decoration: none; color: var(--text); background: var(--ink-2); border: 1px solid var(--hair); border-radius: var(--r-2); padding: 1.1rem 1.2rem; transition: transform 0.15s ease, border-color 0.15s ease; }
.do-card:hover { transform: translateY(-3px); border-color: var(--green); }
.do-card .do-ico { font-size: max(var(--text-floor), 1.6rem); }
.do-card .do-title { font-weight: 800; font-size: max(var(--text-floor), 1.05rem); margin: 0.3rem 0 0.2rem; }
.do-card .do-sub { color: var(--text-dim); font-size: max(var(--text-floor), 0.82rem); }
@media (prefers-reduced-motion: reduce) { .do-card:hover { transform: none; } }
.mcap-delta { font-size: max(var(--text-floor), 0.8rem); font-weight: 800; margin-top: 0.2rem; color: var(--text-dim); }
.mcap-delta.up { color: var(--green-bright); }   /* up is green, down is red — and the ▲ / ▼ glyph says it too */
.mcap-delta.down { color: var(--red-soft); }
button.mcap-panel { cursor: pointer; font: inherit; text-align: center; }
.gwc-tax-chip { display: inline-flex; align-items: center; gap: 0.4rem; margin: 0.4rem 0 0.2rem; background: rgba(255,179,64,0.12); border: 1.5px solid rgba(255,179,64,0.45); color: var(--gold); border-radius: 10px; padding: 0.35rem 0.7rem; font-weight: 800; font-size: max(var(--text-floor), 0.78rem); }
.send-tax-chip { display: inline-flex; align-items: center; gap: 0.4rem; margin: 0.4rem 0 0.2rem; background: color-mix(in srgb, var(--green) 12%, transparent); border: 1.5px solid var(--g-lit); color: var(--green-bright); border-radius: 10px; padding: 0.35rem 0.7rem; font-weight: 800; font-size: max(var(--text-floor), 0.78rem); }

/* ===== Gamification dashboard ===== */
.gamify-card { border-color: color-mix(in srgb, var(--green) 40%, transparent); background: linear-gradient(180deg, var(--ink-3), var(--ink-2)); }
.gdash-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.glevel { display: flex; align-items: center; gap: 0.9rem; }
.glevel-ring {
  width: 68px; height: 68px; border-radius: 50%; flex-shrink: 0; display: grid; place-items: center; position: relative;
  background: radial-gradient(circle at 35% 30%, var(--green-bright), var(--green-dark));
  box-shadow: 0 0 24px var(--g-lit), inset 0 -4px 10px rgba(0,0,0,0.25);
  color: var(--on-green);
}
.glevel-num { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.7rem); line-height: 1; }
.glevel-lbl { position: absolute; bottom: 8px; font-size: max(var(--text-floor), 0.5rem); font-weight: 800; letter-spacing: 0.1em; opacity: 0.75; }
.gtitle { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.35rem); color: var(--green-bright); letter-spacing: 0.02em; }
.grank { font-weight: 800; font-size: max(var(--text-floor), 0.85rem); color: var(--gold); }
.gpoints-box { text-align: right; }
.gpoints { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 2rem); color: var(--gold); line-height: 1; font-variant-numeric: tabular-nums; }
.gpoints-box .glbl { font-size: max(var(--text-floor), 0.78rem); font-weight: 700; color: var(--text-dim); }
.gxp {
  position: relative; height: var(--bar-h, 26px); border-radius: 999px; background: var(--ink); overflow: hidden;
  border: 1.5px solid var(--ink-4); margin: 1rem 0;
}
.gxp-fill { height: 100%; background: linear-gradient(90deg, var(--green-dark), var(--green-bright)); border-radius: 999px; transition: width 0.6s cubic-bezier(0.2,0.8,0.3,1); }
/* A bar with a label inside takes its height from the label: the label sits in the flow (so when it has to wrap on
   a narrow screen, the bar grows with it instead of cutting the second line off) and the fill lies underneath. */
.gxp:has(.gxp-text) { font-size: max(var(--text-floor), 0.75rem); height: auto; min-height: max(var(--bar-h, 26px), calc(1.3em + 6px)); display: grid; align-items: center; }
.gd-bar:has(.gd-text) { height: auto; min-height: max(20px, calc(1.3em + 6px)); display: grid; align-items: center; }
.gs-progress { display: grid; align-items: center; }
.gxp:has(.gxp-text) > .gxp-fill, .gd-bar:has(.gd-text) > .gd-fill { position: absolute; left: 0; top: 0; bottom: 0; height: auto; }
.gxp:has(.gxp-text) > .gxp-text, .gd-bar:has(.gd-text) > .gd-text, .gs-progress > .gs-progress-text { position: relative; inset: auto; display: block; padding: 0.12em 0.7em; line-height: 1.25; text-align: center; overflow-wrap: anywhere; }
.gxp-text { position: absolute; inset: 0; display: grid; place-items: center; font-size: max(var(--text-floor), 0.75rem); font-weight: 800; color: var(--text); text-shadow: 0 1px 2px rgba(0,0,0,0.6); }
@media (prefers-reduced-motion: reduce) { .gxp-fill { transition: none; } }

.gholder {
  background: radial-gradient(ellipse 90% 100% at 50% 0%, rgba(255,179,64,0.12), transparent), var(--ink);
  border: 1.5px solid rgba(255,179,64,0.4); border-radius: 16px; padding: 1rem 1.1rem; margin-bottom: 1.2rem;
}
.gholder-locked { border-color: rgba(159,176,204,0.3); background: var(--ink); }
.ghmult { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.6rem); color: var(--gold); }
.ghmult span { font-size: max(var(--text-floor), 0.95rem); color: var(--text-dim); font-family: 'Rubik', sans-serif; font-weight: 800; }
.ghstats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.6rem; margin: 0.7rem 0 0.2rem; }
.ghstats > div { background: var(--ink-2); border-radius: 10px; padding: 0.5rem 0.4rem; text-align: center; }
.ghstats b { display: block; font-size: max(var(--text-floor), 1rem); color: var(--text); }
.ghstats span { font-size: max(var(--text-floor), 0.68rem); color: var(--text-dim); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; }
.gstale { background: rgba(255,179,64,0.12); border: 1.5px solid rgba(255,179,64,0.45); color: var(--gold); border-radius: 10px; padding: 0.5rem 0.7rem; font-size: max(var(--text-floor), 0.82rem); font-weight: 700; margin: 0.5rem 0; }

/* Diamond Hands level panel */
.gdiamond { background: linear-gradient(180deg, rgba(93,201,255,0.09), transparent); border: 1.5px solid rgba(93,201,255,0.4); border-radius: 12px; padding: 0.75rem 0.85rem; margin: 0.6rem 0; }
.gd-head { display: flex; align-items: center; gap: 0.7rem; }
.gd-emoji { font-size: max(var(--text-floor), 1.9rem); line-height: 1; }
.gd-name { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.1rem); color: var(--diamond); letter-spacing: 0.02em; }
.gd-lvl { font-size: max(var(--text-floor), 0.78rem); font-weight: 700; color: var(--text-dim); }
.gd-bar { position: relative; font-size: max(var(--text-floor), 0.72rem); height: 20px; border-radius: 999px; background: var(--ink); border: 1.5px solid var(--ink-4); overflow: hidden; margin-top: 0.55rem; }
.gd-fill { height: 100%; background: linear-gradient(90deg, var(--diamond-deep), var(--diamond)); border-radius: 999px; transition: width 0.6s ease; }
.gd-text { position: absolute; inset: 0; display: grid; place-items: center; font-size: max(var(--text-floor), 0.7rem); font-weight: 800; color: var(--text); text-shadow: 0 1px 2px rgba(0,0,0,0.6); }
@media (prefers-reduced-motion: reduce) { .gd-fill { transition: none; } }

.gdash-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 1.4rem; }
.gsub { font-family: 'Luckiest Guy', cursive; color: var(--green-bright); font-size: max(var(--text-floor), 1.05rem); margin: 0 0 0.6rem; letter-spacing: 0.02em; }
.gearn { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.3rem; }
.gearn li { list-style: none; }
.gearn-row {
  display: flex; align-items: center; gap: 0.6rem; width: 100%; text-align: left; box-sizing: border-box;
  background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 10px; padding: 0.45rem 0.7rem;
  color: var(--text); cursor: pointer; text-decoration: none; font: inherit;
  transition: transform 0.12s ease, border-color 0.12s ease;
}
.gearn-row:hover { transform: translateX(3px); border-color: color-mix(in srgb, var(--green) 50%, transparent); }
.gearn-done { cursor: default; color: var(--text-mute); filter: saturate(0.5); }   /* not opacity: --text-dim at 72% does not hold 4.5:1 */
.ge-ico { font-size: max(var(--text-floor), 1rem); }
.ge-label { flex: 1; font-size: max(var(--text-floor), 0.85rem); font-weight: 600; }
.ge-pts { font-weight: 800; color: var(--green-bright); font-size: max(var(--text-floor), 0.9rem); }
.ge-go { color: var(--green-bright); font-weight: 800; font-size: max(var(--text-floor), 0.85rem); }
.gearn-done .ge-go { color: var(--gold); }
@media (prefers-reduced-motion: reduce) { .gearn-row:hover { transform: none; } }

/* live "+N points" pop */
.points-pop {
  position: fixed; z-index: 320; pointer-events: none;
  font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.2rem); color: var(--green-bright);
  text-shadow: 0 2px 6px rgba(0,0,0,0.6), 0 0 14px color-mix(in srgb, var(--green) 60%, transparent);
  animation: points-float 1.3s ease-out forwards;
}
@keyframes points-float {
  0% { opacity: 0; transform: translateY(6px) scale(0.8); }
  15% { opacity: 1; transform: translateY(0) scale(1.12); }
  100% { opacity: 0; transform: translateY(-48px) scale(1); }
}

/* gamification rules explainer */
.grules { margin-top: 1.2rem; background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 14px; }
.grules > summary { cursor: pointer; padding: 0.8rem 1rem; font-weight: 800; color: var(--ctl-ink); background: var(--ctl-fill-lo); border-radius: inherit; list-style: none; transition: background 0.15s ease; }
.grules > summary:hover { background: var(--ctl-fill-hi); }
.grules[open] > summary { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.grules > summary::-webkit-details-marker { display: none; }
.grules > summary::after { content: ' ▾'; color: var(--ctl-ink); }
.grules[open] > summary::after { content: ' ▴'; }
.grules-body { padding: 0 1rem 1rem; color: var(--text-dim); font-size: max(var(--text-floor), 0.9rem); line-height: 1.6; }
.grules-body p { margin: 0.5rem 0; }
.grules-body b { color: var(--text); }
.grules-body ul { margin: 0.4rem 0 0.4rem 1.1rem; display: grid; gap: 0.35rem; }
/* connected-wallet selector */
.cw-pick.lit { background: var(--green); color: var(--on-green); }

/* nav level/points badge */
.nav-xp {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.35rem; text-decoration: none;
  background: var(--ink-3); border: 1.5px solid color-mix(in srgb, var(--green) 40%, transparent); border-radius: 999px;
  min-height: var(--nav-ctl); min-width: var(--nav-ctl); padding: 0 0.7rem; margin-right: 0; vertical-align: middle; font-size: var(--nav-fs-s);
}
/* live "who's active — people Sending it right now" counter next to the 🔔 */
.nav-live { display: inline-flex; align-items: center; gap: 0.35rem; min-height: var(--nav-ctl); font-size: var(--nav-fs-s); text-decoration: none; color: var(--text); background: color-mix(in srgb, var(--green) 10%, transparent); border: 1.5px solid color-mix(in srgb, var(--green) 40%, transparent); border-radius: 999px; padding: 0 0.7rem; margin: 0 0.4rem 0 0.15rem; vertical-align: middle; font-weight: 800; font-size: max(var(--text-floor), 0.82rem); white-space: nowrap; }
.nav-live:hover, .nav-live:focus-visible { border-color: var(--green-bright); background: color-mix(in srgb, var(--green) 18%, transparent); }
.nav-live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--green-bright); box-shadow: 0 0 8px var(--green-bright); animation: navLivePulse 1.6s ease-in-out infinite; flex: 0 0 auto; }
@keyframes navLivePulse { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.45; transform: scale(0.65); } }
.nav-live-n { color: var(--green-bright); font-variant-numeric: tabular-nums; }
.nav-live-lbl { color: var(--text-dim); font-weight: 700; font-size: var(--nav-fs-s); }
@media (max-width: 700px) { .nav-live-lbl { display: none; } .nav-live { padding: 0 0.5rem; } } /* 561–700px landscape phones: the label pushed ≡ off-screen */
@media (prefers-reduced-motion: reduce) { .nav-live-dot { animation: none; } }
/* read-only connected-wallet balances pill in the nav */
.nav-bal { display: inline-flex; align-items: center; gap: 0.55rem; text-decoration: none; background: var(--ink-3); border: 1.5px solid var(--ink-4); border-radius: 999px; min-height: var(--nav-ctl); padding: 0 0.7rem; margin-right: 0; vertical-align: middle; font-size: var(--nav-fs-s); font-weight: 800; color: var(--text-dim); }
.nav-bal-item { white-space: nowrap; }
.nav-bal-item b { color: var(--text); font-variant-numeric: tabular-nums; }
.nav-bal-item.send b { color: var(--green-bright); }
.nav-bal-item.gwc b { color: var(--gold); }
.nav-bal-item.eth b { color: var(--diamond); }
@media (max-width: 600px) { .nav-bal { padding: 0 0.5rem; gap: 0.4rem; } .nav-bal-item.eth { display: none; } }
.nav-xp-lv { font-family: 'Luckiest Guy', cursive; font-size: calc(var(--nav-fs-s) * 1.15); color: var(--green-bright); letter-spacing: 0.02em; }
.nav-xp-sep { color: var(--text-dim); font-weight: 800; }
.nav-xp-pts { font-weight: 800; font-size: var(--nav-fs-s); color: var(--gold); font-variant-numeric: tabular-nums; }
.nav-xp.bump { animation: xp-bump 0.4s ease; }
@keyframes xp-bump { 0%, 100% { transform: scale(1); } 40% { transform: scale(1.18); } }
@media (prefers-reduced-motion: reduce) { .points-pop { animation: none; opacity: 1; } .nav-xp.bump { animation: none; } }
@media (max-width: 700px) { .nav-xp-pts, .nav-xp-sep { display: none; } .nav-xp { padding: 0.3rem 0.5rem; margin-right: 0.25rem; } }
.gboard { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.3rem; counter-reset: gb; }
.gboard li { display: flex; align-items: center; gap: 0.55rem; background: var(--ink); border-radius: 10px; padding: 0.4rem 0.6rem; }
.gboard li.gb-me { border: 1.5px solid var(--green); background: color-mix(in srgb, var(--green) 8%, transparent); }
.gb-rank { min-width: 26px; text-align: center; font-weight: 800; font-size: max(var(--text-floor), 0.9rem); }
.gb-ava { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; font-size: max(var(--text-floor), 0.9rem); object-fit: cover; background: var(--ink-3); flex-shrink: 0; }
.gb-name { flex: 1; font-weight: 800; font-size: max(var(--text-floor), 0.85rem); text-decoration: none; color: var(--green-bright); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* a board name inside a sentence ("pts to overtake @name"): the board's colour, without the row layout of .gb-name */
.lb-inline-name { font-weight: 800; color: var(--green-bright); text-decoration: none; overflow-wrap: anywhere; }
.lb-inline-name:hover { text-decoration: underline; }
.lb-inline-name:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 4px; }
.gb-lv { font-size: max(var(--text-floor), 0.72rem); font-weight: 800; color: var(--text-dim); }
.gb-pts { font-weight: 800; font-size: max(var(--text-floor), 0.85rem); color: var(--gold); }

/* public wall level badge */
.wall-level {
  display: inline-flex; align-items: center; gap: 0.4rem; margin-top: 0.4rem;
  background: color-mix(in srgb, var(--green) 12%, transparent); border: 1.5px solid color-mix(in srgb, var(--green) 40%, transparent); color: var(--green-bright);
  border-radius: 999px; padding: 0.3rem 0.9rem; font-weight: 800; font-size: max(var(--text-floor), 0.82rem);
}
/* public wall diamond-hands badge */
.wall-diamond {
  display: inline-flex; align-items: center; gap: 0.4rem; margin-top: 0.4rem;
  background: rgba(93,201,255,0.12); border: 1.5px solid rgba(93,201,255,0.45); color: var(--diamond);
  border-radius: 999px; padding: 0.3rem 0.9rem; font-weight: 800; font-size: max(var(--text-floor), 0.82rem);
}
.gb-dia { font-size: max(var(--text-floor), 0.9rem); line-height: 1; }

/* ===== Send Power dashboard v2 ===== */
/* 1 — Hero Power Core */
.pc-hero { display: flex; align-items: center; gap: 1.3rem; flex-wrap: wrap; }
.pc-core { width: var(--gfx-ring); height: var(--gfx-ring); flex-shrink: 0; filter: drop-shadow(0 0 22px var(--g-veil)); }
.pc-svg { width: 100%; height: 100%; display: block; }
.pc-track { fill: none; stroke: var(--ink-4); stroke-width: 8; }
.pc-arc { fill: none; stroke-width: 8; stroke-linecap: round; transition: stroke-dashoffset 1s cubic-bezier(0.2,0.8,0.3,1); }
.pc-arc-xp { stroke: url(#gXp); }
.pc-arc-dia { stroke: url(#gDia); stroke-width: 7; }
.pc-num { font-family: 'Luckiest Guy', cursive; font-size: var(--gfx-ring-num); fill: var(--text); dominant-baseline: middle; }
.pc-lbl { font-size: var(--gfx-ring-lbl); font-weight: 800; letter-spacing: 0.18em; fill: var(--text-dim); }
.pc-name { flex: 1 1 220px; min-width: 0; }   /* a 220px basis: beside the ring where it fits, underneath it on a phone — never past the screen */
.pc-title { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.5rem); color: var(--green-bright); letter-spacing: 0.02em; line-height: 1.06; }
.pc-rank { font-weight: 800; font-size: max(var(--text-floor), 0.9rem); color: var(--gold); margin-top: 0.1rem; }
.pc-power { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), clamp(1.8rem, 8.5vw, 2.9rem)); color: var(--gold); line-height: 1; font-variant-numeric: tabular-nums; text-shadow: 0 2px 0 var(--gold-deep), 0 0 26px rgba(255,179,64,0.35); margin-top: 0.35rem; }
.pc-power-lbl { font-size: max(var(--text-floor), 0.72rem); font-weight: 800; letter-spacing: 0.14em; color: var(--text-dim); }
.pc-chips { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.6rem; }
.pc-mult { background: linear-gradient(180deg, rgba(255,179,64,0.2), rgba(255,179,64,0.06)); border: 1.5px solid rgba(255,179,64,0.5); color: var(--gold); font-weight: 800; font-size: max(var(--text-floor), 0.82rem); border-radius: 999px; padding: 0.25rem 0.7rem; }
.pc-mult-off { background: var(--ink); border-color: var(--ink-4); color: var(--text-dim); }
.pc-mult-parts { margin-top: 0.35rem; font-size: max(var(--text-floor), 0.74rem); font-weight: 600; color: var(--text-dim); } /* 1 + (Holder−1) + (OG−1) + (Community−1) + … breakdown — boosts add of the boost */
.pc-today { background: color-mix(in srgb, var(--green) 14%, transparent); border: 1.5px solid color-mix(in srgb, var(--green) 40%, transparent); color: var(--green-bright); font-weight: 800; font-size: max(var(--text-floor), 0.82rem); border-radius: 999px; padding: 0.25rem 0.7rem; }

/* 2 — Objective bar */
.gobj { margin: 1rem 0 0.9rem; background: linear-gradient(180deg, color-mix(in srgb, var(--green) 8%, transparent), transparent), var(--ink); border: 1.5px solid color-mix(in srgb, var(--green) 35%, transparent); border-radius: 14px; padding: 0.7rem 0.95rem; }
.gobj-alert { background: linear-gradient(180deg, rgba(255,179,64,0.12), transparent), var(--ink); border-color: rgba(255,179,64,0.5); }
.gobj-primary { font-weight: 800; font-size: max(var(--text-floor), 0.98rem); color: var(--text); line-height: 1.4; }
.gobj-secondary { font-size: max(var(--text-floor), 0.85rem); color: var(--text-dim); margin-top: 0.3rem; line-height: 1.4; }
.gobj a { color: var(--green-bright); font-weight: 800; text-decoration: none; }
.gobj a:hover { text-decoration: underline; }
/* the re-read <button> is a small green pill, not green text — black type needs a fill */
.gobj-link { color: var(--on-green); background: var(--green); border: none; padding: 0.1rem 0.5rem; border-radius: var(--r-pill); font: inherit; font-weight: 800; cursor: pointer; text-decoration: none; }
.gobj-link:hover { background: var(--green-bright); }
.gobj b { color: var(--gold); }

/* 3 — KPI strip */
.kpi-strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.6rem; margin-bottom: 1rem; }
.kpi { background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 12px; padding: 0.6rem 0.5rem; text-align: center; }
.kpi-ico { font-size: max(var(--text-floor), 1.15rem); line-height: 1; }
.kpi-val { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.3rem); margin-top: 0.15rem; color: var(--text); font-variant-numeric: tabular-nums; line-height: 1.05; }
.kpi-sub { font-size: max(var(--text-floor), 0.66rem); font-weight: 700; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.03em; margin-top: 0.15rem; }
.kpi-up { color: var(--green-bright); }
.kpi-gold .kpi-val { color: var(--gold); }
.kpi-green .kpi-val { color: var(--green-bright); }
.kpi-flame .kpi-val { color: #ff8a3d; }
.kpi-dia .kpi-val { color: var(--diamond); }

/* 4 — Sender XP bar */
.xpwrap { margin: 0 0 1.1rem; }
.xprow { display: flex; align-items: center; gap: 0.55rem; }
.xp-cap { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 0.78rem); color: var(--green-bright); flex-shrink: 0; }
.xp-cap.ghost { color: var(--text-dim); }
.xpwrap .gxp { margin: 0; flex: 1; --bar-h: 24px; }
.gxp-notches { position: absolute; inset: 0; pointer-events: none; border-radius: 999px; background: repeating-linear-gradient(90deg, transparent 0, transparent calc(10% - 1px), color-mix(in srgb, var(--ink) calc(0.5 * 100%), transparent) calc(10% - 1px), color-mix(in srgb, var(--ink) calc(0.5 * 100%), transparent) 10%); }
.gxp.near .gxp-fill { background: linear-gradient(90deg, var(--gold-deep), var(--gold), var(--green-bright)); animation: xp-pulse 1.4s ease-in-out infinite; }
.gxp.maxed .gxp-fill { background: linear-gradient(90deg, var(--gold-deep), var(--gold)); }
@keyframes xp-pulse { 0%, 100% { box-shadow: 0 0 8px rgba(255,179,64,0.4); } 50% { box-shadow: 0 0 20px rgba(255,179,64,0.85); } }
.xp-near { text-align: center; font-size: max(var(--text-floor), 0.8rem); font-weight: 800; color: var(--gold); margin-top: 0.35rem; }

/* 5 — Equation strip */
.eqstrip { background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 14px; padding: 0.85rem 0.8rem; margin-bottom: 1.1rem; }
.eq-stale { color: var(--text-mute); filter: saturate(0.4); }
.eq-row { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; justify-content: center; }
.eq-chip { display: inline-flex; flex-direction: column; align-items: center; gap: 0.12rem; background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 10px; padding: 0.4rem 0.7rem; font-weight: 800; font-size: max(var(--text-floor), 1rem); color: var(--text); min-width: 62px; }
.eq-chip small { font-weight: 700; font-size: max(var(--text-floor), 0.6rem); color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.03em; }
.eq-supply { border-color: var(--g-lit); color: var(--green-bright); }
.eq-dia { border-color: rgba(159,224,255,0.45); color: var(--diamond); }
.eq-out { border-color: rgba(255,179,64,0.6); color: var(--gold); background: linear-gradient(180deg, rgba(255,179,64,0.16), transparent); box-shadow: 0 0 18px rgba(255,179,64,0.22); }
.eq-op { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.1rem); color: var(--text-dim); }
.eq-note { text-align: center; font-size: max(var(--text-floor), 0.78rem); color: var(--text-dim); margin: 0.6rem 0 0; }
.eq-note b { color: var(--gold); }

/* 6 — Boost engine: Vault + Diamond Relic */
.engine { margin-bottom: 1.1rem; }
.engine-live { display: grid; grid-template-columns: 1fr; gap: 1rem; }
.eng-h { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.05rem); margin: 0 0 0.6rem; letter-spacing: 0.02em; color: var(--text); }
.engine-locked { background: var(--ink); border: 1.5px dashed var(--ink-4); border-radius: 16px; padding: 1.2rem 1rem; text-align: center; }
.lock-ico { font-size: max(var(--text-floor), 2rem); }
.lock-btns { display: flex; gap: 0.5rem; flex-wrap: wrap; justify-content: center; }
.vault { background: radial-gradient(ellipse 90% 100% at 50% 0%, rgba(255,179,64,0.1), transparent), var(--ink); border: 1.5px solid rgba(255,179,64,0.35); border-radius: 16px; padding: 0.9rem 1rem; }
.vtok { display: flex; align-items: center; gap: 0.7rem; margin-bottom: 0.75rem; }
.vtok-emblem { width: 38px; height: 38px; font-size: max(var(--text-floor), 1rem); }
.vtok-body { flex: 1; min-width: 0; }
.vtok-line { display: flex; align-items: baseline; gap: 0.45rem; flex-wrap: wrap; }
.vtok-amt { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.25rem); color: var(--text); font-variant-numeric: tabular-nums; }
.vtok-sym { font-weight: 800; font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); }
.vtok-pill { margin-left: auto; font-size: max(var(--text-floor), 0.72rem); font-weight: 800; background: var(--ink-3); border: 1px solid var(--ink-4); border-radius: 999px; padding: 0.15rem 0.55rem; color: var(--text); }
.vmeter { position: relative; height: 14px; border-radius: 999px; background: var(--ink-3); border: 1px solid var(--ink-4); overflow: hidden; margin: 0.35rem 0 0.2rem; }
.vmeter-fill { height: 100%; border-radius: 999px; transition: width 0.9s cubic-bezier(0.2,0.8,0.3,1); }
.vmeter-fill.send { background: linear-gradient(90deg, var(--green-dark), var(--green-bright)); }
.vmeter-fill.gwc { background: linear-gradient(90deg, var(--gold-deep), var(--gold)); }
.vtick { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--hair); }
.vtok-cap { font-size: max(var(--text-floor), 0.74rem); color: var(--text-dim); }
.vtok-cap b { color: var(--text); }
.vault-foot { font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); text-align: center; padding: 0.55rem 0 0.2rem; border-top: 1px dashed var(--ink-4); margin-top: 0.2rem; }
.vault-foot b { color: var(--gold); }
.forge { display: flex; align-items: center; gap: 0.85rem; margin-top: 0.6rem; background: linear-gradient(180deg, rgba(255,138,61,0.1), transparent); border: 1.5px solid rgba(255,138,61,0.35); border-radius: 12px; padding: 0.6rem 0.85rem; }
.forge-stale { border-color: rgba(255,179,64,0.5); background: rgba(255,179,64,0.08); }
.forge-flame { line-height: 1; animation: flame-flick 1.8s ease-in-out infinite; }
@keyframes flame-flick { 0%, 100% { transform: scale(1) rotate(-2deg); opacity: 0.92; } 50% { transform: scale(1.09) rotate(2deg); opacity: 1; } }
.forge-days { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 2rem); color: var(--gold); line-height: 1; font-variant-numeric: tabular-nums; }
.forge-unit { font-family: 'Rubik', sans-serif; font-size: max(var(--text-floor), 0.8rem); font-weight: 800; color: var(--text-dim); }
.forge-sub { font-size: max(var(--text-floor), 0.78rem); color: var(--text-dim); margin-top: 0.2rem; }
.forge-sub b { color: var(--text); }
.danger { color: var(--red); font-weight: 800; }
.relic { background: radial-gradient(ellipse 90% 90% at 50% 0%, rgba(159,224,255,0.12), transparent), var(--ink); border: 1.5px solid rgba(159,224,255,0.45); border-radius: 16px; padding: 0.9rem 1rem; text-align: center; box-shadow: inset 0 0 30px rgba(159,224,255,0.05); }
.relic .eng-h { color: var(--diamond); }
.relic-medal-wrap { width: 150px; height: 150px; margin: 0.2rem auto 0.5rem; filter: drop-shadow(0 0 16px rgba(159,224,255,0.32)); }
.relic-medal { width: 100%; height: 100%; display: block; }
.relic-track { fill: none; stroke: var(--ink-4); stroke-width: 6; }
.relic-arc { fill: none; stroke: url(#gRelic); stroke-width: 6; stroke-linecap: round; transition: stroke-dashoffset 1s cubic-bezier(0.2,0.8,0.3,1); }
.relic-disc { fill: rgba(159,224,255,0.06); stroke: rgba(159,224,255,0.28); stroke-width: 1; }
.relic-pip { fill: none; stroke: var(--ink-4); stroke-width: 1.4; }
.relic-pip.on { fill: var(--diamond); stroke: none; }
.relic-pip.cur { fill: var(--gold); stroke: rgba(255,255,255,0.25); stroke-width: 1.5; animation: pip-pulse 1.6s ease-in-out infinite; }
@keyframes pip-pulse { 0%, 100% { opacity: 0.78; } 50% { opacity: 1; } }
.relic-emoji { font-size: max(var(--text-floor), 30px); dominant-baseline: middle; }
.relic-lv { font-family: 'Luckiest Guy', cursive; font-size: var(--gfx-relic-lv); fill: var(--diamond); letter-spacing: 0.06em; }
.relic-name { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.15rem); color: var(--diamond); }
.relic-meta { font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); margin: 0.1rem 0 0.6rem; }
.relic-meta b { color: var(--text); }
.relic-bar { margin-top: 0; }
.relic-max .relic-arc { stroke: var(--gold); }
.relic-max .relic-pip.on { fill: var(--gold); }
.relic-max .gd-fill { background: linear-gradient(90deg, var(--gold-deep), var(--gold)); }

/* 7 — Loot Log */
.loot { margin-bottom: 1.1rem; }
.loot-bar { display: flex; height: 16px; border-radius: 999px; overflow: hidden; background: var(--ink); border: 1.5px solid var(--ink-4); margin-bottom: 0.7rem; }
.loot-bar span { height: 100%; min-width: 2px; }
.loot-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.35rem; }
.loot-list li { display: grid; grid-template-columns: auto 1fr 90px auto; align-items: center; gap: 0.55rem; background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 10px; padding: 0.42rem 0.7rem; }
.ll-ico { font-size: max(var(--text-floor), 1rem); }
.ll-label { font-size: max(var(--text-floor), 0.85rem); font-weight: 700; color: var(--text); display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; text-decoration: none; }
.ll-top { font-size: max(var(--text-floor), 0.64rem); font-weight: 800; color: var(--gold); background: rgba(255,179,64,0.14); border-radius: 999px; padding: 0.05rem 0.4rem; }
.ll-n { font-size: max(var(--text-floor), 0.72rem); font-weight: 700; color: var(--text-dim); }
.ll-track { height: 8px; border-radius: 999px; background: var(--ink-3); overflow: hidden; }
.ll-fill { display: block; height: 100%; border-radius: 999px; transition: width 0.8s cubic-bezier(0.2,0.8,0.3,1); transition-delay: calc(var(--i) * 60ms); }
.ll-pts { font-weight: 800; font-size: max(var(--text-floor), 0.85rem); color: var(--gold); font-variant-numeric: tabular-nums; text-align: right; }
.ll-nudge { border-style: dashed; opacity: 0.9; }
.ll-nudge .ll-label { color: var(--green-bright); }
.loot-foot { text-align: center; font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); margin: 0.6rem 0 0; }
.loot-foot b { color: var(--gold); }

/* 8 — Quest rows: boosted-points preview */
.ge-eff { color: var(--gold); font-size: max(var(--text-floor), 0.78rem); }

@media (min-width: 1040px) { .engine-live { grid-template-columns: 1.15fr 1fr; align-items: start; } }
@media (prefers-reduced-motion: reduce) {
  .pc-arc, .relic-arc, .vmeter-fill, .ll-fill { transition: none; }
  .forge-flame, .relic-pip.cur, .gxp.near .gxp-fill { animation: none; }
}
@media (max-width: 560px) {
  .gdash-cols { grid-template-columns: 1fr; }
  .kpi-strip { grid-template-columns: repeat(2, 1fr); }
  .pc-hero { justify-content: center; text-align: center; }
  .pc-name { text-align: center; min-width: 0; }
  .pc-chips { justify-content: center; }
  .loot-list li { grid-template-columns: auto 1fr auto; }
  .loot-list .ll-track { display: none; }
  .eq-chip { min-width: 54px; padding: 0.35rem 0.5rem; font-size: max(var(--text-floor), 0.9rem); }
}

/* ===== Accessibility ===== */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 500; background: var(--green);
  color: var(--on-green); padding: 0.6rem 1.2rem; border-radius: 0 0 12px 0; font-weight: 800;
}
.skip-link:focus { left: 0; }
:focus-visible { outline: 3px solid var(--green-bright); outline-offset: 2px; border-radius: 4px; }
.btn:focus-visible, .copy-btn:focus-visible, .react-btn:focus-visible { outline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
  html { scroll-behavior: auto; }
  .ticker-track { animation: none; }
}

@media (max-width: 560px) {
  .nav { padding: 0.5rem 0.75rem; gap: 0.5rem; }              /* keep [logo][bell][Lv][account][≡] on one row */
  .nav-logo span { display: none; }                            /* the wordmark goes; the logo image stays (never squashed: see .nav > *) */
  .nav-live { display: none; }                                 /* "N Sending it" pill can't fit beside bell + account + ≡ at phone widths */
  .nav-xp { white-space: nowrap; }
  .profile-link { padding: 0 0.7rem; }
  .swap-row { grid-template-columns: 1fr; }
  }

/* ===== Universal wallet connect picker ===== */
.wc-overlay { position: fixed; inset: 0; z-index: 9100; display: grid; place-items: center; padding: 1rem; background: rgba(4,6,10,0.82); backdrop-filter: blur(6px); }
.wc-modal {
  position: relative; width: min(420px, 100%); max-height: 88vh; overflow-y: auto;
  background: linear-gradient(180deg, var(--ink-3), var(--ink-2)); border: 1.5px solid color-mix(in srgb, var(--green) 40%, transparent);
  border-radius: 20px; padding: 1.4rem 1.3rem 1.5rem; box-shadow: 0 0 60px color-mix(in srgb, var(--green) 16%, transparent), 0 30px 60px rgba(0,0,0,0.6);
}
.wc-x { position: absolute; top: 0.7rem; right: 0.8rem; background: var(--ctl-fill-lo); border: none; color: var(--ctl-ink); font-size: max(var(--text-floor), 1.2rem); cursor: pointer; line-height: 1; padding: 0.3rem; border-radius: 8px; }
.wc-x:hover { color: var(--ctl-ink); background: var(--ctl-fill-hi); }
.wc-title { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.5rem); color: var(--green-bright); margin: 0 0 0.5rem; letter-spacing: 0.02em; }
.wc-note { font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); line-height: 1.5; background: var(--g-wash); border: 1px solid color-mix(in srgb, var(--green) 28%, transparent); border-radius: 12px; padding: 0.6rem 0.75rem; margin: 0 0 1rem; }
.wc-note b { color: var(--green-bright); }
.wc-list { display: grid; gap: 0.5rem; }
.wc-item, .wc-deep {
  display: flex; align-items: center; gap: 0.8rem; width: 100%; box-sizing: border-box; text-align: left; text-decoration: none;
  background: var(--ctl-fill-hi); border: 1.5px solid var(--ctl-fill-hi); border-radius: 14px; padding: 0.7rem 0.85rem; color: var(--ctl-ink);
  font: inherit; font-weight: 700; cursor: pointer; transition: transform 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}
.wc-item:hover, .wc-deep:hover, .wc-item:focus-visible, .wc-deep:focus-visible { transform: translateY(-2px); border-color: var(--green); background: var(--green-bright); color: var(--ctl-ink); }
.wc-ico { width: 34px; height: 34px; border-radius: 9px; flex-shrink: 0; object-fit: contain; background: var(--ink-3); }
.wc-ico-emoji { display: grid; place-items: center; font-size: max(var(--text-floor), 1.2rem); }
.wc-name { flex: 1; font-size: max(var(--text-floor), 0.98rem); }
.wc-go { color: var(--ctl-ink); font-weight: 800; font-size: max(var(--text-floor), 0.85rem); }
.wc-empty { color: var(--text-dim); font-size: max(var(--text-floor), 0.9rem); text-align: center; padding: 0.6rem 0; margin: 0; }
.wc-foot { margin-top: 0.9rem; display: grid; gap: 0.5rem; }
.wc-sub { font-size: max(var(--text-floor), 0.8rem); font-weight: 700; color: var(--text-dim); margin-bottom: 0.1rem; }
.wc-deep { border-style: dashed; }
.wc-deep .wc-go { color: var(--ctl-ink); }
.wc-name { display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap; }
.wc-badge { font-size: max(var(--text-floor), 0.64rem); font-weight: 800; color: var(--on-green); background: linear-gradient(180deg, var(--green-bright), var(--green-dark)); border-radius: 0.75em; padding: 0.08rem 0.45rem; letter-spacing: 0.01em; white-space: normal; max-width: 100%; }   /* wraps: at 320px a one-line badge ran off the picker (a pill on one line, a rounded box on two) */
.wc-feat { border-color: var(--green); box-shadow: 0 0 0 1px color-mix(in srgb, var(--green) 30%, transparent), 0 0 22px color-mix(in srgb, var(--green) 14%, transparent); }
.wc-feat:hover, .wc-feat:focus-visible { border-color: var(--green-bright); }
.wc-tip { font-size: max(var(--text-floor), 0.76rem); color: var(--text-dim); line-height: 1.5; background: color-mix(in srgb, var(--green) 6%, transparent); border: 1px solid var(--g-veil); border-radius: 10px; padding: 0.5rem 0.65rem; margin: 0.3rem 0 0; }
.wc-tip b { color: var(--green-bright); }
@media (prefers-reduced-motion: reduce) { .wc-item, .wc-deep { transition: none; } .wc-item:hover, .wc-deep:hover { transform: none; } }
/* "Last used" on the wallet this browser signed with before: the list opens on every sign-in, and that one is first */
.wc-last { background: var(--ink-1); color: var(--green-bright); }
/* the picker's way out for a wallet that cannot sign (GMGN) or is not listed: the burn proof */
.wc-burn { border-color: color-mix(in srgb, var(--gold) 55%, transparent); }
.wc-burn .wc-badge { background: linear-gradient(180deg, var(--gold), var(--gold-deep)); color: var(--on-gold); }
/* a row's longest badge must never widen the column past the picker (every row would spill off its right edge) */
.wc-list, .wc-foot { grid-template-columns: minmax(0, 1fr); }
.wc-name { min-width: 0; }

/* ===== Proving a wallet by a burn (burnproof.js) — above the ticket (9000) and the picker (9100), below the toasts (9200) and "confirm it's you" (9500) ===== */
.bp-overlay { position: fixed; inset: 0; z-index: 9150; display: grid; place-items: center; padding: 1rem; background: rgba(4,6,10,0.84); backdrop-filter: blur(6px); }
.bp-overlay[hidden] { display: none; }
.bp-card {
  position: relative; width: min(480px, 100%); max-height: 92vh; overflow-y: auto; box-sizing: border-box;
  background: linear-gradient(180deg, var(--ink-3), var(--ink-2)); border: 2px solid color-mix(in srgb, var(--gold) 45%, transparent);
  border-radius: 20px; padding: 1.4rem 1.3rem 1.3rem; box-shadow: 0 0 60px color-mix(in srgb, var(--gold) 14%, transparent), 0 30px 60px rgba(0,0,0,0.6);
}
.bp-x { position: absolute; top: 0.7rem; right: 0.8rem; background: var(--ctl-fill-lo); border: none; color: var(--ctl-ink); width: 34px; height: 34px; border-radius: 50%; cursor: pointer; font-size: max(var(--text-floor), 0.95rem); display: inline-flex; align-items: center; justify-content: center; line-height: 1; padding: 0; }
.bp-x:hover { background: var(--red); color: var(--on-red); }
.bp-kicker { margin: 0 2.4rem 0.2rem 0; font-size: max(var(--text-floor), 0.78rem); font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--gold); }
.bp-title { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.45rem); color: var(--green-bright); margin: 0 2.4rem 0.4rem 0; letter-spacing: 0.02em; text-wrap: balance; }
.bp-card .modal-note { margin: 0.55rem 0; }
.bp-lead { color: var(--text); }
.bp-ok { color: var(--text); font-size: max(var(--text-floor), 0.95rem); }
.bp-mono { font-family: ui-monospace, 'SF Mono', Menlo, monospace; overflow-wrap: anywhere; }
.bp-box { margin: 0.25rem 0 0.7rem; }
.bp-box code { flex: 1; min-width: 0; }
.bp-form { display: grid; gap: 0.15rem; margin-top: 0.4rem; }
.bp-form .addr-input { margin-bottom: 0.45rem; }
.bp-form .btn { width: 100%; margin-top: 0.4rem; }
.bp-steps { margin: 0.2rem 0 0.4rem; padding-left: 1.3rem; display: grid; gap: 0.25rem; color: var(--text-dim); font-size: max(var(--text-floor), 0.85rem); line-height: 1.5; }
.bp-rules { list-style: none; margin: 0.5rem 0; padding: 0.6rem 0.75rem; display: grid; gap: 0.4rem; border-radius: 12px;
  background: color-mix(in srgb, var(--gold) 7%, transparent); border: 1px solid color-mix(in srgb, var(--gold) 30%, transparent);
  color: var(--text-dim); font-size: max(var(--text-floor), 0.8rem); line-height: 1.5; }
.bp-rules b { color: var(--text); }
.bp-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.7rem; }
.bp-actions .btn { flex: 1 1 12rem; }
.bp-status:empty { display: none; }
.bp-alt { text-align: center; margin: 0.6rem 0 0; }
/* the sign-in / sign-up screen names the wallets that work here; open, it lists every one */
.w-works { margin: 0 0 0.8rem; border: 1px solid var(--hair); border-radius: 12px; padding: 0.45rem 0.7rem; background: var(--ink-1); }
.w-works > summary { cursor: pointer; color: var(--text-dim); font-size: max(var(--text-floor), 0.82rem); line-height: 1.45; overflow-wrap: anywhere; list-style: none; }
.w-works > summary::-webkit-details-marker { display: none; }
.w-works > summary::after { content: ' ▾'; }
.w-works[open] > summary::after { content: ' ▴'; }
.w-works > summary:hover, .w-works > summary:focus-visible { color: var(--text); }
.w-works-list { list-style: none; margin: 0.5rem 0 0.1rem; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 9.5rem), 1fr)); gap: 0.25rem 0.6rem;
  font-size: max(var(--text-floor), 0.82rem); color: var(--text); }
.w-works-list li { min-width: 0; overflow-wrap: anywhere; }
.w-works-list small { color: var(--green-bright); font-size: max(var(--text-floor), 0.72rem); font-weight: 700; }
.bp-alt .linklike { margin-top: 0.3rem; }

/* ===== New Pairs Radar ===== */
:root { --triage-high: #ff7a3d; }
.np-hero { text-align: center; padding: 1.6rem 1.25rem 0.4rem; max-width: 760px; margin: 0 auto; }
.np-hero-warn { font-size: max(var(--text-floor), 0.86rem); color: var(--gold); background: rgba(255,179,64,0.08); border: 1px solid rgba(255,179,64,0.3); border-radius: 12px; padding: 0.6rem 0.85rem; max-width: 620px; margin: 0.4rem auto 0; line-height: 1.5; }
.np-hero-warn b { color: var(--text); }
#main { padding: 0.6rem 1rem 4rem; }
.np-wrap { max-width: 900px; margin: 0 auto; }

/* controls */
.np-controls { position: sticky; top: var(--nav-h, 58px); z-index: 30; display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; padding: 0.7rem; margin: 0.4rem 0; background: color-mix(in srgb, var(--ink-2) calc(0.92 * 100%), transparent); backdrop-filter: blur(10px); border: 1.5px solid var(--ink-4); border-radius: 14px; }
.np-search { flex: 1 1 220px; display: flex; align-items: center; gap: 0.4rem; background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 10px; padding: 0.4rem 0.6rem; }
.np-search-input { flex: 1; background: none; border: none; color: var(--text); font: inherit; outline: none; min-width: 0; }
.np-search-input::-webkit-search-cancel-button { display: none; } /* hide the native ✕ — we use our own always-visible one */
.np-search-clear { flex: 0 0 auto; background: var(--ctl-fill-lo); border: none; color: var(--ctl-ink); width: 22px; height: 22px; border-radius: 50%; cursor: pointer; font-size: max(var(--text-floor), 0.82rem); line-height: 1; display: inline-flex; align-items: center; justify-content: center; padding: 0; transition: background 0.15s, color 0.15s; }
.np-search-clear:hover { background: var(--ctl-fill-hi); color: var(--ctl-ink); }
.np-search-clear:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--green-bright); }

/* small copy button next to a token ticker */
/* a green tile like every other control — it was a 60% glyph with no fill, which is the one thing a black-type control cannot be */
.np-tickcopy { background: var(--ctl-fill-lo); color: var(--ctl-ink); border: none; border-radius: 4px; cursor: pointer; font-size: max(var(--text-floor), 0.78em); padding: 0 0.2rem; vertical-align: middle; line-height: 1; transition: background 0.15s ease, transform 0.1s ease; }
.np-tickcopy:hover { background: var(--ctl-fill-hi); color: var(--ctl-ink); transform: scale(1.15); }
.np-tickcopy:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--green-bright); }

/* Hot Feed "Make a Send Call" CTA (direct — no need to expand the detail first) */
.np-slide-cta { margin: 0.55rem 0 0.2rem; }
.np-slide-call { width: 100%; }

/* Send Call widget — "not researched / didn't DYOR" warning */
.sc-nodyor { margin: 0.45rem 0; padding: 0.5rem 0.7rem; background: rgba(255,179,64,0.12); border: 1.5px solid rgba(255,179,64,0.5); border-radius: 9px; color: var(--gold); font-size: max(var(--text-floor), 0.83rem); line-height: 1.4; }
.sc-nodyor b { color: var(--gold); }

/* Honeypot & contract read (in the Contract score-breakdown dropdown) */
.np-contract { margin-top: 0.55rem; }
.np-contract-load { color: var(--text-dim); font-size: max(var(--text-floor), 0.82rem); display: flex; align-items: center; gap: 0.4rem; }
.np-hp { background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 10px; padding: 0.6rem 0.75rem; }
.np-hp-h { font-weight: 800; color: var(--text); margin: 0 0 0.35rem; font-size: max(var(--text-floor), 0.88rem); }
.np-hp-summary { font-size: max(var(--text-floor), 0.83rem); line-height: 1.45; color: var(--text); margin: 0 0 0.5rem; }
.np-hp-sub { font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); margin: 0 0 0.3rem; }
.np-hp-powers { list-style: none; margin: 0 0 0.5rem; padding: 0; display: grid; gap: 0.3rem; }
.np-hp-powers li { font-size: max(var(--text-floor), 0.8rem); line-height: 1.4; padding: 0.35rem 0.5rem; border-radius: 8px; border-left: 3px solid var(--g-lit); background: var(--g-wash); }
.np-hp-crit { border-left-color: var(--red) !important; background: rgba(255,64,64,0.09) !important; }
.np-hp-high { border-left-color: #f0932b !important; background: rgba(240,147,43,0.09) !important; }
.np-hp-med { border-left-color: var(--gold) !important; }
.np-hp-powers b { color: var(--text); }
.np-hp-ok { color: var(--green-bright); font-size: max(var(--text-floor), 0.82rem); margin: 0.3rem 0; }
.np-hp-bad { color: var(--red); font-size: max(var(--text-floor), 0.82rem); margin: 0.3rem 0; }
.np-hp-note { color: var(--text-dim); font-size: max(var(--text-floor), 0.8rem); margin: 0.3rem 0; }
.np-hp-disclaim { color: var(--text-dim); font-size: max(var(--text-floor), 0.74rem); line-height: 1.4; margin: 0.5rem 0 0; }

/* RUGGED banner on a Send Call whose liquidity was pulled */
.sc-rugged { background: var(--red); color: #fff; font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.35rem); text-align: center; padding: 0.5rem 0.7rem; border-radius: 10px; margin-bottom: 0.6rem; letter-spacing: 0.05em; box-shadow: 0 0 20px rgba(255,64,64,0.55); }
.sc-rugged span { display: block; font-family: 'Rubik', system-ui, sans-serif; font-size: max(var(--text-floor), 0.78rem); font-weight: 800; letter-spacing: 0; margin-top: 0.15rem; }
.sc-is-rugged { border-color: var(--red) !important; box-shadow: 0 0 0 1.5px var(--red); }

/* social handle buttons on a public wall */
.wall-socials { display: flex; gap: 0.5rem; flex-wrap: wrap; margin: 0.55rem 0; }
.wall-soc { display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.35rem 0.75rem; border-radius: 999px; background: var(--g-tint); color: var(--text); text-decoration: none; font-weight: 700; font-size: max(var(--text-floor), 0.85rem); border: 1px solid var(--g-edge); transition: background 0.15s ease, color 0.15s ease; }
.wall-soc:hover { background: var(--g-veil); }
.wall-soc-x:hover { color: #1d9bf0; }
.wall-soc-ig:hover { color: #e1306c; }

/* OG badge — shown next to a verified early-buyer's name everywhere. The title carries the hover explanation; a click
   opens the About page's OG section (a link, or a span with data-og-link where it sits inside another link). */
.og-badge { display: inline-flex; align-items: center; vertical-align: middle; margin-left: 0.35rem; padding: 0.02rem 0.4rem; border-radius: 999px; font-size: max(var(--text-floor), 0.62rem); font-weight: 900; letter-spacing: 0.06em; line-height: 1.5; color: var(--on-gold); background: linear-gradient(180deg, var(--gold) 0%, var(--gold-deep) 100%); border: 1px solid rgba(255,179,64,0.65); box-shadow: 0 0 8px rgba(255,179,64,0.4); text-transform: uppercase; cursor: help; white-space: nowrap; }
.og-badge:hover, .og-badge:focus-visible { box-shadow: 0 0 13px rgba(255,179,64,0.75); }
a.og-badge, .og-badge[data-og-link] { cursor: pointer; text-decoration: none; }
a.og-badge:focus-visible { outline: 3px solid var(--green-bright); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .og-badge { box-shadow: none; } }
.og-block { display: flex; align-items: center; gap: 0.8rem; margin: 0.9rem 0; padding: 0.8rem 1rem; border-radius: 14px; background: linear-gradient(100deg, rgba(255,179,64,0.14), rgba(255,179,64,0.05)); border: 1.5px solid rgba(255,179,64,0.5); line-height: 1.5; }
.og-block-badge { flex: 0 0 auto; font-weight: 900; font-size: max(var(--text-floor), 0.95rem); color: var(--on-gold); background: linear-gradient(180deg, var(--gold), var(--gold-deep)); border-radius: 999px; padding: 0.3rem 0.7rem; box-shadow: 0 0 10px rgba(255,179,64,0.5); }
.og-block-body { color: var(--text); font-size: max(var(--text-floor), 0.9rem); }
.og-block-body b { color: var(--gold); }
.og-block-lost { background: rgba(255,93,93,0.08); border-color: rgba(255,93,93,0.4); }
.og-block-lost .og-block-badge { background: none; box-shadow: none; font-size: max(var(--text-floor), 1.4rem); padding: 0; }
.og-block-lost .og-block-body b { color: var(--red); }

/* ===== OG claim banner (top of the landing page) — high-energy, make people WANT it ===== */
.og-banner {
  position: relative; overflow: hidden;
  display: block;   /* a strip: the head is always shown, the rest pops down on a tap (see .og-banner-head / .og-banner-more) */
  text-decoration: none; color: var(--text);
  background: linear-gradient(100deg, #17120a 0%, #3a2a08 22%, #6b4c08 50%, #3a2a08 78%, #17120a 100%);
  background-size: 250% 100%; animation: ogGradient 9s linear infinite;
  border-top: 1px solid rgba(255,179,64,0.35); border-bottom: 2px solid rgba(255,179,64,0.6);
  box-shadow: inset 0 0 45px rgba(255,179,64,0.12), 0 3px 22px rgba(255,179,64,0.15);
  padding: 0; font-size: max(var(--text-floor), 0.9rem); line-height: 1.4;
  transition: box-shadow 0.2s ease;
}
@keyframes ogGradient { 0% { background-position: 0% 50%; } 100% { background-position: 250% 50%; } }
.og-banner:hover { box-shadow: inset 0 0 55px rgba(255,179,64,0.22), 0 6px 32px rgba(255,179,64,0.4); }
/* the head: one row — medal, title, one line, the live countdown, a chevron — a button that pops the rest down */
.og-banner-head { position: relative; z-index: 1; display: flex; align-items: center; flex-wrap: wrap; gap: 0.35rem 0.9rem; width: 100%; min-height: 56px; padding: 0.45rem 1rem; background: none; border: 0; color: var(--text); font: inherit; text-align: left; cursor: pointer; }
.og-banner-head:focus-visible { outline: 3px solid #ffd27a; outline-offset: -3px; }
.og-banner-brief { flex: 1 1 320px; min-width: 0; font-size: max(var(--text-floor), 0.82rem); color: var(--text); }
.og-banner-brief b { color: var(--gold); }
/* scoped under .og-banner: the base .og-timer rule (a column) comes later in this file and would win at equal weight */
.og-banner .og-timer-head { flex-direction: row; align-items: baseline; gap: 0.45rem; padding: 0.2rem 0.7rem; margin-left: auto; }
.og-banner .og-timer-head i, .og-banner .og-timer-head b { white-space: nowrap; }
.og-chev { flex: 0 0 auto; font-size: max(var(--text-floor), 1rem); color: var(--gold); transition: transform 0.2s ease; }
.og-banner.og-open .og-chev { transform: rotate(180deg); }
/* the rest: the full copy, both timers, the one honest action */
.og-banner-more { position: relative; z-index: 1; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0.6rem 1.2rem; padding: 0.1rem 1rem 0.9rem; }
.og-banner-more[hidden] { display: none; }
/* one row at every width: the one-line summary only where it fits on one line; on a tablet the clock without its
   label; on a phone the title and the chevron (the clock is the first thing the pop-down shows) */
@media (max-width: 1699px) { .og-banner-brief { display: none; } }
@media (max-width: 899px) { .og-banner .og-timer-head i { display: none; } .og-banner .og-timer-head b[data-og-deadline]::before { content: '⏳ '; } }
@media (max-width: 560px) { .og-banner .og-timer-head { display: none; } .og-banner .og-banner-head { flex-wrap: nowrap; } .og-banner .og-chev { margin-left: auto; } }
@media (prefers-reduced-motion: reduce) { .og-chev { transition: none; } }

/* diagonal shine sweep */
.og-shine { position: absolute; top: 0; left: -60%; width: 42%; height: 100%; transform: skewX(-20deg); background: linear-gradient(90deg, transparent, var(--g-veil), transparent); animation: ogShine 5.5s ease-in-out infinite; pointer-events: none; }
@keyframes ogShine { 0% { left: -60%; } 55%, 100% { left: 135%; } }
/* floating emoji accents */
.og-confetti { position: absolute; inset: 0; pointer-events: none; }
.og-confetti span { position: absolute; font-size: max(var(--text-floor), 0.85rem); opacity: 0.4; animation: ogFloat 6s ease-in-out infinite; }
.og-confetti span:nth-child(1) { left: 5%; top: 22%; animation-delay: 0s; }
.og-confetti span:nth-child(2) { left: 19%; top: 62%; animation-delay: 1.2s; }
.og-confetti span:nth-child(3) { right: 27%; top: 16%; animation-delay: 0.6s; }
.og-confetti span:nth-child(4) { right: 7%; top: 60%; animation-delay: 2s; }
.og-confetti span:nth-child(5) { left: 45%; top: 10%; animation-delay: 1.6s; }
.og-confetti span:nth-child(6) { right: 41%; bottom: 12%; animation-delay: 2.6s; }
@keyframes ogFloat { 0%,100% { transform: translateY(0) rotate(0); opacity: 0.3; } 50% { transform: translateY(-8px) rotate(12deg); opacity: 0.65; } }
/* bobbing medallion */
.og-banner-badge { position: relative; z-index: 1; flex: 0 0 auto; }
.og-medal { display: inline-block; font-size: max(var(--text-floor), 1.5rem); filter: drop-shadow(0 0 10px rgba(255,179,64,0.85)); animation: ogBob 3s ease-in-out infinite; }
@keyframes ogBob { 0%,100% { transform: translateY(0) rotate(-6deg); } 50% { transform: translateY(-4px) rotate(6deg); } }
/* copy */
.og-banner-copy { position: relative; z-index: 1; flex: 1 1 520px; max-width: 62ch; }
.og-banner-title { display: block; font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.2rem); letter-spacing: 0.5px; color: var(--gold); text-shadow: 0 0 12px rgba(255,179,64,0.5); }
.og-word { background: linear-gradient(180deg, #fff, var(--gold)); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: var(--gold); }
.og-tag { display: inline-block; font-family: 'Rubik', sans-serif; font-size: max(var(--text-floor), 0.58rem); font-weight: 900; text-transform: uppercase; letter-spacing: 0.1em; text-indent: 0.1em; color: var(--on-gold); background: var(--gold); border-radius: 999px; padding: 0.14rem 0.5rem; vertical-align: middle; transform: rotate(-3deg); }
.og-banner-sub { display: block; font-size: max(var(--text-floor), 0.82rem); color: var(--text); margin-top: 0.15rem; }
.og-banner-sub b { color: var(--gold); }
/* timers */
/* The row may shrink and wrap: the banner is overflow:hidden, so a row that refuses to (flex 0 0 auto) is
   simply cut off at 320–375px — and the two things it cuts are the deadlines. */
.og-banner-timers { position: relative; z-index: 1; flex: 0 1 auto; min-width: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: 0.6rem; }
.og-timer { display: flex; flex-direction: column; align-items: center; line-height: 1.15; background: rgba(0,0,0,0.35); border: 1px solid rgba(255,179,64,0.4); border-radius: 12px; padding: 0.32rem 0.6rem; }
.og-timer i { font-style: normal; font-size: max(var(--text-floor), 0.57rem); text-transform: uppercase; letter-spacing: 0.03em; color: var(--gold); font-weight: 800; white-space: nowrap; }
.og-timer b { font-size: max(var(--text-floor), 1.02rem); font-weight: 900; color: #fff; font-variant-numeric: tabular-nums; text-shadow: 0 0 8px rgba(255,179,64,0.5); }
.og-timer b.og-timer-closed { color: var(--text-dim); text-shadow: none; }
/* The red tint sits on a scrim DARKER than the ordinary timer's, not instead of it: a tint alone lightens the
   banner's brightest gradient stop (#6b4c08) under red text to 2.3:1. Black 0.7 under a 0.12 tint measures
   5.0:1 for #ff5d5d at that stop, the worst point of the sweep. */
.og-timer.og-timer-soon { border-color: var(--red); background: linear-gradient(rgba(255,93,93,0.12), rgba(255,93,93,0.12)), rgba(0,0,0,0.7); animation: ogSoon 1s ease-in-out infinite; }
.og-timer.og-timer-soon i { color: var(--red); }
.og-timer.og-timer-soon b { color: var(--red); text-shadow: 0 0 8px rgba(255,93,93,0.6); }
@keyframes ogSoon { 0%,100% { transform: scale(1); } 50% { transform: scale(1.06); } }
/* pulsing CTA pill */
.og-banner-cta { position: relative; z-index: 1; flex: 0 0 auto; font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 0.95rem); letter-spacing: 0.3px; color: var(--on-gold); background: linear-gradient(180deg, #ffd884, var(--gold-deep)); border-radius: 999px; padding: 0.5rem 1.05rem; box-shadow: 0 0 18px rgba(255,179,64,0.5); white-space: nowrap; animation: ogPulse 1.8s ease-in-out infinite; }
@keyframes ogPulse { 0%,100% { transform: scale(1); box-shadow: 0 0 14px rgba(255,179,64,0.4); } 50% { transform: scale(1.05); box-shadow: 0 0 26px rgba(255,179,64,0.75); } }
.og-cta-arrow { display: inline-block; animation: ogArrow 1.2s ease-in-out infinite; }
@keyframes ogArrow { 0%,100% { transform: translateX(0); } 50% { transform: translateX(4px); } }
/* both windows past → calm it down */
.og-banner-closed { filter: grayscale(0.6); opacity: 0.82; animation: none; background-position: 50% 50%; }
.og-banner-closed .og-shine, .og-banner-closed .og-confetti { display: none; }
.og-banner-closed .og-medal, .og-banner-closed .og-banner-cta, .og-banner-closed .og-cta-arrow { animation: none; }
@media (max-width: 760px) {
  .og-banner { font-size: max(var(--text-floor), 0.82rem); padding: 0.7rem 0.9rem; }
  /* the CTA used to vanish below 760px — no button at all on a phone. It now takes its own full-width row. */
  .og-banner-cta { flex: 1 0 100%; text-align: center; margin-top: 0.25rem; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; gap: 0.35rem; }
  .og-medal { font-size: max(var(--text-floor), 1.7rem); }
  .og-banner-title { font-size: max(var(--text-floor), 1.04rem); }
  /* the timers take their own row like the CTA, and a caption may break rather than push past the edge */
  .og-banner-timers { flex: 1 1 100%; }
  .og-timer i { white-space: normal; }
}
@media (prefers-reduced-motion: reduce) {
  .og-banner, .og-medal, .og-confetti span, .og-timer.og-timer-soon, .og-banner-cta, .og-cta-arrow { animation: none; }
  .og-shine { display: none; }
  .og-banner { background-position: 50% 50%; }
}

/* ===== Token-detail popup (TokenModal) ===== */
.tm-modal { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center; padding: 1rem; }
.tm-modal[hidden] { display: none; }
.tm-backdrop { position: absolute; inset: 0; background: rgba(4,7,4,0.72); backdrop-filter: blur(3px); }
/* The popup holds the token's dashboard, so it takes the whole window less a margin (all of it on a phone) — room
   for the dashboard's columns, with the chart in the middle once there is width for three. */
.tm-dialog { position: relative; z-index: 1; width: min(1680px, 100%); height: 100%; max-height: 100%; display: flex; flex-direction: column; background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 16px; box-shadow: 0 20px 60px rgba(0,0,0,0.6); overflow: hidden; }
.tm-head { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; padding: 0.6rem 0.8rem 0.6rem 1.05rem; border-bottom: 1px solid var(--ink-4); background: var(--ink-2); }
.tm-title { flex: 1 1 auto; min-width: 0; font-size: max(var(--text-floor), 0.9rem); font-weight: 800; color: var(--text-dim); margin: 0; overflow-wrap: anywhere; }
.tm-full { flex: 0 0 auto; }
.tm-full[hidden] { display: none; }
.tm-x { flex: 0 0 auto; width: 40px; height: 40px; border-radius: 50%; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); color: var(--ctl-ink); font-size: max(var(--text-floor), 1rem); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; line-height: 1; padding: 0; }
.tm-x:hover, .tm-x:focus-visible { border-color: var(--green); background: var(--ctl-fill-hi); color: var(--ctl-ink); }
.tm-body { flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; padding: 1rem 1.05rem calc(1.3rem + var(--fab-clear)); }   /* the Send it button and the music strip sit over the popup's foot: the last card scrolls clear of them */
.tm-loading, .tm-msg { text-align: center; color: var(--text-dim); padding: 1.6rem 0.5rem; }
.tm-msg.tm-note { text-align: left; color: var(--gold); padding: 0 0 0.85rem; margin: 0; font-weight: 700; }
@media (max-width: 640px) { .tm-modal { padding: 0; } .tm-dialog { border-radius: 0; border: 0; } .tm-body { padding-left: 0.75rem; padding-right: 0.75rem; } }

/* ===== "Conviction Plays" pinned tokens on the public wall ===== */
.wall-pins { margin: 0.5rem 0; } /* tight: same 0.5rem rhythm as the gap between the convicted chips */
.wall-pins-head { display: flex; align-items: center; gap: 0.45rem; font-weight: 800; color: var(--text); margin-bottom: 0.5rem; font-size: max(var(--text-floor), 0.95rem); }
.wall-pins-sub { font-weight: 600; color: var(--text-dim); font-size: max(var(--text-floor), 0.78rem); }
.wall-pins-list { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.pin-chip { display: inline-flex; align-items: center; gap: 0.15rem; background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 999px; padding: 0.28rem 0.5rem 0.28rem 0.34rem; cursor: pointer; } /* whole chip opens the token info popup */
.pin-chip:hover, .pin-chip:focus-within { border-color: var(--green); }
.pin-chip-open { display: inline-flex; align-items: center; gap: 0.45rem; padding: 0.06rem 0.2rem; background: var(--ctl-fill-lo); border: none; color: var(--ctl-ink); font: inherit; font-weight: 700; font-size: max(var(--text-floor), 0.85rem); cursor: pointer; border-radius: 999px; }
.pin-chip-open:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 1px; }
.pin-chip-logo { width: 24px; height: 24px; border-radius: 50%; object-fit: cover; background: var(--ink-3); flex: 0 0 auto; }
.pin-chip-logo-none { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 50%; background: var(--ink-3); font-size: max(var(--text-floor), 0.8rem); flex: 0 0 auto; }
.pin-chip-sym { color: var(--ctl-ink); }
.pin-chip-rm { margin-left: 0.15rem; min-width: 24px; min-height: 24px; padding: 2px; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--red); border: 1px solid var(--red); color: var(--on-red); font-size: max(var(--text-floor), 0.72rem); cursor: pointer; line-height: 1; }
.pin-chip-rm:hover, .pin-chip-rm:focus-visible { background: var(--red-soft); border-color: var(--red-soft); color: var(--ctl-ink); }
.pin-chip-rm.is-armed { border-radius: 999px; padding: 2px 0.6rem; font-weight: 800; white-space: nowrap; font-size: max(var(--text-floor), 0.8rem); }   /* the first tap asks, in words: "Remove $X?" */
.wall-pins-empty { color: var(--text-dim); font-size: max(var(--text-floor), 0.85rem); margin: 0; }
/* conviction chip stats (live mcap + Xs since conviction) */
.pin-chip { position: relative; }
.pin-chip-stats { display: inline-flex; align-items: center; gap: 0.3rem; margin-left: 0.1rem; font-size: max(var(--text-floor), 0.74rem); font-weight: 700; }
.pin-chip-mc { color: var(--text-dim); white-space: nowrap; }
.pin-chip-xs { padding: 0.04rem 0.36rem; border-radius: 999px; white-space: nowrap; }
.pin-chip-xs.up { background: color-mix(in srgb, var(--green) 16%, transparent); color: var(--green-bright); }
.pin-chip-xs.down { background: rgba(255,93,93,0.14); color: var(--red); }
/* hover tooltip: the owner's on-chain holding + how long held */
.pin-hover { position: absolute; left: 50%; bottom: calc(100% + 8px); transform: translateX(-50%); z-index: 9300; min-width: 170px; max-width: 240px; display: none; flex-direction: column; gap: 0.15rem; padding: 0.55rem 0.7rem; background: var(--ink); border: 1.5px solid var(--green); border-radius: 12px; box-shadow: 0 10px 28px rgba(0,0,0,0.55); font-size: max(var(--text-floor), 0.8rem); line-height: 1.4; text-align: left; white-space: normal; pointer-events: none; }
.pin-hover::after { content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border: 6px solid transparent; border-top-color: var(--green); }
.pin-chip:hover .pin-hover, .pin-chip:focus-within .pin-hover { display: flex; }
.pin-hover-hold { color: var(--text); font-weight: 800; }
.pin-hover-usd { color: var(--text-dim); font-weight: 600; }
.pin-hover-since { color: var(--green-bright); font-weight: 700; }
.pin-hover-note { color: var(--text-dim); }
.pin-hover-load { color: var(--text-dim); }
/* paste-to-convict form */
.pin-add { display: flex; gap: 0.5rem; margin-top: 0.7rem; flex-wrap: wrap; }
.pin-add-input { flex: 1; min-width: 200px; margin: 0; font-size: max(var(--text-floor), 0.9rem); }
.pin-add-go { white-space: nowrap; }
.pin-add-msg { color: var(--text-dim); font-size: max(var(--text-floor), 0.82rem); margin: 0.4rem 0 0; min-height: 1em; }
.pin-add-msg:empty { display: none; }
@media (prefers-reduced-motion: no-preference) { .pin-chip:hover .pin-hover, .pin-chip:focus-within .pin-hover { animation: pin-hover-in 0.14s ease; } }
@keyframes pin-hover-in { from { opacity: 0; transform: translateX(-50%) translateY(4px); } to { opacity: 1; transform: translateX(-50%) translateY(0); } }

/* pin-to-wall button on any token's on-chain detail */
.np-pin { display: inline-flex; align-items: center; gap: 0.4rem; font-weight: 800; font-size: max(var(--text-floor), 0.82rem); color: var(--ctl-ink); background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 10px; padding: 0.5rem 0.85rem; cursor: pointer; min-height: 40px; }
.np-pin:hover, .np-pin:focus-visible { border-color: var(--gold); background: var(--gold); color: var(--on-gold); }
.np-pin.is-pinned { background: var(--gold); border-color: var(--gold); color: var(--on-gold); }

/* brief highlight when you're deep-linked to a post/call you just made */
.post-flash { animation: postFlash 2s ease; }
@keyframes postFlash { 0%, 15% { box-shadow: 0 0 0 2px var(--green-bright), 0 0 24px color-mix(in srgb, var(--green) 50%, transparent); } 100% { box-shadow: 0 0 0 0 transparent; } }
@media (prefers-reduced-motion: reduce) { .post-flash { animation: none; box-shadow: 0 0 0 2px var(--green-bright); } }
.np-safety { display: inline-flex; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 999px; padding: 3px; gap: 2px; }
.np-seg { border: none; background: none; color: var(--ctl-ink); font: inherit; font-weight: 800; font-size: max(var(--text-floor), 0.8rem); padding: 0.35rem 0.7rem; border-radius: 999px; cursor: pointer; white-space: nowrap; }
.np-seg.is-on { background: var(--green); color: var(--on-green); }
.np-seg:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 1px; }
.np-sort, .np-more, .np-refresh { background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); color: var(--ctl-ink); font: inherit; font-weight: 700; border-radius: 10px; padding: 0.45rem 0.6rem; cursor: pointer; }
.np-sort { font-size: max(var(--text-floor), 1rem); }
.np-more[aria-expanded="true"] { border-color: var(--green); background: var(--green); color: var(--on-green); }
.np-refresh { font-size: max(var(--text-floor), 1.05rem); line-height: 1; width: 40px; display: inline-flex; align-items: center; justify-content: center; padding-inline: 0; }   /* a 40px block with 0.6rem padding left 13px for a 25px ↻, which ran off to the right */
.np-refresh.spin { animation: np-spin 0.5s linear; }
@keyframes np-spin { to { transform: rotate(360deg); } }
.np-filters { display: flex; flex-wrap: wrap; gap: 0.7rem 1.1rem; padding: 0.7rem 0.9rem; margin-bottom: 0.5rem; background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 12px; align-items: center; }
.np-f, .np-f-range { font-size: max(var(--text-floor), 0.85rem); color: var(--text-dim); font-weight: 700; display: inline-flex; align-items: center; gap: 0.4rem; }
.np-f-range input[type="range"] { accent-color: var(--green); }
.np-f-range output { color: var(--green-bright); min-width: 3ch; }

/* status + newbar */
.np-status { font-size: max(var(--text-floor), 0.84rem); color: var(--text-dim); font-weight: 700; margin: 0.3rem 0.2rem 0.6rem; display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.np-live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--green-bright); box-shadow: 0 0 8px var(--green-bright); animation: np-pulse 2s ease-in-out infinite; flex-shrink: 0; }
.np-live-dot.stale { background: var(--gold); box-shadow: 0 0 8px var(--gold); }
@keyframes np-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }
.np-ago { color: var(--text-dim); }
.np-hidden-link, .np-status button { background: var(--gold); border: none; color: var(--on-gold); font: inherit; font-weight: 800; cursor: pointer; text-decoration: none; padding: 0.3rem 0.7rem; border-radius: var(--r-pill); }
.np-newbar { display: block; width: 100%; background: var(--green); border: 1.5px solid var(--green); color: var(--on-green); font: inherit; font-weight: 800; border-radius: 12px; padding: 0.6rem; margin-bottom: 0.6rem; cursor: pointer; }

/* list + rows */
.np-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.55rem; }
.np-row { list-style: none; min-width: 0; }
.np-sum { list-style: none; cursor: pointer; display: block; }
.np-sum::-webkit-details-marker { display: none; }
.np-sum::marker { content: ""; }
.np-row[data-level="ok"] { --rowtri: var(--green-bright); }
.np-row[data-level="caution"] { --rowtri: var(--gold); }
.np-row[data-level="high"] { --rowtri: var(--triage-high); }
.np-row[data-level="avoid"] { --rowtri: var(--red); }
.np-card { background: linear-gradient(180deg, var(--ink-3), var(--ink-2)); border: 1.5px solid var(--ink-4); border-left: 4px solid var(--rowtri, var(--ink-4)); border-radius: 14px; overflow: hidden; min-width: 0; }
.np-row--new .np-card { animation: np-flash 2.2s ease; }
@keyframes np-flash { 0% { box-shadow: 0 0 0 2px var(--green-bright); } 100% { box-shadow: none; } }

.np-head { display: flex; align-items: center; gap: 0.45rem 0.7rem; flex-wrap: wrap; padding: 0.7rem 0.85rem; cursor: pointer; list-style: none; position: relative; }
.np-head::-webkit-details-marker { display: none; }
.np-head::marker { content: ""; }
.np-gauge { position: relative; width: 44px; height: 44px; display: grid; place-items: center; flex: 0 0 auto; }
.np-gauge-svg { width: 44px; height: 44px; }
.np-gauge-track { fill: none; stroke: var(--ink-4); stroke-width: 4; }
.np-gauge-arc { fill: none; stroke: var(--tri, var(--green-bright)); stroke-width: 4; stroke-linecap: round; transition: stroke-dashoffset 0.8s cubic-bezier(0.2,0.8,0.3,1); }
.np-gauge-num { position: absolute; font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 0.95rem); color: var(--tri, var(--text)); }
.np-t-ok { --tri: var(--green-bright); }
.np-t-caution { --tri: var(--gold); }
.np-t-high { --tri: var(--triage-high); }
.np-t-avoid { --tri: var(--red); }
.np-id { flex: 1 1 44%; min-width: 0; }
.np-name { font-weight: 800; font-size: max(var(--text-floor), 0.98rem); color: var(--text); display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.np-sym { color: var(--text-dim); font-weight: 700; font-size: max(var(--text-floor), 0.85rem); }
.np-meta { display: flex; gap: 0.5rem; font-size: max(var(--text-floor), 0.75rem); color: var(--text-dim); font-weight: 700; margin-top: 0.1rem; }
.np-verdict { display: inline-flex; align-items: center; gap: 0.3rem; font-weight: 800; font-size: max(var(--text-floor), 0.82rem); color: var(--tri); background: color-mix(in srgb, var(--tri) 14%, transparent); border: 1px solid color-mix(in srgb, var(--tri) 45%, transparent); border-radius: 999px; padding: 0.2rem 0.55rem; flex: 0 0 auto; }
.np-stat, .np-liq { text-align: right; flex: 0 0 auto; }
.np-stat-val, .np-liq-val { font-weight: 800; font-size: max(var(--text-floor), 0.9rem); color: var(--text); display: block; }
.np-stat-lbl, .np-liq-lbl { font-size: max(var(--text-floor), 0.66rem); color: var(--text-dim); font-weight: 700; text-transform: uppercase; }
.np-mc .np-stat-val { color: var(--green-bright); } /* accent the market cap so it reads at a glance on the basic row */
.np-chg-slot { flex: 0 0 auto; }
.np-chg-none { color: var(--text-dim); }
.np-chev { flex: 0 0 auto; margin-left: auto; display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 50%; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); color: var(--ctl-ink); font-size: max(var(--text-floor), 0.85rem); transition: transform 0.2s ease, background 0.15s ease, border-color 0.15s ease; } /* --tok (a per-token hue) is never the glyph colour */
/* The ▾ is drawn, not typed: the glyph comes from whatever symbol font the device falls back to, and on a Mac its
   triangle sits 1–2px below the middle of its box. A clipped square is centred by geometry on every device. */
.np-chev, .np-caret { position: relative; color: transparent; }
.np-chev::before, .np-caret::before { content: ''; position: absolute; left: 50%; top: 50%; translate: -50% -50%; margin: 0; width: 0.62em; height: 0.36em; background: var(--ctl-ink); clip-path: polygon(0 0, 100% 0, 50% 100%); }
.np-caret::before { background: var(--on-gold); }
.np-sum:hover .np-chev { background: var(--ctl-fill-hi); border-color: var(--tok, var(--green)); }
details[open] .np-chev { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .np-chev { transition: background 0.15s ease, border-color 0.15s ease; } }

/* ===== token branding (Dexscreener enhanced info) + per-token accent color (--tok, set inline per row) ===== */
.np-logo { flex: 0 0 auto; width: 38px; height: 38px; border-radius: 50%; padding: 2px; background: var(--tok-soft, var(--ink-3)); box-shadow: 0 0 0 2px var(--tok, var(--ink-4)); overflow: hidden; }
.np-logo-img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block; background: var(--ink-3); }
.np-badges { display: inline-flex; gap: 0.3rem; flex-wrap: wrap; margin-top: 0.18rem; }
.np-badge { display: inline-flex; align-items: center; gap: 0.2rem; font-size: max(var(--text-floor), 0.66rem); font-weight: 800; padding: 0.12rem 0.42rem; border-radius: 999px; border: 1px solid; line-height: 1.35; white-space: nowrap; }
.np-badge--dex { color: var(--green-bright); border-color: color-mix(in srgb, var(--green-bright) 45%, transparent); background: color-mix(in srgb, var(--green-bright) 12%, transparent); }
.np-badge--boost { color: var(--gold); border-color: color-mix(in srgb, var(--gold) 45%, transparent); background: color-mix(in srgb, var(--gold) 14%, transparent); }
.np-badge--dext { color: #4aa8ff; border-color: color-mix(in srgb, #4aa8ff 50%, transparent); background: color-mix(in srgb, #4aa8ff 14%, transparent); }
/* branded rows get a subtle accent in their own color (inset so it respects the rounded corners) */
.np-row.np-branded { box-shadow: inset 3px 0 0 0 var(--tok, transparent); }
.np-row.np-branded .np-name { color: color-mix(in srgb, var(--tok) 40%, var(--text)); }

.np-socials { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.6rem 0 0; }
.np-social-btn { display: inline-flex; align-items: center; gap: 0.35rem; font-size: max(var(--text-floor), 0.78rem); font-weight: 700; color: var(--ctl-ink); background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 999px; padding: 0.35rem 0.7rem; text-decoration: none; min-height: 36px; }
.np-social-btn:hover { border-color: var(--tok, var(--green)); background: var(--ctl-fill-hi); color: var(--ctl-ink); }
.np-social-ico { font-size: max(var(--text-floor), 0.9rem); }

/* expanded-detail branding block */
.np-brand { border: 1.5px solid var(--ink-4); border-left: 3px solid var(--tok, var(--ink-4)); border-radius: 14px; overflow: hidden; margin-bottom: 0.9rem; background: var(--tok-soft, var(--ink-2)); }
.np-brand-banner { width: 100%; aspect-ratio: 3 / 1; overflow: hidden; background: var(--ink-3); }
.np-brand-banner .np-logo-img { width: 100%; height: 100%; border-radius: 0; object-fit: cover; }
.np-brand-row { display: flex; align-items: center; gap: 0.7rem; padding: 0.7rem 0.85rem 0.4rem; }
.np-brand-row .np-logo { width: 52px; height: 52px; }
.np-brand-id { min-width: 0; }
.np-brand-name { font-weight: 800; font-size: max(var(--text-floor), 1.02rem); color: var(--text); display: block; }
.np-brandstat { display: flex; flex-wrap: wrap; gap: 0.25rem 1.4rem; padding: 0 0.85rem 0.5rem; font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); }
.np-brandstat b { color: var(--text); font-weight: 800; margin-right: 0.3rem; }
.np-status-yes { color: var(--green-bright); font-weight: 800; }
.np-status-no { color: var(--text-dim); }
.np-status-unk { color: var(--gold); font-weight: 700; }
.np-brand .np-socials { padding: 0 0.85rem 0.5rem; margin: 0; }
.np-brand-note { font-size: max(var(--text-floor), 0.72rem); color: var(--text-dim); line-height: 1.4; padding: 0 0.85rem 0.7rem; margin: 0; }
.np-brand-note b { color: var(--text); }

/* ===== score breakdown (how the health score was assessed, section by section) ===== */
.np-breakdown { display: grid; gap: 0.6rem; }
.np-bd-formula { font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); margin: 0; line-height: 1.5; }
.np-bd-formula b { color: var(--text); }
.np-bd-sec { --g: var(--green-bright); background: var(--ink-2); border: 1.5px solid var(--ink-4); border-left: 3px solid var(--g); border-radius: 12px; padding: 0.6rem 0.75rem; }
.np-bd-gA { --g: var(--green-bright); } .np-bd-gB { --g: #7bd66b; } .np-bd-gC { --g: var(--gold); } .np-bd-gD { --g: #f0932b; } .np-bd-gF { --g: var(--red); }
.np-bd-head { display: block; cursor: pointer; list-style: none; }
.np-bd-head::-webkit-details-marker { display: none; }
.np-bd-head:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--green-bright); border-radius: 8px; }
.np-bd-toprow { display: flex; align-items: center; gap: 0.5rem; }
.np-bd-ico { font-size: max(var(--text-floor), 1rem); }
.np-bd-label { font-weight: 800; font-size: max(var(--text-floor), 0.9rem); color: var(--text); flex: 1; min-width: 0; }
.np-bd-grade { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.05rem); color: var(--g); width: 1.6rem; text-align: center; }
.np-bd-score { font-weight: 800; font-size: max(var(--text-floor), 0.9rem); color: var(--text); }
.np-bd-score i { color: var(--text-dim); font-weight: 700; font-size: max(var(--text-floor), 0.72rem); font-style: normal; }
.np-bd-chev { color: var(--text-dim); font-size: max(var(--text-floor), 0.9rem); transition: transform 0.18s ease; }
.np-bd-sec[open] .np-bd-chev { transform: rotate(180deg); }
.np-bd-bar { display: block; height: 6px; border-radius: 999px; background: var(--ink-4); overflow: hidden; margin: 0.45rem 0; }
.np-bd-bar span { display: block; height: 100%; background: var(--g); border-radius: 999px; }
.np-bd-key { display: block; font-size: max(var(--text-floor), 0.8rem); line-height: 1.35; color: var(--text-dim); display: flex; gap: 0.4rem; align-items: baseline; }
.np-bd-neutraltxt { color: var(--text-dim); }
.np-bd-items { margin-top: 0.5rem; }
.np-bd-sec:not([open]) .np-bd-items, .np-bd-sec:not([open]) .np-contract { display: none; }
.np-bd-items { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.25rem; }
.np-bd-items li { font-size: max(var(--text-floor), 0.8rem); line-height: 1.4; color: var(--text-dim); display: flex; gap: 0.4rem; align-items: baseline; }
.np-bd-win { color: var(--green-bright) !important; }
.np-bd-check { color: var(--green-bright); font-weight: 800; }
.np-bd-x { color: var(--red); font-weight: 800; }
.np-bd-impact { color: var(--red); font-weight: 800; margin-left: auto; white-space: nowrap; }
.np-bd-note { font-size: max(var(--text-floor), 0.72rem); color: var(--text-dim); margin: 0.2rem 0 0; line-height: 1.4; }

/* feed slide branding */
.np-slide-banner { width: 100%; height: 92px; overflow: hidden; background: var(--ink-3); flex: 0 0 auto; }
.np-slide-banner .np-logo-img { width: 100%; height: 100%; border-radius: 0; object-fit: cover; opacity: 0.9; }
.np-slide.np-branded { box-shadow: inset 0 3px 0 0 var(--tok, transparent); }
.np-slide-top { display: flex; align-items: center; gap: 0.6rem; }
.np-slide-top .np-logo { width: 46px; height: 46px; }
.np-slide-idcol { min-width: 0; flex: 1; }

@media (max-width: 560px) {
  .np-logo { width: 32px; height: 32px; }
  .np-social-btn { font-size: max(var(--text-floor), 0.74rem); padding: 0.3rem 0.6rem; }
}

/* flag strip */
.np-flagstrip { display: flex; flex-wrap: wrap; gap: 0.35rem; padding: 0 0.85rem 0.7rem 0.85rem; }
.np-flag { font-size: max(var(--text-floor), 0.72rem); font-weight: 800; border-radius: 999px; padding: 0.18rem 0.5rem; border: 1px solid; white-space: nowrap; }
.np-flag--bad { color: var(--red); background: rgba(255,93,93,0.1); border-color: rgba(255,93,93,0.4); }
.np-flag--warn { color: var(--gold); background: rgba(255,179,64,0.1); border-color: rgba(255,179,64,0.4); }
.np-flag--note { color: var(--text-dim); background: var(--ink); border-color: var(--ink-4); }
.np-flag--ok { color: var(--green-bright); background: color-mix(in srgb, var(--green) 10%, transparent); border-color: color-mix(in srgb, var(--green) 35%, transparent); }
.np-flag-more { font-size: max(var(--text-floor), 0.72rem); font-weight: 800; color: var(--text-dim); padding: 0.18rem 0.4rem; }

/* expanded body */
.np-body { padding: 0 0.85rem 1rem; border-top: 1px solid var(--ink-4); }
.np-why { margin: 0.8rem 0; }
.np-why-h { font-size: max(var(--text-floor), 0.95rem); font-weight: 800; color: var(--text); margin: 0 0 0.5rem; }
.np-why-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4rem; }
.np-why-list li { font-size: max(var(--text-floor), 0.85rem); line-height: 1.45; color: var(--text-dim); background: var(--ink); border-radius: 10px; padding: 0.5rem 0.65rem; border-left: 3px solid var(--ink-4); }
.np-why-bad { border-left-color: var(--red) !important; }
.np-why-warn { border-left-color: var(--gold) !important; }
.np-why-clean { font-size: max(var(--text-floor), 0.88rem); color: var(--green-bright); background: color-mix(in srgb, var(--green) 8%, transparent); border: 1px solid color-mix(in srgb, var(--green) 30%, transparent); border-radius: 10px; padding: 0.6rem 0.7rem; margin: 0.8rem 0; }
.np-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; margin: 0.8rem 0; }
.np-stats .hstat { background: var(--ink); border-radius: 10px; padding: 0.5rem 0.6rem; }
.np-stats .lbl { font-size: max(var(--text-floor), 0.68rem); color: var(--text-dim); font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; }
.np-stats .val { font-weight: 800; font-size: max(var(--text-floor), 0.95rem); color: var(--text); margin-top: 0.15rem; }
.np-stats .val.red { color: var(--red); }
.np-soft { opacity: 0.8; } /* was 0.62 → 4.07:1; 0.8 keeps dimmed stat labels above the 4.5:1 AA floor */
.np-runners-note { font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); margin: 0 0 0.5rem; }
.np-vol { display: flex; align-items: flex-end; gap: 0.5rem; height: 64px; margin: 0.8rem 0 calc(1rem + max(var(--text-floor), 0.72rem)); padding: 0 0.3rem; }
.np-vbar { flex: 1; background: linear-gradient(180deg, var(--green-bright), var(--green-dark)); border-radius: 5px 5px 0 0; position: relative; min-height: 4px; display: flex; align-items: flex-end; justify-content: center; }
.np-vbar i { position: absolute; top: calc(100% + 0.2rem); bottom: auto; line-height: 1; font-size: max(var(--text-floor), 0.66rem); color: var(--text-dim); font-style: normal; font-weight: 700; }
.np-moves { display: flex; gap: 0.4rem; flex-wrap: wrap; margin: 1.4rem 0 0.8rem; }
.np-flow { margin: 0.8rem 0; }
.np-flow-bar { display: flex; height: 12px; border-radius: 999px; overflow: hidden; background: var(--ink); }
.np-flow-buy { background: var(--green); }
.np-flow-sell { background: var(--red); }
.np-flow-legend { font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); margin: 0.4rem 0 0; }
.np-buy { color: var(--green-bright); font-weight: 800; }
.np-sell { color: var(--red); font-weight: 800; }
.np-flow-note b { color: var(--red); }
.np-conc { margin: 0.8rem 0; }
.np-conc-bar { display: flex; height: 12px; border-radius: 999px; overflow: hidden; background: var(--ink); }
.np-conc-top { background: var(--red); }
.np-conc-10 { background: var(--gold); }
.np-conc-txt { font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); margin: 0.4rem 0 0; }
.np-conc-txt b { color: var(--text); }
.np-deployer { font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); margin: 0.8rem 0; display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.np-mono { font-family: ui-monospace, Menlo, monospace; font-size: max(var(--text-floor), 0.78rem); color: var(--text); background: var(--ink); padding: 0.1rem 0.35rem; border-radius: 6px; }
.np-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; margin: 0.9rem 0 0.3rem; }
/* The action bar at the foot of a full token detail — call it, keep it, watch it. Separated from the
   honesty line above by a rule rather than by more space, so it reads as a distinct step rather than as
   a continuation of the caveat. Wraps on narrow widths; every control keeps a full-size tap target. */
.np-body-actions {
  display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center;
  margin: 0.9rem 0 0.2rem; padding-top: 0.85rem; border-top: 1px solid var(--ink-4);
}
/* One row, one tap-target height. .np-pin carries min-height 40px for the dense list row it was built
   for; in this bar it sits beside 44px buttons, and a row of controls at two different heights reads as
   a mistake before it reads as a hierarchy. 44 is also the size the rest of the site uses for a target. */
.np-body-actions .btn, .np-body-actions .np-pin { flex: 0 1 auto; min-height: 44px; }
.np-body-actions .np-pin { border-radius: 999px; padding: 0.5rem 1.1rem; font-size: max(var(--text-floor), 0.95rem); }
/* The watchlist star is an icon-only control everywhere else, and `.np-watch` strips background and
   border to suit that. Here it carries its words and has to look like the buttons beside it, so this is
   deliberately two classes deep: `.np-watch` is declared LATER in this file and would otherwise win on
   source order and quietly un-style the control. */
.np-watch.np-watch-wide {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem; width: auto; height: auto;
  /* .np-watch zeroes background and border for the icon-only form, so the ghost-button chrome has to be
     restated here rather than inherited from .btn-ghost — same values, matched to the buttons beside it. */
  background: var(--ctl-fill-lo); border: 2px solid var(--ctl-fill-lo); border-radius: 999px;
  padding: 0.5rem 1.1rem; min-height: 44px;
  font-family: 'Rubik', sans-serif; font-size: max(var(--text-floor), 0.95rem); color: var(--ctl-ink);
}
.np-watch.np-watch-wide:hover { border-color: var(--gold); background: var(--gold); color: var(--on-gold); }
.np-watch.np-watch-wide.is-on { background: var(--gold); border-color: var(--gold); color: var(--on-gold); }
.np-watch.np-watch-wide .np-watch-lbl { font-weight: 800; font-size: max(var(--text-floor), 0.84rem); }
@media (max-width: 420px) { .np-body-actions .btn { flex: 1 1 100%; justify-content: center; } }
.np-honest { font-size: max(var(--text-floor), 0.74rem); color: var(--text-dim); line-height: 1.5; margin: 0.7rem 0 0; opacity: 0.85; }

/* messages / skeleton */
.np-msg { text-align: center; color: var(--text-dim); background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 14px; padding: 1.6rem 1rem; font-size: max(var(--text-floor), 0.95rem); }
.np-msg code { background: var(--ink-3); padding: 0.05em 0.4em; border-radius: 6px; font-size: max(var(--text-floor), 0.9em); word-break: break-all; }
.np-error { color: var(--gold); }
/* banner above a pasted-address lookup result */
.np-lookup-note { list-style: none; display: flex; align-items: center; gap: 0.5rem 0.7rem; flex-wrap: wrap; font-size: max(var(--text-floor), 0.8rem); font-weight: 700; color: var(--green-bright); background: var(--ink-2); border: 1.5px solid var(--ink-4); border-left: 3px solid var(--green); border-radius: 12px; padding: 0.55rem 0.85rem; margin-bottom: 0.6rem; }
.np-lookup-clear { margin-left: auto; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); color: var(--ctl-ink); font: inherit; font-weight: 700; font-size: max(var(--text-floor), 0.72rem); padding: 0.3rem 0.7rem; border-radius: 999px; cursor: pointer; min-height: 32px; }
.np-lookup-clear:hover { border-color: var(--green); background: var(--ctl-fill-hi); color: var(--ctl-ink); }
.np-lookup-loading code { background: var(--ink-3); padding: 0.05em 0.4em; border-radius: 6px; word-break: break-all; }
.np-skel { display: flex; align-items: center; gap: 0.8rem; background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 14px; padding: 0.8rem; }
.np-skel-ring { width: 44px; height: 44px; border-radius: 50%; flex-shrink: 0; }
.np-skel-lines { flex: 1; display: grid; gap: 0.5rem; }
.np-skel-lines span { height: 12px; border-radius: 6px; }
.np-skel-lines span:first-child { width: 55%; }

@media (min-width: 900px) {
  .np-head { flex-wrap: nowrap; }
  .np-id { flex: 1 1 auto; }
}
@media (max-width: 560px) {
  .np-controls { top: var(--nav-h, 56px); }
  .np-stats { grid-template-columns: repeat(2, 1fr); }
  /* thumb-zone: New Pairs filter/sort controls to >=44px */
  .np-seg { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 0.5rem 0.9rem; font-size: max(var(--text-floor), 0.85rem); }
  .np-safety { padding: 3px; }
  .np-sort, .np-more { min-height: 44px; }
  .np-more { display: inline-flex; align-items: center; justify-content: center; }
  .np-refresh { display: inline-flex; align-items: center; justify-content: center; width: 44px; min-height: 44px; padding: 0; font-size: max(var(--text-floor), 1.15rem); }
  .np-search { flex-basis: 100%; order: -1; }
}
/* ═══ The DEX List: nothing runs past its box ═══
   The numbers (MC, liquidity) and the buttons (📣 📌 ☆) travel as two groups, so a row that runs out of width moves
   them to the next line together instead of starving the name. On a phone each row reads as three tidy lines: the
   health ring and the name; the verdict … the hour's change; MC and liquidity … the buttons. On a wide screen the
   name keeps a real width and whatever does not fit beside it moves under it. A short address never breaks across
   lines; a long one shows as much as fits (.addr-fit). */
.np-nums, .np-acts { display: flex; align-items: center; flex: 0 0 auto; }
.np-nums { gap: 0.7rem; }
.np-acts { gap: 0.4rem; }
@media (min-width: 900px) {
  #np-list .np-head { flex-wrap: wrap; }
  #np-list .np-id { flex: 1 1 14rem; min-width: min(14rem, 100%); }
}
.np-msg code, .np-lookup-loading code, .np-addr-row code { white-space: nowrap; word-break: normal; overflow-wrap: normal; }
.np-msg { overflow-wrap: anywhere; }
/* the Scanner's "All tokens named …" block (newpairs.js namedTokens): every token by that name, traded or not, above the radar's list */
.np-named { margin: 0 0 1rem; padding: 0.9rem 1rem; background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 14px; }
.np-named-h { display: flex; justify-content: space-between; align-items: baseline; gap: 0.6rem; flex-wrap: wrap; margin: 0 0 0.5rem; font-size: max(var(--text-floor), 1rem); overflow-wrap: anywhere; }
.np-named-n { color: var(--text-dim); font-weight: 700; font-variant-numeric: tabular-nums; font-size: max(var(--text-floor), 0.85rem); }
.np-named-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.2rem; }
.np-named-row { display: flex; align-items: center; gap: 0.7rem; min-height: 44px; padding: 0.5rem 0.6rem; border-radius: 12px; color: var(--text); text-decoration: none; }
.np-named-row:hover, .np-named-row:focus-visible { background: color-mix(in srgb, var(--green) 10%, transparent); }
.np-named-row:focus-visible { outline: 3px solid var(--green-bright); outline-offset: 2px; }
.np-named-logo { flex: 0 0 auto; width: 36px; height: 36px; border-radius: 50%; display: grid; place-items: center; object-fit: cover; background: var(--ink-3); border: 1.5px solid var(--ink-4); font-size: max(var(--text-floor), 1.1rem); }
.np-named-main { display: grid; gap: 0.1rem; min-width: 0; flex: 1 1 auto; }
.np-named-name { font-weight: 800; overflow-wrap: anywhere; font-size: max(var(--text-floor), 0.95rem); }
.np-named-stats { color: var(--text-dim); font-variant-numeric: tabular-nums; font-size: max(var(--text-floor), 0.85rem); }
.np-named-main .addr-fit { color: var(--text-dim); font-size: max(var(--text-floor), 0.8rem); }
.np-named-none, .np-named-note { margin: 0.3rem 0 0; color: var(--text-dim); font-size: max(var(--text-floor), 0.85rem); line-height: 1.5; }
.np-named-none.is-warn, .search-note.is-warn { color: var(--gold); }   /* a source could not be asked: the list may be short, and it says so in words */
.np-badges, .np-badge { max-width: 100%; }
.np-badge { white-space: normal; }
html body .np-viewswitch .np-vs-txt { overflow-wrap: normal; line-height: 1.1; text-align: center; }   /* "Best Runners" breaks between its words, never inside one */
html .np-meta .tok-comm { border-radius: 0.8rem; }   /* a tag that wraps still reads as one chip */
@media (max-width: 560px) {
  .sc-panel { padding-inline: 0; }   /* one gutter (the page's), not two: 40px more for every row */
  .np-controls, body.np-mode-list .np-controls { position: static; }   /* five rows of controls pinned under the bar left a sliver of list */
  .np-search { min-width: 0; }
  .np-safety { display: flex; width: 100%; }
  .np-safety .np-seg { flex: 1 1 0; min-width: 0; padding-inline: 0.4rem; }
  .np-sort-wrap { flex: 1 1 10rem; min-width: 0; display: flex; }
  .np-sort { width: 100%; min-width: 0; }
  #np-list .np-head { gap: 0.45rem 0.5rem; padding: 0.6rem 0.7rem; }
  #np-list .np-id { flex: 1 1 calc(100% - 44px - 0.5rem); }
  #np-list .np-head:has(> .np-logo) .np-id { flex-basis: calc(100% - 44px - 32px - 1rem); }
  #np-list .np-verdict { order: 1; }
  #np-list .np-chg-slot { order: 2; margin-left: auto; }
  #np-list .np-head::after { content: ''; order: 3; flex: 0 0 100%; margin-top: -0.45rem; }
  #np-list .np-nums { order: 4; display: flex; gap: 0.7rem; align-items: center; }
  #np-list .np-acts { order: 5; display: flex; gap: 0.4rem; align-items: center; margin-left: auto; }
  #np-list .np-stat { text-align: left; }
  #np-list .np-flagstrip { padding: 0 0.7rem 0.6rem; }
}
@media (max-width: 400px) { #np-list .np-flag { white-space: normal; max-width: 100%; border-radius: 0.9rem; text-align: center; } }
/* ═══ Which chart: ours (on-chain), Dexscreener's or CoinGecko's — a row of three, the picked one filled ═══ */
.chart-switch { display: grid; gap: 0.5rem; min-width: 0; }
.chart-switch [hidden] { display: none !important; }
.chart-src { display: flex; flex-wrap: wrap; gap: 4px; padding: 3px; width: fit-content; max-width: 100%; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 14px; }
.chart-src-btn { flex: 1 1 auto; display: inline-flex; align-items: center; justify-content: center; text-align: center; min-height: 40px; padding: 0.3rem 0.85rem; border: 0; border-radius: 11px; background: none; color: var(--ctl-ink); font: inherit; font-weight: 800; font-size: max(var(--text-floor), 0.82rem); line-height: 1.15; cursor: pointer; }
.chart-src-btn:hover { background: var(--ctl-fill-hi); }
.chart-src-btn.is-on { background: var(--green); color: var(--on-green); }
.chart-src-btn:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 1px; }
@media (pointer: coarse), (max-width: 560px) { .chart-src-btn { min-height: 44px; } }
.chart-embed { width: 100%; height: clamp(380px, 62vh, 560px); border-radius: 12px; overflow: hidden; background: var(--ink); border: 1px solid var(--ink-4); }
.chart-embed-frame { display: block; width: 100%; height: 100%; border: 0; }
.chart-src-note { margin: 0; color: var(--text-dim); font-size: max(var(--text-floor), 0.8rem); }
@media (prefers-reduced-motion: reduce) {
  .np-gauge-arc { transition: none; }
  .np-live-dot { animation: none; }
  .np-refresh.spin { animation: none; }
  .np-row--new .np-card { animation: none; }
  .np-chev { transition: none; }
}

/* ===== Read-only restriction banner (anti-gaming) ===== */
#readonly-bar { background: linear-gradient(180deg, rgba(255,93,93,0.16), rgba(255,93,93,0.05)), var(--ink-2); border-bottom: 2px solid var(--red); color: var(--text); }
.ro-inner { max-width: 900px; margin: 0 auto; padding: 0.9rem 1.25rem 1.1rem; }
.ro-top { display: flex; align-items: center; justify-content: space-between; gap: 0.8rem; flex-wrap: wrap; }
.ro-badge { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.1rem); color: var(--red); letter-spacing: 0.02em; }
.ro-countdown { font-weight: 800; font-size: max(var(--text-floor), 0.92rem); color: var(--gold); background: var(--ink); border: 1.5px solid rgba(255,179,64,0.45); border-radius: 999px; padding: 0.28rem 0.75rem; font-variant-numeric: tabular-nums; }
.ro-why { font-size: max(var(--text-floor), 0.9rem); color: var(--text-dim); line-height: 1.5; margin: 0.55rem 0 0.75rem; }
.ro-why b { color: var(--text); }
.ro-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 0.8rem; }
.ro-col { background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 12px; padding: 0.6rem 0.85rem; }
.ro-col h4 { margin: 0 0 0.4rem; font-size: max(var(--text-floor), 0.82rem); font-weight: 800; }
.ro-ok h4 { color: var(--green-bright); }
.ro-no h4 { color: var(--red); }
.ro-col ul { margin: 0; padding-left: 1.15rem; display: grid; gap: 0.28rem; }
.ro-col li { font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); line-height: 1.4; }
.ro-foot { font-size: max(var(--text-floor), 0.78rem); color: var(--text-dim); margin: 0.75rem 0 0; opacity: 0.85; }
@media (max-width: 560px) { .ro-cols { grid-template-columns: 1fr; } .ro-badge { font-size: max(var(--text-floor), 1rem); } }

/* ===== Wallet-tracking capacity (scales with $GWC diamond-handing) ===== */
.track-cap { background: var(--ink); border: 1.5px solid rgba(159,224,255,0.35); border-radius: 12px; padding: 0.7rem 0.85rem; margin-bottom: 1rem; }
.track-cap-top { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; }
.track-cap-count { font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; }
.track-cap-tier { font-size: max(var(--text-floor), 0.78rem); font-weight: 800; color: var(--diamond); }
.track-cap-bar { height: 8px; border-radius: 999px; background: var(--ink-3); overflow: hidden; margin: 0.5rem 0 0.4rem; }
.track-cap-fill { height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--diamond-deep), var(--diamond)); transition: width 0.5s ease; }
.track-cap-fill.full { background: linear-gradient(90deg, var(--gold-deep), var(--gold)); }
.track-cap-note { font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); margin: 0; line-height: 1.5; }
.track-cap-note b { color: var(--text); }
.track-cap-note b.track-cap-full-hint { color: var(--gold); }
.track-cap-note a { color: var(--green-bright); font-weight: 700; text-decoration: none; }
/* watchlist wallet-tab capacity note turns amber when full, so "reset on remove" reads clearly */
.wl-cap-full { color: var(--gold); font-weight: 700; }
@media (prefers-reduced-motion: reduce) { .track-cap-fill { transition: none; } }

/* ===== Quest-board hover popups (per-achievement info) ===== */
.gearn-li { position: relative; }
.ge-tip {
  position: absolute; left: 0; right: 0; bottom: calc(100% + 6px); z-index: 30;
  background: var(--ink-2); border: 1.5px solid var(--green); border-radius: 10px;
  padding: 0.5rem 0.65rem; font-size: max(var(--text-floor), 0.78rem); color: var(--text-dim); line-height: 1.45;
  box-shadow: 0 12px 28px rgba(0,0,0,0.55);
  opacity: 0; transform: translateY(4px); pointer-events: none; transition: opacity 0.15s ease, transform 0.15s ease;
}
.ge-tip::after { content: ''; position: absolute; top: 100%; left: 22px; border: 6px solid transparent; border-top-color: var(--green); }
.ge-tip b { color: var(--text); }
.gearn-li:hover .ge-tip, .gearn-li:has(> .gearn-row:focus-visible) .ge-tip { opacity: 1; transform: translateY(0); } /* the row's own keyboard focus shows the tip; the ⓘ button's focus must not (it would re-show a tip the user just closed) */
.gearn-passive { font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); margin: 0.6rem 0 0; line-height: 1.5; background: color-mix(in srgb, var(--green) 6%, transparent); border: 1px solid color-mix(in srgb, var(--green) 25%, transparent); border-radius: 10px; padding: 0.5rem 0.65rem; }
.gearn-passive b { color: var(--green-bright); }
@media (prefers-reduced-motion: reduce) { .ge-tip { transition: none; } }

/* ===== Rocket cursor 🚀: its rules live in cursor.css, loaded by every page that loads cursor.js (privacy and terms too, which do not load this file) ===== */

/* ===================================================================
   ABOUT PAGE (about.html) — namespaced .ab-* / section-scoped
   =================================================================== */

/* --- Hero extras --- */
.about-hero .one-line { max-width: 46ch; margin: 1.2rem auto 0; font-size: max(var(--text-floor), 1.18rem); line-height: 1.6; color: var(--text); }
.about-hero .one-line b { color: var(--green-bright); }
.hl-green { color: var(--green-bright); text-shadow: 0 3px 0 var(--green-dark), 0 0 30px color-mix(in srgb, var(--green) 35%, transparent); }
.tldr-chips { list-style: none; display: flex; flex-wrap: wrap; gap: 0.55rem; justify-content: center; margin: 1.5rem auto 0; padding: 0; max-width: 640px; }
.tldr-chips li { background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 999px; padding: 0.45rem 0.95rem; font-size: max(var(--text-floor), 0.85rem); font-weight: 600; color: var(--text-dim); }

/* --- Alt background band variants --- */
.alt-bg-2 { background: radial-gradient(120% 100% at 50% 0%, color-mix(in srgb, var(--green) 6%, transparent), transparent 60%), var(--ink); }

/* --- What it is: dictionary definition card --- */
.def-card { max-width: 760px; margin: 0 auto; background: linear-gradient(180deg, var(--ink-3), var(--ink-2)); border: 2px solid color-mix(in srgb, var(--green) 30%, transparent); border-left: 6px solid var(--green); border-radius: 22px; padding: 1.8rem 1.9rem; box-shadow: 0 18px 40px rgba(0,0,0,0.45); }
.def-word { font-size: max(var(--text-floor), clamp(2.2rem, 7vw, 3.2rem)); color: var(--green-bright); line-height: 1; margin: 0; }
.def-phon { font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: max(var(--text-floor), 1rem); color: var(--text-dim); font-weight: 400; letter-spacing: 0; }
.def-pos { font-style: italic; color: var(--text-dim); margin: 0.35rem 0 1rem; font-size: max(var(--text-floor), 0.95rem); }
.def-body { line-height: 1.7; color: var(--text); }
.def-body b { color: var(--green-bright); }
.def-tags { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 1.2rem 0 0.4rem; }
.def-tag { background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 10px; padding: 0.4rem 0.8rem; font-size: max(var(--text-floor), 0.82rem); font-weight: 600; color: var(--text-dim); }
.def-share { margin-top: 1.1rem; }

/* --- Truth row --- */
.truth-row { display: grid; grid-template-columns: 1fr; gap: 1rem; max-width: 980px; margin: 2rem auto 0; }
@media (min-width: 820px) { .truth-row { grid-template-columns: repeat(3, 1fr); } }
.truth-item { display: flex; gap: 0.9rem; align-items: flex-start; background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 16px; padding: 1.1rem 1.2rem; line-height: 1.55; font-size: max(var(--text-floor), 0.95rem); }
.truth-item b { color: var(--green-bright); }
.truth-ico { font-size: max(var(--text-floor), 1.7rem); flex-shrink: 0; line-height: 1; }

/* --- Token mini cards --- */
.tok-mini-grid { display: grid; grid-template-columns: 1fr; gap: 1.1rem; max-width: 980px; margin: 2rem auto 0; }
@media (min-width: 720px) { .tok-mini-grid { grid-template-columns: repeat(2, 1fr); } }
.tok-mini { display: flex; gap: 1rem; align-items: flex-start; background: linear-gradient(180deg, var(--ink-3), var(--ink-2)); border: 2px solid var(--g-veil); border-radius: 18px; padding: 1.3rem 1.4rem; }
.tok-mini-body { flex: 1; min-width: 0; }
.tok-mini-body h3 { margin: 0 0 0.7rem; font-size: max(var(--text-floor), 1.1rem); }
.verify-note { margin-top: 1.6rem; font-size: max(var(--text-floor), 0.92rem); }
.verify-note b { color: var(--green-bright); }

/* --- Get started: progress rail + check-offs --- */
.gs-progress { position: relative; max-width: 780px; margin: 0 auto 1.6rem; font-size: max(var(--text-floor), 0.8rem); min-height: max(26px, calc(1.3em + 6px)); background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 999px; overflow: hidden; }
.gs-progress-fill { position: absolute; inset: 0 auto 0 0; width: 0; background: linear-gradient(90deg, var(--green-dark), var(--green-bright)); transition: width 0.4s cubic-bezier(.2,.8,.2,1); }
.gs-progress-text { position: absolute; inset: 0; display: grid; place-items: center; font-size: max(var(--text-floor), 0.8rem); font-weight: 800; color: var(--text); mix-blend-mode: normal; line-height: 1.2; }
.gs-steps { max-width: 780px; margin: 0 auto; }
.gs-check { flex-shrink: 0; padding: 0; border: none; background: none; cursor: pointer; border-radius: 50%; }
.gs-check .step-num { transition: transform 0.15s ease, box-shadow 0.15s ease; border: 3px solid transparent; }
.gs-check:focus-visible { outline: 3px solid var(--green-bright); outline-offset: 3px; }
.gs-steps .step.is-done { border-color: color-mix(in srgb, var(--green) 60%, transparent); }
.gs-steps .step.is-done .step-num { background: linear-gradient(180deg, var(--green-bright), var(--green)); box-shadow: 0 0 0 3px color-mix(in srgb, var(--green) 35%, transparent), 0 4px 0 var(--green-dark); }
.gs-check .step-num { position: relative; }
.gs-steps .step.is-done .step-num { color: transparent; }   /* hides the digit (or 🔐) the ✓ stands in for */
.gs-steps .step.is-done .step-num::after { content: '✓'; position: absolute; inset: 0; display: grid; place-items: center; margin: 0; color: var(--on-green); }
.gs-steps .step.is-done h3 { text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--green) 50%, transparent); }
.gs-check[aria-pressed="true"] .step-num { transform: scale(1.04); }
.gs-done-msg { text-align: center; margin-top: 1.4rem; font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.3rem); color: var(--green-bright); }
.security-step .step-num { background: linear-gradient(180deg, var(--diamond), var(--diamond-deep)); }

/* --- Feature pillars --- */
.pillar-grid { display: grid; grid-template-columns: 1fr; gap: 1.1rem; max-width: 980px; margin: 0 auto; align-items: start; }   /* start: a closed card is its own height, not the row's — stretched, the shorter one showed an empty band under its header */
@media (min-width: 720px) { .pillar-grid { grid-template-columns: repeat(2, 1fr); } }
.pillar { background: linear-gradient(180deg, var(--ink-3), var(--ink-2)); border: 2px solid var(--g-veil); border-radius: 18px; overflow: hidden; transition: border-color 0.15s ease; }
.pillar[open] { border-color: color-mix(in srgb, var(--green) 50%, transparent); }
.pillar > summary { display: flex; align-items: center; gap: 0.95rem; padding: 1.2rem 1.3rem; cursor: pointer; list-style: none; background: var(--ctl-fill-lo); color: var(--ctl-ink); transition: background 0.15s ease; }
.pillar > summary:hover { background: var(--ctl-fill-hi); }
/* black type on the green summary: title, sub-line and caret all take the ink */
.pillar > summary .pillar-title, .pillar > summary .pillar-sub, .pillar > summary .pillar-caret { color: var(--ctl-ink); }
.pillar > summary::-webkit-details-marker { display: none; }
.pillar-plate { flex-shrink: 0; width: 50px; height: 50px; border-radius: 50%; display: grid; place-items: center; font-size: max(var(--text-floor), 1.5rem); box-shadow: inset 0 0 0 2px var(--g-veil), 0 6px 16px rgba(0,0,0,0.4); }
.pillar-plate.send { background: radial-gradient(circle at 30% 30%, color-mix(in srgb, var(--green) 35%, transparent), var(--ink)); }
.pillar-plate.gwc { background: radial-gradient(circle at 30% 30%, rgba(255,197,0,0.35), var(--ink)); }
.pillar-plate.diamond { background: radial-gradient(circle at 30% 30%, rgba(120,200,255,0.35), var(--ink)); }
.pillar-head { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.15rem; }
.pillar-title { font-weight: 800; font-size: max(var(--text-floor), 1.08rem); color: var(--text); }
.pillar-sub { font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); }
.pillar-caret { flex-shrink: 0; color: var(--text-dim); transition: transform 0.2s ease; }
.pillar[open] .pillar-caret { transform: rotate(180deg); }
.pillar-body { padding: 0 1.3rem 1.4rem; line-height: 1.65; color: var(--text-dim); }
.pillar-body p { margin: 0 0 0.9rem; }
.pillar-body b { color: var(--green-bright); }
.ab-mini-list { margin: 0.2rem 0 0.4rem; padding-left: 1.15rem; display: grid; gap: 0.5rem; }
.ab-mini-list li { line-height: 1.6; }
.ab-mini-list li::marker { color: var(--green); }
.pillar-note { background: rgba(0,200,5,0.08); border: 1.5px solid rgba(0,200,5,0.3); border-radius: 12px; padding: 0.7rem 0.9rem; font-size: max(var(--text-floor), 0.88rem); }
.pillar-note b { color: var(--rh-green); }

/* --- Send Power demo --- */
.ab-demo { max-width: 720px; margin: 0 auto 1.4rem; }
.ab-demo-h { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.4rem); margin: 0 0 0.5rem; color: var(--green-bright); letter-spacing: 0.02em; }
.ab-demo-sub { color: var(--text-dim); line-height: 1.6; margin: 0 0 1.4rem; font-size: max(var(--text-floor), 0.95rem); }
.ab-demo-sub b { color: var(--text); }
.ab-row { margin-bottom: 1.3rem; }
.ab-lbl { display: block; font-weight: 700; margin-bottom: 0.5rem; font-size: max(var(--text-floor), 0.95rem); }
.ab-lbl b { color: var(--green-bright); }
.ab-select { width: 100%; min-height: 44px; background: var(--ink); color: var(--text); border: 1.5px solid var(--ink-4); border-radius: 12px; padding: 0.6rem 0.9rem; font-size: max(var(--text-floor), 1rem); font-family: inherit; }
.ab-hint { display: block; margin-top: 0.4rem; font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); }
input[type="range"] { width: 100%; accent-color: var(--green); min-height: 44px; cursor: pointer; }
#ab-days { accent-color: var(--diamond); }
.ab-eq { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0.5rem; margin-top: 1.5rem; padding: 1rem; background: var(--ink); border: 1.5px dashed color-mix(in srgb, var(--green) 40%, transparent); border-radius: 14px; }
.ab-eq-chip { background: var(--ink-3); border: 1.5px solid var(--ink-4); border-radius: 10px; padding: 0.5rem 0.85rem; font-size: max(var(--text-floor), 0.9rem); font-weight: 600; }
.ab-eq-chip b { color: var(--text); }
.ab-eq-op { font-size: max(var(--text-floor), 1.3rem); font-weight: 800; color: var(--text-dim); }
.ab-eq-mult b { color: var(--gold); }
.ab-eq-total { background: linear-gradient(180deg, var(--green-bright), var(--green-dark)); border-color: transparent; color: var(--on-green); }
.ab-eq-total b { color: var(--on-green); }
.ab-cap { text-align: center; margin-top: 0.9rem; font-weight: 800; color: var(--gold); }
/* The $100 hold floor: a rule, not fine print, so it is lifted out of the small type above it. */
.ab-floor {
  margin-top: 1.1rem; padding: 0.85rem 1rem; border-radius: 12px; font-size: max(var(--text-floor), 0.9rem); line-height: 1.6;
  background: color-mix(in srgb, var(--green) 8%, transparent); border: 1px solid color-mix(in srgb, var(--green) 28%, transparent); color: var(--text);
}
.ab-floor b { color: var(--green-bright); }
.ab-fine { margin-top: 1.2rem; font-size: max(var(--text-floor), 0.8rem); line-height: 1.6; color: var(--text-dim); }
.ab-fine b { color: var(--text); }

/* --- Rocket levels track --- */
.ab-levels { max-width: 720px; margin: 0 auto 1.4rem; }
.ab-track { position: relative; margin: 1.6rem 0 0.6rem; padding-top: 1.6rem; }
.ab-track-bar { height: 10px; border-radius: 999px; background: var(--ink); border: 1.5px solid var(--ink-4); overflow: hidden; }
.ab-track-fill { display: block; height: 100%; width: 20%; background: linear-gradient(90deg, var(--green-dark), var(--green-bright)); transition: width 0.5s cubic-bezier(.2,.8,.2,1); }
.ab-rocket { position: absolute; top: 0; left: 20%; transform: translateX(-50%); font-size: max(var(--text-floor), 1.5rem); transition: left 0.5s cubic-bezier(.2,.8,.2,1); }
.no-anim .ab-track-fill, .no-anim .ab-rocket { transition: none !important; }
.ab-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: space-between; margin-top: 1rem; }
.ab-chip { flex: 1; min-width: 44px; min-height: 44px; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 12px; color: var(--ctl-ink); font-weight: 800; font-size: max(var(--text-floor), 1rem); cursor: pointer; transition: transform 0.12s ease, border-color 0.12s ease, color 0.12s ease, background 0.12s ease; }
.ab-chip:hover { transform: translateY(-2px); background: var(--ctl-fill-hi); border-color: color-mix(in srgb, var(--green) 50%, transparent); }
.ab-chip.is-on { background: linear-gradient(180deg, var(--green-bright), var(--green-dark)); color: var(--on-green); border-color: transparent; }
.ab-chip:focus-visible { outline: 3px solid var(--green-bright); outline-offset: 3px; }
.ab-readout { text-align: center; margin-top: 1.1rem; font-weight: 800; color: var(--green-bright); font-size: max(var(--text-floor), 1.05rem); }

/* --- Holder Boost + Diamond engines --- */
.ab-engines { display: grid; grid-template-columns: 1fr; gap: 1.1rem; max-width: 980px; margin: 1.6rem auto 0; }
@media (min-width: 860px) { .ab-engines { grid-template-columns: 1fr 1fr; align-items: start; } }
.ab-eng-h { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.2rem); margin: 0 0 0.7rem; letter-spacing: 0.02em; }
.ab-engine p { line-height: 1.6; color: var(--text-dim); }
.ab-engine b { color: var(--text); }
.ab-formula { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin: 1rem 0; }
.ab-f-chip { background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 10px; padding: 0.45rem 0.75rem; font-size: max(var(--text-floor), 0.82rem); font-weight: 700; }
.ab-f-op { font-weight: 800; color: var(--text-dim); }
.ab-f-dia { border-color: rgba(120,200,255,0.5); color: var(--diamond); }
.ab-f-out { background: linear-gradient(180deg, var(--gold), var(--gold-deep)); border-color: transparent; color: #2a1e00; }
.ab-dia-warn { background: rgba(120,200,255,0.08); border: 1.5px solid rgba(120,200,255,0.3); border-radius: 12px; padding: 0.7rem 0.9rem; font-size: max(var(--text-floor), 0.88rem); margin-top: 1rem; }
.ab-dia-warn b { color: var(--diamond); }
.ab-dia-ladder { list-style: none; margin: 0.6rem 0 0; padding: 0; }
.ab-dia-ladder li { display: grid; grid-template-columns: 1.6rem 1fr auto auto; align-items: center; gap: 0.6rem; padding: 0.5rem 0.2rem; border-bottom: 1px solid var(--ink-4); font-size: max(var(--text-floor), 0.9rem); }
.ab-dia-ladder li:last-child { border-bottom: none; }
.ab-dia-e { font-size: max(var(--text-floor), 1.1rem); text-align: center; }
.ab-dia-n { font-weight: 600; color: var(--text); }
.ab-dia-d { color: var(--text-dim); font-size: max(var(--text-floor), 0.82rem); }
.ab-dia-x { font-weight: 800; color: var(--gold); min-width: 2.6rem; text-align: right; }
.ab-dia-top .ab-dia-n { color: var(--gold); }
.ab-dia-top .ab-dia-x { color: var(--green-bright); }

/* --- How-to-Buy step 1: the wallet list ---------------------------------
   Rendered from the same registry the picker uses. Each entry is a real link
   to an official download page, so it works with JS off and reads correctly
   to a screen reader as a list of links. */
.g1-alt { margin-top: 0.7rem; }
.g1-wallets { list-style: none; margin: 0.6rem 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr)); gap: 0.45rem; }
/* wrap allowed so a badge drops to its own line instead of squeezing the name */
.g1-w-link { display: flex; align-items: center; gap: 0.4rem 0.5rem; flex-wrap: wrap; min-height: 44px; padding: 0.5rem 0.7rem;
  background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 10px;
  text-decoration: none; color: var(--ctl-ink); font-size: max(var(--text-floor), 0.88rem); font-weight: 600; }
.g1-w-link:hover, .g1-w-link:focus-visible { border-color: var(--green); background: var(--ctl-fill-hi); color: var(--ctl-ink); }
.g1-w-ico { font-size: max(var(--text-floor), 1.05rem); line-height: 1; }
.g1-w-name { flex: 1 1 auto; min-width: 0; overflow-wrap: break-word; }
.g1-w-tag { font-size: max(var(--text-floor), 0.62rem); font-weight: 800; text-transform: uppercase; letter-spacing: 0.04em;
  padding: 0.15rem 0.4rem; border-radius: 0.75em; white-space: normal; max-width: 100%; box-sizing: border-box; text-align: center;   /* at the text floor a one-line badge was wider than its tile and ran out of it: it wraps (a pill on one line, a rounded box on two) */
  background: var(--ink-1); color: var(--gold); }   /* badges on a green tile: ink pills, so the gold / green words stay legible at every step of the fill ladder */
.g1-w-tag.is-here { background: var(--ink-1); color: var(--green-bright); }
.g1-w-more { grid-column: 1 / -1; }
.g1-more { width: 100%; min-height: 44px; box-sizing: border-box; background: var(--ctl-fill-lo); border: 1.5px dashed var(--edge-ctl); border-radius: 10px; padding: 0.5rem 0.7rem; color: var(--ctl-ink); font: inherit; font-weight: 700; font-size: max(var(--text-floor), 0.88rem); cursor: pointer; }
.g1-more:hover, .g1-more:focus-visible { border-color: var(--green); background: var(--ctl-fill-hi); }
.g1-actions { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; margin-top: 0.8rem; }
.g1-hint { font-size: max(var(--text-floor), 0.85rem); color: var(--text-dim); }
.g1-safe { margin-top: 0.8rem; font-size: max(var(--text-floor), 0.85rem); color: var(--text-dim); line-height: 1.55; }
.g1-safe b { color: var(--text); }

/* --- Linked wallets list (Profile → Security) ---------------------------
   One row per linked wallet. The 2FA wallet is marked with a word as well as
   a colour, because "which of these is my key" is exactly the question you
   cannot afford to answer wrong. Rows wrap rather than truncate the address
   on a phone: a half-shown address invites signing from the wrong wallet. */
.wl-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.wl-row { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap;
  background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 12px; padding: 0.6rem 0.75rem; }
.wl-row.is-2fa { border-color: color-mix(in srgb, var(--green) 45%, transparent); background: color-mix(in srgb, var(--green) 7%, var(--ink-2)); }
.wl-ico { font-size: max(var(--text-floor), 1.1rem); line-height: 1; }
.wl-addr { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: max(var(--text-floor), 0.85rem); color: var(--text);
  overflow-wrap: anywhere; flex: 1 1 12rem; min-width: 0; }
.wl-tag { font-size: max(var(--text-floor), 0.7rem); font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase;
  padding: 0.2rem 0.5rem; border-radius: 999px; white-space: nowrap;
  background: color-mix(in srgb, var(--green) 22%, transparent); color: var(--green-bright); }
.wl-acts { display: flex; gap: 0.4rem; margin-left: auto; flex-wrap: wrap; }
.wl-acts .btn { white-space: nowrap; }
@media (max-width: 460px) { .wl-acts { margin-left: 0; width: 100%; } .wl-acts .btn { flex: 1 1 auto; } }

/* --- Send Power decay ---------------------------------------------------
   The counterweight to the levels card. Deliberately amber rather than red:
   decay is a rule of the game, not an error state, and a red card here would
   read as "something has gone wrong with your account". Every meaning is
   carried by words as well as colour, so it survives greyscale and colour
   blindness — the rate table's ceiling row says "The ceiling" in text. */
.ab-decay { max-width: 980px; margin: 1.4rem auto 0; border-color: color-mix(in srgb, var(--gold) 32%, transparent); }
.ab-decay > p { color: var(--text-dim); line-height: 1.65; }
.ab-decay > p b { color: var(--text); }
.ab-decay-cols { display: grid; grid-template-columns: 1fr; gap: 1.1rem; margin-top: 1.1rem; }
@media (min-width: 880px) { .ab-decay-cols { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); align-items: start; } }

/* The rate ladder is a real <table>: it is tabular data, and a screen reader
   should announce "Days away 7, taken that day 1.2%" rather than read a grid
   of loose spans. It scrolls inside its own box so a narrow phone never
   scrolls the whole page sideways. */
.ab-decay-rates { overflow-x: auto; }
.ab-decay-table { width: 100%; border-collapse: collapse; font-size: max(var(--text-floor), 0.9rem); font-variant-numeric: tabular-nums; }
.ab-decay-table caption { text-align: left; font-weight: 800; color: var(--gold); padding-bottom: 0.5rem; font-size: max(var(--text-floor), 0.95rem); }
.ab-decay-table th, .ab-decay-table td { text-align: left; padding: 0.55rem 0.7rem 0.55rem 0; border-bottom: 1px solid var(--ink-4); }
.ab-decay-table thead th { font-size: max(var(--text-floor), 0.76rem); text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-mute); font-weight: 700; }
.ab-decay-table tbody th { font-weight: 800; color: var(--text); white-space: nowrap; }
.ab-decay-table tbody td:nth-child(2) { font-weight: 800; color: var(--gold); white-space: nowrap; }
.ab-decay-table tbody td:last-child { color: var(--text-dim); font-size: max(var(--text-floor), 0.84rem); padding-right: 0; }
.ab-decay-table tbody tr:last-child th, .ab-decay-table tbody tr:last-child td { border-bottom: none; }
/* These two must out-rank the `tbody td:nth-child(2)` gold above, which is a
   more specific selector than a bare `td.class` — hence the tbody here. The
   colour is reinforcement only: the "why" column states "free" and "the
   ceiling" in words, so the table still reads correctly in greyscale. */
.ab-decay-table tbody td.ab-decay-free { color: var(--green-bright); }
.ab-decay-table tbody td.ab-decay-max { color: var(--red); }

.ab-decay-side { display: grid; gap: 0.9rem; align-content: start; }
.ab-decay-stop { background: color-mix(in srgb, var(--green) 9%, transparent); border: 1.5px solid color-mix(in srgb, var(--green) 34%, transparent); border-radius: 12px; padding: 0.8rem 0.95rem; }
.ab-decay-stop-h { margin: 0 0 0.35rem; font-weight: 800; color: var(--green-bright); font-size: max(var(--text-floor), 0.95rem); }
.ab-decay-stop p { margin: 0; color: var(--text-dim); line-height: 1.6; font-size: max(var(--text-floor), 0.9rem); }
.ab-decay-stop p b { color: var(--text); }
.ab-decay-adds { font-size: max(var(--text-floor), 0.88rem); }
.ab-decay-adds li { color: var(--text-dim); }
.ab-decay-adds b { color: var(--text); }
.ab-note-gwc { background: color-mix(in srgb, var(--gold) 10%, transparent); border: 1.5px solid color-mix(in srgb, var(--gold) 32%, transparent); border-radius: 12px; padding: 0.65rem 0.85rem; font-size: max(var(--text-floor), 0.87rem); margin: 0.7rem 0 0; line-height: 1.55; }
.ab-note-gwc b { color: var(--gold); }

/* --- Fair & Safe --- */
.safe-grid { display: grid; grid-template-columns: 1fr; gap: 1.1rem; max-width: 980px; margin: 0 auto 2.4rem; }
@media (min-width: 820px) { .safe-grid { grid-template-columns: repeat(3, 1fr); } }
.safe-card h3 { margin: 0.6rem 0 0.5rem; font-size: max(var(--text-floor), 1.05rem); }
.safe-card p { color: var(--text-dim); line-height: 1.6; font-size: max(var(--text-floor), 0.92rem); margin: 0; }
.safe-card b { color: var(--green-bright); }
.safe-ico { font-size: max(var(--text-floor), 2rem); line-height: 1; }
.faq-h { text-align: center; font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.4rem); color: var(--green-bright); margin: 0 0 1.2rem; letter-spacing: 0.02em; }
.faq { max-width: 660px; margin: 0 auto; }
.faq .reassure { margin: 0 auto 0.7rem; max-width: 660px; }

/* --- Reduced motion safety: never leave About content hidden --- */
@media (prefers-reduced-motion: reduce) {
  .about-hero ~ * .reveal, main .reveal { opacity: 1; transform: none; transition: none; }
  .gs-progress-fill, .ab-track-fill, .ab-rocket, .pillar-caret { transition: none; }
}

/* ===== A11y: resting form-control borders that clear WCAG 1.4.11 (>=3:1) on all card/page surfaces ===== */
.addr-input, .composer textarea, #compose-modal textarea, .np-search, .ab-select, #post-text, #pc-text {
  /* Was var(--edge-ctl), a blue-grey hardcoded beside the very token that exists to carry this exact value.
     Pointing it at --edge-ctl means the one documented control-boundary colour is the one actually used,
     and a future ramp change cannot leave this rule behind clearing less than 3:1. */
  border-color: var(--edge-ctl);
}
/* focus + active states keep their higher-specificity green border (defined above) */

/* ===== Mobile: enlarge modal dismiss targets to >=44px (affordance; backdrop-tap/Esc already close) ===== */
@media (max-width: 560px) {
  .modal-x { width: 44px; height: 44px; display: grid; place-items: center; font-size: max(var(--text-floor), 1.1rem); }
  .wc-x { width: 44px; height: 44px; display: grid; place-items: center; padding: 0; font-size: max(var(--text-floor), 1.2rem); }
}

/* ===================================================================
   NEW PAIRS RADAR v2 — advanced tracker (chips, density, grouped filters, rich detail)
   =================================================================== */
.np-search-input { font-size: max(var(--text-floor), 16px); }   /* no iOS zoom on focus */

/* preset quick-filter chips — horizontal scroll, never overflows the page */
.np-chips { display: flex; gap: 0.4rem; overflow-x: auto; padding: 0.2rem 0.1rem 0.6rem; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.np-chips::-webkit-scrollbar { display: none; }
.np-chip { flex: 0 0 auto; min-height: 36px; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); color: var(--ctl-ink); font: inherit; font-weight: 800; font-size: max(var(--text-floor), 0.8rem); border-radius: 999px; padding: 0.4rem 0.8rem; cursor: pointer; white-space: nowrap; transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease; }
.np-chip:hover { border-color: color-mix(in srgb, var(--green) 50%, transparent); background: var(--ctl-fill-hi); color: var(--ctl-ink); }
.np-chip[aria-pressed="true"] { background: var(--green); border-color: var(--green); color: var(--on-green); }
.np-chip:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 1px; }

/* density toggle */
.np-density { display: inline-flex; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 10px; padding: 2px; gap: 2px; }
.np-den { border: none; background: none; color: var(--ctl-ink); font: inherit; font-weight: 800; font-size: max(var(--text-floor), 0.78rem); padding: 0.4rem 0.6rem; border-radius: 8px; cursor: pointer; }
.np-den.is-on { background: var(--green); color: var(--on-green); }
.np-den:focus-visible { outline: 2px solid var(--ctl-ink); outline-offset: 1px; }

/* active-filter count badge on the Filters button */
.np-count-badge { display: inline-grid; place-items: center; min-width: 1.25rem; height: 1.25rem; background: var(--green); color: var(--on-green); border-radius: 999px; font-size: max(var(--text-floor), 0.7rem); font-weight: 800; padding: 0 0.3rem; margin-left: 0.15rem; }

/* grouped advanced filter panel */
.np-fgroup { border: 1px solid var(--ink-4); border-radius: 12px; padding: 0.6rem 0.85rem; margin: 0; display: flex; flex-wrap: wrap; gap: 0.6rem 1.1rem; align-items: center; }
.np-fgroup-h { font-size: max(var(--text-floor), 0.72rem); font-weight: 800; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.04em; padding: 0 0.3rem; }
.np-fgroup--hide { border-color: rgba(255,93,93,0.3); }
.np-f select { background: var(--ink); border: 1.5px solid var(--edge-ctl); color: var(--text); font: inherit; font-size: max(var(--text-floor), 16px); border-radius: 8px; padding: 0.35rem 0.4rem; min-height: 40px; }
.np-savedviews { display: flex; flex-wrap: wrap; gap: 0.4rem; width: 100%; }
.np-savedview { display: inline-flex; align-items: center; gap: 0.1rem; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 999px; padding: 0 0.25rem 0 0.6rem; }
.np-sv-apply { background: none; border: none; color: var(--ctl-ink); cursor: pointer; font: inherit; font-weight: 700; font-size: max(var(--text-floor), 0.8rem); padding: 0.4rem 0.3rem; min-height: 40px; }
.np-sv-apply:focus-visible, .np-savedview .np-sv-del:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 1px; }
.np-savedview .np-sv-del { background: none; border: none; color: var(--ctl-ink); cursor: pointer; font-size: max(var(--text-floor), 0.9rem); line-height: 1; padding: 0 0.3rem; min-height: 44px; min-width: 32px; }
.np-filters-foot { display: flex; gap: 0.5rem; width: 100%; margin-top: 0.3rem; flex-wrap: wrap; align-items: center; }
.np-saveform { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; width: 100%; }
.np-saveform .np-saveinput { margin: 0; width: auto; flex: 1; min-width: 140px; }

/* expanded detail groups */
.np-detail-group { border-top: 1px solid var(--ink-4); }
.np-detail-group > summary.np-detail-h { font-size: max(var(--text-floor), 0.82rem); font-weight: 800; color: var(--ctl-ink); background: var(--ctl-fill-lo); border-radius: 8px; padding: 0.6rem 0.75rem; cursor: pointer; list-style: none; display: flex; align-items: center; gap: 0.4rem; transition: background 0.15s ease; }
.np-detail-group > summary.np-detail-h:hover { background: var(--ctl-fill-hi); }
.np-detail-group > summary.np-detail-h::-webkit-details-marker { display: none; }
.np-detail-group > summary.np-detail-h::after { content: '▾'; margin-left: auto; color: var(--ctl-ink); transition: transform 0.2s ease; }
.np-detail-group[open] > summary.np-detail-h::after { transform: rotate(180deg); }
.np-detail-body { padding: 0.2rem 0.15rem 0.8rem; }
.np-reserves { font-size: max(var(--text-floor), 0.84rem); color: var(--text-dim); margin: 0.2rem 0 0.6rem; }
.np-reserves b { color: var(--text); font-variant-numeric: tabular-nums; }
.np-supply { font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); }
.np-supply b { color: var(--text); }
/* txn table (scrolls inside its own container) */
.np-txwrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin-top: 0.5rem; }
.np-txtable { width: 100%; font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); border-collapse: collapse; min-width: 260px; }
.np-txtable th, .np-txtable td { padding: 0.3rem 0.5rem; text-align: right; white-space: nowrap; }
.np-txtable th:first-child, .np-txtable td:first-child { text-align: left; }
.np-txtable thead th { color: var(--text-dim); font-weight: 800; border-bottom: 1px solid var(--ink-4); }
.np-txtable .np-tx-buy { color: var(--green-bright); font-variant-numeric: tabular-nums; }
.np-txtable .np-tx-sell { color: var(--red); font-variant-numeric: tabular-nums; }
/* top-10 holders (scroll-contained) */
.np-holders { max-height: 240px; overflow: auto; -webkit-overflow-scrolling: touch; display: grid; gap: 0.3rem; margin-top: 0.4rem; }
.np-holder { display: flex; align-items: center; gap: 0.5rem; font-size: max(var(--text-floor), 0.8rem); background: var(--ink); border-radius: 8px; padding: 0.3rem 0.5rem; }
.np-holder .np-hrank { color: var(--text-dim); font-weight: 800; min-width: 1.5rem; }
.np-holder code { color: var(--green-bright); font-family: ui-monospace, Menlo, monospace; }
.np-holder .np-hpct { margin-left: auto; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; }
/* contract group: address rows with copy */
.np-addr-row { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin: 0.35rem 0; font-size: max(var(--text-floor), 0.82rem); }
.np-addr-row .np-addr-lbl { color: var(--text-dim); min-width: 5.5rem; font-weight: 700; }
.np-addr-row code { color: var(--green-bright); font-family: ui-monospace, Menlo, monospace; word-break: break-all; }
.np-owner { font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; margin: 0.35rem 0; }
.np-owner.renounced b { color: var(--green-bright); }
.np-owner.owned b { color: var(--gold); }
.np-kv { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.5rem; }

/* compact density: hide the flagstrip + tighten the head */
.np-list.is-compact .np-flagstrip { display: none; }
.np-list.is-compact .np-head { padding: 0.5rem 0.7rem; }

@media (max-width: 600px) {
  .np-chip, .np-den, .np-more, .np-refresh { min-height: 44px; }
  .np-kv { grid-template-columns: 1fr; }
  .copy-btn { min-height: 44px; min-width: 44px; display: inline-grid; place-items: center; padding: 0.45rem; }
}

/* perfect 100 verdict — "Looks Good, Send It 🚀" gets a celebratory glow */
.np-verdict.np-t-perfect { background: linear-gradient(180deg, var(--g-veil), color-mix(in srgb, var(--green-bright) 12%, transparent)); border-color: var(--green-bright); box-shadow: 0 0 16px color-mix(in srgb, var(--green-bright) 35%, transparent); }
.np-verdict.np-t-perfect .np-verdict-word { color: var(--green-bright); }
@media (prefers-reduced-motion: no-preference) { .np-verdict.np-t-perfect { animation: np-perfect-pulse 2s ease-in-out infinite; } }
@keyframes np-perfect-pulse { 0%,100% { box-shadow: 0 0 12px color-mix(in srgb, var(--green-bright) 30%, transparent); } 50% { box-shadow: 0 0 22px color-mix(in srgb, var(--green-bright) 55%, transparent); } }

/* ===================================================================
   NEW PAIRS — 🎬 HOT FEED (TikTok-style swipeable view for health>=75)
   =================================================================== */
:root { --np-switch-h: 3.25rem; }
.np-viewswitch { position: sticky; top: var(--nav-h, 58px); z-index: 40; display: flex; gap: 4px; height: var(--np-switch-h); margin: 0 0 0.4rem; padding: 5px; background: color-mix(in srgb, var(--ink-2) calc(0.92 * 100%), transparent); backdrop-filter: blur(10px); border: 1.5px solid var(--ink-4); border-radius: 999px; }
.np-vs-btn { flex: 1 1 0; min-width: 0; display: inline-flex; align-items: center; justify-content: center; gap: 0.3rem; min-height: 44px; padding: 0 0.35rem; border: none; background: none; color: var(--ctl-ink); font: inherit; font-weight: 800; font-size: max(var(--text-floor), clamp(0.72rem, 2.7vw, 0.9rem)); white-space: nowrap; border-radius: 999px; cursor: pointer; } /* equal thirds that shrink to fit — never overlap/overflow at any width */
.np-vs-btn[aria-selected="true"] { background: var(--green); color: var(--on-green); }
.np-vs-btn:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 2px; }
.np-vs-ico { flex: 0 0 auto; }
.np-vs-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; } /* last-resort: a label can never overflow its tab */
@media (max-width: 430px) { .np-viewswitch .np-vs-ico { display: none; } .np-vs-btn { padding: 0 0.2rem; gap: 0; } } /* drop the emoji on small screens so the full label fits the equal-thirds tab */
/* keep list controls clear of the sticky switch */
body.np-mode-list .np-controls { top: calc(var(--nav-h, 58px) + var(--np-switch-h)); }
/* At 400% zoom (a 320x256 viewport, SC 1.4.10 Reflow) the wrapped filter bar is taller than the viewport,
   so pinning it left nothing of the list to read and put the fixed player on top of the Safer segment.
   Under 500px of height the bar and the view tabs scroll with the page instead. */
@media (max-height: 500px) {
  .np-controls, body.np-mode-list .np-controls { position: static; }
  body.np-mode-list .np-viewswitch { position: relative; top: auto; } /* relative, not static: the ::before pill needs a positioned box; top reset, or the sticky offset becomes a downward shove */
}
/* mode visibility */
body.np-mode-feed .np-hero, body.np-mode-feed .np-controls, body.np-mode-feed .np-chips, body.np-mode-feed .np-filters, body.np-mode-feed .np-status, body.np-mode-feed .np-newbar, body.np-mode-feed #np-strategies, body.np-mode-feed #np-strat-note, body.np-mode-feed #np-list, body.np-mode-feed footer { display: none !important; }
/* Best Runners mode: hide the DEX-list chrome, keep only the runners panel */
body.np-mode-runners .np-controls, body.np-mode-runners .np-chips, body.np-mode-runners .np-filters, body.np-mode-runners .np-status, body.np-mode-runners .np-newbar, body.np-mode-runners #np-list { display: none !important; }

/* ===== Best Runners ===== */
.np-runners { margin-top: 0.2rem; }
.np-runners-bar { display: flex; justify-content: center; margin-bottom: 0.6rem; }
.np-runwin { display: inline-flex; gap: 0.3rem; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 999px; padding: 0.25rem; flex-wrap: wrap; justify-content: center; }
.np-runners-status { text-align: center; color: var(--text-dim); font-size: max(var(--text-floor), 0.88rem); margin: 0 0 0.9rem; min-height: 1.2em; }
.np-runners-status b { color: var(--text); }
.np-runners-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.6rem; max-width: 760px; margin: 0 auto; counter-reset: runner; }
.np-runner { display: grid; grid-template-columns: 34px 40px minmax(0,1fr) auto; align-items: center; gap: 0.5rem 0.7rem; padding: 0.7rem 0.9rem; background: linear-gradient(180deg, var(--ink-3), var(--ink-2)); border: 1.5px solid color-mix(in srgb, var(--green) 18%, transparent); border-radius: 16px; transition: border-color 0.15s ease, transform 0.15s ease; cursor: pointer; } /* whole row opens the on-chain detail popup */
.np-runner:hover { border-color: color-mix(in srgb, var(--green) 40%, transparent); transform: translateY(-2px); }
.np-runner:nth-child(1) { border-color: rgba(255,179,64,0.5); box-shadow: 0 0 22px rgba(255,179,64,0.14); }
.np-runner:nth-child(2) { border-color: rgba(192,192,205,0.4); }
.np-runner:nth-child(3) { border-color: rgba(205,127,50,0.4); }
.np-runner-rank { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.15rem); color: var(--text-dim); text-align: center; }
.np-runner:nth-child(1) .np-runner-rank { color: var(--gold); }
.np-runner-logo { width: 40px; height: 40px; }
.np-runner-logo-img { width: 40px; height: 40px; border-radius: 12px; object-fit: cover; background: var(--ink-4); }
.np-runner-logo-none { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 12px; background: var(--ink-4); font-size: max(var(--text-floor), 1.2rem); }
.np-runner-id { min-width: 0; }
.np-runner-sym { display: inline-block; font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.05rem); color: var(--on-green); letter-spacing: 0.02em; line-height: 1.1; background: var(--green); border: 0; padding: 0.1rem 0.5rem; border-radius: var(--r-pill); margin: 0; cursor: pointer; text-align: left; max-width: 100%; }
.np-runner-sym:hover { background: var(--green-bright); color: var(--ctl-ink); }
.np-runner-sym:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 2px; border-radius: 4px; }
/* full token name on ONE line spanning the whole card; never truncated. Long names scroll within their own row
   (scrollbar hidden) instead of wrapping or breaking the layout, so it stays readable at every width. */
.np-runner-name { grid-column: 1 / -1; display: block; font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); font-weight: 600; white-space: normal; overflow-wrap: anywhere; overflow-y: hidden; max-width: 100%; }
.np-runner-name::-webkit-scrollbar { display: none; }
.np-runner-gain { font: inherit; letter-spacing: normal; white-space: nowrap; } /* sits beside the market cap, same design as the other metric text… */
.np-runner-gain.up { color: var(--green-bright); }                              /* …just keeping its green coloring */
.np-runner-gain.down { color: var(--red); }
.np-runner-metrics { grid-column: 3 / 5; display: flex; flex-wrap: wrap; gap: 0.3rem 0.7rem; font-size: max(var(--text-floor), 0.78rem); color: var(--text-dim); font-weight: 600; margin-top: 0.1rem; }
.np-runner-metrics b { color: var(--text); }
/* Xs since the scanner caught it — the number carries the colour, so it overrides the neutral `b` above */
.np-runner-since { white-space: nowrap; }
.np-runner-since i { font-style: normal; font-weight: 600; color: var(--text-dim); }
.np-runner-metrics .np-runner-since.up b { color: var(--green-bright); }
.np-runner-metrics .np-runner-since.down b { color: var(--red); }
.np-runner-note { color: var(--gold); font-weight: 700; }
.np-runner-actions { grid-column: 3 / 5; display: flex; gap: 0.4rem; margin-top: 0.35rem; }
.np-runner-pin, .np-runner-chart { width: 38px; height: 38px; display: inline-flex; align-items: center; justify-content: center; border-radius: 10px; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); color: var(--ctl-ink); font-size: max(var(--text-floor), 1rem); cursor: pointer; text-decoration: none; }
.np-runner-pin:hover, .np-runner-chart:hover { border-color: var(--green); background: var(--ctl-fill-hi); color: var(--ctl-ink); }
.np-runner-pin.is-pinned { border-color: var(--gold); color: var(--on-gold); background: var(--gold); }
.np-runner-pin:focus-visible, .np-runner-chart:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 1px; }
.np-runners-foot { text-align: center; color: var(--text-dim); font-size: max(var(--text-floor), 0.78rem); margin: 1.4rem auto 0; max-width: 60ch; line-height: 1.5; }
@media (min-width: 560px) {
  .np-runner { grid-template-columns: 40px 44px minmax(0,1fr) auto; }
  .np-runner-id { grid-column: 3; grid-row: 1; justify-self: start; } /* keep the symbol beside the logo on row 1 (not stranded below); name flows to its own full-width row */
  .np-runner-metrics { grid-column: 3; grid-row: 1; justify-self: end; margin: 0; text-align: right; justify-content: flex-end; }
  .np-runner-actions { grid-column: 4; grid-row: 1; margin: 0; }
}
@media (prefers-reduced-motion: reduce) { .np-runner { transition: none; } .np-runner:hover { transform: none; } }

/* feed scroller: TikTok column, 100dvh minus nav minus switch */
/* .np-feed is a <section>, so `section { padding: 4.2rem 1.25rem }` (line 377) was silently handing the
   scroller 134px of dead scroll height and taking 40px off the width of every card. Refusing that padding
   and moving the scrolling to the track fixes two things at once, and the two MUST ship together: the
   track's `height: 100%` resolves against this element's content box, so padding here would shrink the
   track below a slide and break mandatory snap.

   The track scrolls; this stays put. .np-feed-chrome (the live pill and the 🆕 jump button), .np-feed-dyor,
   .np-feed-nav and .np-feed-hint are absolutely positioned against this element — and an absolute child of
   a SCROLL container scrolls away with the content, which is why the live counter and the jump-to-newest
   button were hundreds of pixels off-screen from the second card onward. They are pinned now for free,
   with no sticky conversion and no change to their own rules.

   -webkit-overflow-scrolling is dropped deliberately: a no-op on iOS 13+ and a known irritant for snap. */
.np-feed { position: relative; padding: 0; overflow: hidden; background: var(--ink); }
.np-feed-track { height: 100%; overflow-y: auto; overflow-x: hidden; scroll-snap-type: y mandatory; scroll-behavior: smooth; overscroll-behavior: contain; }
.np-slide { height: calc(100dvh - var(--nav-h, 58px) - var(--np-switch-h)); scroll-snap-align: start; scroll-snap-stop: always; position: relative; display: flex; flex-direction: column; justify-content: center; padding: 1rem; content-visibility: auto; contain-intrinsic-size: 1px calc(100dvh - var(--nav-h,58px) - var(--np-switch-h)); --rowtri: var(--green-bright); }
@supports not (height: 100dvh) { .np-slide { height: calc(100vh - var(--nav-h, 58px) - var(--np-switch-h)); } }
.np-slide[data-level="caution"] { --rowtri: var(--gold); }
.np-slide[data-level="high"]    { --rowtri: var(--triage-high); }
.np-slide[data-level="avoid"]   { --rowtri: var(--red); }
/* The card was a scroll DEAD-END: it is the scroller AND it had overscroll-behavior: contain, and it
   covers about 72% of a phone screen — so a swipe that began over it scrolled a few lines of text and then
   refused to chain into the feed, while .np-feed-nav is display:none under (hover: none), leaving no other
   way forward. Containment belongs on the feed track alone. It keeps overflow-y: auto as a last resort —
   overflow: hidden here would turn "below a hidden fold" into "unreachable", and the first thing it would
   swallow is the honesty paragraph. */
.np-slide-inner { width: 100%; max-width: 520px; margin: 0 auto; display: flex; flex-direction: column; gap: 0.7rem; max-height: 100%; overflow-y: auto; overflow-x: hidden; background: linear-gradient(180deg, var(--ink-3), var(--ink-2)); border: 1.5px solid var(--ink-4); border-top: 4px solid var(--rowtri); border-radius: 20px; padding: 1.1rem; box-shadow: 0 12px 40px rgba(0,0,0,0.45); }
.np-slide .np-gauge, .np-slide .np-gauge-svg { width: 104px; height: 104px; }
.np-slide .np-gauge-num { font-size: max(var(--text-floor), 2rem); }
.np-slide-hero { display: flex; align-items: center; justify-content: center; gap: 0.8rem; }
.np-slide-verdict-wrap { display: flex; flex-direction: column; gap: 0.35rem; align-items: flex-start; }
.np-slide-verdict { font-size: max(var(--text-floor), 1rem); padding: 0.35rem 0.8rem; }
.np-slide-health { font-size: max(var(--text-floor), 0.8rem); font-weight: 700; color: var(--text-dim); }
.np-slide-name { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), clamp(1.4rem, 6vw, 2rem)); color: var(--text); line-height: 1.05; text-align: center; overflow-wrap: anywhere; margin: 0; }
.np-slide-sym { color: var(--green-bright); }
.np-slide-sub { text-align: center; font-size: max(var(--text-floor), 0.82rem); font-weight: 700; color: var(--text-dim); margin: 0; }
.np-slide-price { display: flex; align-items: center; justify-content: center; gap: 0.5rem; flex-wrap: wrap; }
.np-slide-priceval { font-weight: 800; font-size: max(var(--text-floor), 1.2rem); color: var(--text); font-variant-numeric: tabular-nums; }
/* Spacing, not structure. Going four-wide was measured to overflow the card horizontally — `1fr` is
   `minmax(auto, 1fr)`, so a long figure pushes its own track wider than the column it sits in. Two cells
   a row still fits every value; the height comes out of the padding and the gap instead. */
.np-slide-stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.4rem; }
.np-slide-stats > div { background: var(--ink); border-radius: 12px; padding: 0.4rem 0.55rem; text-align: center; min-width: 0; }
.np-slide-stats .np-slide-mc { grid-column: 1 / -1; background: color-mix(in srgb, var(--green) 12%, var(--ink)); border: 1px solid color-mix(in srgb, var(--green) 30%, transparent); }
.np-slide-stats .np-slide-mc b { font-size: max(var(--text-floor), 1.35rem); color: var(--green-bright); }
.np-slide-stats i { display: block; font-style: normal; font-size: max(var(--text-floor), 0.66rem); text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-dim); font-weight: 700; }
.np-slide-stats b { font-size: max(var(--text-floor), 1rem); color: var(--text); font-variant-numeric: tabular-nums; }
.np-slide-stats b.red { color: var(--red); }
/* "not read yet" is longer than a figure and must not shout like one — it is the absence of a reading,
   not a value. Smaller and dimmed, so a cell that could not be read never draws the eye like one that could. */
.np-slide-stats b.dim { font-size: max(var(--text-floor), 0.7rem); font-weight: 800; color: var(--text-mute); letter-spacing: 0; }
.np-slide .np-flagstrip { justify-content: center; padding: 0; }
.np-slide-honest { font-size: max(var(--text-floor), 0.72rem); line-height: 1.5; color: var(--text-dim); opacity: 0.85; text-align: center; margin: 0; }
.np-slide-details { border-top: 1px solid var(--ink-4); margin-top: 0.45rem; padding-top: 0.5rem; }
.np-slide-more { cursor: pointer; font-weight: 800; color: var(--ctl-ink); font-size: max(var(--text-floor), 0.9rem); list-style: none; display: flex; align-items: center; justify-content: center; gap: 0.55rem; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 12px; padding: 0.65rem 1rem; min-height: 46px; transition: background 0.15s ease, border-color 0.15s ease; }
.np-slide-more::-webkit-details-marker { display: none; }
.np-slide-more::after { content: '▾'; color: currentColor; transition: transform 0.2s ease; }
.np-slide-details[open] .np-slide-more::after { transform: rotate(180deg); }
.np-slide-more:hover, .np-slide-more:focus-visible { background: var(--ctl-fill-hi); border-color: var(--tok, var(--green)); }
@media (prefers-reduced-motion: reduce) { .np-slide-more::after { transition: none; } }
/* right rail */
/* The rail sat on top of the card's right-hand 46px — including the honesty paragraph, the one line the
   site must not obscure. It also reserved --fab-clear, the strip the fixed player and SEND IT button own;
   in feed mode the FEED's own bottom edge already clears them (see --np-feed-h), so reserving it again
   pushed the rail up into the card instead of down out of it.

   The fix is to reserve the strip with PADDING ON THE SLIDE rather than to move the rail out of it: the
   card is sized by `max-height: 100%`, a percentage that resolves against the slide's CONTENT box, so
   padding shrinks the card by exactly the strip the rail occupies and the two can no longer overlap. */
.np-slide-rail { position: absolute; right: 0.6rem; bottom: 0.6rem; display: flex; flex-direction: column; gap: 0.6rem; z-index: 3; }
@media (max-width: 640px), (max-height: 700px) {
  /* On a phone there is no gutter beside the card, so the rail becomes a row beneath it, in space the
     slide reserves for it. 46px keeps the site's 44px touch-target floor. */
  .np-slide { padding-bottom: calc(0.6rem + 46px + 0.6rem); }
  .np-slide-rail { flex-direction: row; left: 50%; right: auto; transform: translateX(-50%); bottom: 0.6rem; gap: 0.45rem; }
  .np-slide-rail .np-rail-btn { width: 46px; height: 46px; --ava: 46px; }

  /* Reserving the rail's strip costs the card 65px, so the card has to give 65px back — out of SPACING and
     out of the gauge, never out of the honesty paragraph. Measured at 375x812: content 660px in a 596px
     box before this, 598px after, so nothing is left behind a hidden fold. The gauge stays well above the
     44px floor and keeps its number legible at 1.6rem. */
  .np-slide-inner { gap: 0.45rem; padding: 0.9rem; }
  .np-slide .np-gauge, .np-slide .np-gauge-svg { width: 80px; height: 80px; }
  .np-slide .np-gauge-num { font-size: max(var(--text-floor), 1.6rem); }
  .np-slide-hero { gap: 0.7rem; }
  /* the disclosure keeps a 44px target — the site's floor — and gives back the rest of its padding */
  .np-slide-more { padding: 0.45rem 1rem; min-height: 44px; font-size: max(var(--text-floor), 0.86rem); }
  .np-slide-honest { font-size: max(var(--text-floor), 0.7rem); line-height: 1.45; }
}
.np-rail-btn { width: 52px; height: 52px; display: grid; place-items: center; border-radius: 50%; background: var(--ctl-fill-lo); backdrop-filter: blur(6px); border: 1.5px solid var(--ctl-fill-lo); color: var(--ctl-ink); font-size: max(var(--text-floor), 1.3rem); text-decoration: none; cursor: pointer; }
.np-rail-btn:hover { border-color: var(--green); background: var(--ctl-fill-hi); color: var(--ctl-ink); }
.np-rail-btn:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 2px; }
/* The rail's discs: glyphs sized from the disc (--ava), no inherited .copy-btn padding squeezing the 📋 off-centre, and the
   🚀 with its private "you ×N" tally stacked and centred as one group (a two-row grid split the disc in half, so the
   rocket sat in the top half even with no tally). */
.np-rail-btn { --ava: 52px; padding: 0; font-family: inherit; line-height: 1; font-size: calc(var(--ava) * 0.46); }
.np-feed-react { grid-auto-flow: row; place-content: center; gap: 1px; }
.np-rail-count { font-size: max(11px, calc(var(--ava) * 0.22)); font-weight: 800; line-height: 1; white-space: nowrap; color: var(--ctl-ink); }
.np-rail-count:empty { display: none; }
/* chrome */
.np-feed-chrome { position: absolute; top: 0.5rem; left: 0; right: 0; z-index: 5; display: flex; justify-content: center; gap: 0.5rem; flex-wrap: wrap; padding: 0 0.6rem; pointer-events: none; }
.np-feed-live { display: inline-flex; align-items: center; gap: 0.35rem; font-size: max(var(--text-floor), 0.72rem); font-weight: 800; color: var(--text-dim); background: color-mix(in srgb, var(--ink) calc(0.7 * 100%), transparent); border: 1px solid var(--ink-4); border-radius: 999px; padding: 0.25rem 0.6rem; }
.np-feed-fresh { pointer-events: auto; font: inherit; font-size: max(var(--text-floor), 0.74rem); font-weight: 800; color: var(--on-green); background: var(--green); border: 1.5px solid var(--green); border-radius: 999px; padding: 0.3rem 0.7rem; cursor: pointer; min-height: 32px; }
.np-feed-dyor { position: absolute; top: 0.5rem; left: 0.6rem; z-index: 5; font-size: max(var(--text-floor), 0.64rem); font-weight: 800; color: var(--gold); background: rgba(255,179,64,0.12); border: 1px solid rgba(255,179,64,0.35); border-radius: 999px; padding: 0.2rem 0.5rem; pointer-events: none; }
/* Moved to the LEFT gutter: it shared a column with the action rail, and it is only shown where there is
   actually a gutter to put it in. `display: none` under (hover: none) is replaced by a positive test, so
   the rule cannot leave a touch reader with no forward control and no rail either. */
.np-feed-nav { position: absolute; left: 0.6rem; right: auto; top: 50%; transform: translateY(-50%); z-index: 4; display: none; flex-direction: column; gap: 0.5rem; }
.np-feed-nav .np-rail-btn { width: 44px; height: 44px; --ava: 44px; font-size: calc(var(--ava) * 0.46); }
@media (hover: hover) and (min-width: 700px) { .np-feed-nav { display: flex; } }
.np-feed-hint { position: absolute; bottom: 1.2rem; left: 50%; transform: translateX(-50%); z-index: 5; font-size: max(var(--text-floor), 0.75rem); font-weight: 800; color: var(--text); background: color-mix(in srgb, var(--ink) calc(0.75 * 100%), transparent); border: 1px solid var(--ink-4); border-radius: 999px; padding: 0.35rem 0.8rem; pointer-events: none; }
.np-slide--intro .np-slide-inner { text-align: center; align-items: center; }
.np-slide-newtag { position: absolute; top: 0.6rem; left: 0.6rem; z-index: 3; font-size: max(var(--text-floor), 0.66rem); font-weight: 800; color: var(--green-bright); background: color-mix(in srgb, var(--green) 16%, transparent); border: 1px solid var(--green); border-radius: 999px; padding: 0.15rem 0.5rem; }
.np-feed-msg { height: 100%; display: grid; place-items: center; text-align: center; padding: 2rem; color: var(--text-dim); }
@media (prefers-reduced-motion: no-preference) {
  .np-slide { transition: opacity 0.3s ease; }
  .np-slide:not(.is-active) { opacity: 0.55; }
  .np-feed-react.pop { animation: np-pop 0.4s ease; }
  .np-feed-hint { animation: np-bob 1.6s ease-in-out infinite; }
}
@keyframes np-pop { 0%{transform:scale(1);} 40%{transform:scale(1.35);} 100%{transform:scale(1);} }
@keyframes np-bob { 0%,100%{transform:translateX(-50%) translateY(0);} 50%{transform:translateX(-50%) translateY(-5px);} }
@media (prefers-reduced-motion: reduce) { .np-feed-track { scroll-behavior: auto; } .np-slide .np-gauge-arc { transition: none; } }

/* ===================================================================
   WATCHLIST save-buttons + WATCHLIST page + NOTIFICATIONS bell
   =================================================================== */
/* ☆/★ save button (feed rail + list row + watchlist) */
.np-watch { background: var(--ctl-fill-lo); border: none; cursor: pointer; color: var(--ctl-ink); font-size: max(var(--text-floor), 1.15rem); line-height: 1; padding: 0.3rem; border-radius: 8px; flex-shrink: 0; }
.np-watch:hover { color: var(--on-gold); background: var(--gold); }
.np-watch.is-on { color: var(--on-gold); background: var(--gold); }
.np-watch:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 2px; }
.np-rail-btn.np-watch { color: var(--ctl-ink); font-size: max(var(--text-floor), 1.3rem); }
.np-rail-btn.np-watch.is-on { color: var(--on-gold); border-color: var(--gold); background: var(--gold); }
.np-row-watch { min-width: 40px; min-height: 40px; }
@media (max-width: 600px) { .np-row-watch { min-width: 44px; min-height: 44px; } }
/* watchlist remove ✕ */
.np-wl-remove { background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); color: var(--ctl-ink); cursor: pointer; width: 34px; height: 34px; border-radius: 50%; font-size: max(var(--text-floor), 0.9rem); line-height: 1; flex-shrink: 0; }
.np-wl-remove:hover { border-color: var(--red); background: var(--red); color: var(--on-red); }
.np-wl-remove:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 2px; }
@media (max-width: 600px) { .np-wl-remove { width: 44px; height: 44px; } }

/* notifications bell + dropdown */
#nav-notif { position: relative; display: inline-flex; }
.notif-bell { position: relative; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); color: var(--ctl-ink); width: var(--nav-ctl); height: var(--nav-ctl); padding: 0; border-radius: 999px; cursor: pointer; font-family: inherit; font-size: var(--nav-fs); line-height: 1; display: inline-grid; place-items: center; }   /* a button does not inherit the page font on its own: the count was drawn in Arial */
.notif-bell:hover { border-color: var(--green); }
.notif-bell:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 2px; }
.notif-badge { position: absolute; top: calc(var(--notif-badge) * -0.28); right: calc(var(--notif-badge) * -0.28); box-sizing: border-box; min-width: var(--notif-badge); height: var(--notif-badge); padding: 0 0.3em; background: var(--red); color: var(--on-red); /* dark-on-red ≈ 6:1; white-on-red was 3:1 */ border-radius: 999px; font-size: var(--nav-fs-badge); font-weight: 800; line-height: 1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; white-space: nowrap; display: grid; place-items: center; box-shadow: 0 0 0 2px var(--ink-2); pointer-events: none; }   /* a ring in the page colour separates it from the bell */
/* The digits sit in their own block trimmed to cap height and baseline, so the circle centres the ink of "3" or "9+" itself
   rather than a line box whose ascent and descent differ (which left them a pixel high). Browsers without text-box
   centre the line box, as before. */
.notif-badge-n { display: block; text-box: trim-both cap alphabetic; }
/* The panel pops up on the LEFT side of the screen, pinned just under the bar, at every width (the owner's call; in the
   pop-down bar the bell sits beside the logo, so the list opens right under it). It once hung from the bell's left edge,
   which ran a 360px panel off the right side of every tablet, and then sat at the screen's right edge, which on a laptop
   put it 400px or more from the bell. Its width is in text units
   (26em ≈ 50 characters a line), capped to the screen, so the text can follow the site's size floor on a wide
   display without turning each notification into a narrow column; its height stops short of the screen's bottom
   and the list scrolls inside. (Fixed inside the nav: the nav's backdrop-filter makes the bar the containing block,
   and the bar is full-width and pinned to the top, so the offsets land where they read.) */
.notif-panel { position: fixed; top: calc(var(--nav-h, 60px) + 8px); left: 8px; right: auto; font-size: max(var(--text-floor), 0.95rem); width: min(26em, calc(100vw - 16px)); max-height: calc(100vh - var(--nav-h, 60px) - 24px); overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 16px; box-shadow: 0 20px 50px rgba(0,0,0,0.55); z-index: 100; }
.notif-head { display: flex; align-items: center; justify-content: space-between; gap: 0.6em; padding: 0.6em 0.8em; border-bottom: 1px solid var(--ink-4); font-weight: 800; font-size: max(var(--text-floor), 1em); position: sticky; top: 0; z-index: 1; background: var(--ink-2); }
.notif-clearall { flex-shrink: 0; background: var(--gold); border: none; color: var(--on-gold); font: inherit; font-weight: 700; font-size: max(var(--text-floor), 0.85em); cursor: pointer; min-height: max(36px, 1.9em); padding: 0 0.8em; border-radius: var(--r-pill); white-space: nowrap; }
.notif-list { display: flex; flex-direction: column; }
.notif-item { display: flex; gap: 0.6rem; align-items: flex-start; padding: 0.65rem 0.9rem; border-bottom: 1px solid var(--hair); }
.notif-ico { font-size: max(var(--text-floor), 1.15em); flex-shrink: 0; line-height: 1.3; }
.notif-body { flex: 1; min-width: 0; }
.notif-text { font-size: max(var(--text-floor), 1em); color: var(--text); line-height: 1.45; overflow-wrap: anywhere; word-break: break-word; }
.notif-time { font-size: max(var(--text-floor), 0.8em); color: var(--text-dim); margin-top: 0.15em; }
.notif-x { background: var(--ctl-fill-lo); border: none; color: var(--ctl-ink); cursor: pointer; font-size: max(var(--text-floor), 0.85em); padding: 0; border-radius: 8px; flex-shrink: 0; min-width: max(36px, 1.9em); min-height: max(36px, 1.9em); display: inline-grid; place-items: center; }
.notif-x:hover { background: var(--red); color: var(--on-red); }
.notif-empty { padding: 1.4em 0.9em; text-align: center; color: var(--text-dim); font-size: max(var(--text-floor), 1em); }

@supports (height: 100dvh) { .notif-panel { max-height: calc(100dvh - var(--nav-h, 60px) - 24px); } }   /* the phone's toolbar-aware height */
/* a phone: the full width between 8px margins */
@media (max-width: 600px) { .notif-panel { left: 8px; right: 8px; width: auto; } }
/* a finger does the pointing: the dismiss and clear-all targets grow to 44px */
@media (pointer: coarse) { .notif-x { min-width: max(44px, 1.9em); min-height: max(44px, 1.9em); } .notif-clearall { min-height: max(44px, 1.9em); } }
/* Sendy, the ✏️ button and the music player float above the page; while the list is open the bar (and the panel
   inside it) rises above them, so no notification is ever hidden under one */
.nav:has(#notif-panel.open) { z-index: 300; }
.nav:has(.nav-menu.open), .nav:has(.nav-profile.open) { z-index: 300; }   /* and the open menu and account menu, which Sendy would otherwise cover */
.notif-panel:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }   /* opened from the keyboard, focus moves into the list */

/* keep the signed-in persistent cluster (logo + 🔔 + Lv + account + ≡) on one row on small phones */


/* ===================================================================
   WATCHLIST PAGE — token/wallet tabs, add-wallet form, wallet rows
   =================================================================== */
.wl-bar { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; margin: 0.2rem 0 0.5rem; }
.wl-cta { white-space: nowrap; }
.wl-addform { background: linear-gradient(180deg, var(--ink-3), var(--ink-2)); border: 1.5px solid var(--ink-4); border-radius: 16px; padding: 0.9rem 1rem; margin: 0.2rem 0 0.8rem; }
.wl-addrow { display: flex; gap: 0.5rem; margin-top: 0.5rem; flex-wrap: wrap; }
.wl-addrow .addr-input { margin: 0; flex: 1; min-width: 160px; }
.wl-wallet-row .wl-w-ico { font-size: max(var(--text-floor), 1.3rem); flex-shrink: 0; width: 42px; text-align: center; }
.wl-wallet-row .np-name { font-size: max(var(--text-floor), 1.02rem); }
.wl-wallet-row .wl-w-addr { color: var(--text-dim); font-family: ui-monospace, Menlo, monospace; font-size: max(var(--text-floor), 0.8rem); }
.wl-wallet-body { padding: 0.2rem 0.15rem 0.6rem; }
/* :not(.btn) — this is for inline links inside a message. Without it, it out-specifies every
   .btn-* variant and repaints button labels green-and-underlined on their own fill. */
.np-msg-link, .np-msg a:not(.btn) { color: var(--green-bright); text-decoration: underline; font-weight: 700; }
/* panels keep the global focus ring */

/* ===================== SEND CALLS ===================== */
.sc-widget { --tok: var(--green-bright); background: linear-gradient(180deg, color-mix(in srgb, var(--tok) 9%, var(--ink-2)), var(--ink-2)); border: 1.5px solid var(--ink-4); border-left: 4px solid var(--tok); border-radius: 16px; padding: 0.8rem 0.9rem; margin: 0.6rem 0; }
.sc-g { --gc: var(--green-bright); }
.sc-gS { --gc: #b06bff; } .sc-gA { --gc: var(--green-bright); } .sc-gB { --gc: #7bd66b; } .sc-gC { --gc: var(--gold); } .sc-gD { --gc: #f0932b; } .sc-gE { --gc: var(--text-dim); } .sc-gF { --gc: var(--red); }
.sc-top { display: flex; align-items: center; gap: 0.6rem; }
.sc-logo { flex: 0 0 auto; width: 40px; height: 40px; border-radius: 50%; padding: 2px; background: color-mix(in srgb, var(--tok) 16%, transparent); box-shadow: 0 0 0 2px var(--tok); display: grid; place-items: center; overflow: hidden; font-size: max(var(--text-floor), 1.2rem); }
.sc-logo-none { box-shadow: 0 0 0 2px var(--ink-4); background: var(--ink-3); }
.sc-id { min-width: 0; flex: 1; }
.sc-name { display: block; font-weight: 800; font-size: max(var(--text-floor), 1rem); color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sc-name b { color: color-mix(in srgb, var(--tok) 40%, var(--text)); }
.sc-when { display: block; font-size: max(var(--text-floor), 0.74rem); color: var(--text-dim); font-weight: 700; margin-top: 0.1rem; }
.sc-grade { flex: 0 0 auto; display: grid; place-items: center; line-height: 1; font-size: max(var(--text-floor), 1.4rem); color: var(--gc); }
.sc-grade i { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 0.8rem); font-style: normal; margin-top: 0.1rem; }
.sc-xrow { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; margin: 0.7rem 0 0.5rem; }
.sc-x { background: var(--ink-3); border: 1.5px solid var(--ink-4); border-radius: 12px; padding: 0.5rem 0.6rem; text-align: center; }
.sc-x i { display: block; font-size: max(var(--text-floor), 0.66rem); text-transform: uppercase; letter-spacing: 0.03em; color: var(--text-dim); font-weight: 800; font-style: normal; }
.sc-x b { display: block; font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.5rem); margin-top: 0.15rem; letter-spacing: 0.02em; }
.sc-x.sc-up b { color: var(--green-bright); } .sc-x.sc-down b { color: var(--red); } .sc-x.sc-flat b { color: var(--text-dim); }
.sc-x-max { border-color: color-mix(in srgb, var(--tok) 35%, var(--ink-4)); }
.sc-mcs { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; font-size: max(var(--text-floor), 0.78rem); color: var(--text-dim); font-weight: 700; }
.sc-mcs b { color: var(--text); }
.sc-arrow, .sc-dot { color: var(--text-dim); }
.sc-actions { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.7rem; }
.sc-btn { display: inline-flex; align-items: center; gap: 0.3rem; font-size: max(var(--text-floor), 0.78rem); font-weight: 800; color: var(--ctl-ink); background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 999px; padding: 0.4rem 0.75rem; text-decoration: none; cursor: pointer; min-height: 38px; }
.sc-btn:hover { border-color: var(--tok); background: var(--ctl-fill-hi); }
.sc-hop { background: var(--green); border-color: var(--green); color: var(--on-green); }
.sc-hop.hopped { background: var(--ctl-fill-mute); border-color: var(--ctl-fill-mute); color: var(--ctl-ink); }
.sc-hop:disabled { background: var(--ctl-fill-dis); border-color: var(--ctl-fill-dis); color: var(--ctl-ink); cursor: not-allowed; }
.sc-hopn { background: color-mix(in srgb, var(--ink) 30%, transparent); border-radius: 999px; padding: 0 0.4em; font-size: max(var(--text-floor), 0.72rem); }
.sc-track { color: var(--on-gold); background: var(--gold); border-color: var(--gold); }
.sc-info { color: var(--ctl-ink); }
/* #lb-help on the leaderboard is a bare .sc-info (no .sc-btn) and was rendering in the browser's own grey.
   Same inline pill as .sc-senders-toggle, on the control ladder, so it reads as one of ours. */
.sc-info:not(.sc-btn) { background: var(--ctl-fill-lo); border: none; color: var(--ctl-ink); font: inherit; font-weight: 700; font-size: max(var(--text-floor), 0.82rem); cursor: pointer; padding: 0.2rem 0.7rem; border-radius: var(--r-pill); }
.sc-info:not(.sc-btn):hover, .sc-info:not(.sc-btn):focus-visible { background: var(--ctl-fill-hi); }
.sc-explain { margin-top: 0.6rem; font-size: max(var(--text-floor), 0.78rem); line-height: 1.5; color: var(--text-dim); background: var(--ink-3); border-radius: 12px; padding: 0.6rem 0.75rem; }
.sc-explain b { color: var(--text); }
@media (max-width: 560px) { .sc-x b { font-size: max(var(--text-floor), 1.25rem); } .sc-logo { width: 34px; height: 34px; } }

/* ===== public-wall tabs (Posts / Send Calls / Leaderboard) + call stats + leaderboard ===== */
.wall-tabs { display: flex; gap: 0.4rem; margin: 0.4rem 0 1rem; flex-wrap: wrap; }
.wall-tab { font-weight: 800; font-size: max(var(--text-floor), 0.88rem); color: var(--ctl-ink); background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 999px; padding: 0.5rem 1rem; cursor: pointer; min-height: 42px; }
.wall-tab:hover { color: var(--ctl-ink); background: var(--ctl-fill-hi); border-color: var(--green); }
.wall-tab.active { color: var(--ink-1); background: var(--green-bright); border-color: var(--green-bright); }
.wall-tab:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 2px; }
.sc-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.5rem; margin-bottom: 1rem; }
.sc-stat { background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 12px; padding: 0.6rem 0.4rem; text-align: center; }
.sc-stat b { display: block; font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.25rem); color: var(--text); }
.sc-stat b.sc-up { color: var(--green-bright); }
.sc-stat i { display: block; font-size: max(var(--text-floor), 0.66rem); font-style: normal; color: var(--text-dim); font-weight: 700; margin-top: 0.15rem; }
.sc-stat-load, .lb-load { color: var(--text-dim); padding: 1rem; text-align: center; }
.sc-list { display: grid; gap: 0.2rem; }
.lb-intro { color: var(--text-dim); font-size: max(var(--text-floor), 0.85rem); margin: 0 0 0.7rem; }
.lb-windows { display: flex; gap: 0.35rem; flex-wrap: wrap; margin-bottom: 0.9rem; }
.lb-win { font-weight: 800; font-size: max(var(--text-floor), 0.8rem); color: var(--ctl-ink); background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 999px; padding: 0.35rem 0.8rem; cursor: pointer; min-height: 38px; }
.lb-win.active { color: var(--ink-1); background: var(--gold); border-color: var(--gold); }
.lb-win:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 2px; }
.lb-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4rem; }
.lb-row { display: flex; align-items: center; gap: 0.6rem; background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 12px; padding: 0.5rem 0.7rem; }
.lb-row.lb-top { border-color: color-mix(in srgb, var(--gold) 40%, var(--ink-4)); }
.lb-rank { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.1rem); color: var(--text-dim); width: 1.6rem; text-align: center; flex: 0 0 auto; }
.lb-top .lb-rank { color: var(--gold); }
.lb-ava { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; flex: 0 0 auto; display: grid; place-items: center; background: var(--ink-3); font-size: max(var(--text-floor), 1.1rem); }
.lb-name { font-weight: 800; color: var(--text); text-decoration: none; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-name:hover { text-decoration: underline; }
.lb-grade { font-size: max(var(--text-floor), 1.2rem); flex: 0 0 auto; }
.lb-x { text-align: right; flex: 0 0 auto; }
.lb-x b { display: block; font-weight: 800; color: var(--green-bright); }
.lb-x i { display: block; font-size: max(var(--text-floor), 0.66rem); font-style: normal; color: var(--text-dim); font-weight: 700; }
.lb-empty { color: var(--text-dim); text-align: center; padding: 1.5rem; }
@media (max-width: 480px) { .sc-stats { grid-template-columns: repeat(2, 1fr); } }

/* loot-log (achievement log) Today/All-time toggle */
.ll-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; flex-wrap: wrap; }
.ll-toggle { display: inline-flex; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 999px; padding: 2px; }
.ll-toggle button { font-weight: 800; font-size: max(var(--text-floor), 0.72rem); color: var(--ctl-ink); background: none; border: none; border-radius: 999px; padding: 0.3rem 0.7rem; cursor: pointer; min-height: 30px; }
.ll-toggle button.active { color: var(--ink-1); background: var(--green-bright); }
.ll-toggle button:focus-visible { outline: 2px solid var(--ctl-ink); outline-offset: 1px; }
.sc-stale { font-size: max(var(--text-floor), 0.72rem); color: var(--gold); background: color-mix(in srgb, var(--gold) 10%, transparent); border-radius: 8px; padding: 0.35rem 0.5rem; margin: 0.4rem 0 0; line-height: 1.4; }

/* Send Call widget → expand to the full New Pairs on-chain detail */
.sc-toggle { display: flex; align-items: center; justify-content: center; gap: 0.55rem; width: 100%; text-align: center; font-weight: 800; font-size: max(var(--text-floor), 0.9rem); color: var(--ctl-ink); background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 12px; padding: 0.7rem 1rem; cursor: pointer; margin-top: 0.7rem; min-height: 48px; transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease; }
.sc-toggle::after { content: '▾'; font-size: max(var(--text-floor), 0.95rem); line-height: 1; color: currentColor; transition: transform 0.2s ease; }
.sc-toggle[aria-expanded="true"]::after { transform: rotate(180deg); }
.sc-toggle--dash::after { content: none; }   /* it opens the dashboard popup — nothing unfolds here, so no caret */
/* a radar or watchlist row, and the Hot Feed's "Full dashboard", open the dashboard popup: no unfold caret on them */
.np-sum--dash .np-chev { display: none; }
.np-slide-dashrow { border-top: 1px solid var(--ink-4); margin-top: 0.45rem; padding-top: 0.5rem; }
.np-slide-more.np-slide-more--dash { width: 100%; font-family: inherit; }
.np-slide-more.np-slide-more--dash::after { content: none; }
.sc-toggle:hover, .sc-toggle:focus-visible { background: var(--ctl-fill-hi); border-color: var(--tok, var(--green)); color: var(--ctl-ink); }
@media (prefers-reduced-motion: reduce) { .sc-toggle::after { transition: none; } }
.sc-widget.sc-expanded { cursor: default; }
.sc-detail { margin-top: 0.7rem; border-top: 1.5px solid var(--ink-4); padding-top: 0.5rem; }
.sc-detail .np-body { padding: 0; }
.sc-detail-msg { color: var(--text-dim); text-align: center; padding: 1rem; font-size: max(var(--text-floor), 0.85rem); }

/* diamond-hands hold bonus chip + Send Call rules list */
.sc-hold { font-size: max(var(--text-floor), 0.74rem); font-weight: 800; color: var(--green-bright); background: color-mix(in srgb, var(--green-bright) 10%, transparent); border: 1px solid color-mix(in srgb, var(--green-bright) 30%, transparent); border-radius: 10px; padding: 0.35rem 0.6rem; margin-top: 0.5rem; }
.sc-explain p { margin: 0 0 0.5rem; }
.sc-explain p:last-child { margin-bottom: 0; }
.sc-explain-h { color: var(--text) !important; font-size: max(var(--text-floor), 0.85rem); }
.sc-rules { margin: 0 0 0.5rem; padding-left: 1.15rem; display: grid; gap: 0.4rem; }
.sc-rules li { line-height: 1.5; }
.sc-rules b { color: var(--text); }
.sc-explain-note { color: var(--gold) !important; font-weight: 700; }
.ge-var { color: #8ad4ff; font-weight: 800; }

/* Send Call daily allowance card (gamify dashboard) */
.g-callcap { background: linear-gradient(180deg, color-mix(in srgb, var(--green) 8%, transparent), transparent); border: 1.5px solid color-mix(in srgb, var(--green) 38%, transparent); border-radius: 12px; padding: 0.75rem 0.85rem; margin: 0.6rem 0; }
.gcc-head { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; margin-bottom: 0.5rem; }
.gcc-title { font-weight: 800; color: var(--text); }
.gcc-count { font-variant-numeric: tabular-nums; color: var(--text-dim); font-weight: 700; }
.gcc-count b { color: var(--green-bright); font-size: max(var(--text-floor), 1.15em); }
.gcc-bar { height: 8px; border-radius: 6px; background: var(--glass-sheen); overflow: hidden; }
.gcc-bar span { display: block; height: 100%; background: linear-gradient(90deg, var(--green-dark), var(--green-bright)); border-radius: 6px; transition: width 0.4s ease; }
.gcc-note { margin: 0.5rem 0 0.35rem; color: var(--text-dim); font-size: max(var(--text-floor), 0.88rem); line-height: 1.35; }
.gcc-boost { margin: 0; font-size: max(var(--text-floor), 0.88rem); color: var(--text); }

/* Read-only redemption CTA — buy & hold $SEND to lift a restriction early */
.ro-redeem { margin-top: 0.75rem; padding: 0.75rem 0.85rem; border-radius: 10px; background: color-mix(in srgb, var(--green) 9%, transparent); border: 1.5px solid color-mix(in srgb, var(--green) 42%, transparent); }
.ro-redeem-h { margin: 0 0 0.3rem; font-weight: 800; color: var(--green-bright); }
.ro-redeem-t { margin: 0 0 0.65rem; font-size: max(var(--text-floor), 0.86rem); color: var(--text-dim); line-height: 1.45; }
.ro-redeem .btn { width: 100%; }

/* Probation banner — holding the bought $SEND to clear a lifted restriction (sell early → doubled) */
#probation-bar { background: linear-gradient(90deg, color-mix(in srgb, var(--green) 18%, transparent), color-mix(in srgb, var(--green) 6%, transparent)); border-bottom: 2px solid color-mix(in srgb, var(--green) 50%, transparent); padding: 0.6rem 1rem; }
.pb-inner { max-width: 900px; margin: 0 auto; display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; }
.pb-badge { font-family: 'Luckiest Guy', cursive; color: var(--green-bright); white-space: nowrap; }
.pb-msg { flex: 1; min-width: 220px; font-size: max(var(--text-floor), 0.86rem); color: var(--text); line-height: 1.35; }
.pb-countdown { font-variant-numeric: tabular-nums; font-weight: 800; color: var(--on-green); background: var(--green); padding: 0.22rem 0.65rem; border-radius: 999px; white-space: nowrap; }

/* Send Call SIZE row — how much $ the caller & followers put in on-chain */
.sc-size { display: flex; flex-wrap: wrap; gap: 0.35rem 0.9rem; margin: 0.5rem 0; padding: 0.5rem 0.7rem; background: var(--g-wash); border: 1px solid color-mix(in srgb, var(--green) 28%, transparent); border-radius: 9px; font-size: max(var(--text-floor), 0.84rem); }
.sc-size-item { color: var(--text-dim); white-space: nowrap; }
.sc-size-item b { color: var(--text); }
.sc-size-total b { color: var(--green-bright); }
.sc-size-mult { color: #ffcf3f; font-style: normal; font-weight: 800; }

/* Send Call "who else Sent It": one block per sender.
   Line one is who (avatar, 💎 level, @name, OG). It never shrinks below its own width, so the name is never squeezed
   into a column one letter wide; only a name longer than the whole row wraps. Line two is what they did; each figure
   stays whole and the set wraps as a group. Line three is what others said (🔥 🚀 💬), with the thread under it.
   The box is a size container, so the layout follows the room the card has rather than the window: a card in a 640px
   feed at the text floor's largest size holds only a phone's worth of characters. */
/* The avatar grows with the text (a 20px disc beside a 25px name read as a dot). Registered as a length so the em is
   resolved once, on the row, and every child (the disc, its glyph, the indents) gets the same pixels. */
@property --sc-ava { syntax: '<length>'; inherits: true; initial-value: 20px; }
.sc-senders { margin: 0.5rem 0; padding: 0.55rem 0.7rem; background: var(--g-wash); border: 1px solid var(--hair); border-radius: 10px; container: sc-senders / inline-size; }
.sc-senders-head { font-size: max(var(--text-floor), 0.85rem); font-weight: 700; color: var(--text-dim); margin-bottom: 0.2rem; }
.sc-senders-head b { color: var(--green-bright); }
.sc-senders-sub { font-weight: 400; }
.sc-senders-list { list-style: none; margin: 0; padding: 0; display: grid; }
.sc-sender { display: grid; gap: 0.3rem; font-size: max(var(--text-floor), 0.82rem); min-width: 0; padding: 0.45rem 0; --sc-ava: max(20px, 1.2em); }
.sc-sender + .sc-sender { border-top: 1px solid var(--hair); }
.sc-sender-out .sc-sender-main { opacity: 0.72; }
.sc-sender-main { display: flex; flex-wrap: wrap; align-items: center; gap: 0.2rem 0.6rem; min-width: 0; }
.sc-sender-diamond { flex: 0 0 auto; font-size: max(var(--text-floor), 0.74rem); font-weight: 800; color: #7fd3ff; background: rgba(93,201,255,0.14); border-radius: 999px; padding: 0.02rem 0.32rem; white-space: nowrap; }
.sc-sender-stats { display: flex; flex-wrap: wrap; align-items: center; gap: 0.2rem 0.6rem; margin-left: auto; min-width: 0; max-width: 100%; }
.sc-sender-stats > * { flex: 0 0 auto; white-space: nowrap; }
.sc-sender-pnl { font-weight: 800; }
.sc-sender-pnl.sc-up { color: var(--green-bright); } .sc-sender-pnl.sc-down { color: var(--red); } .sc-sender-pnl.sc-flat { color: var(--text-dim); }
.sc-sender-hold { font-weight: 700; }
.sc-sender-hold.sc-holding { color: #7fd3ff; } .sc-sender-hold.sc-soldout { color: var(--red); } .sc-sender-hold.sc-nobuy { color: var(--text-dim); }
.sc-sender-when { color: var(--text-dim); }
.sc-sender-who { display: flex; flex-wrap: wrap; align-items: center; gap: 0.15rem 0.35rem; text-decoration: none; color: var(--text); flex: 1 0 auto; min-width: 0; max-width: 100%; }
.sc-sender-who:hover .sc-sender-name, .sc-sender-who:focus-visible .sc-sender-name { text-decoration: underline; }
.sc-sender-ava { width: var(--sc-ava); height: var(--sc-ava); border-radius: 50%; flex: 0 0 auto; object-fit: cover; }
.sc-sender-ava-emoji { display: inline-flex; align-items: center; justify-content: center; font-size: max(var(--text-floor), 0.95rem); background: var(--g-wash); line-height: 1; }
/* at most the row less the avatar, so a long name keeps its place beside the avatar and the badges after it wrap */
.sc-sender-name { font-weight: 700; flex: 0 1 auto; min-width: 0; max-width: calc(100% - var(--sc-ava) - 0.35rem); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sc-sender-mc { color: var(--text-dim); }
.sc-sender-mc b { color: var(--text); }
.sc-sender-sent { color: var(--text-dim); }
.sc-sender-sent b { color: var(--green-bright); }
/* the reactions and the comment toggle, lined up under the name */
.sc-sender-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; padding-left: calc(var(--sc-ava) + 0.35rem); }
.sc-sbtn { display: inline-flex; align-items: center; gap: 0.25rem; min-height: 32px; padding: 0.1rem 0.65rem; border: 1px solid var(--edge-ctl); border-radius: var(--r-pill); background: transparent; color: var(--text); font-family: inherit; font-size: max(var(--text-floor), 0.8rem); font-weight: 700; line-height: 1.2; cursor: pointer; }
.sc-sbtn:hover { border-color: var(--green); }
.sc-sbtn:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 2px; }
.sc-sbtn.on, .sc-sbtn[aria-expanded="true"] { border-color: var(--green); background: var(--g-tint); }
/* yours, said in shape as well as colour: a border twice as thick (the padding gives the pixel back, so nothing moves) */
.sc-sbtn.on { border-width: 2px; padding: calc(0.1rem - 1px) calc(0.65rem - 1px); }
.sc-sbtn[disabled] { opacity: 0.6; cursor: default; }
.sc-sbtn-n { font-variant-numeric: tabular-nums; }
/* the thread under one sender */
.sc-thread { display: grid; gap: 0.45rem; margin-left: calc(var(--sc-ava) + 0.35rem); padding: 0.4rem 0 0.15rem 0.6rem; border-left: 2px solid var(--hair); min-width: 0; }
.sc-thread[hidden], .sc-thread-list[hidden] { display: none; }
.sc-thread-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.45rem; }
.sc-cmt { display: flex; align-items: flex-start; gap: 0.4rem; min-width: 0; --sc-ava: max(20px, 1.1em); }
.sc-cmt-body { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; line-height: 1.4; }
.sc-cmt-who { font-weight: 700; color: var(--text); text-decoration: none; }
.sc-cmt-who:hover, .sc-cmt-who:focus-visible { text-decoration: underline; }
.sc-cmt-when { color: var(--text-dim); font-size: max(var(--text-floor), 0.72rem); white-space: nowrap; }
.sc-cmt-report { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; align-self: flex-start; min-width: 24px; min-height: 24px; padding: 0 0.3rem; border: none; border-radius: 4px; background: none; color: var(--text-dim); font-size: max(var(--text-floor), 0.75rem); cursor: pointer; }
.sc-cmt-report:hover { color: var(--red); }
.sc-cmt-report:focus-visible { outline: 2px solid var(--green-bright); }
.sc-cmt-report[aria-pressed="true"] { opacity: 0.55; }
.sc-thread-msg { margin: 0; color: var(--text-dim); font-size: max(var(--text-floor), 0.8rem); }
.sc-thread-form { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; }
.sc-thread-lbl { display: flex; flex: 1 1 12em; min-width: 0; }
.sc-thread-input { flex: 1 1 auto; width: 100%; min-width: 0; min-height: 32px; padding: 0.3rem 0.6rem; border: 1px solid var(--edge-ctl); border-radius: var(--r-2); background: var(--ink-1); color: var(--text); font-family: inherit; font-size: max(var(--text-floor), 0.85rem); }
.sc-thread-input:focus { border-color: var(--green); }
.sc-thread-input:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 1px; }
@media (pointer: coarse) {
  .sc-sbtn, .sc-thread-input { min-height: 44px; }
  .sc-cmt-report { min-width: 44px; min-height: 44px; }   /* a thumb-sized flag in its own column, clear of the comment's text */
  .sc-thread-input { font-size: max(var(--text-floor), max(16px, 1em)); }   /* under 16px, iOS Safari zooms the page into the field */
}
/* forced colours repaint every border and fill alike: the pressed and open states keep the system's highlight */
@media (forced-colors: active) {
  .sc-sbtn.on, .sc-sbtn[aria-expanded="true"] { background: Highlight; color: HighlightText; border-color: Highlight; }   /* system colours survive forcing, the focus ring included */
}
/* a narrow card: the figures take their own line, under the name */
@container sc-senders (max-width: 34em) { .sc-sender-stats { flex-basis: 100%; margin-left: 0; padding-left: calc(var(--sc-ava) + 0.35rem); } }
/* narrower still: no indent, every line gets the full width */
@container sc-senders (max-width: 20em) { .sc-sender-stats, .sc-sender-acts { padding-left: 0; } .sc-thread { margin-left: 0; } }
.sc-senders-toggle { margin-top: 0.45rem; background: var(--green); border: none; color: var(--on-green); font-weight: 700; font-size: max(var(--text-floor), 0.82rem); cursor: pointer; padding: 0.2rem 0.7rem; border-radius: var(--r-pill); }
.sc-senders-toggle:hover { background: var(--green-bright); }
.sc-senders-toggle:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--green-bright); border-radius: 4px; }

/* ============================================================
   COMMUNITIES — grid cards, detail hero, level bars, the wall
   ============================================================ */

/* --- start-a-community form (grid page hero) --- */
.comm-start { display: flex; gap: 0.6rem; max-width: 620px; margin: 0 auto; flex-wrap: wrap; }
.comm-start .addr-input { flex: 1; min-width: 220px; margin: 0; }
.comm-start-msg { text-align: center; color: var(--text-dim); font-size: max(var(--text-floor), 0.9rem); min-height: 1.2em; margin: 0.6rem auto 0; max-width: 620px; }
.comm-start-msg a { color: var(--green-bright); font-weight: 700; }
.comm-rules { max-width: 620px; margin: 1.1rem auto 0; }
.comm-rules-list { margin: 0.4rem 0 0.2rem 1.1rem; display: grid; gap: 0.5rem; padding: 0; }
.comm-rules-list li { line-height: 1.55; }

/* --- toolbar: tabs + sorts --- */
.comm-bar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 0.9rem; }
.comm-tabs { display: inline-flex; gap: 0.4rem; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 999px; padding: 0.25rem; }
.comm-tab {
  background: none; border: none; color: var(--ctl-ink); font-weight: 800; font-size: max(var(--text-floor), 0.9rem);
  padding: 0.5rem 1rem; border-radius: 999px; cursor: pointer; transition: all 0.15s ease; min-height: 40px;
}
.comm-tab:hover { color: var(--ctl-ink); background: var(--ctl-fill-hi); }
.comm-tab.is-on { background: var(--green); color: var(--on-green); }
.comm-tab:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--ctl-ink); }
.comm-sorts { display: inline-flex; gap: 0.4rem; flex-wrap: wrap; }
.comm-status { color: var(--text-dim); font-size: max(var(--text-floor), 0.88rem); margin: 0 0 1rem; min-height: 1.2em; }
.comm-status b { color: var(--text); }

/* --- the square grid --- */
.comm-grid { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); }   /* wide enough for a name and its LIVE pill at the floor size */
.comm-card {
  --comm-lift: 22px;   /* how far the body rises into the banner, so the logo straddles its bottom edge */
  border-radius: 20px; overflow: hidden; position: relative;   /* the card is as tall as its text (it was a fixed square, which clipped at the floor size) */
  background: linear-gradient(180deg, var(--ink-3), var(--ink-2)); border: 1px solid color-mix(in srgb, var(--green) 18%, transparent);
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.comm-card:hover { transform: translateY(-5px); box-shadow: 0 16px 40px rgba(0,0,0,0.5), 0 0 0 1px color-mix(in srgb, var(--green) 30%, transparent); border-color: var(--g-lit); }
.comm-card:focus-within { border-color: var(--green); box-shadow: 0 0 0 3px color-mix(in srgb, var(--green) 40%, transparent); }
.comm-card-link { display: flex; flex-direction: column; height: 100%; text-decoration: none; color: var(--text); outline: none; }
/* the card link keeps the global focus ring */
.comm-card-banner {
  display: block; flex: 0 0 120px; background-size: cover; background-position: center; position: relative;
  border-bottom: 1px solid rgba(0,0,0,0.4);
}
.comm-card-banner::after { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, color-mix(in srgb, var(--ink) calc(0.05 * 100%), transparent), color-mix(in srgb, var(--ink-2) calc(0.85 * 100%), transparent)); }
.comm-card-banner-none, .comm-hero-banner:not(.has-img) { background: radial-gradient(120% 120% at 30% 20%, color-mix(in srgb, var(--green) 28%, transparent), var(--ink-3) 70%); }
.comm-card-body { flex: 1; display: flex; flex-direction: column; gap: 0.5rem; padding: 0 0.9rem 0.85rem; margin-top: calc(-1 * var(--comm-lift)); position: relative; z-index: 1; }
/* The logo straddles the banner's edge; the symbol and name sit beside it, starting BELOW that edge. They used to be
   bottom-aligned with the 46px logo, and at the larger text sizes the two lines are taller than it, so "$SEND" rode
   up into the banner (22px at desktop width, 17px on every card on a phone). A long name wraps in its own column. */
.comm-card-head { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start; column-gap: 0.55rem; }
.comm-card-logo {
  width: 46px; height: 46px; border-radius: 13px; object-fit: cover; flex-shrink: 0;
  border: 2.5px solid var(--ink-2); background: var(--ink-4); box-shadow: 0 4px 12px rgba(0,0,0,0.5);
}
.comm-card-logo-none { display: grid; place-items: center; font-size: max(var(--text-floor), 1.5rem); }
.comm-card-id { min-width: 0; padding-top: calc(var(--comm-lift) + 0.3rem); }
.comm-card-sym { display: block; font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.15rem); color: var(--green-bright); letter-spacing: 0.02em; line-height: 1.1; overflow-wrap: anywhere; }
.comm-card-name { display: block; font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.comm-card-metrics { display: grid; grid-template-columns: 1fr 1fr; gap: 0.3rem 0.5rem; font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); margin-top: auto; }
.comm-card-metrics b { color: var(--text); font-weight: 800; }
.comm-card-metrics .price-chip { font-size: max(var(--text-floor), 0.76rem); padding: 0.1rem 0.45rem; }
.comm-card-foot { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; flex-wrap: wrap; }   /* the LIVE pill takes its own line when the card is narrow */

/* pill + activity pulse (shared grid + detail) */
.comm-pill { font-size: max(var(--text-floor), 0.72rem); font-weight: 800; padding: 0.22rem 0.6rem; border-radius: 1.1em; max-width: 100%; text-align: center; }   /* 1.1em: a full pill on one line; a wrapped one is a rounded box whose centred lines stay clear of its corners */   /* a long pill (the sandbox one) wraps inside its card rather than running out of it */
.comm-pill-live { background: color-mix(in srgb, var(--green) 16%, transparent); color: var(--green-bright); border: 1px solid color-mix(in srgb, var(--green) 40%, transparent); }
.comm-pill-pending { background: rgba(255,179,64,0.14); color: var(--gold); border: 1px solid rgba(255,179,64,0.35); }
.comm-pulse { display: inline-flex; align-items: center; gap: 0.35rem; font-size: max(var(--text-floor), 0.74rem); font-weight: 800; color: var(--text-dim); }
.comm-pulse i { width: 8px; height: 8px; border-radius: 50%; background: currentColor; box-shadow: 0 0 0 0 currentColor; }
.comm-pulse.tier-dormant { color: #96a6c0; } /* AA-contrast on the card/hero backgrounds while staying visibly dimmer than active tiers */
.comm-pulse.tier-warm { color: var(--gold); }
.comm-pulse.tier-active { color: var(--green); }
.comm-pulse.tier-hot { color: var(--green-bright); }
.comm-pulse.tier-blazing { color: #ff7a2b; }
.comm-pulse.tier-active i, .comm-pulse.tier-hot i, .comm-pulse.tier-blazing i { animation: comm-ping 1.6s ease-out infinite; }
@keyframes comm-ping { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--green) 50%, transparent); } 70% { box-shadow: 0 0 0 7px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }

/* go-live progress bar (grid card foot) */
.comm-golive { display: block; height: 5px; border-radius: 999px; background: var(--ink); overflow: hidden; }
.comm-golive-fill { display: block; height: 100%; background: linear-gradient(90deg, var(--gold-deep), var(--gold)); border-radius: 999px; }

/* ---------- detail page ---------- */
.comm-hero { padding: 0; overflow: hidden; margin-bottom: 1.4rem; }
.comm-hero-banner { height: 150px; background-size: cover; background-position: center; border-bottom: 1px solid rgba(0,0,0,0.35); }
/* no banner image → a shorter brand band, so the empty state reads as a header rather than 150px of void.
   (`:empty` cannot tell them apart: the div never has child nodes either way — hence the explicit modifier.) */
.comm-hero-banner:not(.has-img) { height: 90px; }
/* The name and subtitle used to be pulled up ON TOP of the banner image, where a busy banner made them hard to
   read — and for a community with NO banner the same offset pulled them into nothing, so the card's overflow:hidden
   clipped the name away entirely. Now only the LOGO overlaps (it is opaque, so it always reads), and every word of
   the identity block sits below the image. */
.comm-hero-body { padding: 1rem 1.3rem 1.3rem; position: relative; }
.comm-hero-top { display: flex; align-items: flex-start; gap: 0.9rem; flex-wrap: wrap; }   /* top-aligned: a name that wraps to two lines no longer drags the logo down the card */
.comm-hero-logo {
  width: 86px; height: 86px; border-radius: 20px; object-fit: cover; flex-shrink: 0;
  border: 4px solid var(--ink-2); background: var(--ink-4); box-shadow: 0 6px 18px rgba(0,0,0,0.55);
}
.comm-hero-logo-none { display: grid; place-items: center; font-size: max(var(--text-floor), 2.6rem); }
.comm-hero-id { flex: 1 1 240px; min-width: 0; padding-bottom: 4px; }   /* min-width:0 so a long name wraps instead of forcing the row wider than the card */
.comm-hero-name { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), clamp(1.5rem, 4.5vw, 2.1rem)); color: var(--text); margin: 0; line-height: 1.2; overflow-wrap: anywhere; }   /* line-height 1.2: at 1.1 the ascenders of this face were shaved by the overflow */
.comm-hero-name b { color: var(--green-bright); }
.comm-hero-sub { color: var(--text-dim); font-size: max(var(--text-floor), 0.9rem); margin: 0.3rem 0 0; overflow-wrap: anywhere; }
.comm-hero-metrics { display: flex; flex-wrap: wrap; gap: 0.5rem 1.1rem; margin: 1rem 0; color: var(--text-dim); font-size: max(var(--text-floor), 0.92rem); font-weight: 600; }
.comm-hero-metrics b { color: var(--text); font-weight: 800; }
.comm-hero-status { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; margin-bottom: 0.4rem; }
.comm-hero-actions { margin: 0.4rem 0 0.2rem; }
.comm-join-btn { width: 100%; }
.comm-2x-badge {
  align-self: center; background: linear-gradient(180deg, var(--green-bright), var(--green-dark)); color: var(--on-green);
  font-weight: 900; font-size: max(var(--text-floor), 0.82rem); padding: 0.4rem 0.8rem; border-radius: 999px; white-space: nowrap;
  box-shadow: 0 0 18px color-mix(in srgb, var(--green) 40%, transparent);
}

/* go-live panel (pending detail) */
.comm-golive-panel { background: var(--ink); border: 1.5px dashed rgba(255,179,64,0.4); border-radius: 14px; padding: 1rem 1.1rem; margin: 0.6rem 0; }
.comm-golive-head { font-size: max(var(--text-floor), 1.05rem); font-weight: 700; color: var(--text); margin-bottom: 0.6rem; }
.comm-golive-head b { color: var(--gold); }
.comm-golive-panel .gxp { margin: 0; --bar-h: 20px; }
.comm-golive-panel .gxp-fill { background: linear-gradient(90deg, var(--gold-deep), var(--gold)); }

/* level bars (community + conviction) */
.comm-xp { margin: 0.9rem 0; }
.comm-xp-head { display: flex; align-items: baseline; justify-content: space-between; font-weight: 700; font-size: max(var(--text-floor), 0.92rem); color: var(--text); margin-bottom: 0.3rem; }
.comm-xp-head b { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.05rem); letter-spacing: 0.03em; }
.comm-xp .gxp { margin: 0; --bar-h: 22px; }
.comm-xp-sub { font-size: max(var(--text-floor), 0.78rem); color: var(--text-dim); margin-top: 0.25rem; text-align: right; }
.comm-xp-community .gxp-fill { background: linear-gradient(90deg, var(--green-dark), var(--green-bright)); }
.comm-xp-community .comm-xp-head b { color: var(--green-bright); }
.comm-xp-conv .gxp-fill { background: linear-gradient(90deg, #7a3bd0, #c07bff); }
.comm-xp-conv .comm-xp-head { color: #d9b8ff; }
.comm-xp-conv .comm-xp-head b { color: #c07bff; }

/* wall lock + composer + comments */
.comm-wall { max-width: 640px; margin: 0 auto; }
.comm-wall-locked {
  text-align: center; color: var(--text-dim); font-size: max(var(--text-floor), 0.95rem); line-height: 1.6;
  background: var(--ink); border: 1.5px dashed var(--ink-4); border-radius: 14px; padding: 1.1rem 1.2rem; margin-bottom: 1.4rem;
}
.comm-wall-locked b { color: var(--text); }
.comm-cmt-zone { margin-top: 0.7rem; border-top: 1px solid var(--ink-4); padding-top: 0.7rem; display: grid; gap: 0.5rem; }
.comm-cmt { font-size: max(var(--text-floor), 0.9rem); line-height: 1.45; }
.comm-cmt .c-who { color: var(--green-bright); font-weight: 800; text-decoration: none; }
.comm-cmt .c-text { color: var(--text); }
.comm-cmt-form { display: flex; gap: 0.5rem; margin-top: 0.2rem; }
.comm-cmt-form .addr-input { flex: 1; margin: 0; font-size: max(var(--text-floor), 0.9rem); padding: 0.6rem 0.8rem; }

/* conviction badge on the public wall's Convicted-In chips */
.conv-badge {
  display: inline-flex; align-items: center; gap: 0.2rem; margin-left: 0.35rem; vertical-align: middle;
  background: linear-gradient(180deg, #7a3bd0, #4a1e8a); color: #eddfff; font-weight: 800; font-size: max(var(--text-floor), 0.68rem);
  padding: 0.08rem 0.42rem; border-radius: 999px; border: 1px solid rgba(192,123,255,0.5); white-space: nowrap;
  text-decoration: none; transition: transform 0.12s ease, box-shadow 0.12s ease;
}
a.conv-badge:hover { transform: translateY(-1px); box-shadow: 0 3px 10px rgba(122,59,208,0.5); text-decoration: none; }
a.conv-badge:focus-visible { outline: none; box-shadow: 0 0 0 2px #c07bff; }

/* gamify dashboard: community 2x chip */
.eq-comm { background: color-mix(in srgb, var(--green) 16%, transparent) !important; color: var(--green-bright) !important; border-color: color-mix(in srgb, var(--green) 40%, transparent) !important; }

@media (prefers-reduced-motion: reduce) {
  .comm-card { transition: none; }
  .comm-card:hover { transform: none; }
  .comm-pulse i { animation: none !important; }
  .comm-mini { transition: border-color 0.15s ease; }
  .comm-mini:hover { transform: none; }
  a.conv-badge { transition: box-shadow 0.12s ease; }
  a.conv-badge:hover { transform: none; }
}
@media (max-width: 560px) {
  /* let the card grow to fit head + metrics + foot + go-live bar instead of clipping them inside a fixed square */
  .comm-card { aspect-ratio: auto; min-height: 220px; }
  .comm-card-banner { flex: 0 0 96px; }
  .comm-card-foot { flex-wrap: wrap; row-gap: 0.35rem; } /* status pill drops to its own line rather than being clipped on a narrow 2-col phone grid */
  .comm-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr)); gap: 0.8rem; }
  .comm-card-sym { font-size: max(var(--text-floor), 1rem); }
  .comm-card-metrics { font-size: max(var(--text-floor), 0.76rem); }
  .comm-tab { min-height: 44px; }
}

/* gamify dashboard: community & conviction block */
.comm-block { background: linear-gradient(100deg, color-mix(in srgb, var(--green) 16%, transparent), color-mix(in srgb, var(--green) 5%, transparent)); border-color: color-mix(in srgb, var(--green) 50%, transparent); align-items: flex-start; flex-direction: column; }
.comm-block .og-block-body { width: 100%; }
.comm-block .og-block-body b { color: var(--green-bright); }
.comm-block-badge { background: linear-gradient(180deg, var(--green-bright), var(--green-dark)) !important; color: var(--on-green) !important; box-shadow: 0 0 12px color-mix(in srgb, var(--green) 50%, transparent) !important; }
.comm-invite .og-block-body b { color: var(--green-bright); }
.comm-mini-grid { display: grid; gap: 0.7rem; grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr)); margin-top: 0.8rem; }
.comm-mini { display: block; background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 12px; padding: 0.7rem 0.8rem; text-decoration: none; color: var(--text); transition: border-color 0.15s ease, transform 0.15s ease; }
.comm-mini:hover { border-color: var(--green); transform: translateY(-2px); text-decoration: none; }
.comm-mini:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--green-bright); }
.comm-mini-head { font-size: max(var(--text-floor), 0.95rem); margin-bottom: 0.3rem; }
.comm-mini-head b { color: var(--green-bright); font-family: 'Luckiest Guy', cursive; letter-spacing: 0.02em; }
.comm-mini-name { color: var(--text-dim); font-size: max(var(--text-floor), 0.82rem); }
.comm-mini .comm-xp { margin: 0.45rem 0 0; }
.comm-mini .comm-xp .gxp { --bar-h: 16px; }
.comm-mini .comm-xp-head { font-size: max(var(--text-floor), 0.82rem); }
.comm-mini .comm-xp-head b { font-size: max(var(--text-floor), 0.9rem); }

/* community holder-gate notice */
.comm-gate-msg { margin: 0.5rem 0 0; padding: 0.6rem 0.8rem; background: rgba(255,179,64,0.12); border: 1.5px solid rgba(255,179,64,0.4); border-radius: 12px; color: var(--text); font-size: max(var(--text-floor), 0.88rem); line-height: 1.5; }
.comm-gate-msg .linklike { font-size: max(var(--text-floor), 0.88rem); }

/* ===== Community members roster (public; ranked by community member level) ===== */
.comm-members { margin: 0.9rem 0; padding: 1rem 1.1rem 0.8rem; }
.comm-members-h { display: flex; align-items: baseline; gap: 0.45rem; flex-wrap: wrap; margin: 0 0 0.2rem; font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.25rem); color: var(--green-bright); letter-spacing: 0.02em; }
.comm-members-sub { font-family: 'Rubik', sans-serif; font-weight: 700; font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); letter-spacing: 0; }
.comm-members-note { margin: 0 0 0.7rem; }
.comm-members-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4rem; max-height: 22rem; overflow-y: auto; scrollbar-width: thin; }
.cm-row { display: flex; align-items: center; gap: 0.55rem; min-width: 0; padding: 0.45rem 0.6rem; background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 12px; }
.cm-row.cm-creator { border-color: rgba(255,179,64,0.45); }
.cm-rank { flex: 0 0 1.6rem; text-align: center; font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 0.95rem); color: var(--text-dim); }
.cm-ava { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%; object-fit: cover; background: var(--ink-3); display: inline-flex; align-items: center; justify-content: center; font-size: max(var(--text-floor), 1rem); }
.cm-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 800; font-size: max(var(--text-floor), 0.9rem); color: var(--text); text-decoration: none; }
.cm-name:hover, .cm-name:focus-visible { color: var(--green-bright); text-decoration: underline; }
.cm-crown { flex: 0 0 auto; font-size: max(var(--text-floor), 0.9rem); }
.cm-lvl { flex: 0 0 auto; margin-left: auto; white-space: nowrap; font-size: max(var(--text-floor), 0.74rem); font-weight: 800; color: var(--green-bright); background: color-mix(in srgb, var(--green) 12%, transparent); border: 1px solid color-mix(in srgb, var(--green) 30%, transparent); border-radius: 999px; padding: 0.18rem 0.55rem; }
@media (max-width: 480px) { .cm-lvl { font-size: max(var(--text-floor), 0.7rem); padding: 0.15rem 0.45rem; } .comm-members-h { font-size: max(var(--text-floor), 1.1rem); } }
.comm-2x-badge.comm-2x-off { background: rgba(255,179,64,0.12); border-color: rgba(255,179,64,0.45); color: var(--gold); box-shadow: none; } /* member whose holding can't currently be verified: 3× paused, not active */

/* 1281–1599px: the full 8-link inline nav + search must fit on ONE line beside the bell + (signed-in) account chip (audit #16 — no wrap;
   the base desktop sizing only fits signed-in from ~1600px) */
/* In the inline row the search is an icon that expands on focus as an OVERLAY (absolute, anchored right) — an in-flow
   expansion re-wrapped the row and moved the field out from under the cursor. In the pop-down it is a full-width field. */
.nav:not(.is-compact) .nav-search { position: relative; width: var(--nav-ctl); height: var(--nav-ctl); flex: 0 0 var(--nav-ctl); }
.nav:not(.is-compact) .nav-search input { width: var(--nav-ctl); padding-right: 0.2rem; }
.nav:not(.is-compact) .nav-search input::placeholder { color: transparent; }
.nav:not(.is-compact) .nav-search input:focus { position: absolute; right: 0; top: 50%; transform: translateY(-50%); width: max(240px, 19em); padding-right: 1rem; z-index: 5; }   /* wide enough for the whole "find Senders or Scan Tokens" */
.nav:not(.is-compact) .nav-search input:focus::placeholder { color: var(--text-dim); }
.nav:not(.is-compact) .nav-search .s-icon { z-index: 6; }

/* ===== Quest-board ⓘ toggles (audit #24: rules were hover-only; mobile has no hover) ===== */
.gearn-li { display: flex; align-items: center; gap: 0.35rem; }
.gearn-li > .gearn-row { flex: 1 1 auto; min-width: 0; }
.ge-info {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%; cursor: pointer;
  border: 1.5px solid var(--ctl-fill-lo); background: var(--ctl-fill-lo); color: var(--ctl-ink);
  font-weight: 800; font-size: max(var(--text-floor), 0.95rem); line-height: 1; display: inline-grid; place-items: center;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.ge-info:hover, .ge-info[aria-expanded="true"] { border-color: var(--green); background: var(--green); color: var(--on-green); }
.ge-info:focus-visible { outline: 3px solid var(--green-bright); outline-offset: 2px; }
.gearn-li.is-open .ge-tip { opacity: 1; transform: translateY(0); pointer-events: auto; }
@media (prefers-reduced-motion: reduce) { .ge-info { transition: none; } }

/* ===== Swap panel inline status (audit #43: errors were 2.6s toasts only) ===== */
.swap-status { color: var(--text-dim); }
.swap-status.is-error { color: var(--red); font-weight: 700; }
.swap-status.is-ok { color: var(--green-bright); font-weight: 700; }

/* ===== GIF pause/play control (WCAG 2.2.2 — every animated GIF in a post can be stopped) ===== */
.gif-wrap { position: relative; display: inline-block; max-width: 100%; }
.gif-toggle {
  position: absolute; right: 8px; bottom: 8px; width: 36px; height: 36px; border-radius: 50%; cursor: pointer;
  border: 1.5px solid var(--ctl-fill-hi); background: var(--ctl-fill-hi); color: var(--ctl-ink); font-size: max(var(--text-floor), 0.95rem); line-height: 1;
  display: grid; place-items: center; backdrop-filter: blur(4px);
}
.gif-toggle:hover { background: var(--green-bright); border-color: var(--green-bright); }
.gif-toggle:focus-visible { outline: 3px solid var(--green-bright); outline-offset: 2px; }

/* ===== Official ($Send / $GWC) communities: pinned strip + badge ===== */
.comm-officials { margin: 0.2rem 0 1.4rem; padding: 1rem 1rem 1.1rem; border-radius: 18px; background: linear-gradient(180deg, color-mix(in srgb, var(--green) 10%, transparent), color-mix(in srgb, var(--green) 3%, transparent)); border: 1.5px solid color-mix(in srgb, var(--green) 35%, transparent); }
.comm-officials-h { font-family: 'Luckiest Guy', cursive; color: var(--green-bright); font-size: max(var(--text-floor), 1.35rem); margin: 0 0 0.3rem; letter-spacing: 0.02em; }
.comm-officials-note { margin: 0 0 0.8rem; }
.comm-grid-official { margin: 0; }
.comm-pill-official { background: linear-gradient(180deg, var(--gold), var(--gold-deep)); color: var(--on-gold); border-color: transparent; }
.comm-card-official { box-shadow: 0 0 0 2px rgba(255,179,64,0.45), 0 10px 30px rgba(0,0,0,0.35); }
@media (max-width: 480px) { .comm-officials { padding: 0.8rem; } .comm-officials-h { font-size: max(var(--text-floor), 1.15rem); } }

/* ===== Composer mode switch: 🧱 Post to the Wall · 📣 Send Call (paste a contract address) ===== */
.cmp-modes { display: flex; gap: 0.35rem; padding: 0.25rem; margin: 0 0 0.8rem; background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); border-radius: 999px; }
.cmp-mode {
  flex: 1 1 0; min-width: 0; cursor: pointer; border: none; border-radius: 999px; padding: 0.55rem 0.6rem;
  background: transparent; color: var(--ctl-ink); font-family: 'Rubik', sans-serif; font-weight: 800; font-size: max(var(--text-floor), 0.9rem);
  min-height: 44px; transition: background 0.15s ease, color 0.15s ease;
}
.cmp-mode:hover { color: var(--ctl-ink); background: var(--ctl-fill-hi); }
.cmp-mode.is-on { background: linear-gradient(180deg, var(--green-bright), var(--green-dark)); color: var(--on-green); }
.cmp-mode:focus-visible { outline: 3px solid var(--ctl-ink); outline-offset: 2px; }
.cmp-nudge { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin: 0.5rem 0 0; padding: 0.5rem 0.7rem; border-radius: 12px; font-size: max(var(--text-floor), 0.85rem); color: var(--text-dim); background: rgba(255,179,64,0.1); border: 1.5px solid rgba(255,179,64,0.4); }
.cmp-call-preview:empty { display: none; }
.cmp-call-preview { margin: 0.6rem 0; }
/* Opt-in to publishing your wallet on a Send Call. Deliberately quiet — it is a choice, not a prompt. */
.cmp-call-share { display: flex; align-items: flex-start; gap: 0.55rem; margin: 0.6rem 0 0; font-size: max(var(--text-floor), 0.86rem); line-height: 1.45; color: var(--muted); cursor: pointer; }
.cmp-call-share input { margin-top: 0.2rem; flex: none; accent-color: var(--accent); }
.cmp-call-share small { display: block; font-size: max(var(--text-floor), 0.78rem); opacity: 0.85; }
.cmp-call-tok { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; padding: 0.7rem; border-radius: 14px; background: var(--ink-2); border: 1.5px solid var(--ink-4); }
.cmp-call-logo { width: 40px; height: 40px; border-radius: 50%; flex: 0 0 auto; object-fit: cover; }
.cmp-call-logo-none { display: grid; place-items: center; background: var(--ink-3); font-size: max(var(--text-floor), 1.2rem); }
.cmp-call-id { display: flex; flex-direction: column; min-width: 0; }
.cmp-call-id b { color: var(--green-bright); font-size: max(var(--text-floor), 1.05rem); }
.cmp-call-name { color: var(--text-dim); font-size: max(var(--text-floor), 0.8rem); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmp-call-stats { display: flex; gap: 0.8rem; flex-wrap: wrap; margin-left: auto; font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); }
.cmp-call-stats b { color: var(--text); }
.cmp-call-warn { color: var(--gold); }
@media (prefers-reduced-motion: reduce) { .cmp-mode { transition: none; } }
@media (max-width: 480px) { .cmp-call-stats { margin-left: 0; width: 100%; } }

/* ===== Wallet-tracker hand-off card on the Watchlist page (moved out of tracker.css so watchlist.html
   no longer downloads the whole 12 KB tracker sheet for five rules) ===== */
.addr-input[aria-invalid="true"] { border-color: var(--red); }
.wl-trk-card { display: flex; align-items: center; justify-content: center; gap: 0.6rem 1rem; flex-wrap: wrap; text-align: left; padding: 0.9rem 1rem; margin: 0 0 1rem; }
.wl-trk-card b { color: var(--text); }
.wl-trk-card .btn { flex: 0 0 auto; }
@media (max-width: 480px) { .wl-trk-card { flex-direction: column; align-items: stretch; text-align: center; } }

/* ===== Send Power boost in the nav level badge (⚡N× beside Lv N — the multiplier every point is paid at) ===== */
.nav-xp-boost { color: var(--gold); font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; }
.nav-xp-boost::before { content: ''; }
@media (max-width: 700px) { .nav-xp-boost { font-size: var(--nav-fs-s); } }

/* ===== 📈 live chart inside a token's on-chain detail (New Pairs list + feed, lookup, token popup,
   Send Call widget, watchlist). One embed per open detail; loading="lazy" keeps offscreen ones idle. ===== */
.np-chart { position: relative; border: 1.5px solid var(--ink-4); border-radius: 12px; overflow: hidden; background: var(--ink); }
.np-chart-frame { display: block; width: 100%; height: 320px; border: 0; background: var(--ink); }
.np-chart-note { margin: 0.45rem 0 0; font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); }
.np-chart-note a { color: var(--green-bright); }
@media (max-width: 640px) { .np-chart-frame { height: 260px; } }

/* ===== 📣 Send Call straight from a DEX-list row =====
   Two-press: the first press arms it (turns green, reads "Sure?"), the second posts. A Send Call is permanent,
   so a single stray tap on a dense row must never be able to make one. */
.np-row-call { background: var(--ctl-fill-lo); border: none; cursor: pointer; color: var(--ctl-ink); font-size: max(var(--text-floor), 1.05rem); line-height: 1;
  padding: 0.3rem; border-radius: 8px; flex-shrink: 0; min-width: 40px; min-height: 40px; white-space: nowrap; }
.np-row-call:hover { color: var(--ctl-ink); background: var(--ctl-fill-hi); }
.np-row-call:focus-visible { outline: 2px solid var(--green-bright); outline-offset: 2px; }
.np-row-call.is-armed { color: var(--on-green); background: var(--green-bright); font-size: max(var(--text-floor), 0.78rem); font-weight: 700; padding: 0.3rem 0.5rem; }
.np-row-call[disabled] { background: var(--ctl-fill-dis); color: var(--ctl-ink); cursor: not-allowed; }
@media (max-width: 600px) { .np-row-call { min-width: 44px; min-height: 44px; } }

/* ══════════════════════════════════════════════════════════════════════════
   CYPHERPUNK SYNTHWAVE OVERHAUL
   Appended deliberately: every rule below is a visual override of something
   defined earlier. Nothing here changes markup, behaviour or class names, so
   deleting this whole block returns the site to its previous appearance.
   ══════════════════════════════════════════════════════════════════════════ */

/* ---------- 1. The world: horizon grid + scanlines ----------
   Both live on body pseudo-elements that were previously unused, so no DOM is
   added. They are position:fixed and pointer-events:none, and they animate
   TRANSFORM only — never background-position, which would repaint the whole
   viewport every frame forever. */
body {
  /* The two washes were violet (#191036 / #230f3a) — the last and largest thing on the page still
     painting the old identity, sitting behind every screen at full viewport size. Re-cast into the
     brand's own family: a deep green-black at the top, a warmer one at the foot. Kept as literals rather
     than derived from --green, because prefs.js live-overrides the accent per reader and the WORLD
     should not change colour when somebody picks a different highlight. */
  background:
    radial-gradient(120% 80% at 50% 0%,   #0b1107 0%, transparent 60%),
    radial-gradient(100% 70% at 50% 100%, #0f1509 0%, transparent 62%),
    var(--void);
  font-family: var(--font-body);
}
body::before {
  content: ''; position: fixed; left: -50%; right: -50%; bottom: -10%; height: 62vh;
  z-index: -2; pointer-events: none;
  background-image:
    repeating-linear-gradient(to right,  var(--grid-line) 0 1px, transparent 1px var(--grid-gap)),
    repeating-linear-gradient(to bottom, var(--grid-line-2) 0 1px, transparent 1px var(--grid-gap));
  transform: perspective(var(--grid-persp)) rotateX(var(--grid-tilt)) translateZ(0);
  transform-origin: 50% 100%;
  mask-image: linear-gradient(to top, #000 0%, rgba(0,0,0,0.35) 45%, transparent 88%);
  -webkit-mask-image: linear-gradient(to top, #000 0%, rgba(0,0,0,0.35) 45%, transparent 88%);
  animation: sw-grid 18s linear infinite;
  will-change: transform;
}
body::after {
  content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: repeating-linear-gradient(to bottom, var(--scan) 0 1px, transparent 1px var(--scan-period));
  opacity: 0.55;
}
@keyframes sw-grid {
  from { transform: perspective(var(--grid-persp)) rotateX(var(--grid-tilt)) translate3d(0, 0, 0); }
  to   { transform: perspective(var(--grid-persp)) rotateX(var(--grid-tilt)) translate3d(0, var(--grid-gap), 0); }
}

/* ---------- 2. Glass chrome ----------
   backdrop-filter is expensive, so it is spent only on chrome and overlays.
   List items (.post, .np-row, .lb-row, .comm-card) get the glass LOOK — sheen,
   rim, gradient — and no blur, which keeps a long feed cheap to scroll. */
.nav {
  background: linear-gradient(180deg, var(--glass-sheen), transparent 38%), var(--glass-nav);
  backdrop-filter: blur(var(--blur)) saturate(var(--sat));
  -webkit-backdrop-filter: blur(var(--blur)) saturate(var(--sat));
  border-bottom: 1px solid var(--g-edge);
  box-shadow: 0 1px 0 var(--hair), var(--shadow-1);
}
.card {
  position: relative;
  background: linear-gradient(180deg, var(--glass-sheen), transparent 38%), var(--glass-hi);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: 1px solid var(--g-edge);
  border-radius: var(--r-4);
  box-shadow: var(--shadow-2), inset 0 1px 0 var(--glass-edge);
}
.post, .np-row, .lb-row, .comm-card, .gearn-row, .wallet-row {
  background: linear-gradient(180deg, var(--glass-sheen), transparent 46%), var(--glass-lo);
  border-color: var(--hair);
}

/* ---------- 3. Neon, spent sparingly ----------
   Glow is reserved for the display face and for primary actions. Applying it to
   body copy is what makes neon designs unreadable, so it is scoped by class. */
.display, .section-title.display {
  text-shadow:
    0 0 var(--glow-1) var(--glow-g),
    0 0 var(--glow-3) color-mix(in srgb, var(--green) 30%, transparent);
}
.btn-primary {
  border: 1px solid color-mix(in srgb, var(--green-bright) 70%, var(--green) 30%);
  box-shadow:
    0 6px 0 var(--green-dark),
    0 10px 28px var(--glow-g),
    inset 0 1px 0 color-mix(in srgb, var(--green-bright) 70%, transparent);
}
.btn-primary:hover { box-shadow: 0 6px 0 var(--green-dark), 0 14px 40px var(--glow-g), inset 0 1px 0 color-mix(in srgb, var(--green-bright) 85%, transparent); }

/* ---------- 4. Control boundaries (WCAG 1.4.11) ----------
   --ink-4 is decorative from here on. Anything focusable or clickable that was
   bordered with it fails 3:1 against our surfaces (.btn-ghost was 1.34:1), so
   interactive edges move to --edge-ctl, which clears it at 4.29:1. */
.np-controls, .np-search,
.pin-chip, .gd-bar, .notif-panel, .sc-widget, .sc-x-max, .np-feed-hint {
  border-color: var(--edge-ctl);
}
/* (.btn-ghost, .intro-skip, .np-viewswitch, .cmp-modes, .np-row-call are light pills now — the fill itself clears 3:1) */
.pin-chip:hover { border-color: var(--edge-ctl-lit); }

/* ---------- 5. Focus ----------
   Pinned to --focus (== --text), never to the accent. prefs.js lets a user set
   the accent to any colour including one invisible against glass; the focus
   ring has to survive that, so it is deliberately outside the themable set.
   The halo guarantees the ring reads against neon, glass and video alike. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  box-shadow: 0 0 0 6px var(--focus-halo);
  border-radius: var(--r-1);
}

/* ---------- 6. Honest degradation ----------
   Each of these keeps the site fully usable rather than merely static. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nav  { background: var(--glass-menu); }
  .card { background: linear-gradient(180deg, var(--ink-3), var(--ink-2)); }
}
@media (prefers-reduced-transparency: reduce) {
  .nav  { background: var(--glass-menu); backdrop-filter: none; -webkit-backdrop-filter: none; }
  .card { background: linear-gradient(180deg, var(--ink-3), var(--ink-2)); backdrop-filter: none; -webkit-backdrop-filter: none; }
  body::after { display: none; }
}
@media (prefers-contrast: more) {
  :root { --text-dim: #d6dccd; --text-mute: #c2c9b6; --edge-ctl: #a7b399; --glass-sheen: transparent; }
  .card, .nav { background: var(--ink-2); backdrop-filter: none; -webkit-backdrop-filter: none; }
  .float-emoji.faint { opacity: 0.5; }   /* the back plane rejoins the front one rather than sitting at 0.3 */
  body::before, body::after { display: none; }
}
@media (forced-colors: active) {
  .card, .nav, .post { border: 1px solid CanvasText; background: Canvas; }
  body::before, body::after { display: none; }
  :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible { outline: 3px solid Highlight; box-shadow: none; }
}
@media (prefers-reduced-motion: reduce) {
  body::before { animation: none; }
}

/* ---------- 7. Readability over user-chosen wall backgrounds ----------
   MANDATORY, and it ships with the glass rather than after it. A user may set
   wall_bg to any hex, #ffffff included. Without this, --text-dim over white
   composites to 3.93:1 and fails AA. The scrim pins the effective backdrop back
   to the dark ramp, restoring 7.26:1 whatever the user picks. */
.themed-page .card,
.themed-page .post {
  background:
    linear-gradient(180deg, var(--glass-sheen), transparent 38%),
    linear-gradient(0deg, var(--glass-scrim), var(--glass-scrim)),
    var(--glass-hi);
}

/* ---------- 8. Motion and micro-interaction ----------
   Rules: transform and opacity only, so everything stays on the compositor.
   Nothing animates width, height, top, left, filter or box-shadow on a hover
   path. Nothing is parked at opacity 0 waiting for an observer — every element
   is fully visible at rest, and motion only ever adds to that. */
.btn, .btn-primary, .btn-ghost, .btn-sm {
  transition: transform var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out);
}
.btn:hover, .btn-primary:hover, .btn-ghost:hover { transform: translateY(-2px); }
.btn:active, .btn-primary:active, .btn-ghost:active { transform: translateY(1px); }

.card, .post, .comm-card, .np-row, .lb-row {
  transition: transform var(--dur-3) var(--ease-out), border-color var(--dur-2) var(--ease-out), box-shadow var(--dur-3) var(--ease-out);
}
.comm-card:hover, .np-row:hover {
  transform: translateY(-3px);
  border-color: var(--g-edge);
  box-shadow: var(--shadow-2), 0 0 var(--glow-2) var(--g-tint);
}

/* nav links get an underlight that grows from the centre — scaleX only */
.nav-menu a { position: relative; transition: color var(--dur-2) var(--ease-out); }
.nav-menu a::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -3px; height: 2px;
  background: linear-gradient(90deg, transparent, var(--green), transparent);
  transform: scaleX(0); transform-origin: 50% 50%;
  transition: transform var(--dur-2) var(--ease-out);
  pointer-events: none;
}
.nav-menu a:hover::after, .nav-menu a.active::after, .nav-menu a:focus-visible::after { transform: scaleX(1); }

/* the always-on FAB gets a slow neon breath so it reads as live, not stuck */
#compose-fab { animation: sw-breathe 3.2s var(--ease-xp) infinite; }
@keyframes sw-breathe {
  0%, 100% { transform: translateZ(0) scale(1); }
  50%      { transform: translateZ(0) scale(1.045); }
}

/* points and level-ups pop rather than appear */
.toast { animation: sw-pop var(--dur-3) var(--ease-pop) both; }
@keyframes sw-pop {
  from { transform: translateY(-8px) scale(0.96); opacity: 0; }
  to   { transform: translateY(0)   scale(1);    opacity: 1; }
}

/* the level badge pulses once when it changes; .bump is already toggled in JS */
.nav-xp.bump { animation: sw-bump var(--dur-4) var(--ease-pop); }
@keyframes sw-bump {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.18); }
  100% { transform: scale(1); }
}

/* MOTION POLICY: everything above collapses to instant, and the site stays
   fully usable and still looks designed — not merely frozen. */
@media (prefers-reduced-motion: reduce) {
  .btn:hover, .btn-primary:hover, .btn-ghost:hover,
  .comm-card:hover, .np-row:hover { transform: none; }
  .nav-menu a::after { transition: none; }
  #compose-fab, .toast, .nav-xp.bump { animation: none; }
  .card, .post, .comm-card, .np-row, .lb-row, .btn, .btn-primary, .btn-ghost { transition: none; }
}

/* ---------- 9. Colour editor (profile settings) ---------- */
.theme-editor { margin-top: 0.6rem; }
.theme-rows { display: grid; gap: 0.55rem; }
.theme-row {
  display: grid; grid-template-columns: 1fr 44px 92px; gap: 0.6rem; align-items: center;
  background: var(--glass-well); border: 1px solid var(--hair); border-radius: var(--r-2); padding: 0.5rem 0.7rem;
}
.theme-lab { display: grid; line-height: 1.25; }
.theme-lab b { font-size: max(var(--text-floor), 0.92rem); }
.theme-lab i { font-style: normal; font-size: max(var(--text-floor), 0.76rem); color: var(--text-mute); }
.theme-row input[type="color"] {
  width: 44px; height: 34px; padding: 0; border: 1.5px solid var(--edge-ctl);
  border-radius: var(--r-1); background: none; cursor: pointer;
}
/* A hex field beside every swatch, because a native colour picker is unusable with a keyboard
   alone and impossible with a screen reader. */
.theme-hex {
  width: 92px; font-family: var(--mono, monospace); font-size: max(var(--text-floor), 0.82rem);
  background: var(--ink); color: var(--text); border: 1.5px solid var(--edge-ctl);
  border-radius: var(--r-1); padding: 0.35rem 0.45rem;
}
.theme-applied { grid-column: 1 / -1; font-size: max(var(--text-floor), 0.78rem); color: var(--gold); }
.theme-applied:empty { display: none; }
.theme-note { font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); line-height: 1.5; margin: 0.7rem 0 0;
  background: var(--o-wash); border-left: 3px solid var(--gold); border-radius: 0 var(--r-1) var(--r-1) 0; padding: 0.6rem 0.8rem; }
.theme-actions { margin-top: 0.7rem; }
@media (max-width: 520px) {
  .theme-row { grid-template-columns: 1fr 44px; }
  .theme-hex { grid-column: 1 / -1; width: 100%; }
}

/* ---------- 10. Wall density ----------
   `section { padding: 4.2rem 1.25rem }` is written for the landing page, where big airy bands are
   the point. A public wall is a feed: the same rule put 67px of dead space above AND below every
   feature block, so the check-in card alone spanned 302px for 168px of content. These sections are
   feed furniture, so they get feed spacing. */
#checkin,
.wall-pins,
#panel-posts,
#panel-calls,
#panel-lb,
#pub-pins {
  padding: 0 0 0.9rem;
}
#checkin:empty, .wall-pins:empty { padding: 0; }
/* the tab panels sit directly under the tab strip, so they need no top gap of their own */
#panel-posts, #panel-calls, #panel-lb { padding-top: 0.2rem; }

/* ---------- 11. Chain selector (New Pairs) ---------- */
.np-chainbar { display: flex; gap: 0.4rem; flex-wrap: wrap; margin: 0 0 0.6rem; }
.np-chain-btn {
  display: inline-flex; align-items: center; gap: 0.35rem;
  background: var(--ctl-fill-lo); color: var(--ctl-ink);
  border: 1.5px solid var(--ctl-fill-lo); border-radius: var(--r-pill);
  padding: 0.38rem 0.8rem; font-size: max(var(--text-floor), 0.85rem); font-weight: 600; cursor: pointer;
  transition: transform var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out), background var(--dur-2) var(--ease-out);
}
.np-chain-btn:hover { transform: translateY(-1px); background: var(--ctl-fill-hi); border-color: var(--edge-ctl-lit); }
.np-chain-btn.is-on { color: var(--on-green); border-color: var(--green); background: var(--green); }
/* "lite" is a real distinction, not decoration: it means the deep on-chain checks cannot run there */
.np-chain-lite {
  font-style: normal; font-size: max(var(--text-floor), 0.62rem); text-transform: uppercase; letter-spacing: var(--tr-caps);
  background: var(--o-tint); color: var(--gold); padding: 0.1rem 0.35rem; border-radius: var(--r-1);
}
.np-chain-note {
  font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); line-height: 1.5; margin: 0 0 0.8rem;
  background: var(--o-wash); border-left: 3px solid var(--gold);
  border-radius: 0 var(--r-1) var(--r-1) 0; padding: 0.55rem 0.8rem;
}
@media (prefers-reduced-motion: reduce) { .np-chain-btn:hover { transform: none; } }

/* ---------- 12. Video wall backgrounds ----------
   Fixed behind everything, with a scrim that does the same job the still-image gradient does:
   guarantee wall text stays readable over footage we did not choose. */
.wall-bg-video {
  position: fixed; inset: 0; z-index: -3;
  width: 100%; height: 100%; object-fit: cover;
  pointer-events: none;
}
.wall-bg-scrim {
  position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background: linear-gradient(rgba(6,8,12,0.82), rgba(6,8,12,0.9));
}
/* a profile slot preview may hold a video too */
.img-slot video { max-width: 100%; border-radius: var(--r-2); display: block; }
@media (prefers-reduced-motion: reduce) { .wall-bg-video { display: none; } .wall-bg-scrim { background: var(--ink); } }

/* ---------- 13. On-chain chart (replaces the embedded third-party chart) ---------- */
.onchain-chart { background: var(--glass-well); border: 1px solid var(--hair); border-radius: var(--r-2); padding: 0.6rem 0.7rem; }
/* wrap, not overflow: five timeframe buttons, a live price and a source chip do not fit across a phone,
   and a row that refuses to wrap makes the whole PAGE scroll sideways rather than just itself */
.oc-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.35rem 0.6rem; margin-bottom: 0.4rem; }
.oc-tfs { display: flex; flex-wrap: wrap; gap: 0.25rem; }   /* seven timeframes wrap on a narrow phone rather than push the chart past the screen */
.oc-tf {
  background: var(--ctl-fill-lo); color: var(--ctl-ink); border: 1px solid var(--ctl-fill-lo);
  border-radius: var(--r-1); padding: 0.2rem 0.5rem; font-size: max(var(--text-floor), 0.75rem); font-weight: 700; cursor: pointer;
}
.oc-tf:hover { color: var(--ctl-ink); background: var(--ctl-fill-hi); border-color: var(--ctl-fill-hi); }
.oc-tf.is-on { color: var(--on-green); border-color: var(--green); background: var(--green); }
/* "on-chain" is a provenance claim, so it is stated plainly rather than as decoration */
.oc-src { font-size: max(var(--text-floor), 0.68rem); color: var(--text-mute); letter-spacing: var(--tr-caps); text-transform: uppercase; }
/* The live price takes the direction colour, so the number and the line always agree. */
.oc-live { font-family: var(--mono, ui-monospace, monospace); font-size: max(var(--text-floor), 0.95rem); font-weight: 700; margin-left: auto; margin-right: 0.6rem; }
.onchain-chart.is-up   .oc-live { color: var(--green-bright); }
.onchain-chart.is-down .oc-live { color: var(--red); }
.onchain-chart.is-up   { border-color: color-mix(in srgb, var(--green) 22%, transparent); }
.onchain-chart.is-down { border-color: rgba(255,93,93,0.22); }
/* a one-frame pulse each second so a changing number reads as live rather than static */
.oc-live.tick { animation: oc-tick 420ms var(--ease-out, ease-out); }
@keyframes oc-tick { 0% { transform: scale(1.12); } 100% { transform: scale(1); } }
@media (prefers-reduced-motion: reduce) { .oc-live.tick { animation: none; } }
.oc-canvas { display: block; width: 100%; height: 240px; }
.oc-status { font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); margin: 0.35rem 0 0; }
.oc-data { margin-top: 0.4rem; }
/* a small green pill, not muted text — black type needs a ground (same construction as .linklike) */
.oc-data > summary { cursor: pointer; display: inline-flex; align-items: center; font-size: max(var(--text-floor), 0.78rem); font-weight: 700; color: var(--ctl-ink); background: var(--ctl-fill-lo); border-radius: var(--r-pill); padding: 0.3rem 0.7rem; min-height: 32px; list-style: none; transition: background 0.15s ease; }
.oc-data > summary:hover { background: var(--ctl-fill-hi); }
.oc-table-wrap { overflow-x: auto; max-height: 260px; overflow-y: auto; margin-top: 0.4rem; }
.oc-table { width: 100%; border-collapse: collapse; font-size: max(var(--text-floor), 0.78rem); font-variant-numeric: tabular-nums; }
.oc-table th { position: sticky; top: 0; background: var(--ink-2); color: var(--text-mute); text-align: right;
  font-weight: 600; padding: 0.35rem 0.5rem; border-bottom: 1px solid var(--edge-ctl); }
.oc-table th:first-child, .oc-table td:first-child { text-align: left; }
.oc-table td { text-align: right; padding: 0.3rem 0.5rem; border-bottom: 1px solid var(--hair); }
@media (max-width: 640px) { .oc-canvas { height: 200px; } }

/* ══════════════════════════════════════════════════════════════════════════
   14. SEGMENTED CONTROLS — New Pairs toggles
   The three toggle groups on this page were still wearing the pre-overhaul
   blue-grey palette and swapped their active state instantly, which reads as a
   flicker rather than a movement. They are now one consistent control with a
   pill that SLIDES between segments.

   The indicator is the container's own ::before, positioned from :has() — so
   there is no new DOM, no JS, and the animation is a transform, which stays off
   the layout path. Buttons sit above it on z-index and only transition colour.
   ══════════════════════════════════════════════════════════════════════════ */

/* ---- shared indicator geometry ---- */
/* sticky, NOT relative. It inherits `top: var(--nav-h)` from the base rule, and on a relatively
   positioned box that is a downward OFFSET, not a threshold — the switcher was shoved 63px down
   the page and sat on top of the feed below it. Sticky establishes a containing block for the
   ::before indicator just as well, so the pill still works. */
.np-viewswitch { position: sticky; isolation: isolate; }
/* Only the view switcher gets a SLIDING pill. It is display:flex at full width with flex:1 1 0, so
   its three tabs are genuinely equal thirds and a fractional indicator lands exactly (measured:
   187.3px indicator against a 187px tab). .np-safety and .np-runwin are inline-flex and shrink to
   fit their labels, so their segments are NOT equal width — a fractional pill would sit visibly
   off-centre there. They get a filled active segment instead, which is correct at any label width. */
.np-viewswitch::before {
  content: ''; position: absolute; z-index: 0;
  top: var(--seg-pad); bottom: var(--seg-pad); left: var(--seg-pad);
  width: calc((100% - 2 * var(--seg-pad) - (var(--seg-n) - 1) * var(--seg-gap)) / var(--seg-n));
  border-radius: var(--r-pill);
  background: linear-gradient(180deg, var(--green-bright), var(--green));
  box-shadow: 0 2px 14px var(--glow-g), inset 0 1px 0 color-mix(in srgb, var(--green-bright) 70%, transparent);
  transform: translateX(calc(var(--seg-i, 0) * (100% + var(--seg-gap))));
  transition: transform var(--dur-3) var(--ease-out);
  pointer-events: none;
}
.np-vs-btn, .np-seg { position: relative; z-index: 1; }

/* ---- view switcher (3 tabs) ---- */
.np-viewswitch {
  --seg-pad: 5px; --seg-gap: 4px; --seg-n: 3;
  background: var(--ctl-fill-lo);   /* a light track, so the unselected tabs' black labels have a ground */
  backdrop-filter: blur(var(--blur)) saturate(var(--sat));
  -webkit-backdrop-filter: blur(var(--blur)) saturate(var(--sat));
  border: 1px solid var(--hair);
  box-shadow: var(--shadow-1), inset 0 1px 0 var(--glass-edge);
}
.np-viewswitch:has(.np-vs-btn:nth-child(2)[aria-selected="true"]) { --seg-i: 1; }
.np-viewswitch:has(.np-vs-btn:nth-child(3)[aria-selected="true"]) { --seg-i: 2; }
.np-vs-btn { transition: color var(--dur-2) var(--ease-out); }
.np-vs-btn:hover { color: var(--ctl-ink); }
/* the ink is a token now, not a literal, so a user-chosen accent keeps its contrast */
.np-vs-btn[aria-selected="true"] { background: none; color: var(--on-green); }

/* ---- safety filter (3) and time window (5) ---- */
.np-safety, .np-runwin {
  background: var(--ctl-fill-lo); border: 1px solid var(--ctl-fill-lo);
}
.np-safety .np-seg, .np-runwin .np-seg {
  text-align: center;
  transition: color var(--dur-2) var(--ease-out), background var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out);
}
.np-seg:hover { color: var(--ctl-ink); background: var(--ctl-fill-hi); }
.np-seg.is-on {
  background: linear-gradient(180deg, var(--green-bright), var(--green));
  color: var(--on-green);
  box-shadow: 0 2px 12px var(--glow-g), inset 0 1px 0 color-mix(in srgb, var(--green-bright) 70%, transparent);
}

/* Focus must read against BOTH the dark track and the bright pill, so it uses the
   theme-independent focus token rather than the accent (which a user can change). */
.np-vs-btn:focus-visible, .np-seg:focus-visible {
  outline: 3px solid var(--ctl-ink); outline-offset: -2px; box-shadow: none;   /* inset on a light track / bright pill: the ink is the one colour that reads on both */
}

/* :has() is broadly supported, but where it is not the pill would sit under the
   first segment forever — so fall back to the old solid-fill active state. */
@supports not selector(:has(*)) {
  .np-viewswitch::before { display: none; }
  .np-vs-btn[aria-selected="true"] { background: linear-gradient(180deg, var(--green-bright), var(--green)); color: var(--on-green); }
}
@media (prefers-reduced-motion: reduce) {
  .np-viewswitch::before { transition: none; }
  .np-safety .np-seg, .np-runwin .np-seg { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   15. Footer clearance + gold buttons
   ══════════════════════════════════════════════════════════════════════════ */

/* ---- footer sits under two fixed elements ----
   #compose-fab is pinned bottom-right at `bottom: 1rem` and stands ~50px tall; #music-player is
   pinned bottom-left at the same offset and stands ~52px. Both therefore occupy the bottom ~68px
   of every viewport. The footer's own padding-bottom was 3rem (48px), so scrolling to the end of
   ANY page parked the FAB and the player on top of the last line of fine print. The clearance
   used to live in a max-width:560px block, which is backwards — the overlap is not a phone
   problem, it happens at every width because both elements are pinned to the viewport, not the
   column. The size of that strip is --fab-clear (declared with the palette) — the scanner's
   settings panel reserves the same strip for the same reason. */
footer {
  padding-bottom: var(--fab-clear);
  position: relative;
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--green) 4%, transparent), transparent 220px),
    var(--ink);
  border-top: 1px solid var(--hair);
}
/* the accent hairline is drawn, not bordered, so it can fade at the edges and follow a custom
   accent instead of the old hard-coded color-mix(in srgb, var(--green) 18%, transparent) */
footer::before {
  content: ''; position: absolute; top: -1px; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--green), transparent);
  opacity: 0.5; pointer-events: none;
}
.disclaimer {
  color: var(--on-green);
  box-shadow: 0 4px 0 var(--green-dark), 0 10px 26px var(--glow-g);
  border: 1px solid color-mix(in srgb, var(--green-bright) 70%, var(--green) 30%);
}
footer .fine a { color: var(--gold); }
footer .nav-foot a { color: var(--text-dim); text-decoration: none; transition: color var(--dur-2) var(--ease-out); }
footer .nav-foot a:hover { color: var(--green-bright); }

/* ---- gold buttons ----
   .btn-primary got the glass/hairline pass in section 3; .btn-gold never did, so the two sat
   side by side on the watchlist looking like they came from different sites. Same construction,
   gold tokens — and the tokens mean a user-picked highlight carries through instead of the old
   literal var(--gold-deep) / rgba(255,179,64,…). */
.btn-gold {
  color: var(--on-gold);
  background: linear-gradient(180deg, var(--gold), var(--gold-deep));
  border: 1px solid color-mix(in srgb, var(--gold) 70%, var(--gold-deep) 30%);
  box-shadow:
    0 6px 0 var(--gold-deep),
    0 10px 28px var(--glow-o),
    inset 0 1px 0 color-mix(in srgb, var(--gold) 70%, transparent);
}
.btn-gold:hover { transform: translateY(-2px); box-shadow: 0 6px 0 var(--gold-deep), 0 14px 40px var(--glow-o), inset 0 1px 0 color-mix(in srgb, var(--gold) 85%, transparent); }
.btn-gold:active { transform: translateY(1px); }
.btn-gold:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.btn-gold, .btn-rh { transition: transform var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out); }
@media (prefers-reduced-motion: reduce) { .btn-gold:hover, .btn-gold:active { transform: none; } }

/* ---- watchlist "wallet tracking has its own page" card ----
   a flat --ink-2 panel among glass ones. Same well treatment as the other notices, and the CTA
   gets room to read as the primary action of the card rather than a link in a paragraph. */
.wl-trk-card {
  background: linear-gradient(180deg, var(--glass-sheen), transparent 40%), var(--glass-well);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: 1px solid var(--hair); border-radius: var(--r-3);
  box-shadow: var(--shadow-1), inset 0 1px 0 var(--glass-edge);
  padding: 0.9rem 1.1rem; gap: 0.7rem 1.2rem;
}
.wl-trk-card > span { color: var(--text-dim); line-height: 1.55; }

/* ---- Hot Feed fills the viewport exactly ----
   The feed's height was `100dvh - nav - switch`, which ignores #main's own padding (0.6rem top,
   4rem bottom) and the switcher's 0.4rem margin. Those 80 leftover pixels made the whole PAGE
   scrollable underneath a full-height scroll container — and the moment you scrolled them, the
   sticky switcher pinned under the nav and sat on top of the feed again. Subtracting the real
   chrome makes the column exactly one viewport tall, so there is nothing to scroll and nothing
   to overlap. 1rem = #main's 0.6rem padding-top + the switcher's 0.4rem margin-bottom. */
body.np-mode-feed { --np-feed-h: calc(100dvh - var(--nav-h, 58px) - var(--np-switch-h) - 1rem); }
@supports not (height: 100dvh) {
  body.np-mode-feed { --np-feed-h: calc(100vh - var(--nav-h, 58px) - var(--np-switch-h) - 1rem); }
}
/* responsive.css puts padding-bottom: var(--fab-reserve) on <body> so nothing is stranded under the player
   and the FAB. In feed mode there is nothing below the feed to strand, and those pixels were the last of
   the page scroll that let the sticky switcher creep over the feed. The pinned strip is reserved inside
   the slide instead, where it costs card height only at the widths that need it. */
body.np-mode-feed { padding-bottom: 0; }
body.np-mode-feed #main { padding-bottom: 0; }
body.np-mode-feed .np-feed,
body.np-mode-feed .np-slide { height: var(--np-feed-h); }
body.np-mode-feed .np-slide { contain-intrinsic-size: 1px var(--np-feed-h); }

/* ---- footer nav ----
   The separators used to be literal "·" text nodes between the anchors. .nav-foot is a flex
   container, so each one was its own flex ITEM: it took a full 1.1rem gap on both sides, and
   when the row wrapped a lone dot could land at the start of the next line. A CSS-drawn
   separator fixes the orphan but not the mirror case — the link ending a wrapped row still
   trails a dot, and no selector can know where the row broke. Column spacing separates the
   links on its own at this size, so the separator goes entirely: nothing to orphan, nothing
   to trail, and no decorative glyph for a screen reader to read out. */
footer .nav-foot { gap: 0.65rem 1.5rem; align-items: center; }
footer .nav-foot a:focus-visible,
footer .fine a:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: 4px; }

/* ══════════════════════════════════════════════════════════════════════════
   16. OG tiers — gold / silver / bronze
   ══════════════════════════════════════════════════════════════════════════ */

/* Nothing in the palette read as silver or bronze, so both are new. They are deliberately FIXED
   rather than derived from --gold: --gold is user-overridable through the colour picker (prefs.js
   GROUPS.highlight), and three tiers mixed from one accent would all shift together and stop being
   distinguishable the moment somebody picked a custom highlight. --diamond was the other candidate
   for silver and is rejected on meaning, not looks: it already belongs to the Diamond Hands hold
   streak, and a Silver OG wearing the Diamond colour would collide with an unrelated status.
   Each tier carries its own ink token so the label stays legible on its own fill. */
:root {
  --silver: #cfd6e4; --silver-deep: #8e99ad; --on-silver: #14161c;
  --bronze: #e2a465; --bronze-deep: #a06a30; --on-bronze: #1c0f04;  /* measured 6.11:1 against its own fill; the first pick sat at 4.60, passing but with no margin at the badge's 0.62rem */
  /* Diamond OG: an ice-white-to-violet cut, so it never reads as the flat cyan of the Diamond Hands streak (--diamond) */
  --og-diamond: #eef9ff; --og-diamond-mid: #8fd3f4; --og-diamond-deep: #9b8cff; --on-og-diamond: #0a0f24;
}

/* The base .og-badge rule still paints gold, so gold needs no variant — but it does need its ink
   taken off the hardcoded var(--on-gold) it has always used, which goes near-black-on-near-black under a
   dark custom highlight. */
.og-badge--gold { color: var(--on-gold); }
.og-badge--silver {
  color: var(--on-silver);
  background: linear-gradient(180deg, var(--silver) 0%, var(--silver-deep) 100%);
  border-color: color-mix(in srgb, var(--silver) 65%, transparent);
  box-shadow: 0 0 8px color-mix(in srgb, var(--silver) 40%, transparent);
}
.og-badge--silver:hover { box-shadow: 0 0 13px color-mix(in srgb, var(--silver) 70%, transparent); }
.og-badge--bronze {
  color: var(--on-bronze);
  background: linear-gradient(180deg, var(--bronze) 0%, var(--bronze-deep) 100%);
  border-color: color-mix(in srgb, var(--bronze) 65%, transparent);
  box-shadow: 0 0 8px color-mix(in srgb, var(--bronze) 40%, transparent);
}
.og-badge--bronze:hover { box-shadow: 0 0 13px color-mix(in srgb, var(--bronze) 70%, transparent); }
.og-badge--diamond {
  color: var(--on-og-diamond);
  background: linear-gradient(135deg, var(--og-diamond) 0%, var(--og-diamond-mid) 48%, var(--og-diamond-deep) 100%);
  border-color: color-mix(in srgb, var(--og-diamond-mid) 70%, transparent);
  box-shadow: 0 0 10px color-mix(in srgb, var(--og-diamond-mid) 55%, transparent);
}
.og-badge--diamond::before { content: '💎'; margin-right: 0.15em; }
.og-badge--diamond:hover { box-shadow: 0 0 16px color-mix(in srgb, var(--og-diamond-deep) 70%, transparent); }
/* the existing reduced-motion rule drops the gold glow; the variants need the same treatment */
@media (prefers-reduced-motion: reduce) { .og-badge--silver, .og-badge--bronze, .og-badge--diamond { box-shadow: none; } }

/* The dashboard block. .og-block is reused as a generic layout class by the community and arcade
   cards (gamify.js builds `og-block comm-invite` and `og-block comm-block`), so tier colour goes on
   a modifier and never on .og-block itself — restyling the base would bleed into those cards. */
.og-block--silver { background: linear-gradient(100deg, color-mix(in srgb, var(--silver) 14%, transparent), color-mix(in srgb, var(--silver) 5%, transparent)); border-color: color-mix(in srgb, var(--silver) 50%, transparent); }
.og-block--silver .og-block-badge { background: linear-gradient(180deg, var(--silver), var(--silver-deep)); color: var(--on-silver); box-shadow: 0 0 10px color-mix(in srgb, var(--silver) 50%, transparent); }
.og-block--silver .og-block-body b { color: var(--silver); }
.og-block--bronze { background: linear-gradient(100deg, color-mix(in srgb, var(--bronze) 14%, transparent), color-mix(in srgb, var(--bronze) 5%, transparent)); border-color: color-mix(in srgb, var(--bronze) 50%, transparent); }
.og-block--bronze .og-block-badge { background: linear-gradient(180deg, var(--bronze), var(--bronze-deep)); color: var(--on-bronze); box-shadow: 0 0 10px color-mix(in srgb, var(--bronze) 50%, transparent); }
.og-block--bronze .og-block-body b { color: var(--bronze); }
.og-block--diamond { background: linear-gradient(100deg, color-mix(in srgb, var(--og-diamond-mid) 16%, transparent), color-mix(in srgb, var(--og-diamond-deep) 8%, transparent)); border-color: color-mix(in srgb, var(--og-diamond-mid) 55%, transparent); }
.og-block--diamond .og-block-badge { background: linear-gradient(135deg, var(--og-diamond), var(--og-diamond-mid) 50%, var(--og-diamond-deep)); color: var(--on-og-diamond); box-shadow: 0 0 12px color-mix(in srgb, var(--og-diamond-mid) 55%, transparent); }
.og-block--diamond .og-block-body b { color: var(--og-diamond-mid); }

/* .eq-og had no rule at all — the OG chip in the Send Power equation fell back to neutral .eq-chip.
   Now it carries the tier, so the chip and the badge agree at a glance. */
.eq-og { background: color-mix(in srgb, var(--gold) 16%, transparent); border-color: color-mix(in srgb, var(--gold) 45%, transparent); color: var(--gold); }
.eq-og--silver { background: color-mix(in srgb, var(--silver) 16%, transparent); border-color: color-mix(in srgb, var(--silver) 45%, transparent); color: var(--silver); }
.eq-og--bronze { background: color-mix(in srgb, var(--bronze) 16%, transparent); border-color: color-mix(in srgb, var(--bronze) 45%, transparent); color: var(--bronze); }
.eq-og--diamond { background: color-mix(in srgb, var(--og-diamond-mid) 16%, transparent); border-color: color-mix(in srgb, var(--og-diamond-mid) 50%, transparent); color: var(--og-diamond-mid); }

/* ══════════════════════════════════════════════════════════════════════════
   17. Video profile pictures
   ══════════════════════════════════════════════════════════════════════════ */
/* Every avatar class is written on the class, not on img, so a <video> wearing the same class already
   gets the circle, the size and object-fit: cover. What a video does NOT get from those rules is a
   ground to sit on while the first frame decodes, or a guarantee it can't overflow its circle on the
   one class that sets display:grid for the emoji fallback — so both are pinned here for every site. */
video.post-avatar, video.c-ava, video.cm-ava, video.gb-ava, video.lb-ava, video.h-ava, video.sc-sender-ava, video.wall-avatar-img {
  display: block; object-fit: cover; object-position: center; background: var(--ink-3); overflow: hidden;
}
.wall-avatar video.wall-avatar-img { grid-area: 1 / 1; width: 100%; height: 100%; }

/* ══════════════════════════════════════════════════════════════════════════
   18. Loot Log explanations
   ══════════════════════════════════════════════════════════════════════════ */
/* The Quest Board already explains every action in a .ge-tip that appears on hover and goes when the
   cursor leaves, with a ⓘ for keyboard and touch. The Loot Log lists the SAME kinds but only showed a
   label and a number, so the reader had to guess what "Diamond hands" was paid for. It now borrows the
   exact same tip, anchored on the row; the ⓘ lives inside the label cell so the row's 4-column grid is
   untouched, and the tip is absolutely positioned so it takes no cell either. */
.loot-list li.ll-li { position: relative; }
.ll-info {
  display: inline-grid; place-items: center; width: 20px; height: 20px; margin-left: 0.35rem; border-radius: 50%;
  border: 1.5px solid var(--ctl-fill-lo); background: var(--ctl-fill-lo); color: var(--ctl-ink); font: inherit; font-size: max(var(--text-floor), 0.7rem); font-weight: 800; line-height: 1;
  cursor: pointer; vertical-align: middle; transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.ll-info:hover, .ll-info[aria-expanded="true"] { border-color: var(--green); background: var(--green); color: var(--on-green); }
.ll-info:focus-visible { outline: 3px solid var(--green-bright); outline-offset: 2px; }
.ll-li:hover .ge-tip, .ll-li.is-open .ge-tip, .ll-li:has(> .ll-label > .ll-info:focus-visible) .ge-tip { opacity: 1; transform: translateY(0); }
.ll-li.is-open .ge-tip { pointer-events: auto; }
@media (prefers-reduced-motion: reduce) { .ll-info { transition: none; } }

/* ══════════════════════════════════════════════════════════════════════════
   19. Biggest Sender — the Arena toggle and the weekly board
   ══════════════════════════════════════════════════════════════════════════ */
.arena-head { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; margin-bottom: 0.5rem; }
.arena-head .gsub { margin: 0; }
.arena-tabs { display: inline-flex; gap: 4px; padding: 4px; border-radius: var(--r-pill); background: var(--ctl-fill-lo); border: 1px solid var(--ctl-fill-lo); }
.arena-tab {
  font: inherit; font-weight: 800; font-size: max(var(--text-floor), 0.78rem); padding: 0.3rem 0.7rem; border-radius: var(--r-pill); border: none; cursor: pointer;
  background: transparent; color: var(--ctl-ink); white-space: nowrap; min-height: 32px; transition: color var(--dur-2) var(--ease-out), background var(--dur-2) var(--ease-out);
}
.arena-tab:hover { color: var(--ctl-ink); background: var(--ctl-fill-hi); }
.arena-tab.is-on { background: linear-gradient(180deg, var(--green-bright), var(--green)); color: var(--on-green); box-shadow: 0 2px 10px var(--glow-g); }
.arena-tab:focus-visible { outline: 2px solid var(--ctl-ink); outline-offset: 2px; }
.comp-clock { font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); margin: 0 0 0.5rem; }
.comp-clock b { color: var(--gold); }
.comp-mine { font-size: max(var(--text-floor), 0.82rem); line-height: 1.5; margin: 0.6rem 0 0; padding: 0.55rem 0.7rem; border-radius: var(--r-2); background: color-mix(in srgb, var(--gold) 12%, transparent); border: 1px solid color-mix(in srgb, var(--gold) 40%, transparent); color: var(--text); }
.comp-mine b { color: var(--gold); }
.comp-last { font-size: max(var(--text-floor), 0.78rem); text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); margin: 0.9rem 0 0.35rem; }
.gboard-compact li { opacity: 0.92; }
.gb-prize { font-weight: 900; font-size: max(var(--text-floor), 0.72rem); color: var(--on-gold); background: linear-gradient(180deg, var(--gold), var(--gold-deep)); border-radius: var(--r-pill); padding: 0.1rem 0.45rem; margin-left: 0.3rem; white-space: nowrap; }
.comp-rules { font-size: max(var(--text-floor), 0.78rem); line-height: 1.5; color: var(--text-dim); margin: 0.7rem 0 0; }
.comp-rules b { color: var(--text); }
.pc-week { display: inline-flex; align-items: center; gap: 0.25rem; font-weight: 900; font-size: max(var(--text-floor), 0.78rem); color: var(--on-gold); background: linear-gradient(180deg, var(--gold), var(--gold-deep)); border-radius: var(--r-pill); padding: 0.2rem 0.6rem; cursor: help; }
@media (prefers-reduced-motion: reduce) { .arena-tab { transition: none; } }

/* ══════════════════════════════════════════════════════════════════════════
   20. Nav account control: name is a link, caret is the menu · Data API page
   ══════════════════════════════════════════════════════════════════════════ */
.nav-profile > .profile-link { border-radius: 999px 0 0 999px; padding-right: 0.55rem; } /* only the split chip — the signed-out Sign In pill shares the class */
.nav-profile:hover > .profile-link, .nav-profile:hover > .np-caret-btn { transform: translateY(-1px); } /* the two halves lift together */
.np-caret-btn {
  display: inline-flex; align-items: center; justify-content: center; min-height: 40px; min-width: 44px; padding: 0 0.575rem; margin-left: -1px; /* 44px: on touch it is the only route into the menu */
  border: none; border-radius: 0 999px 999px 0; cursor: pointer; color: var(--on-gold); font: inherit;
  background: linear-gradient(180deg, var(--gold), var(--gold-deep)); transition: transform 0.15s ease;
}
.np-caret-btn:hover { transform: translateY(-1px); }
#main .ab-mini-list code, .dk-addr { word-break: break-all; overflow-wrap: anywhere; } /* a 42-char address must wrap on a phone, not clip */
.np-caret-btn:focus-visible { outline: 3px solid var(--green-bright); outline-offset: 2px; }
.dk-card { display: grid; gap: 0.7rem; }
.dk-stat { display: flex; justify-content: space-between; gap: 1rem; padding: 0.55rem 0; border-bottom: 1px solid var(--hair); font-size: max(var(--text-floor), 0.92rem); }
.dk-stat b { font-variant-numeric: tabular-nums; }
.dk-bar { height: 12px; border-radius: 999px; background: var(--ink); border: 1px solid var(--hair); overflow: hidden; }
.dk-bar > span { display: block; height: 100%; background: linear-gradient(90deg, var(--green), var(--green-bright)); width: 0; transition: width 0.4s ease; }
.dk-key { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: max(var(--text-floor), 0.92rem); word-break: break-all; padding: 0.7rem 0.8rem; border-radius: var(--r-2); background: var(--ink); border: 1px solid var(--edge-ctl); color: var(--text); }
.dk-actions { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.dk-endpoints td, .dk-endpoints th { text-align: left; padding: 0.45rem 0.6rem; border-bottom: 1px solid var(--hair); vertical-align: top; font-size: max(var(--text-floor), 0.86rem); }
.dk-endpoints code { font-size: max(var(--text-floor), 0.82rem); }
.dk-note { font-size: max(var(--text-floor), 0.86rem); color: var(--text-dim); line-height: 1.55; }
pre.dk-pre { overflow-x: auto; padding: 0.75rem 0.9rem; border-radius: var(--r-2); background: var(--ink); border: 1px solid var(--hair); font-size: max(var(--text-floor), 0.8rem); line-height: 1.5; }
@media (prefers-reduced-motion: reduce) { .np-caret-btn, .dk-bar > span { transition: none; } }

/* ===== 21. The sandbox community — branded for a listed company, not a token ===== */
.comm-stock-note { margin: 0 0 0.9rem; font-size: max(var(--text-floor), 0.8rem); line-height: 1.55; color: var(--text-dim); padding: 0.55rem 0.7rem; border-radius: var(--r-2); background: rgba(159,224,255,0.06); border: 1px solid rgba(159,224,255,0.28); }
.comm-stock-note b { color: var(--text); }
.comm-supply-note { background: color-mix(in srgb, var(--green) 7%, transparent); border-color: color-mix(in srgb, var(--green) 32%, transparent); }
.np-src { font-size: max(var(--text-floor), 0.68rem); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-mute); margin-left: 0.35rem; }
.np-src-chain { color: var(--green-bright); }
.comm-src { font-size: max(var(--text-floor), 0.68rem); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--green-bright); margin-left: 0.2rem; }
.comm-pill-sandbox { background: rgba(159,224,255,0.12); color: var(--diamond); border-color: rgba(159,224,255,0.4); }
.comm-card-stockline { display: block; font-size: max(var(--text-floor), 0.72rem); line-height: 1.45; color: var(--text-dim); margin: 0.35rem 0 0.2rem; }
.comm-card-stockline b { color: var(--gold); }
.comm-sandbox-line { margin: 0.6rem 0 0; font-size: max(var(--text-floor), 0.8rem); line-height: 1.5; color: var(--text-dim); }
.comm-sandbox-line a { color: var(--diamond); }

/* ===== 22. Community pages: one vertical rhythm, and the holders-only wall =====
   Every top-level block on communities.html and community.html is spaced by ONE gap on the column that holds
   them, not by per-element margins — those were 0px in two places (sections touching) and 1/10/14/18/22px in
   the rest. A `gap` also ignores hidden sections, so a community with no proposals leaves no double space. */
:root { --sec-gap: 1.4rem; }
.comm-page { display: flex; flex-direction: column; gap: var(--sec-gap); }
/* the element+class selector beats a bare .wk / .comm-bar from a later stylesheet, so ONE gap really is the only
   thing setting vertical space here; left/right margins are untouched, so a max-width block still centres */
div.comm-page > *, header.comm-page > * { margin-top: 0; margin-bottom: 0; }
.comm-back { font-size: max(var(--text-floor), 0.92rem); }
.comm-back .btn { text-decoration: none; }   /* an <a> styled as a button must not also wear a link underline */
.comm-hero-top-page { text-align: center; padding: 3rem 1.25rem 1.5rem; }
/* auto side margins on a flex item make it shrink-to-fit, so the rules disclosure jumped 448px → 620px the
   moment it opened. Full width inside the column instead, with each item's own max-width still deciding. */
.comm-hero-top-page > .comm-start, .comm-hero-top-page > .comm-start-msg, .comm-hero-top-page > .comm-rules { width: 100%; }
.comm-more-row { text-align: center; margin-top: 1.2rem; }   /* the button must not sit flush against the last post */
.comm-more-row:has(> [hidden]) { display: none; }           /* no empty band under the last post */

/* the start form: the placeholder was cut off mid-word at ~600px, so the field takes its own row before that */
.comm-start { justify-content: center; }   /* when the field takes its own row, the button stays under the middle of it */
.comm-start .addr-field { position: relative; display: flex; flex: 1 1 340px; min-width: 0; }
.comm-start .addr-field .addr-input { flex: 1 1 auto; min-width: 0; margin: 0; padding-right: 3rem; }
.addr-clear {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 38px; height: 38px; border-radius: 50%; cursor: pointer;
  border: 1.5px solid var(--ctl-fill-lo); background: var(--ctl-fill-lo); color: var(--ctl-ink);
  font-size: max(var(--text-floor), 0.95rem); line-height: 1; display: grid; place-items: center; padding: 0;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.addr-clear:hover { border-color: var(--green); background: var(--ctl-fill-hi); color: var(--ctl-ink); }
.addr-clear:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.addr-input[aria-invalid="true"] { border-color: var(--red); }
@media (prefers-reduced-motion: reduce) { .addr-clear { transition: none; } }
.comm-start .btn { flex: 0 0 auto; }

/* ---------- the two walls ---------- */
.cw-tabs { display: inline-flex; gap: 4px; padding: 4px; border-radius: var(--r-pill); background: var(--ctl-fill-lo); border: 1px solid var(--ctl-fill-lo); margin-bottom: 0.7rem; }
.cw-tab {
  border: none; background: none; cursor: pointer; border-radius: var(--r-pill);
  padding: 0.5rem 0.95rem; min-height: 44px; font-weight: 800; font-size: max(var(--text-floor), 0.88rem); color: var(--ctl-ink);
  font-family: inherit; transition: background 0.15s ease, color 0.15s ease;
}
.cw-tab:hover { color: var(--ctl-ink); background: var(--ctl-fill-hi); }
.cw-tab.is-on { background: linear-gradient(180deg, var(--green-bright), var(--green)); color: var(--on-green); box-shadow: 0 2px 10px var(--glow-g); }
.cw-tab:focus-visible { outline: 3px solid var(--ctl-ink); outline-offset: 2px; }
.cw-note { margin: 0 0 0.9rem; font-size: max(var(--text-floor), 0.84rem); line-height: 1.55; color: var(--text-dim); }
.cw-note b { color: var(--text); }
.composer.is-private { border-color: rgba(159,224,255,0.55); box-shadow: 0 0 0 1px rgba(159,224,255,0.18), 0 18px 40px rgba(0,0,0,0.45); }
.post-private { border-color: rgba(159,224,255,0.45); }
.post-lock {
  display: inline-block; margin-left: 0.4rem; font-size: max(var(--text-floor), 0.66rem); font-weight: 900; letter-spacing: 0.02em;
  border-radius: var(--r-pill); padding: 0.1rem 0.45rem; white-space: nowrap;
  background: rgba(159,224,255,0.14); color: var(--diamond); border: 1px solid rgba(159,224,255,0.42);
}
@media (prefers-reduced-motion: reduce) { .cw-tab { transition: none; } }

/* ===== 23. Block 0 — the first buyers, on every token detail (public/block0.js) ===== */
.np-b0 { display: block; }
.b0-msg { margin: 0; font-size: max(var(--text-floor), 0.88rem); line-height: 1.6; color: var(--text-dim); padding: 0.7rem 0.85rem; border-radius: var(--r-2); background: var(--ink); border: 1px solid var(--ink-4); }
.b0-wait { border-color: rgba(159,224,255,0.35); color: var(--diamond); }
.b0-fail { border-color: rgba(255,179,64,0.45); color: var(--gold); }
.b0-good { border-color: color-mix(in srgb, var(--green) 40%, transparent); color: var(--green-bright); }
.b0-head { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem 0.8rem; margin-bottom: 0.7rem; }
.b0-verdict { font-weight: 900; font-size: max(var(--text-floor), 0.78rem); letter-spacing: 0.04em; text-transform: uppercase; border-radius: var(--r-pill); padding: 0.25rem 0.7rem; white-space: nowrap; }
.b0-acc { background: color-mix(in srgb, var(--green) 14%, transparent); color: var(--green-bright); border: 1px solid var(--g-lit); }
.b0-sell, .b0-out { background: rgba(255,93,93,0.13); color: var(--red); border: 1px solid rgba(255,93,93,0.45); }
.b0-unk { background: rgba(159,224,255,0.12); color: var(--diamond); border: 1px solid rgba(159,224,255,0.4); }
.b0-block { font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); font-variant-numeric: tabular-nums; }
.b0-block b { color: var(--text); }
.b0-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 0.5rem; margin-bottom: 0.8rem; }
.b0-tile { background: var(--ink); border-radius: 12px; padding: 0.6rem 0.7rem; display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.b0-tile b { font-family: 'Luckiest Guy', 'Rubik', cursive; font-size: max(var(--text-floor), 1.35rem); line-height: 1.1; color: var(--green-bright); letter-spacing: 0.02em; font-variant-numeric: tabular-nums; }
.b0-tile span { font-size: max(var(--text-floor), 0.73rem); color: var(--text-dim); line-height: 1.35; }
.b0-up { color: var(--green-bright); }
.b0-down { color: var(--red); }
.b0-ledger { background: var(--ink); border: 1px solid var(--ink-4); border-radius: 12px; padding: 0.7rem 0.85rem; margin-bottom: 0.8rem; }
.b0-ledger h4 { margin: 0 0 0.5rem; font-size: max(var(--text-floor), 0.82rem); text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); font-weight: 800; }
.b0-led-row { display: flex; flex-wrap: wrap; gap: 0.4rem 1.1rem; font-size: max(var(--text-floor), 0.86rem); color: var(--text-dim); font-variant-numeric: tabular-nums; }
.b0-led-row b { color: var(--text); font-weight: 800; }
.b0-pnl b { font-size: max(var(--text-floor), 1rem); }
.b0-wallets { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.b0-w { background: var(--ink); border: 1px solid var(--ink-4); border-radius: 12px; padding: 0.6rem 0.75rem; }
.b0-w-head { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.35rem; }
.b0-addr { font-family: ui-monospace, Menlo, monospace; font-size: max(var(--text-floor), 0.82rem); color: var(--text); }
.b0-tag { font-size: max(var(--text-floor), 0.68rem); font-weight: 900; border-radius: var(--r-pill); padding: 0.1rem 0.45rem; white-space: nowrap; }
.b0-w-stats { display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); font-variant-numeric: tabular-nums; }
.b0-w-stats b { color: var(--text); font-weight: 800; }
.b0-w-stats i { font-style: normal; opacity: 0.75; }
.b0-conn { margin-top: 0.45rem; }
.b0-conn summary { cursor: pointer; font-size: max(var(--text-floor), 0.8rem); color: var(--ctl-ink); background: var(--ctl-fill-lo); border-radius: var(--r-pill); padding: 0.3rem 0.7rem; font-weight: 700; min-height: 32px; display: inline-flex; align-items: center; list-style: none; transition: background 0.15s ease; }
.b0-conn summary::-webkit-details-marker { display: none; }   /* Safari before 18.4 drew its triangle inside the pill, off-centring the label */
.b0-conn summary:hover { background: var(--ctl-fill-hi); }
.b0-conn summary:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.b0-conn ul { list-style: none; margin: 0.35rem 0 0; padding: 0; display: grid; gap: 0.25rem; }
.b0-conn li { display: flex; flex-wrap: wrap; gap: 0.2rem 0.8rem; font-size: max(var(--text-floor), 0.78rem); color: var(--text-dim); background: var(--ink-2); border-radius: 8px; padding: 0.3rem 0.5rem; font-variant-numeric: tabular-nums; }
.b0-conn code { font-family: ui-monospace, Menlo, monospace; color: var(--text); }
.b0-none { margin: 0.35rem 0 0; font-size: max(var(--text-floor), 0.78rem); color: var(--text-dim); }
.b0-more { opacity: 0.7; }
.b0-note { margin: 0.6rem 0 0; font-size: max(var(--text-floor), 0.78rem); line-height: 1.5; color: var(--gold); }
.b0-fine { margin: 0.6rem 0 0; font-size: max(var(--text-floor), 0.75rem); line-height: 1.55; color: var(--text-dim); }
.b0-fine b { color: var(--text); }
@media (max-width: 420px) { .b0-tiles { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); } }

/* ===== 23b. Bundlers — bought and moved in one block, on every token detail (public/bundlers.js) =====
   The block-0 panel's tiles, messages and pop-down pill are reused as they are; these are the bundler rows. */
.np-bd { display: block; }
.bd-lead { margin: 0 0 0.6rem; font-size: max(var(--text-floor), 0.9rem); line-height: 1.5; color: var(--text); }
.bd-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.55rem; }
.bd-b { background: var(--ink); border: 1px solid var(--ink-4); border-radius: 12px; padding: 0.65rem 0.75rem; min-width: 0; }
.bd-b-head { display: flex; align-items: center; flex-wrap: wrap; gap: 0.35rem 0.5rem; margin-bottom: 0.3rem; }
.bd-b-n { font-size: max(var(--text-floor), 0.92rem); font-weight: 900; color: var(--text); }
.bd-kind { font-size: max(var(--text-floor), 0.7rem); font-weight: 800; border-radius: var(--r-pill); padding: 0.12rem 0.5rem; background: rgba(255,179,64,0.12); color: var(--gold); border: 1px solid rgba(255,179,64,0.4); overflow-wrap: anywhere; }
.bd-b-when { margin: 0 0 0.35rem; font-size: max(var(--text-floor), 0.78rem); line-height: 1.5; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.bd-b-when a { color: var(--diamond); white-space: nowrap; }
.bd-b-stats, .bd-wl-stats { display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); font-variant-numeric: tabular-nums; }
.bd-b-stats b, .bd-wl-stats b { color: var(--text); font-weight: 800; }
.bd-b-stats b.b0-up { color: var(--green-bright); }
.bd-b-stats b.b0-down { color: var(--red); }
.bd-b-stats i, .bd-wl-stats i { font-style: normal; opacity: 0.75; }
.bd-wallets .bd-wl-list { gap: 0.3rem; }
.bd-wallets .bd-wl { display: block; padding: 0.4rem 0.55rem; }
.bd-wl-head { display: flex; align-items: center; flex-wrap: wrap; gap: 0.2rem 0.6rem; margin-bottom: 0.2rem; }
.bd-addr { font-family: ui-monospace, Menlo, monospace; font-size: max(var(--text-floor), 0.8rem); color: var(--diamond); }
code.bd-addr { color: var(--text); }
.bd-roles { font-size: max(var(--text-floor), 0.72rem); color: var(--text-dim); }
/* a P&L tile's figure keeps its sign colour: `.b0-tile b` (green) is more specific than `.b0-down`, so a loss was drawn green */
.b0-tile b.b0-down { color: var(--red); }
.b0-tile b.b0-flat { color: var(--text); }
.bd-none { display: grid; gap: 0.25rem; }
.bd-none p { margin: 0; }
.bd-none .bd-none-h { font-size: max(var(--text-floor), 1.05rem); font-weight: 900; color: var(--green-bright); line-height: 1.3; }

/* --- The 90-day beta campaign banner ------------------------------------
   Amber for the deadline, green for what you keep — the two things a reader
   needs to tell apart at a glance. Never colour alone: the countdown says
   "ends", the badge column says "keep". */
.beta-card { max-width: 980px; margin: 0 auto; border-color: color-mix(in srgb, var(--gold) 34%, transparent); }
.beta-head { display: flex; align-items: center; gap: 0.9rem; flex-wrap: wrap;
  padding-bottom: 0.85rem; border-bottom: 1px solid var(--ink-4); }
.beta-k { font-size: max(var(--text-floor), 0.66rem); letter-spacing: 0.13em; text-transform: uppercase; color: var(--gold); font-weight: 800; }
.beta-when { font-weight: 800; color: var(--text); font-size: max(var(--text-floor), 1rem); font-variant-numeric: tabular-nums; }
.beta-count { margin-left: auto; font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), clamp(1.3rem, 5vw, 2rem));
  color: var(--gold); font-variant-numeric: tabular-nums; text-shadow: 0 0 18px rgba(255,179,64,0.45); }
.beta-cols { display: grid; grid-template-columns: 1fr; gap: 1rem; margin-top: 1rem; }
@media (min-width: 780px) { .beta-cols { grid-template-columns: 1fr 1fr; gap: 1.6rem; } }
.beta-h { margin: 0 0 0.4rem; font-size: max(var(--text-floor), 1rem); color: var(--green-bright); }
.beta-live { font-size: max(var(--text-floor), 0.68rem); letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-mute); font-weight: 700; }
.beta-board { list-style: none; margin: 0.6rem 0 0; padding: 0; display: grid; gap: 0.35rem; counter-reset: b; }
.beta-row { display: flex; align-items: center; gap: 0.6rem; padding: 0.45rem 0.65rem; min-width: 0;
  background: var(--ink-2); border: 1px solid var(--ink-4); border-radius: 9px; font-size: max(var(--text-floor), 0.9rem); }
.beta-row.is-top { border-color: color-mix(in srgb, var(--gold) 45%, transparent);
  background: color-mix(in srgb, var(--gold) 8%, var(--ink-2)); }
.beta-pl { font-weight: 800; color: var(--gold); min-width: 2.1rem; font-variant-numeric: tabular-nums; }
.beta-av { font-size: max(var(--text-floor), 1.05rem); }
.beta-nm { font-weight: 700; color: var(--text); overflow-wrap: anywhere; min-width: 0; text-decoration: none; }
.beta-nm:hover { text-decoration: underline; }
.beta-nm:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 4px; }
.beta-pt { margin-left: auto; font-weight: 800; color: var(--green-bright); font-variant-numeric: tabular-nums; white-space: nowrap; }
.beta-empty { color: var(--text-dim); font-size: max(var(--text-floor), 0.9rem); padding: 0.5rem 0; }

/* ═══ chart: hover readout, marker layers and the toggle row ════════════════════════════════════════
   The plot is position:relative so the tip is positioned inside the card it belongs to and can never
   escape it — a tooltip that hangs off the edge of a chart in a list is worse than no tooltip. */
.oc-plot { position: relative; }
/* The canvas keeps pan-y so a phone can still scroll the page by dragging over the chart; only the two
   scale strips below claim the gesture outright. */
.oc-canvas { touch-action: pan-y; }

/* ---- the two scales, as things you can actually grab ----------------------------------------------
   Laid exactly over the margins draw() reserves: PAD.b = 46px along the bottom for the time axis, and
   PAD.r = 70px down the right for the price gutter. The y strip is inset 12px from the plot so it never
   steals the hover from a marker sitting on the last candle. A cursor change alone would not announce
   these — the site hides the native cursor while the rocket is on — so they carry a faint arrow that
   comes up on hover and focus. */
.oc-grab {
  position: absolute; z-index: 3; margin: 0; padding: 0;
  background: transparent; border: 0; border-radius: 6px;
  color: var(--ctl-ink); font: inherit; font-size: max(var(--text-floor), 0.8rem); line-height: 1;
  display: grid; place-items: center; opacity: 0; transition: opacity 0.15s ease, background 0.15s ease;
  touch-action: none; -webkit-user-select: none; user-select: none;
}
.oc-grab-x { left: 8px; right: 70px; bottom: 0; height: 46px; cursor: ew-resize; place-items: end; padding: 0 4px 3px 0; touch-action: pan-y; }   /* a vertical swipe over the time axis scrolls the page, never zooms */
.oc-grab-y { top: 12px; bottom: 46px; right: 0; width: 58px; cursor: ns-resize; place-items: start end; padding: 2px 3px 0 0; }
/* The glyph sits in the same margin as the axis labels, so it carries its own ground rather than
   printing itself through whatever number happens to be behind it. */
.oc-grab > span {
  display: grid; place-items: center; height: 1.35em; padding: 0 0.28rem; border-radius: 5px; line-height: 1;
  background: var(--ctl-fill-lo);
}
/* The double arrows are drawn (an SVG mask in the text colour), not typed: ↔ and ↕ come from a fallback symbol font
   whose arrows sit 1–2px off the middle of the tab. */
.oc-grab-ico { display: block; width: 1em; height: 0.6em; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 12'%3E%3Cpath d='M0 6 5 1v3h10V1l5 5-5 5V8H5v3z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 12'%3E%3Cpath d='M0 6 5 1v3h10V1l5 5-5 5V8H5v3z'/%3E%3C/svg%3E") center / 100% 100% no-repeat; }
.oc-grab-ico-y { width: 0.6em; height: 1em;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 20'%3E%3Cpath d='M6 0l5 5H8v10h3l-5 5-5-5h3V5H1z'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 20'%3E%3Cpath d='M6 0l5 5H8v10h3l-5 5-5-5h3V5H1z'/%3E%3C/svg%3E"); }
.oc-plot:hover .oc-grab, .oc-grab:focus-visible, .oc-grab.is-dragging { opacity: 1; }
/* An edge, not a fill. A tinted block over the axis washes out the very labels you are dragging the
   scale to read; a line along the edge the strip owns says the same thing and leaves them legible. */
.oc-grab:hover, .oc-grab.is-dragging { color: var(--ctl-ink); }
.oc-grab:hover > span, .oc-grab.is-dragging > span { background: var(--green-bright); }
.oc-grab-x:hover, .oc-grab-x.is-dragging { box-shadow: inset 0 2px 0 0 color-mix(in srgb, var(--green) 70%, transparent); }
.oc-grab-y:hover, .oc-grab-y.is-dragging { box-shadow: inset -2px 0 0 0 color-mix(in srgb, var(--green) 70%, transparent); }
.oc-grab:focus-visible { outline: 2px solid var(--green); outline-offset: -2px; opacity: 1; }
/* Returns the chart to the window it was fetched for. Only present while the view has been moved, so it
   is never a control that does nothing. */
.oc-reset {
  position: absolute; z-index: 5; top: 6px; left: 10px;
  padding: 0.2rem 0.5rem; border-radius: 999px; cursor: pointer;
  background: var(--ctl-fill-lo);
  border: 1px solid var(--ctl-fill-lo); color: var(--ctl-ink);
  font: inherit; font-size: max(var(--text-floor), 0.68rem); font-weight: 700; letter-spacing: var(--tr-caps);
}
.oc-reset:hover { color: var(--on-green); background: var(--green); border-color: var(--green); }
.oc-reset:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
/* On a phone these strips are the only elements that take the touch outright, so they are kept as small
   as they can be and still be hit: a 58px-wide band down the right edge that refuses to scroll the page
   is a worse trade than a slightly harder scale to grab. */
@media (max-width: 640px) {
  .oc-grab-y { width: 34px; }
  .oc-grab-x { height: 30px; }
  /* the status line under the chart already says where the numbers come from, at more length */
  .oc-src { display: none; }
  .oc-live { margin-right: 0; }
}
@media (prefers-reduced-motion: reduce) { .oc-grab { transition: none; } }
.oc-tip {
  position: absolute; z-index: 4; pointer-events: none;
  min-width: 190px; max-width: 300px; padding: 0.55rem 0.65rem;
  background: color-mix(in srgb, var(--bg-1, #10131f) 94%, transparent);
  border: 1px solid var(--hair); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.45);
  font-size: max(var(--text-floor), 0.8rem); line-height: 1.45; color: var(--text);
}
.oc-tip.is-wide { max-width: 360px; }
.oc-tip-t { font-size: max(var(--text-floor), 0.7rem); letter-spacing: var(--tr-caps); text-transform: uppercase; color: var(--text-mute); margin-bottom: 0.35rem; }
.oc-tip-row { display: flex; justify-content: space-between; gap: 1rem; }
.oc-tip-row b { font-family: var(--mono, ui-monospace, monospace); font-variant-numeric: tabular-nums; }
.oc-tip-dim, .oc-tip-dim b { color: var(--text-dim); font-weight: 600; }
.oc-tip-list { list-style: none; margin: 0.3rem 0 0; padding: 0; display: grid; gap: 0.25rem; }
.oc-tip-list li { font-size: max(var(--text-floor), 0.78rem); line-height: 1.4; }
/* The caveat is part of the number, not decoration under it: a market cap built on today's supply, or a
   figure rounded because it is not yours, has to say so wherever it is read. */
.oc-tip-note { margin-top: 0.35rem; padding-top: 0.3rem; border-top: 1px solid var(--hair); font-size: max(var(--text-floor), 0.64rem); line-height: 1.35; color: var(--text-mute); }

.oc-up { color: var(--green-bright); font-weight: 700; }
.oc-dn { color: var(--red); font-weight: 700; }

.oc-legend { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.45rem; }
.oc-mk {
  display: inline-flex; align-items: center; gap: 0.3rem;
  padding: 0.22rem 0.5rem; border-radius: 999px; cursor: pointer;
  background: var(--ctl-fill-lo); border: 1px solid var(--ctl-fill-lo); color: var(--ctl-ink);
  font: inherit; font-size: max(var(--text-floor), 0.7rem); font-weight: 600; line-height: 1.6;
}
.oc-mk:hover { color: var(--ctl-ink); background: var(--ctl-fill-hi); border-color: var(--ctl-fill-hi); }
.oc-mk.is-on { color: var(--on-green); border-color: var(--green); background: var(--green); }
/* A layer with nothing in this window is dimmed rather than hidden — "no Send Calls here" is information,
   and a control that vanishes when its count is zero just looks broken. It must still read as ON though:
   at 0.45 an enabled-but-empty layer was indistinguishable from a disabled one, so the toggle stopped
   telling you what it was actually doing. */
/* dimmed by FILL, not by opacity — opacity on a light pill is what pushes the black label under 4.5:1 */
.oc-mk.is-empty:not(.is-on) { background: var(--ctl-fill-mute); border-color: var(--ctl-fill-mute); }
.oc-mk.is-empty.is-on { background: var(--green-dark); border-color: var(--green-dark); }
/* a count the current timeframe cannot reach — the events exist, the window does not include them */
.oc-mk-out { font-size: max(var(--text-floor), 0.64rem); }
.oc-mk-g { font-size: max(var(--text-floor), 0.85rem); }
.oc-mk-n { font-family: var(--mono, ui-monospace, monospace); font-variant-numeric: tabular-nums; }
.oc-mk-clean { margin-left: auto; }
@media (max-width: 640px) { .oc-mk-clean { margin-left: 0; } .oc-tip { max-width: 240px; } }
@media (prefers-reduced-motion: reduce) { .oc-tip { transition: none; } }

/* ═══ 💀 REKT + 🗂️ YOUR RECORD ════════════════════════════════════════════════════════════════════════
   The dashboard used to be one-sided: every block on it was a way to gain, while the engine behind it
   also drains a balance for absence, mutes accounts on a ladder that never resets, shrinks a caller's
   allowance and revokes badges on a sell. None of that reached the screen, so the first a person heard
   of any of it was a notification saying it had already happened.

   Three rules hold this section together:
   1. RISK IS NEVER COLOUR ALONE. Every row that carries a consequence pairs its colour with a glyph
      (▲ / ✓ / ○ / ✕) and with words. Someone who cannot separate the red from the green reads exactly
      the same warning, and so does anyone on a monochrome display or a printed page.
   2. IT IS NOT BEHIND A DISCLOSURE. The rulebook below it is a <details> because it is reference; a
      consequence you can be surprised by has to be visible without a click.
   3. THE STATE SITS NEXT TO THE RULE. Each card states the rule and then this account's standing
      against it, because a rule with no standing is a poster and a standing with no rule is a telling-off. */
.grekt, .grec { margin-top: 1.6rem; }
.grekt-head { margin-bottom: 0.8rem; }
.grekt-lede { margin: 0.2rem 0 0; color: var(--text-dim); font-size: max(var(--text-floor), 0.88rem); line-height: 1.55; max-width: 70ch; }

/* auto-fit, so this is one column on a phone and two or three on a desk without a media query per breakpoint */
.grekt-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 0.9rem; align-items: start; }

.rekt-card {
  background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 14px;
  padding: 0.9rem 1rem 1rem; display: flex; flex-direction: column; gap: 0.5rem;
}
/* something is ACTIVE against this account right now — the left rail is the shape, the word in the
   pill is the message, and neither depends on the other being perceivable */
.rekt-card.is-live { border-color: rgba(255,93,93,0.45); box-shadow: inset 3px 0 0 0 var(--red); }
.rekt-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; }
.rekt-h { margin: 0; font-size: max(var(--text-floor), 0.98rem); font-weight: 800; color: var(--text); }
.rekt-h5 { margin: 0.5rem 0 0.15rem; font-size: max(var(--text-floor), 0.74rem); font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-mute); }
.rekt-lede { margin: 0; font-size: max(var(--text-floor), 0.85rem); line-height: 1.55; color: var(--text-dim); }
.rekt-p { margin: 0.1rem 0 0; font-size: max(var(--text-floor), 0.82rem); line-height: 1.55; color: var(--text-dim); }
.rekt-p b, .rekt-lede b, .rekt-list b { color: var(--text); }
.rekt-last { margin: 0.2rem 0 0; font-size: max(var(--text-floor), 0.76rem); color: var(--text-mute); }

.rekt-state { font-size: max(var(--text-floor), 0.68rem); font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; padding: 0.18rem 0.5rem; border-radius: 999px; white-space: nowrap; }
.rekt-state-safe { color: var(--green-bright); background: var(--g-tint); border: 1px solid color-mix(in srgb, var(--green) 38%, transparent); }
.rekt-state-bad  { color: var(--red-soft);           background: rgba(255,93,93,0.14); border: 1px solid rgba(255,93,93,0.45); }
.rekt-state-warn { color: var(--gold);       background: rgba(255,179,64,0.14); border: 1px solid rgba(255,179,64,0.45); }

.rekt-list { list-style: none; margin: 0.15rem 0 0; padding: 0; display: grid; gap: 0.45rem; }
.rekt-row { display: grid; grid-template-columns: 1.1rem 1fr; gap: 0.5rem; align-items: start; font-size: max(var(--text-floor), 0.82rem); line-height: 1.5; color: var(--text-dim); }
/* the glyph IS the severity — ▲ warns, ✓ confirms, ○ is neutral. Colour only reinforces it. */
.rekt-dot { font-size: max(var(--text-floor), 0.72rem); line-height: 1.5; color: var(--text-mute); text-align: center; }
.rekt-row-bad .rekt-dot { color: var(--red); }
.rekt-row-ok  .rekt-dot { color: var(--green-bright); }

.rekt-ladder { list-style: none; counter-reset: none; margin: 0.3rem 0 0; padding: 0; display: grid; gap: 0.3rem; }
.rekt-rung { display: flex; align-items: center; gap: 0.5rem; font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); padding: 0.35rem 0.5rem; border-radius: 9px; background: var(--ink-3); border: 1px solid transparent; }
.rekt-rung-n { flex: none; width: 1.35rem; height: 1.35rem; border-radius: 50%; display: grid; place-items: center; place-content: center; line-height: 1; font-size: max(var(--text-floor), 0.72rem); font-weight: 800; background: var(--ink-4); color: var(--text-dim); }   /* line-height 1: a 1.5 line box is taller than the disc and grew from its top, which dropped the digit 4px */
.rekt-rung.is-on { border-color: rgba(255,93,93,0.5); background: rgba(255,93,93,0.09); color: var(--text); }
.rekt-rung.is-on .rekt-rung-n { background: var(--red); color: #2a0a0a; }
.rekt-rung-you { margin-left: auto; font-size: max(var(--text-floor), 0.64rem); font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--red-soft); }

.rekt-live { border-radius: 10px; padding: 0.6rem 0.7rem; background: rgba(255,93,93,0.09); border: 1px solid rgba(255,93,93,0.4); font-size: max(var(--text-floor), 0.82rem); line-height: 1.55; color: var(--text); }
.rekt-live p { margin: 0 0 0.45rem; }
.rekt-live p:last-child { margin-bottom: 0; }
.rekt-live a { color: var(--green-bright); }

.rekt-split { display: grid; grid-template-columns: 1fr 1fr; gap: 0.7rem; margin-top: 0.2rem; }
.rekt-yes, .rekt-no { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.25rem; font-size: max(var(--text-floor), 0.78rem); line-height: 1.45; }
.rekt-yes li, .rekt-no li { display: grid; grid-template-columns: 0.9rem 1fr; gap: 0.4rem; color: var(--text-dim); }
.rekt-yes li span[aria-hidden] { color: var(--green-bright); }
.rekt-no  li span[aria-hidden] { color: var(--red); }
@media (max-width: 460px) { .rekt-split { grid-template-columns: 1fr; } }

/* ---- the rolling ceiling meter on the Quest Board ---- */
.gcap { margin-top: 0.7rem; background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 12px; padding: 0.6rem 0.7rem; }
.gcap-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; font-size: max(var(--text-floor), 0.8rem); font-weight: 800; color: var(--text-dim); margin-bottom: 0.4rem; }
.gcap-head b { color: var(--text); font-variant-numeric: tabular-nums; }
.gcap-fill { background: linear-gradient(90deg, var(--gold), var(--gold-deep)); }
.gcap-note { margin: 0.4rem 0 0; font-size: max(var(--text-floor), 0.75rem); line-height: 1.5; color: var(--text-mute); }
.gcap-note b { color: var(--text-dim); }

/* ---- losses in the Loot Log ---- */
.loot-losses { margin-top: 0.5rem; padding-top: 0.5rem; border-top: 1px dashed var(--ink-4); }
.ll-pts-loss { color: var(--red-soft); }
.ll-fill-loss { background: linear-gradient(90deg, #ff5d5d, #8c2020) !important; }
.loot-foot-loss { color: var(--text-mute); }
.loot-foot-loss a { color: var(--green-bright); }
/* a negative day must not be red text sitting in a green chip — the whole chip changes side */
.pc-today.is-down { color: var(--red-soft); background: rgba(255,93,93,0.14); border-color: rgba(255,93,93,0.45); }
.kpi-dn { color: var(--red-soft); }

/* ---- 🗂️ your record: name/value pairs, announced as such ---- */
.rec-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(168px, 100%), 1fr)); gap: 0.55rem; margin: 0; }
.rec { background: var(--ink); border: 1.5px solid var(--ink-4); border-left-width: 3px; border-radius: 11px; padding: 0.55rem 0.65rem; }
.rec-k { margin: 0; font-size: max(var(--text-floor), 0.66rem); font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-mute); }
.rec-v { margin: 0.15rem 0 0; font-size: max(var(--text-floor), 1.02rem); font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; line-height: 1.2; }
.rec-sub { display: block; margin-top: 0.15rem; font-size: max(var(--text-floor), 0.7rem); font-weight: 600; color: var(--text-dim); letter-spacing: 0; text-transform: none; font-variant-numeric: normal; line-height: 1.4; }
/* the left border carries the state as a THICKNESS and a POSITION, not only a hue */
.rec-ok   { border-left-color: var(--green); }
.rec-bad  { border-left-color: var(--red); }
.rec-bad .rec-v { color: var(--red-soft); }
.rec-warn { border-left-color: var(--gold); }
.rec-warn .rec-v { color: var(--gold); }

@media (prefers-contrast: more) {
  .rekt-card, .rec { border-color: var(--text-mute); }
  .rekt-state { border-width: 2px; }
}

/* ---- the community / conviction XP table in the rulebook ---- */
.gxp-table-wrap { margin: 0.6rem 0; overflow-x: auto; }   /* a table never makes the page scroll sideways */
.gxp-table { width: 100%; border-collapse: collapse; font-size: max(var(--text-floor), 0.8rem); min-width: 330px; }
.gxp-table caption { text-align: left; font-size: max(var(--text-floor), 0.7rem); font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-mute); padding-bottom: 0.35rem; }
.gxp-table th, .gxp-table td { padding: 0.35rem 0.5rem; text-align: left; border-bottom: 1px solid var(--ink-4); }
.gxp-table thead th { font-size: max(var(--text-floor), 0.7rem); font-weight: 800; color: var(--text-mute); white-space: nowrap; }
.gxp-table tbody th { font-weight: 600; color: var(--text-dim); }
.gxp-table td { color: var(--green-bright); font-variant-numeric: tabular-nums; white-space: nowrap; }
.gxp-na { color: var(--text-mute); }
.gxp-foot { margin: 0.45rem 0 0; font-size: max(var(--text-floor), 0.78rem); line-height: 1.5; color: var(--text-mute); }
.gxp-foot b { color: var(--text-dim); }
/* the floor, named on the equation strip: the term shrinks for a reason, and the reason is worth a sentence */
.eq-dust { margin: 0.35rem 0 0; font-size: max(var(--text-floor), 0.78rem); line-height: 1.5; color: var(--gold); }
.eq-dust a { color: var(--gold); }

/* ---- notification rows that go somewhere ----------------------------------------------------------
   The panel used to be role="menu" full of plain divs. It is a LIST now, because that is what it is: some
   rows link to the thing they are about, each has its own dismiss button, and a menu role promised arrow-
   key behaviour that was never implemented. The whole row is the link so the hit target is the row, not
   the sentence inside it (WCAG 2.5.8 — a target you can actually hit). */
.notif-list { list-style: none; margin: 0; padding: 0; }
.notif-item { display: flex; gap: 0.6rem; align-items: stretch; padding: 0; border-bottom: 1px solid var(--hair); }
.notif-go {
  display: flex; gap: 0.6rem; align-items: flex-start; flex: 1 1 auto; min-width: 0;
  padding: 0.6em 0.3em 0.6em 0.8em; color: inherit; text-decoration: none;
}
.notif-item.is-link .notif-go:hover { background: color-mix(in srgb, var(--green) 8%, transparent); }
/* --focus, not an accent token. prefs.js re-solves --green-bright / --gold / --accent from the user's own
   colour choices and clamps them only against --ink, so a focus ring built from one of them can end up
   near-invisible on this panel for somebody who picked an unlucky theme. A focus ring is the one thing
   that may never depend on a preference. Inset, because the row is flush to the panel edge. */
.notif-item.is-link .notif-go:focus-visible { outline: 3px solid var(--focus); outline-offset: -3px; border-radius: 8px; }
/* full opacity: a 35% alpha of the accent composites to roughly 2.8:1 on this panel, under the 3:1 a
   non-text indicator needs (WCAG 1.4.11) */
.notif-item.is-link .notif-text { text-decoration: underline; text-decoration-color: var(--green-bright); text-underline-offset: 2px; }
/* a row scrolled to by the keyboard must not hide under the sticky nav */
.notif-go { scroll-margin-top: 44px; scroll-margin-bottom: 8px; }
.notif-body { display: flex; flex-direction: column; min-width: 0; }
.notif-x { align-self: center; margin-right: 0.5em; }
.notif-empty { padding: 1em 0.9em; }

/* ---- the alert toggle on someone else's wall ----
   Reads as off by default and clearly lit when on, with the state in aria-pressed as well as in the
   label — a bell that only changes colour tells a colour-blind reader nothing, and tells a screen-reader
   user nothing at all. */
.btn-alert.on {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--on-gold);
}
.btn-alert.on:hover { background: var(--gold-deep); border-color: var(--gold-deep); color: var(--ctl-ink); }

/* ---- the alert list in Settings ---- */
.alert-list { list-style: none; margin: 0.5rem 0 0; padding: 0; display: grid; gap: 0.4rem; }
.alert-row {
  display: flex; align-items: center; justify-content: space-between; gap: 0.6rem;
  background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 10px; padding: 0.45rem 0.6rem;
}
.alert-who { color: var(--green-bright); font-weight: 800; text-decoration: none; }
.alert-who:hover { text-decoration: underline; }

/* ═══ SCANNER: strategies and the settings that move when you press one ═════════════════════════════
   A strategy is a saved search shape, not a grade — so these read as controls, not as badges, and the
   pressed one is marked by a border and a word as well as a colour. */
.np-strats { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; margin: 0.6rem 0 0.35rem; }
.np-strats-lead { font-size: max(var(--text-floor), 0.78rem); font-weight: 800; color: var(--text-mute); letter-spacing: 0.03em; margin-right: 0.2rem; }
.np-strat {
  font: inherit; font-size: max(var(--text-floor), 0.82rem); font-weight: 700; cursor: pointer;
  background: var(--ctl-fill-lo); color: var(--ctl-ink);
  border: 1.5px solid var(--ctl-fill-lo); border-radius: 999px; padding: 0.38rem 0.75rem; min-height: 34px;
}
.np-strat:hover { border-color: color-mix(in srgb, var(--green) 45%, transparent); background: var(--ctl-fill-hi); color: var(--ctl-ink); }
.np-strat:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.np-strat.is-on {
  background: var(--green);
  border-color: var(--green); color: var(--on-green);
}
.np-strat-note { margin: 0 0 0.5rem; font-size: max(var(--text-floor), 0.8rem); line-height: 1.5; color: var(--text-dim); }
.np-strat-note b { color: var(--text); }
/* the half of a filter that is honest: what it cannot tell you */
.np-strat-cannot { display: block; margin-top: 0.2rem; font-size: max(var(--text-floor), 0.76rem); color: var(--gold); }
.np-strat-edited { margin-left: 0.4rem; font-size: max(var(--text-floor), 0.74rem); font-weight: 800; color: var(--text-mute); }

/* A setting a strategy just moved. Motion is how this is normally delivered, but the INFORMATION is the
   mark — so under reduced motion the mark simply stays put instead of pulsing and fading. */
.np-f-moved { position: relative; border-radius: 8px; }
.np-f-moved::after {
  content: 'changed'; position: absolute; top: -7px; right: 4px;
  font-size: max(var(--text-floor), 0.56rem); font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-1); background: var(--green-bright); border-radius: 999px; padding: 0.05rem 0.32rem;
}
@media (prefers-reduced-motion: no-preference) {
  .np-f-moved { animation: npMoved 2.6s ease-out; }
  @keyframes npMoved {
    0%   { background: color-mix(in srgb, var(--green) 30%, transparent); }
    70%  { background: color-mix(in srgb, var(--green) 16%, transparent); }
    100% { background: transparent; }
  }
}

/* ---- market cap then → now, on a token's detail ---- */
.np-captrail { margin: 0.6rem 0 0.2rem; }
.np-captrail > .lbl { font-size: max(var(--text-floor), 0.68rem); font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-mute); margin-bottom: 0.3rem; }
.np-captrail .lbl i { font-style: normal; font-weight: 600; text-transform: none; letter-spacing: 0; opacity: 0.8; }
.np-capx { font-size: max(var(--text-floor), 0.78rem); font-weight: 800; margin-left: 0.25rem; }
.np-capx.up { color: var(--green-bright); }
.np-capx.down { color: var(--red-soft); }
.np-cap-note { margin: 0.35rem 0 0; font-size: max(var(--text-floor), 0.72rem); line-height: 1.5; color: var(--text-mute); }
.np-cap-note b { color: var(--text-dim); }

/* The middle tier — 75 and above. Green, because it IS good, but flat: no gradient, no glow, no pulse.
   "Send It" has to stay the louder of the two at a glance, and the difference between them is a real
   difference in what was checked, not decoration. */
.np-verdict.np-t-good { background: color-mix(in srgb, var(--green) 10%, transparent); border-color: color-mix(in srgb, var(--green-bright) 40%, transparent); }
.np-verdict.np-t-good .np-verdict-word, .np-why-h .np-verdict-word.np-t-good { color: var(--green-bright); }

/* The reader's own bar. It reads GREEN, exactly like the site's own — the words are the same, and a
   different hue for the same sentence only ever said "yours counts for less".

   Losing the colour difference costs nothing that was load-bearing, because colour was never carrying the
   attribution: it reaches neither a screen reader, nor a colour-blind reader, nor forced-colours mode.
   The chip no longer distinguishes them at all: same rocket, same words, same green, by request. Whose
   judgement it was is now carried by the spoken line — "matching the filters you set — your settings, not
   ours" — and by the detail panel's heading, which reads "Why your settings say" rather than "Why we say".

   It keeps its own class so it stays addressable, and stops short of .np-t-perfect's pulse: the site's own
   bar is the rarer thing and may still celebrate louder. Same colour, same words, different signature. */
.np-verdict.np-t-yours { background: linear-gradient(180deg, var(--g-veil), color-mix(in srgb, var(--green-bright) 12%, transparent)); border-color: var(--green-bright); box-shadow: 0 0 16px color-mix(in srgb, var(--green-bright) 35%, transparent); }
.np-verdict.np-t-yours .np-verdict-word { color: var(--green-bright); }
/* The detail panel's heading — "Why we say <word>" / "Why your settings say <word>" — puts the word in a
   bare .np-verdict-word with no .np-verdict wrapper, so neither chip rule above reaches it. It used to be
   coloured for the reader's bar (which matched on the bare class) and not for the site's (which needs the
   descendant), i.e. exactly backwards. Both now read the same, which is the point of the whole change —
   and this heading is the ONLY verdict text on the Send Wall, communities, support and profiles. */
.np-why-h .np-verdict-word.np-t-perfect, .np-why-h .np-verdict-word.np-t-yours { color: var(--green-bright); }
/* The byline. Both bars award the same words now, so this is the thing that says whose judgement it was.
   It is sized to be READ, not to be technically present: 0.66rem on a 0.78rem chip is the smallest it can
   be and still carry a claim this load-bearing. It is never aria-hidden and never colour-only — the icon
   differs too, and the spoken line says it in words. */
/* The chip is one row again — no byline — so the wrap and the width cap that existed only to hold it are
   gone with it. */

/* ═══ SCANNER SETTINGS AS A POP-DOWN ════════════════════════════════════════════════════════════════
   It used to be an inline block: opening it pushed the whole list down the page, and on a long panel the
   rows you were reading vanished under it. It is anchored under the controls row now and floats over the
   list instead, so what you were looking at stays where it was.

   .np-controls is sticky at z-index 30, so this has to sit above it AND be positioned against a container
   that is not itself the sticky element — the panel is a sibling, absolutely positioned inside the page
   column, which keeps it out of the sticky stacking context. */
.np-filters {
  position: absolute; z-index: 45; left: 0; right: 0;
  max-height: min(70vh, 620px); overflow-y: auto; overscroll-behavior: contain;
  margin-top: 0.2rem;
  /* Reserve the strip the pinned controls own. Measured before this line existed: with the panel scrolled
     to its end the footer sat at 805–849 while #music-player held 788–849 and #compose-fab 799–850, both
     at z-index 240+ against this panel's 45 — "Save current view" and "Reset filters" were not close to
     the pinned buttons, they were behind them, and could not be clicked at all. */
  padding-bottom: calc(0.7rem + var(--fab-clear));
  box-shadow: 0 24px 60px rgba(0,0,0,0.6);
  border-color: color-mix(in srgb, var(--green) 30%, var(--ink-4));
  align-items: flex-start;
}
/* the anchor: the page column the controls row already lives in */
.np-wrap { position: relative; }
.np-fhead {
  position: sticky; top: 0; z-index: 2;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.4rem 0.7rem;
  width: 100%; margin: -0.7rem -0.9rem 0.35rem; padding: 0.6rem 0.9rem 0.5rem;
  width: calc(100% + 1.8rem);
  background: var(--ink); border-bottom: 1px solid var(--ink-4);
}
.np-fhead-title { margin: 0; font-size: max(var(--text-floor), 0.95rem); font-weight: 800; color: var(--text); }
.np-fhead-sub { margin: 0; font-size: max(var(--text-floor), 0.76rem); color: var(--text-mute); flex: 1 1 auto; }
.np-fhead-sub b { color: var(--text-dim); }
.np-fclose {
  margin-left: auto; flex: none; cursor: pointer;
  width: 34px; height: 34px; border-radius: 9px; font-size: max(var(--text-floor), 0.95rem); line-height: 1;
  background: var(--ctl-fill-lo); border: 1.5px solid var(--ctl-fill-lo); color: var(--ctl-ink);
}
.np-fclose:hover { color: var(--on-red); border-color: var(--red); background: var(--red); }
.np-fclose:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

/* Tap-outside-to-close needs something to tap. Invisible on a desktop, a real dimmer on a phone where the
   panel becomes a sheet and the page behind it must read as inert. */
.np-sheet-backdrop { position: fixed; inset: 0; z-index: 40; background: transparent; }

@media (max-width: 760px) {
  /* On a phone an anchored pop-down is just a tall box in a narrow column, so it becomes a bottom sheet:
     thumb-reachable, dismissable by tapping the dimmed page, and it never covers the nav. */
  .np-filters {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto;
    max-height: 82dvh; margin: 0; border-radius: 18px 18px 0 0;
    /* same clearance as the desktop pop-down: as a fixed bottom sheet this sits UNDER the pinned
       player and SEND IT button (z 240+ vs 45), so the strip they occupy has to stay reserved here too. */
    border-bottom: 0; padding-bottom: calc(0.7rem + var(--fab-clear));
  }
  .np-sheet-backdrop { background: rgba(4,6,14,0.6); backdrop-filter: blur(2px); }
  .np-fhead { margin-top: -0.7rem; }
}
@media (prefers-reduced-motion: no-preference) {
  .np-filters { animation: npSheetIn 0.16s ease-out; }
  @keyframes npSheetIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
  @media (max-width: 760px) {
    @keyframes npSheetIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
  }
}

/* ---- Save and Reset also live at the top --------------------------------------------------------
   Reserving the strip stops the footer pair being covered, but it still sits past eight fieldsets. The
   same two actions sit in the sticky header as well, so neither needs a scroll to the end to reach. */
.np-filters-foot { position: relative; z-index: 1; }
.np-fhead-acts { display: flex; gap: 0.4rem; flex: 0 0 auto; }
.np-fhead-acts .btn { white-space: nowrap; }
/* the "name this view" form opens wherever Save was pressed; in the header that means its own row */
.np-fhead .np-saveform { order: 5; flex-basis: 100%; padding-top: 0.15rem; }
@media (max-width: 560px) {
  .np-fhead-sub { order: 3; flex-basis: 100%; }
  .np-fhead-acts { order: 2; }
}

/* ===== tip bubble — the description popup every control carries (see public/tips.js) ==============
   Positioned in script with position:fixed, so this only has to dress it. It must read on top of the
   modal layer (500) but under the rocket cursor (9998/9999), which is decorative and pointer-events:none.
   pointer-events stays AUTO: SC 1.4.13 requires the pointer be able to travel into the description. */
.tip-bubble {
  position: fixed; z-index: 9990; pointer-events: auto;
  max-width: 300px; padding: 0.5rem 0.65rem;
  font-size: max(var(--text-floor), 0.8rem); line-height: 1.4; font-weight: 600;
  color: var(--text); background: var(--ink-2);
  border: 1.5px solid var(--edge-ctl); border-radius: var(--r-2);
  box-shadow: var(--shadow-2);
  opacity: 0; transform: translateY(2px);
  transition: opacity 0.13s ease, transform 0.13s ease;
}
.tip-bubble.is-on { opacity: 1; transform: none; }
/* reduced motion: no travel, no fade — it is either there or it is not */
.tip-bubble.is-instant { transition: none; transform: none; }
@media (prefers-reduced-motion: reduce) { .tip-bubble { transition: none; transform: none; } }

/* ===== voice memos ===============================================================================
   The 🎤 button sits beside the photo attach and matches it, because they are the same kind of thing:
   two ways to put something in a post. It only changes character while it is actually listening. */
.voice-btn { cursor: pointer; font-variant-numeric: tabular-nums; }
.voice-btn.is-recording {
  color: var(--on-red); border-color: var(--red);
  background: var(--red);
}
/* A recording indicator has to be visible without colour — somebody who cannot tell red from grey still
   needs to know the microphone is live — so it pulses as well, and says "Stop" in words. */
@media (prefers-reduced-motion: no-preference) {
  .voice-btn.is-recording { animation: voice-pulse 1.1s ease-in-out infinite; }
  @keyframes voice-pulse { 50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--red) 22%, transparent); } }
}
.media-preview-audio { width: 100%; min-height: 40px; display: block; }

/* A posted memo. Labelled rather than a bare <audio>, so somebody scrolling past knows what it is
   before they press play, and a screen reader is told the same thing. */
.post-voice { display: flex; flex-direction: column; gap: 0.35rem; margin: 0.6rem 0 0.2rem; }
.post-voice-tag {
  align-self: flex-start; font-size: max(var(--text-floor), 0.72rem); font-weight: 800; letter-spacing: 0.02em;
  color: var(--green-bright); background: color-mix(in srgb, var(--green) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--green-bright) 34%, transparent);
  border-radius: 999px; padding: 0.12rem 0.55rem;
}
.post-audio { width: 100%; max-width: 420px; height: 40px; }

/* ===== the Security panel's own state ============================================================
   Wallets, sign-in methods and two-factor all live in one <details>, and a <details> opens shut. The
   summary carries the state so the answer to "am I covered?" is readable without opening anything. */
.sec-state { font-family: 'Rubik', sans-serif; font-size: max(var(--text-floor), 0.72rem); font-weight: 800; letter-spacing: 0.01em; color: var(--ctl-ink); margin-left: 0.5rem; }
/* No second factor is worth noticing, but it is not an error — the site does not require one. Gold,
   not red, and the words say it either way for anyone who cannot see the colour. Gold as a FILL: the
   summary it sits in is green now, and gold type on green clears nothing. */
.sec-state.sec-state-warn { color: var(--on-gold); background: var(--gold); border-radius: var(--r-pill); padding: 0.12rem 0.55rem; }
.sec-jump { margin: -0.6rem 0 1.2rem; }

/* ---------- motion pause (WCAG 2.2.2) ----------
   Decorative motion that starts by itself and never stops — the ticker, the OG banner's sweeps, the hero
   field, the world grid, the breathing FAB — needs a control the reader can reach without an account.
   html.motion-off is set by the ⏸ button in the nav (app.js) and remembered per browser; it pauses every
   ambient animation while leaving state animations (toasts, fills, focus) alone. Hover or focus inside the
   ticker also pauses it, which is what makes the scrolling text readable at all. */
.ticker:hover .ticker-track, .ticker:focus-within .ticker-track { animation-play-state: paused; }
html.motion-off .ticker-track, html.motion-off .float-emoji, html.motion-off .hero-logo, html.motion-off .hero h1 .rocket,
html.motion-off #compose-fab, html.motion-off .og-banner, html.motion-off .og-banner::before, html.motion-off .og-shine,
html.motion-off .og-confetti span, html.motion-off .og-medal, html.motion-off .og-banner-cta, html.motion-off .og-cta-arrow,
html.motion-off body::before, html.motion-off .rh-badge .dot, html.motion-off .mcap-value.pumping, html.motion-off .np-verdict.np-t-perfect,
html.motion-off #music-player .eq span, html.motion-off .relic-pip, html.motion-off .forge-flame, html.motion-off .gxp.near .gxp-fill,
/* the same infinite pulses the prefers-reduced-motion rules stop — the switch is for readers without the OS setting */
html.motion-off .nav-live-dot, html.motion-off .og-timer.og-timer-soon, html.motion-off .np-live-dot, html.motion-off .comm-pulse i, html.motion-off .np-feed-hint { animation-play-state: paused !important; }
html.motion-off #matrix-rain { display: none; }
.motion-btn { display: inline-flex; align-items: center; justify-content: center; min-width: var(--nav-ctl); min-height: var(--nav-ctl); border-radius: 999px; border: 1.5px solid var(--ctl-fill-lo); background: var(--ctl-fill-lo); color: var(--ctl-ink); font: inherit; font-size: var(--nav-fs); cursor: pointer; margin-right: 0; }
.motion-btn:hover, .motion-btn:focus-visible { color: var(--ctl-ink); background: var(--ctl-fill-hi); border-color: var(--green); }
.motion-btn[aria-pressed="true"] { color: var(--on-green); background: var(--green); border-color: var(--green); }

/* the zoom strips are hover-revealed, which on a touch screen means invisible: show them where there is no hover */
@media (hover: none) { .oc-grab { opacity: 0.85; } }
@media (max-width: 400px) { .feed-sort #sort-caption { flex: 1 1 100%; text-align: center; } }
/* the hero logo as a control: a button reset that keeps the image's own bob/glow and the global focus ring */
.hero-logo-btn { display: inline-block; padding: 0; margin: 0; border: 0; background: none; cursor: pointer; line-height: 0; border-radius: 24px; }
.hero-logo-btn:focus-visible { outline: 3px solid var(--focus); outline-offset: 6px; }

/* ---------- layering the ticket forced ----------
   #invite-overlay sits at 9000. Three things must be able to appear OVER it: the wallet picker it opens
   (was 500 — it opened invisibly for every mobile visitor), the confirm-mode sign-in pane the proof step
   can raise (was 400), and the toasts (were 200). All stay under the rocket cursor's 9998. */
#auth-modal.is-confirm { z-index: 9500; }
.modal-note.is-err { color: var(--red); }
.snap-tablewrap:focus-visible, .comm-members-list:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
/* the holdings tooltip on a Conviction Play chip: reachable on touch (a tap opens it) and by focus */
.pin-hover { pointer-events: auto; }
.foot-tour { margin: 1.1rem 0 0; }
.pc-eggs { background: color-mix(in srgb, var(--gold) 12%, transparent); border: 1.5px solid color-mix(in srgb, var(--gold) 40%, transparent); color: var(--gold); font-weight: 800; font-size: max(var(--text-floor), 0.72rem); padding: 0.22rem 0.6rem; border-radius: var(--r-pill); white-space: nowrap; }
.gearn-still { cursor: default; }

/* the one red button on the site: account deletion (X02). Black type on the red fill, like every other CTA. */
.btn-danger { background: var(--red-soft, #ff6b6b); color: var(--ink-1); border-color: transparent; }
.btn-danger:hover:not(:disabled) { filter: brightness(1.08); }
.danger-zone { border-top: 1px solid var(--hair); margin-top: 1rem; padding-top: 0.2rem; }

/* moderation queue (admin.html) */
.adm-report { padding: 0.9rem 1rem; }
.adm-ov { padding: 1rem 1.1rem; margin-bottom: 1.6rem; }
.adm-ov-head { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; }
.adm-h2 { font-size: max(var(--text-floor), 1.2rem); margin: 0 0 0.6rem; }
.adm-h3 { font-size: max(var(--text-floor), 1rem); margin: 0.9rem 0 0.3rem; }
.adm-ov-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: 0.4rem 1.8rem; }
.adm-ov-sub { margin: 0.6rem 0 0.2rem; }
.adm-ov-list { margin: 0; padding-left: 1.3rem; font-size: max(var(--text-floor), 0.9rem); line-height: 1.6; overflow-wrap: anywhere; }
.adm-ov .dk-stat span { flex: 1 1 auto; }
.adm-ov .dk-stat b { flex: 0 1 auto; min-width: 0; max-width: 62%; text-align: right; overflow-wrap: break-word; }   /* break-word, not anywhere: a short figure such as 10 never splits */
.adm-report .post-head { color: var(--muted); font-size: max(var(--text-floor), 0.85rem); margin-bottom: 0.4rem; }
.adm-reason { font-style: italic; margin: 0.3rem 0; }
.adm-quote { margin: 0.4rem 0; padding: 0.5rem 0.8rem; border-left: 3px solid var(--green); background: var(--g-wash); border-radius: 6px; white-space: pre-wrap; word-break: break-word; }
.adm-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.6rem; }
/* daily active users (admin.html): two bar charts drawn with plain boxes, one height each, and every number in the table under them */
.adm-dau-ctl { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.adm-dau-range { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.adm-dau-range .btn[aria-pressed="true"] { background: var(--green); color: var(--on-green); border-color: var(--green); }
.adm-dau-today { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr)); gap: 0 1.6rem; margin-bottom: 0.4rem; }
.adm-dau-today .dk-stat span { min-width: 0; }
.adm-dau-today .dk-stat b { white-space: nowrap; max-width: none; flex: 0 0 auto; }   /* a figure or a date is never split; the label beside it wraps instead */
.adm-chart { margin: 1.1rem 0 0; min-width: 0; }
.adm-chart figcaption { font-weight: 800; margin: 0 0 0.45rem; font-size: max(var(--text-floor), 0.95rem); }
.adm-chart figcaption small { font-weight: 500; color: var(--text-dim); font-size: max(var(--text-floor), 0.85rem); }
.adm-chart-plot { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.5rem; height: 170px; }
.adm-chart-y { display: flex; flex-direction: column; justify-content: space-between; text-align: right; color: var(--text-dim); font-variant-numeric: tabular-nums; font-size: max(var(--text-floor), 0.8rem); line-height: 1; }
.adm-chart-bars { position: relative; display: flex; align-items: flex-end; gap: 2px; min-width: 0; border-left: 1px solid var(--ink-4); border-bottom: 1px solid var(--ink-4);
  background: repeating-linear-gradient(to top, transparent 0, transparent calc(50% - 1px), var(--hair) calc(50% - 1px), var(--hair) 50%); }
.adm-bar { flex: 1 1 0; min-width: 1px; height: var(--h); min-height: 0; border-radius: 3px 3px 0 0; background: var(--bar, var(--green)); }
.adm-bar.is-zero { min-height: 1px; opacity: 0.35; }
.adm-bar.is-none { height: 100%; background: repeating-linear-gradient(135deg, transparent 0 4px, var(--hair) 4px 6px); border-radius: 0; }
.adm-bar.is-today { box-shadow: inset 0 0 0 2px var(--text); }
.adm-chart--visitors { --bar: var(--gold); }
.adm-chart-x { display: flex; justify-content: space-between; gap: 0.5rem; margin-left: 2.6rem; color: var(--text-dim); font-variant-numeric: tabular-nums; font-size: max(var(--text-floor), 0.8rem); }
.adm-dau-notes { margin: 1rem 0 0; padding-left: 1.2rem; color: var(--text-dim); font-size: max(var(--text-floor), 0.88rem); line-height: 1.6; }
.adm-dau-notes b { color: var(--text); }
.adm-dau-table { overflow-x: auto; margin-top: 0.6rem; }
.adm-dau-table table { border-collapse: collapse; font-variant-numeric: tabular-nums; font-size: max(var(--text-floor), 0.85rem); white-space: nowrap; }
.adm-dau-table th, .adm-dau-table td { padding: 0.35rem 0.55rem; border-bottom: 1px solid var(--hair); text-align: right; }
.adm-dau-table th:first-child, .adm-dau-table td:first-child { text-align: left; position: sticky; left: 0; background: var(--ink-2); }
.adm-dau-table thead th { color: var(--text-dim); font-weight: 800; white-space: normal; vertical-align: bottom; }
/* admin invite codes (admincodes.js): a grid like a member's ticket, then who signed up with them */
.adm-codes-lede { margin: 0 0 0.7rem; }
/* Google Analytics on the admin page (adminanalytics.js) */
.adm-ga-setup { list-style: none; margin: 0 0 0.8rem; padding: 0; display: grid; gap: 0.4rem; font-size: max(var(--text-floor), 0.88rem); line-height: 1.55; color: var(--text-dim); }
.adm-ga-setup b { color: var(--text); }
.adm-ga-setup .is-on b { color: var(--green-bright); }
.adm-ga-setup code { font-family: ui-monospace, Menlo, monospace; color: var(--text); }
.adm-ga-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr)); gap: 0.5rem; margin: 0 0 0.9rem; }
.adm-ga-tile { background: var(--ink); border: 1px solid var(--ink-4); border-radius: 12px; padding: 0.6rem 0.7rem; display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.adm-ga-tile b { font-size: max(var(--text-floor), 1.35rem); font-weight: 900; color: var(--text); line-height: 1.15; font-variant-numeric: tabular-nums; }
.adm-ga-tile span { font-size: max(var(--text-floor), 0.75rem); color: var(--text-dim); line-height: 1.35; }
.adm-ga-tile i { font-style: normal; font-size: max(var(--text-floor), 0.72rem); color: var(--text-dim); opacity: 0.8; }
.adm-ga-chart { margin: 0 0 1rem; }
.adm-ga-chart svg { display: block; width: 100%; height: 140px; }
.adm-ga-chart rect { fill: var(--green); }
.adm-ga-chart figcaption { display: flex; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; font-size: max(var(--text-floor), 0.75rem); color: var(--text-dim); margin-top: 0.3rem; }
.adm-ga-tbls { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); gap: 0.4rem 1.2rem; }
.adm-ga-tbl { min-width: 0; }
.adm-ga-tbl h3 { margin: 0.4rem 0 0.2rem; font-size: max(var(--text-floor), 0.9rem); color: var(--text); }
.adm-ga-tbl td:first-child { white-space: normal; overflow-wrap: anywhere; max-width: 18rem; }
.adm-ga-err { margin: 0.8rem 0 0; font-size: max(var(--text-floor), 0.82rem); line-height: 1.5; color: var(--gold); overflow-wrap: anywhere; }
.adm-ga-bad { color: var(--gold); }
#adm-ga-sum, .adm-ga-setup li { overflow-wrap: anywhere; }   /* Google's errors carry long console URLs */
.adm-codes-show { display: flex; flex-wrap: wrap; gap: 0.35rem; margin: 0 0 0.4rem; }
.adm-codes-show .btn[aria-pressed="false"] { background: transparent; color: var(--text); border: 1px solid var(--edge-ctl); box-shadow: none; }   /* which list is showing reads by shape, not colour alone: outlined, or filled */
.adm-codes-show .btn[aria-pressed="true"] { background: var(--green); color: var(--on-green); border-color: var(--green); }
.adm-code-list { list-style: none; margin: 0.4rem 0 0; padding: 0; display: grid; gap: 0.45rem; grid-template-columns: repeat(auto-fill, minmax(min(190px, 100%), 1fr)); }
.adm-code-list li { margin: 0; min-width: 0; }
.adm-code { display: flex; flex-direction: column; align-items: flex-start; gap: 0.15rem; box-sizing: border-box; width: 100%; min-height: 44px; margin: 0; padding: 0.5rem 0.7rem;
  border: 1px solid var(--edge-ctl); border-radius: 10px; background: var(--ink-3); color: var(--text); font-family: inherit; text-align: left; overflow-wrap: anywhere; }
button.adm-code { cursor: pointer; }
button.adm-code:hover { border-color: var(--green); }
button.adm-code:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.adm-code-chars { font-family: var(--mono); font-weight: 800; letter-spacing: 0.08em; font-size: max(var(--text-floor), 1rem); }
.adm-code-tag { color: var(--text-dim); font-size: max(var(--text-floor), 0.8rem); line-height: 1.35; }
.adm-code-tag a, .adm-codes-table a { color: var(--green-bright); font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }
.adm-code-tag small, .adm-codes-table small { font-size: max(var(--text-floor), 0.78rem); color: var(--text-dim); }
.adm-code.is-used .adm-code-chars { text-decoration: line-through; color: var(--text-dim); }
.adm-code.is-pending { border-style: dashed; border-color: var(--gold); }
.adm-codes-gone { font-style: italic; }
.adm-codes-table { overflow-x: auto; }
.adm-codes-table table { border-collapse: collapse; width: 100%; font-size: max(var(--text-floor), 0.88rem); }
.adm-codes-table th, .adm-codes-table td { padding: 0.4rem 0.55rem; border-bottom: 1px solid var(--hair); text-align: left; vertical-align: top; }
.adm-codes-table thead th { color: var(--text-dim); font-weight: 800; white-space: nowrap; }
.adm-codes-table td { white-space: nowrap; }   /* a name, a code and a date stay whole: the table scrolls in its own box on a phone */
.adm-codes-table td small { display: block; white-space: normal; min-width: 9em; }
.adm-codes-mono { font-family: var(--mono); letter-spacing: 0.06em; white-space: nowrap; }
.adm-codes-more { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; margin-top: 1rem; }
/* a member's kept history (adminrestore.js) */
.adm-hist-find { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin: 0 0 0.5rem; }
.adm-hist-find .addr-input { flex: 1 1 12rem; min-width: 0; }
.adm-hist-list { list-style: none; margin: 0.4rem 0 0; padding: 0; display: grid; gap: 0.45rem; }
.adm-hist-row { padding: 0.55rem 0.7rem; border: 1px solid var(--edge-ctl); border-radius: 10px; background: var(--ink-3); display: grid; gap: 0.35rem; }
.adm-hist-what { font-size: max(var(--text-floor), 0.92rem); line-height: 1.45; overflow-wrap: break-word; }
.adm-hist-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.8rem; color: var(--text-dim); font-size: max(var(--text-floor), 0.82rem); }
.adm-hist-done { color: var(--green-bright); font-weight: 700; }
.adm-hist-no { font-style: italic; }
.adm-hist-kind { flex: 0 1 auto; width: auto; max-width: 100%; }
#adm-hist-older { margin-top: 0.7rem; }
@media (pointer: coarse) { .adm-code-tag a, .adm-codes-table a { display: inline-flex; align-items: center; min-height: 44px; } }   /* a profile link is a finger's target too */




/* ===== Dashboard sections, quest board and the play tabs ===========================================
   Each overview section is a disclosure whose summary carries a live one-line reading, so a shut
   dashboard still answers "how am I doing" and the detail is one tap away. The summary is the control:
   it is a real <summary>, so it is keyboard-operable and announced as a disclosure with no ARIA. */
.gsec { border: 1px solid var(--hair); border-radius: var(--r-2, 14px); background: var(--glass-lo); margin: 0 0 0.8rem; overflow: hidden; }
.gsec + .gsec { margin-top: 0.8rem; }
.gsec-sum { display: flex; align-items: center; gap: 0.7rem; padding: 0.85rem 1rem; cursor: pointer; list-style: none; min-height: 56px;
  background: var(--glass-hi); transition: background var(--dur-2, 0.16s) ease; }
.gsec-sum::-webkit-details-marker { display: none; }
.gsec-sum:hover { background: color-mix(in srgb, var(--green) 10%, var(--glass-hi)); }
.gsec-sum:focus-visible { outline: 3px solid var(--focus, var(--green-bright)); outline-offset: -3px; }
.gsec-ico { font-size: max(var(--text-floor), 1.2rem); flex: none; line-height: 1; }
.gsec-txt { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; flex: 1 1 auto; }
.gsec-t { font-family: 'Luckiest Guy', cursive; color: var(--green-bright); font-size: max(var(--text-floor), 1rem); letter-spacing: 0.02em; }
/* the live reading: one line, never wrapped into a paragraph — it is a glance, not a read */
.gsec-d { font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gsec-chev { flex: none; color: var(--text-mute); font-size: max(var(--text-floor), 0.9rem); transition: transform var(--dur-2, 0.16s) ease; }
.gsec[open] > .gsec-sum > .gsec-chev { transform: rotate(180deg); }
.gsec[open] > .gsec-sum { border-bottom: 1px solid var(--hair); }
.gsec-body { padding: 1rem; }
.gsec-body > .grekt, .gsec-body > .grules { margin-top: 0; }
@media (prefers-reduced-motion: reduce) { .gsec-chev { transition: none; } }

/* the two tabs: quests, or the boards */
.play-tabs { display: inline-flex; flex-wrap: wrap; max-width: 100%; gap: 4px; padding: 4px; border-radius: var(--r-pill); background: var(--ctl-fill-lo); border: 1px solid var(--ctl-fill-lo); margin-bottom: 0.9rem; }
.play-tab { min-height: 44px; padding: 0 1.1rem; border: 0; border-radius: var(--r-pill); background: none; color: var(--ctl-ink);
  font: inherit; font-weight: 800; font-size: max(var(--text-floor), 0.92rem); cursor: pointer; white-space: normal; text-align: center; }
.play-tab:hover { background: var(--ctl-fill-hi); }
.play-tab.is-on { background: linear-gradient(180deg, var(--green-bright), var(--green)); color: var(--on-green); box-shadow: 0 2px 10px var(--glow-g); }
.play-tab:focus-visible { outline: 3px solid var(--ctl-ink); outline-offset: -2px; }

/* the board's own head: what is left, and the filters */
.qhead { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.6rem; margin-bottom: 0.8rem; }
.qcount { margin: 0; font-size: max(var(--text-floor), 0.9rem); color: var(--text-dim); }
.qcount b { color: var(--green-bright); }
.qchips { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.qchip { min-height: 44px; padding: 0.3rem 0.8rem; border-radius: var(--r-pill); border: 1px solid var(--ctl-fill-lo);
  background: var(--ctl-fill-lo); color: var(--ctl-ink); font: inherit; font-weight: 700; font-size: max(var(--text-floor), 0.82rem); cursor: pointer; white-space: nowrap; }
.qchip:hover { background: var(--ctl-fill-hi); border-color: var(--ctl-fill-hi); }
.qchip.is-on { background: linear-gradient(180deg, var(--green-bright), var(--green)); color: var(--on-green); border-color: transparent; }
.qchip:focus-visible { outline: 3px solid var(--ctl-ink); outline-offset: 2px; }
.qchip-n { opacity: 0.75; font-variant-numeric: tabular-nums; }
.qgroup + .qgroup { margin-top: 1.1rem; }
.qgroup-h { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem; margin: 0 0 0.5rem;
  font-family: 'Luckiest Guy', cursive; color: var(--text); font-size: max(var(--text-floor), 0.95rem); letter-spacing: 0.02em; }
.qgroup-b { font-family: 'Rubik', sans-serif; font-weight: 400; font-size: max(var(--text-floor), 0.78rem); color: var(--text-mute); letter-spacing: 0; }
@media (max-width: 560px) { .qhead { flex-direction: column; align-items: stretch; } }

/* ===== The tape: recent on-chain transactions under a chart =========================================
   The colours are a second signal, never the only one — every chip carries its word ("up", "down",
   "new", "no entry here") in the same element, so the tape reads the same to somebody who cannot tell
   the three apart. Blue is the site's diamond token, which is already the "rare / new" colour here. */
.oc-tape { width: 100%; border-collapse: collapse; font-size: max(var(--text-floor), 0.82rem); font-variant-numeric: tabular-nums; }
.oc-tape th, .oc-tape td { text-align: left; padding: 0.4rem 0.5rem; border-bottom: 1px solid var(--hair); white-space: nowrap; }
.oc-tape th { color: var(--text-dim); font-weight: 700; font-size: max(var(--text-floor), 0.74rem); letter-spacing: var(--tr-caps, 0.06em); text-transform: uppercase; }
.oc-tape td { color: var(--text); }
.oc-tape .oc-num { text-align: right; }
.oc-tape tbody tr:hover { background: var(--g-wash); }
/* the side is a word first: the tint only reinforces it */
.oc-side { font-weight: 800; }
.oc-tape tr.is-buy .oc-side { color: var(--green-bright); }
.oc-tape tr.is-sell .oc-side { color: var(--red-soft); }
/* the wallet chip: address above, state word (and its P/L) below, both inside the link */
.oc-w { display: inline-flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; gap: 0.05rem; line-height: 1.2; padding: 0.2rem 0.5rem;
  border-radius: var(--r-1, 8px); border: 1px solid transparent; text-decoration: none; font-family: var(--mono, ui-monospace, monospace); }
.oc-w-a { font-size: max(var(--text-floor), 0.8rem); }
.oc-w-s { font-size: max(var(--text-floor), 0.66rem); font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; opacity: 0.95; font-family: 'Rubik', sans-serif; }
.oc-w.is-up { color: var(--green-bright); background: var(--g-wash); border-color: var(--g-edge); }
.oc-w.is-down { color: var(--red-soft); background: var(--r-tint); border-color: var(--r-edge); }
.oc-w.is-first { color: var(--diamond); background: var(--d-tint); border-color: var(--d-edge); }
.oc-w.is-unknown { color: var(--text-mute); background: var(--glass-well); border-color: var(--hair); }
.oc-w:hover { filter: brightness(1.12); }
.oc-w:focus-visible { outline: 3px solid var(--focus, var(--green-bright)); outline-offset: 2px; }
.oc-w.is-flat { color: var(--text-dim); background: var(--glass-well); border-color: var(--hair); }
.oc-tx { display: inline-flex; align-items: center; min-height: 24px; font-family: var(--mono, ui-monospace, monospace); font-size: max(var(--text-floor), 0.78rem); color: var(--gold); text-decoration: none; }
.oc-tx:hover, .oc-tx:focus-visible { text-decoration: underline; }
.oc-tx:focus-visible { outline: 3px solid var(--focus, var(--green-bright)); outline-offset: 2px; }
.oc-tape-note { font-size: max(var(--text-floor), 0.76rem); color: var(--text-mute); line-height: 1.55; margin: 0.6rem 0 0; white-space: normal; }
.oc-k { font-weight: 800; color: var(--text-dim); }
.oc-k.is-up { color: var(--green-bright); } .oc-k.is-down { color: var(--red-soft); } .oc-k.is-first { color: var(--diamond); }
/* The TABLE scrolls, not the whole panel: the legend under it explains the columns, so it must stay put
   rather than slide away from them. Every column survives on a phone — the one carrying the money is not
   a column to delete, and a hidden cell would make the caption describe a table that is not there. */
.oc-tape-scroll { overflow-x: auto; }
@media (pointer: coarse) { .oc-w, .oc-tx { min-height: 44px; } }

/* ===== The matrix grid: every control is a tile of green cells ==================================
   Two layers under the label, above the fill (isolation + z-index -1):
     ::before  the grid itself — dark cell lines on the green, faint at rest, and on hover the
               lines drift downward like the rain in the page's own background
     ::after   the pointer's light — cells near the cursor light up green-bright, with a soft halo.
               --mx/--my are set by app.js on pointermove (percent of the control); keyboard focus
               lights the centre.
   Press: the whole tile flashes. Reduced motion / the ⏸ switch: no drift, no flash — the pointer
   light still follows, since it only moves when the pointer does. Text contrast is untouched: the
   lines are 1px at 26% ink, the lit cells are the same green the label already clears.

   Every button-like control on the site is in these lists: the .btn family, the segment tabs on their
   green tracks, the small round ✕ / ☆ / 📌 / ⓘ controls, the menu items, the chips, and the disclosure
   summaries that have no caret pseudo-element of their own. The ones that are already absolutely or
   fixed positioned (.modal-x, .wc-x, .media-preview-rm, .intro-skip, .gif-toggle, .oc-reset,
   .addr-clear, #compose-fab) take only the stacking context, never `position: relative` — that would
   pull them back into the flow. Controls whose ::before/::after already draw something (the .switch
   knob, the .mp-hint arrow, the ▾ of .sc-toggle / .np-slide-more / the setting-card, reassure, grules
   and np-detail summaries, the ▸ of .trk-token) are deliberately absent: they wear the same green fill
   and the same ink, without the layers. So is .np-runner-sym: responsive.css, which loads after this
   sheet, owns its ::after as the 24px / 44px phantom hit box around an 18px symbol, and this block's
   `pointer-events: none`, coarse-pointer lit cells and forced-colors `display: none` would have made
   that box un-tappable, painted it, or deleted it. app.js keeps the same list for the pointer tracking. */
/* ===== The Scanner page (newpairs.html): two tabs, the address form, the members' door ==============
   The tab strip is the dashboard's pill strip (.play-tabs) in the radar's colours; the result panel is the
   same detail the token popup renders, so it takes the popup's classes untouched. */
.sc-tabs { display: flex; gap: 4px; padding: 4px; margin: 0.2rem auto 1rem; width: max-content; max-width: 100%; border-radius: var(--r-pill); background: var(--ctl-fill-lo); border: 1px solid var(--ctl-fill-lo); }
.sc-tab { min-height: 44px; padding: 0 1.1rem; border: 0; border-radius: var(--r-pill); background: none; color: var(--ctl-ink); font: inherit; font-weight: 800; font-size: max(var(--text-floor), 0.95rem); cursor: pointer; white-space: nowrap; display: inline-flex; align-items: center; gap: 0.35rem; }
.sc-tab:hover { background: var(--ctl-fill-hi); }
.sc-tab.is-on { background: linear-gradient(180deg, var(--green-bright), var(--green)); color: var(--on-green); box-shadow: 0 2px 10px var(--glow-g); }
.sc-tab:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.sc-lock { font-size: max(var(--text-floor), 0.85em); }
.sc-panel { max-width: 900px; margin: 0 auto; }
.sc-form { display: flex; gap: 0.5rem; align-items: stretch; max-width: 720px; margin: 0 auto; }
.sc-field { position: relative; flex: 1 1 auto; min-width: 0; display: flex; }
.sc-addr { flex: 1 1 auto; min-width: 0; width: 100%; padding: 0.8rem 2.6rem 0.8rem 1rem; border-radius: 12px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: max(var(--text-floor), 0.98rem); letter-spacing: 0.02em;
  background: color-mix(in srgb, var(--ink) 70%, transparent); color: var(--text); border: 1.5px solid var(--edge-ctl); }
/* the clear button lives inside the box, on the right, and only while there is something to clear */
.sc-clear { position: absolute; right: 0.45rem; top: 50%; transform: translateY(-50%); width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--hair);
  background: color-mix(in srgb, var(--ink) 55%, transparent); color: var(--text-dim); font-size: max(var(--text-floor), 0.85rem); font-weight: 800; line-height: 1; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.sc-clear:hover { color: var(--text); border-color: var(--edge-ctl); background: color-mix(in srgb, var(--green) 12%, transparent); }
.sc-clear:focus-visible { outline: 3px solid var(--focus); outline-offset: 1px; }
.sc-clear[hidden] { display: none; }
.sc-addr::placeholder { color: var(--text-mute); font-family: 'Rubik', system-ui, sans-serif; letter-spacing: 0; }
.sc-addr:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-color: var(--green); }
.sc-go { flex: 0 0 auto; }
.sc-help { max-width: 720px; margin: 0.55rem auto 0; font-size: max(var(--text-floor), 0.82rem); color: var(--text-dim); line-height: 1.5; text-align: center; }
.sc-chains { display: flex; flex-wrap: wrap; gap: 0.4rem; justify-content: center; margin: 0.8rem auto 0; }
.sc-chain { display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.3rem 0.7rem; border-radius: var(--r-pill); font-size: max(var(--text-floor), 0.8rem); font-weight: 700; border: 1px solid var(--hair); color: var(--text-dim); }
.sc-chain.is-on { background: color-mix(in srgb, var(--green) 14%, transparent); border-color: color-mix(in srgb, var(--green) 45%, transparent); color: var(--green-bright); }
.sc-chain.is-soon { opacity: 0.8; border-style: dashed; }
.sc-try { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; justify-content: center; margin: 0.9rem auto 0; font-size: max(var(--text-floor), 0.85rem); color: var(--text-dim); }
.sc-status { min-height: 1.4em; margin: 0.8rem auto 0; max-width: 720px; text-align: center; font-size: max(var(--text-floor), 0.9rem); font-weight: 600; color: var(--text-dim); line-height: 1.5; }
.sc-status.is-ok { color: var(--green-bright); }
.sc-status.is-err { color: var(--red-soft); }
.sc-result { margin: 1rem auto 0; }
.sc-result:empty { display: none; }
.sc-hit { text-align: center; margin: 0 0 0.8rem; }
/* the scanned token's Send Call buttons: the wall, and the reader's squad when they are in one */
.sc-hit-call { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.5rem; margin: 0.6rem 0 0.35rem; }
.call-row .btn { max-width: 100%; min-width: 0; overflow-wrap: anywhere; }   /* a 40-character squad name wraps inside the pill on a phone */
/* the shared Send Call pair (compose.js callRowHTML): its buttons flow into whatever actions row holds it */
.np-body-actions .call-row { display: contents; }
.wl-actions { margin-top: 0.6rem; }
/* a person's @name in a page's byline opens their Send Wall */
.wall-link { color: inherit; font-weight: 700; text-decoration: none; border-bottom: 1px dotted currentColor; }
.wall-link:hover { border-bottom-style: solid; }
.wall-link:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 3px; }
.sc-hit-k { margin: 0; font-size: max(var(--text-floor), 0.75rem); letter-spacing: 0.14em; text-transform: uppercase; font-weight: 800; color: var(--text-mute); }
.sc-hit-k code { letter-spacing: 0; text-transform: none; font-size: max(var(--text-floor), 0.85rem); }
.sc-hit-h { margin: 0.2rem 0 0.1rem; font-family: 'Luckiest Guy', cursive; font-weight: 400; letter-spacing: 0.02em; font-size: max(var(--text-floor), clamp(1.4rem, 5vw, 2rem)); line-height: 1.1; color: var(--text); overflow-wrap: anywhere; }
.sc-hit-h .hl { color: var(--green-bright); }
.sc-hit-h:focus { outline: none; }
.sc-hit-a { margin: 0; font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); overflow-wrap: anywhere; }
.sc-hit-a code { font-size: max(var(--text-floor), 0.78rem); }
.sc-recent { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; justify-content: center; margin: 1.2rem auto 0; font-size: max(var(--text-floor), 0.82rem); color: var(--text-mute); }
.sc-recent-list { display: inline-flex; flex-wrap: wrap; gap: 0.35rem; }
.sc-community { margin-top: 0.6rem; }
.sc-chip-meta { font-weight: 600; opacity: 0.75; font-size: max(var(--text-floor), 0.72rem); margin-left: 0.25rem; }
.sc-foot-note { max-width: 720px; margin: 1rem auto 0; text-align: center; font-size: max(var(--text-floor), 0.78rem); line-height: 1.55; color: var(--text-mute); }
/* the scan's own facts under the hit header: when it was read, how many times anyone has scanned it */
.sc-hit-s { margin: 0.35rem 0 0; font-size: max(var(--text-floor), 0.8rem); color: var(--text-dim); }
.sc-hit-s .sc-stale { display: block; margin-top: 0.35rem; color: var(--gold); font-weight: 700; }
.sc-hit-s .sc-hit-note { display: block; margin-top: 0.3rem; color: var(--text-mute); font-size: max(var(--text-floor), 0.78rem); }
.sc-locked { max-width: 560px; margin: 0.5rem auto 1rem; padding: 1.2rem 1.25rem; text-align: center; border-radius: var(--r-3); background: linear-gradient(180deg, var(--ink-3), var(--ink-2)); border: 1.5px solid color-mix(in srgb, var(--green) 35%, transparent); }
.sc-locked-h { margin: 0 0 0.4rem; font-family: 'Luckiest Guy', cursive; font-weight: 400; letter-spacing: 0.02em; font-size: max(var(--text-floor), 1.4rem); color: var(--green-bright); }
.sc-locked-p { margin: 0 0 0.9rem; font-size: max(var(--text-floor), 0.92rem); line-height: 1.55; color: var(--text-dim); }
/* the feed is a full-screen mode and already hides the hero: the tab strip goes with it, and comes back with any other view */
body.np-mode-feed .sc-tabs { display: none; }
@media (max-width: 560px) {
  .sc-form { flex-direction: column; }
  .sc-tabs { width: 100%; }
  .sc-tab { flex: 1 1 0; justify-content: center; padding: 0 0.6rem; font-size: max(var(--text-floor), 0.88rem); }
}

.btn, .react-btn, .feed-tab, .dtab, .oc-tf, .np-seg, .np-vs-btn, .mp-btn, .copy-btn, .nav-toggle, .sc-hop, .np-row-call, .motion-btn, .npm-item, .auth-seg, .auth-tab, .profile-link, .np-caret-btn, .swap-choice, .file-label, .vote-btn, .sort-btn, .linklike, .oauth-btn, .btn-follow, .gobj-link, .wc-item, .wc-deep, .np-search-clear, .np-tickcopy, .tm-x, .pin-chip-open, .pin-chip-rm, .np-pin, .np-sort, .np-more, .np-refresh, .np-hidden-link, .np-status button, .np-newbar, .np-lookup-clear, .ab-chip, .np-chip, .np-den, .np-sv-apply, .np-sv-del, .np-runner-pin, .np-runner-chart, .np-rail-btn, .np-feed-fresh, .np-watch, .np-wl-remove, .notif-bell, .notif-clearall, .notif-x, .sc-btn, .sc-senders-toggle, .wall-tab, .lb-win, .ll-toggle button, .comm-tab, .ge-info, .cmp-mode, .np-chain-btn, .oc-mk, .ll-info, .arena-tab, .np-social-btn, .cw-tab, .np-strat, .np-fclose, .pillar > summary, .oc-data > summary, .b0-conn summary, .risk-chip, .g1-w-link, .sc-info, .sc-tab {
  position: relative; isolation: isolate;
}
/* already positioned (absolute / fixed) — only the stacking context, so they stay where they are pinned */
.modal-x, .wc-x, .media-preview-rm, .intro-skip, .gif-toggle, .oc-reset, .addr-clear, #compose-fab {
  isolation: isolate;
}
.btn::before, .react-btn::before, .feed-tab::before, .dtab::before, .oc-tf::before, .np-seg::before, .np-vs-btn::before, .mp-btn::before, .copy-btn::before, .nav-toggle::before, .sc-hop::before, .np-row-call::before, .motion-btn::before, .npm-item::before, .auth-seg::before, .auth-tab::before, .profile-link::before, .np-caret-btn::before, .swap-choice::before, .file-label::before, .vote-btn::before, .sort-btn::before, .linklike::before, .oauth-btn::before, .btn-follow::before, .gobj-link::before, .wc-item::before, .wc-deep::before, .np-search-clear::before, .np-tickcopy::before, .tm-x::before, .pin-chip-open::before, .pin-chip-rm::before, .np-pin::before, .np-sort::before, .np-more::before, .np-refresh::before, .np-hidden-link::before, .np-status button::before, .np-newbar::before, .np-lookup-clear::before, .ab-chip::before, .np-chip::before, .np-den::before, .np-sv-apply::before, .np-sv-del::before, .np-runner-pin::before, .np-runner-chart::before, .np-rail-btn::before, .np-feed-fresh::before, .np-watch::before, .np-wl-remove::before, .notif-bell::before, .notif-clearall::before, .notif-x::before, .sc-btn::before, .sc-senders-toggle::before, .wall-tab::before, .lb-win::before, .ll-toggle button::before, .comm-tab::before, .ge-info::before, .cmp-mode::before, .np-chain-btn::before, .oc-mk::before, .ll-info::before, .arena-tab::before, .np-social-btn::before, .cw-tab::before, .np-strat::before, .np-fclose::before, .pillar > summary::before, .oc-data > summary::before, .b0-conn summary::before, .modal-x::before, .wc-x::before, .media-preview-rm::before, .intro-skip::before, .gif-toggle::before, .oc-reset::before, .addr-clear::before, #compose-fab::before, .risk-chip::before, .g1-w-link::before, .sc-info::before, .sc-tab::before,
.btn::after, .react-btn::after, .feed-tab::after, .dtab::after, .oc-tf::after, .np-seg::after, .np-vs-btn::after, .mp-btn::after, .copy-btn::after, .nav-toggle::after, .sc-hop::after, .np-row-call::after, .motion-btn::after, .npm-item::after, .auth-seg::after, .auth-tab::after, .profile-link::after, .np-caret-btn::after, .swap-choice::after, .file-label::after, .vote-btn::after, .sort-btn::after, .linklike::after, .oauth-btn::after, .btn-follow::after, .gobj-link::after, .wc-item::after, .wc-deep::after, .np-search-clear::after, .np-tickcopy::after, .tm-x::after, .pin-chip-open::after, .pin-chip-rm::after, .np-pin::after, .np-sort::after, .np-more::after, .np-refresh::after, .np-hidden-link::after, .np-status button::after, .np-newbar::after, .np-lookup-clear::after, .ab-chip::after, .np-chip::after, .np-den::after, .np-sv-apply::after, .np-sv-del::after, .np-runner-pin::after, .np-runner-chart::after, .np-rail-btn::after, .np-feed-fresh::after, .np-watch::after, .np-wl-remove::after, .notif-bell::after, .notif-clearall::after, .notif-x::after, .sc-btn::after, .sc-senders-toggle::after, .wall-tab::after, .lb-win::after, .ll-toggle button::after, .comm-tab::after, .ge-info::after, .cmp-mode::after, .np-chain-btn::after, .oc-mk::after, .ll-info::after, .arena-tab::after, .np-social-btn::after, .cw-tab::after, .np-strat::after, .np-fclose::after, .pillar > summary::after, .oc-data > summary::after, .b0-conn summary::after, .modal-x::after, .wc-x::after, .media-preview-rm::after, .intro-skip::after, .gif-toggle::after, .oc-reset::after, .addr-clear::after, #compose-fab::after, .risk-chip::after, .g1-w-link::after, .sc-info::after, .sc-tab::after {
  content: ''; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
}
.btn::before, .react-btn::before, .feed-tab::before, .dtab::before, .oc-tf::before, .np-seg::before, .np-vs-btn::before, .mp-btn::before, .copy-btn::before, .nav-toggle::before, .sc-hop::before, .np-row-call::before, .motion-btn::before, .npm-item::before, .auth-seg::before, .auth-tab::before, .profile-link::before, .np-caret-btn::before, .swap-choice::before, .file-label::before, .vote-btn::before, .sort-btn::before, .linklike::before, .oauth-btn::before, .btn-follow::before, .gobj-link::before, .wc-item::before, .wc-deep::before, .np-search-clear::before, .np-tickcopy::before, .tm-x::before, .pin-chip-open::before, .pin-chip-rm::before, .np-pin::before, .np-sort::before, .np-more::before, .np-refresh::before, .np-hidden-link::before, .np-status button::before, .np-newbar::before, .np-lookup-clear::before, .ab-chip::before, .np-chip::before, .np-den::before, .np-sv-apply::before, .np-sv-del::before, .np-runner-pin::before, .np-runner-chart::before, .np-rail-btn::before, .np-feed-fresh::before, .np-watch::before, .np-wl-remove::before, .notif-bell::before, .notif-clearall::before, .notif-x::before, .sc-btn::before, .sc-senders-toggle::before, .wall-tab::before, .lb-win::before, .ll-toggle button::before, .comm-tab::before, .ge-info::before, .cmp-mode::before, .np-chain-btn::before, .oc-mk::before, .ll-info::before, .arena-tab::before, .np-social-btn::before, .cw-tab::before, .np-strat::before, .np-fclose::before, .pillar > summary::before, .oc-data > summary::before, .b0-conn summary::before, .modal-x::before, .wc-x::before, .media-preview-rm::before, .intro-skip::before, .gif-toggle::before, .oc-reset::before, .addr-clear::before, #compose-fab::before, .risk-chip::before, .g1-w-link::before, .sc-info::before, .sc-tab::before {
  background-image:
    linear-gradient(var(--mx-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--mx-line) 1px, transparent 1px);
  background-size: var(--mx-size) var(--mx-size);
  opacity: 0.42;
  transition: opacity var(--dur-2, 0.16s) ease;
}
.btn::after, .react-btn::after, .feed-tab::after, .dtab::after, .oc-tf::after, .np-seg::after, .np-vs-btn::after, .mp-btn::after, .copy-btn::after, .nav-toggle::after, .sc-hop::after, .np-row-call::after, .motion-btn::after, .npm-item::after, .auth-seg::after, .auth-tab::after, .profile-link::after, .np-caret-btn::after, .swap-choice::after, .file-label::after, .vote-btn::after, .sort-btn::after, .linklike::after, .oauth-btn::after, .btn-follow::after, .gobj-link::after, .wc-item::after, .wc-deep::after, .np-search-clear::after, .np-tickcopy::after, .tm-x::after, .pin-chip-open::after, .pin-chip-rm::after, .np-pin::after, .np-sort::after, .np-more::after, .np-refresh::after, .np-hidden-link::after, .np-status button::after, .np-newbar::after, .np-lookup-clear::after, .ab-chip::after, .np-chip::after, .np-den::after, .np-sv-apply::after, .np-sv-del::after, .np-runner-pin::after, .np-runner-chart::after, .np-rail-btn::after, .np-feed-fresh::after, .np-watch::after, .np-wl-remove::after, .notif-bell::after, .notif-clearall::after, .notif-x::after, .sc-btn::after, .sc-senders-toggle::after, .wall-tab::after, .lb-win::after, .ll-toggle button::after, .comm-tab::after, .ge-info::after, .cmp-mode::after, .np-chain-btn::after, .oc-mk::after, .ll-info::after, .arena-tab::after, .np-social-btn::after, .cw-tab::after, .np-strat::after, .np-fclose::after, .pillar > summary::after, .oc-data > summary::after, .b0-conn summary::after, .modal-x::after, .wc-x::after, .media-preview-rm::after, .intro-skip::after, .gif-toggle::after, .oc-reset::after, .addr-clear::after, #compose-fab::after, .risk-chip::after, .g1-w-link::after, .sc-info::after, .sc-tab::after {
  background-image:
    radial-gradient(circle at var(--mx, 50%) var(--my, 50%), var(--mx-glow) 0, transparent 46px),
    radial-gradient(circle, var(--mx-cell) 0 1.7px, transparent 2px);
  background-size: 100% 100%, var(--mx-size) var(--mx-size);
  background-position: 0 0, calc(var(--mx-size) / 2) calc(var(--mx-size) / 2);
  -webkit-mask-image: radial-gradient(circle 48px at var(--mx, 50%) var(--my, 50%), #000 0, transparent 100%);
          mask-image: radial-gradient(circle 48px at var(--mx, 50%) var(--my, 50%), #000 0, transparent 100%);
  opacity: 0;
  transition: opacity var(--dur-2, 0.16s) ease;
}
.btn:hover::before, .react-btn:hover::before, .feed-tab:hover::before, .dtab:hover::before, .oc-tf:hover::before, .np-seg:hover::before, .np-vs-btn:hover::before, .mp-btn:hover::before, .copy-btn:hover::before, .nav-toggle:hover::before, .sc-hop:hover::before, .np-row-call:hover::before, .motion-btn:hover::before, .npm-item:hover::before, .auth-seg:hover::before, .auth-tab:hover::before, .profile-link:hover::before, .np-caret-btn:hover::before, .swap-choice:hover::before, .file-label:hover::before, .vote-btn:hover::before, .sort-btn:hover::before, .linklike:hover::before, .oauth-btn:hover::before, .btn-follow:hover::before, .gobj-link:hover::before, .wc-item:hover::before, .wc-deep:hover::before, .np-search-clear:hover::before, .np-tickcopy:hover::before, .tm-x:hover::before, .pin-chip-open:hover::before, .pin-chip-rm:hover::before, .np-pin:hover::before, .np-sort:hover::before, .np-more:hover::before, .np-refresh:hover::before, .np-hidden-link:hover::before, .np-status button:hover::before, .np-newbar:hover::before, .np-lookup-clear:hover::before, .ab-chip:hover::before, .np-chip:hover::before, .np-den:hover::before, .np-sv-apply:hover::before, .np-sv-del:hover::before, .np-runner-pin:hover::before, .np-runner-chart:hover::before, .np-rail-btn:hover::before, .np-feed-fresh:hover::before, .np-watch:hover::before, .np-wl-remove:hover::before, .notif-bell:hover::before, .notif-clearall:hover::before, .notif-x:hover::before, .sc-btn:hover::before, .sc-senders-toggle:hover::before, .wall-tab:hover::before, .lb-win:hover::before, .ll-toggle button:hover::before, .comm-tab:hover::before, .ge-info:hover::before, .cmp-mode:hover::before, .np-chain-btn:hover::before, .oc-mk:hover::before, .ll-info:hover::before, .arena-tab:hover::before, .np-social-btn:hover::before, .cw-tab:hover::before, .np-strat:hover::before, .np-fclose:hover::before, .pillar > summary:hover::before, .oc-data > summary:hover::before, .b0-conn summary:hover::before, .modal-x:hover::before, .wc-x:hover::before, .media-preview-rm:hover::before, .intro-skip:hover::before, .gif-toggle:hover::before, .oc-reset:hover::before, .addr-clear:hover::before, #compose-fab:hover::before, .risk-chip:hover::before, .g1-w-link:hover::before, .sc-info:hover::before, .sc-tab:hover::before,
.btn:focus-visible::before, .react-btn:focus-visible::before, .feed-tab:focus-visible::before, .dtab:focus-visible::before, .oc-tf:focus-visible::before, .np-seg:focus-visible::before, .np-vs-btn:focus-visible::before, .mp-btn:focus-visible::before, .copy-btn:focus-visible::before, .nav-toggle:focus-visible::before, .sc-hop:focus-visible::before, .np-row-call:focus-visible::before, .motion-btn:focus-visible::before, .npm-item:focus-visible::before, .auth-seg:focus-visible::before, .auth-tab:focus-visible::before, .profile-link:focus-visible::before, .np-caret-btn:focus-visible::before, .swap-choice:focus-visible::before, .file-label:focus-visible::before, .vote-btn:focus-visible::before, .sort-btn:focus-visible::before, .linklike:focus-visible::before, .oauth-btn:focus-visible::before, .btn-follow:focus-visible::before, .gobj-link:focus-visible::before, .wc-item:focus-visible::before, .wc-deep:focus-visible::before, .np-search-clear:focus-visible::before, .np-tickcopy:focus-visible::before, .tm-x:focus-visible::before, .pin-chip-open:focus-visible::before, .pin-chip-rm:focus-visible::before, .np-pin:focus-visible::before, .np-sort:focus-visible::before, .np-more:focus-visible::before, .np-refresh:focus-visible::before, .np-hidden-link:focus-visible::before, .np-status button:focus-visible::before, .np-newbar:focus-visible::before, .np-lookup-clear:focus-visible::before, .ab-chip:focus-visible::before, .np-chip:focus-visible::before, .np-den:focus-visible::before, .np-sv-apply:focus-visible::before, .np-sv-del:focus-visible::before, .np-runner-pin:focus-visible::before, .np-runner-chart:focus-visible::before, .np-rail-btn:focus-visible::before, .np-feed-fresh:focus-visible::before, .np-watch:focus-visible::before, .np-wl-remove:focus-visible::before, .notif-bell:focus-visible::before, .notif-clearall:focus-visible::before, .notif-x:focus-visible::before, .sc-btn:focus-visible::before, .sc-senders-toggle:focus-visible::before, .wall-tab:focus-visible::before, .lb-win:focus-visible::before, .ll-toggle button:focus-visible::before, .comm-tab:focus-visible::before, .ge-info:focus-visible::before, .cmp-mode:focus-visible::before, .np-chain-btn:focus-visible::before, .oc-mk:focus-visible::before, .ll-info:focus-visible::before, .arena-tab:focus-visible::before, .np-social-btn:focus-visible::before, .cw-tab:focus-visible::before, .np-strat:focus-visible::before, .np-fclose:focus-visible::before, .pillar > summary:focus-visible::before, .oc-data > summary:focus-visible::before, .b0-conn summary:focus-visible::before, .modal-x:focus-visible::before, .wc-x:focus-visible::before, .media-preview-rm:focus-visible::before, .intro-skip:focus-visible::before, .gif-toggle:focus-visible::before, .oc-reset:focus-visible::before, .addr-clear:focus-visible::before, #compose-fab:focus-visible::before, .risk-chip:focus-visible::before, .g1-w-link:focus-visible::before, .sc-info:focus-visible::before, .sc-tab:focus-visible::before {
  opacity: 0.85;
  animation: mx-rain 1.1s linear infinite;
}
.btn:hover::after, .react-btn:hover::after, .feed-tab:hover::after, .dtab:hover::after, .oc-tf:hover::after, .np-seg:hover::after, .np-vs-btn:hover::after, .mp-btn:hover::after, .copy-btn:hover::after, .nav-toggle:hover::after, .sc-hop:hover::after, .np-row-call:hover::after, .motion-btn:hover::after, .npm-item:hover::after, .auth-seg:hover::after, .auth-tab:hover::after, .profile-link:hover::after, .np-caret-btn:hover::after, .swap-choice:hover::after, .file-label:hover::after, .vote-btn:hover::after, .sort-btn:hover::after, .linklike:hover::after, .oauth-btn:hover::after, .btn-follow:hover::after, .gobj-link:hover::after, .wc-item:hover::after, .wc-deep:hover::after, .np-search-clear:hover::after, .np-tickcopy:hover::after, .tm-x:hover::after, .pin-chip-open:hover::after, .pin-chip-rm:hover::after, .np-pin:hover::after, .np-sort:hover::after, .np-more:hover::after, .np-refresh:hover::after, .np-hidden-link:hover::after, .np-status button:hover::after, .np-newbar:hover::after, .np-lookup-clear:hover::after, .ab-chip:hover::after, .np-chip:hover::after, .np-den:hover::after, .np-sv-apply:hover::after, .np-sv-del:hover::after, .np-runner-pin:hover::after, .np-runner-chart:hover::after, .np-rail-btn:hover::after, .np-feed-fresh:hover::after, .np-watch:hover::after, .np-wl-remove:hover::after, .notif-bell:hover::after, .notif-clearall:hover::after, .notif-x:hover::after, .sc-btn:hover::after, .sc-senders-toggle:hover::after, .wall-tab:hover::after, .lb-win:hover::after, .ll-toggle button:hover::after, .comm-tab:hover::after, .ge-info:hover::after, .cmp-mode:hover::after, .np-chain-btn:hover::after, .oc-mk:hover::after, .ll-info:hover::after, .arena-tab:hover::after, .np-social-btn:hover::after, .cw-tab:hover::after, .np-strat:hover::after, .np-fclose:hover::after, .pillar > summary:hover::after, .oc-data > summary:hover::after, .b0-conn summary:hover::after, .modal-x:hover::after, .wc-x:hover::after, .media-preview-rm:hover::after, .intro-skip:hover::after, .gif-toggle:hover::after, .oc-reset:hover::after, .addr-clear:hover::after, #compose-fab:hover::after, .risk-chip:hover::after, .g1-w-link:hover::after, .sc-info:hover::after, .sc-tab:hover::after,
.btn:focus-visible::after, .react-btn:focus-visible::after, .feed-tab:focus-visible::after, .dtab:focus-visible::after, .oc-tf:focus-visible::after, .np-seg:focus-visible::after, .np-vs-btn:focus-visible::after, .mp-btn:focus-visible::after, .copy-btn:focus-visible::after, .nav-toggle:focus-visible::after, .sc-hop:focus-visible::after, .np-row-call:focus-visible::after, .motion-btn:focus-visible::after, .npm-item:focus-visible::after, .auth-seg:focus-visible::after, .auth-tab:focus-visible::after, .profile-link:focus-visible::after, .np-caret-btn:focus-visible::after, .swap-choice:focus-visible::after, .file-label:focus-visible::after, .vote-btn:focus-visible::after, .sort-btn:focus-visible::after, .linklike:focus-visible::after, .oauth-btn:focus-visible::after, .btn-follow:focus-visible::after, .gobj-link:focus-visible::after, .wc-item:focus-visible::after, .wc-deep:focus-visible::after, .np-search-clear:focus-visible::after, .np-tickcopy:focus-visible::after, .tm-x:focus-visible::after, .pin-chip-open:focus-visible::after, .pin-chip-rm:focus-visible::after, .np-pin:focus-visible::after, .np-sort:focus-visible::after, .np-more:focus-visible::after, .np-refresh:focus-visible::after, .np-hidden-link:focus-visible::after, .np-status button:focus-visible::after, .np-newbar:focus-visible::after, .np-lookup-clear:focus-visible::after, .ab-chip:focus-visible::after, .np-chip:focus-visible::after, .np-den:focus-visible::after, .np-sv-apply:focus-visible::after, .np-sv-del:focus-visible::after, .np-runner-pin:focus-visible::after, .np-runner-chart:focus-visible::after, .np-rail-btn:focus-visible::after, .np-feed-fresh:focus-visible::after, .np-watch:focus-visible::after, .np-wl-remove:focus-visible::after, .notif-bell:focus-visible::after, .notif-clearall:focus-visible::after, .notif-x:focus-visible::after, .sc-btn:focus-visible::after, .sc-senders-toggle:focus-visible::after, .wall-tab:focus-visible::after, .lb-win:focus-visible::after, .ll-toggle button:focus-visible::after, .comm-tab:focus-visible::after, .ge-info:focus-visible::after, .cmp-mode:focus-visible::after, .np-chain-btn:focus-visible::after, .oc-mk:focus-visible::after, .ll-info:focus-visible::after, .arena-tab:focus-visible::after, .np-social-btn:focus-visible::after, .cw-tab:focus-visible::after, .np-strat:focus-visible::after, .np-fclose:focus-visible::after, .pillar > summary:focus-visible::after, .oc-data > summary:focus-visible::after, .b0-conn summary:focus-visible::after, .modal-x:focus-visible::after, .wc-x:focus-visible::after, .media-preview-rm:focus-visible::after, .intro-skip:focus-visible::after, .gif-toggle:focus-visible::after, .oc-reset:focus-visible::after, .addr-clear:focus-visible::after, #compose-fab:focus-visible::after, .risk-chip:focus-visible::after, .g1-w-link:focus-visible::after, .sc-info:focus-visible::after, .sc-tab:focus-visible::after {
  opacity: 1;
}
/* the press: every cell lights at once, then the pointer light takes over again */
.btn:active::after, .react-btn:active::after, .feed-tab:active::after, .dtab:active::after, .oc-tf:active::after, .np-seg:active::after, .np-vs-btn:active::after, .mp-btn:active::after, .copy-btn:active::after, .nav-toggle:active::after, .sc-hop:active::after, .np-row-call:active::after, .motion-btn:active::after, .npm-item:active::after, .auth-seg:active::after, .auth-tab:active::after, .profile-link:active::after, .np-caret-btn:active::after, .swap-choice:active::after, .file-label:active::after, .vote-btn:active::after, .sort-btn:active::after, .linklike:active::after, .oauth-btn:active::after, .btn-follow:active::after, .gobj-link:active::after, .wc-item:active::after, .wc-deep:active::after, .np-search-clear:active::after, .np-tickcopy:active::after, .tm-x:active::after, .pin-chip-open:active::after, .pin-chip-rm:active::after, .np-pin:active::after, .np-sort:active::after, .np-more:active::after, .np-refresh:active::after, .np-hidden-link:active::after, .np-status button:active::after, .np-newbar:active::after, .np-lookup-clear:active::after, .ab-chip:active::after, .np-chip:active::after, .np-den:active::after, .np-sv-apply:active::after, .np-sv-del:active::after, .np-runner-pin:active::after, .np-runner-chart:active::after, .np-rail-btn:active::after, .np-feed-fresh:active::after, .np-watch:active::after, .np-wl-remove:active::after, .notif-bell:active::after, .notif-clearall:active::after, .notif-x:active::after, .sc-btn:active::after, .sc-senders-toggle:active::after, .wall-tab:active::after, .lb-win:active::after, .ll-toggle button:active::after, .comm-tab:active::after, .ge-info:active::after, .cmp-mode:active::after, .np-chain-btn:active::after, .oc-mk:active::after, .ll-info:active::after, .arena-tab:active::after, .np-social-btn:active::after, .cw-tab:active::after, .np-strat:active::after, .np-fclose:active::after, .pillar > summary:active::after, .oc-data > summary:active::after, .b0-conn summary:active::after, .modal-x:active::after, .wc-x:active::after, .media-preview-rm:active::after, .intro-skip:active::after, .gif-toggle:active::after, .oc-reset:active::after, .addr-clear:active::after, #compose-fab:active::after, .risk-chip:active::after, .g1-w-link:active::after, .sc-info:active::after, .sc-tab:active::after {
  -webkit-mask-image: none; mask-image: none; opacity: 0.9;
}
@keyframes mx-rain { from { background-position: 0 0, 0 0; } to { background-position: 0 var(--mx-size), 0 0; } }
/* disabled tiles are still tiles, but nothing in them moves or lights */
.btn:disabled::before, .btn[aria-disabled="true"]::before, .react-btn:disabled::before, .sc-hop:disabled::before, .sc-btn:disabled::before, .np-row-call[disabled]::before, .pin-chip-rm:disabled::before, .sc-info:disabled::before, .sc-tab:disabled::before { animation: none; opacity: 0.35; }
.btn:disabled::after, .btn[aria-disabled="true"]::after, .react-btn:disabled::after, .sc-hop:disabled::after, .sc-btn:disabled::after, .np-row-call[disabled]::after, .pin-chip-rm:disabled::after, .sc-info:disabled::after, .sc-tab:disabled::after { display: none; }
@media (prefers-reduced-motion: reduce) {
  .btn::before, .react-btn::before, .feed-tab::before, .dtab::before, .oc-tf::before, .np-seg::before, .np-vs-btn::before, .mp-btn::before, .copy-btn::before, .nav-toggle::before, .sc-hop::before, .np-row-call::before, .motion-btn::before, .npm-item::before, .auth-seg::before, .auth-tab::before, .profile-link::before, .np-caret-btn::before, .swap-choice::before, .file-label::before, .vote-btn::before, .sort-btn::before, .linklike::before, .oauth-btn::before, .btn-follow::before, .gobj-link::before, .wc-item::before, .wc-deep::before, .np-search-clear::before, .np-tickcopy::before, .tm-x::before, .pin-chip-open::before, .pin-chip-rm::before, .np-pin::before, .np-sort::before, .np-more::before, .np-refresh::before, .np-hidden-link::before, .np-status button::before, .np-newbar::before, .np-lookup-clear::before, .ab-chip::before, .np-chip::before, .np-den::before, .np-sv-apply::before, .np-sv-del::before, .np-runner-pin::before, .np-runner-chart::before, .np-rail-btn::before, .np-feed-fresh::before, .np-watch::before, .np-wl-remove::before, .notif-bell::before, .notif-clearall::before, .notif-x::before, .sc-btn::before, .sc-senders-toggle::before, .wall-tab::before, .lb-win::before, .ll-toggle button::before, .comm-tab::before, .ge-info::before, .cmp-mode::before, .np-chain-btn::before, .oc-mk::before, .ll-info::before, .arena-tab::before, .np-social-btn::before, .cw-tab::before, .np-strat::before, .np-fclose::before, .pillar > summary::before, .oc-data > summary::before, .b0-conn summary::before, .modal-x::before, .wc-x::before, .media-preview-rm::before, .intro-skip::before, .gif-toggle::before, .oc-reset::before, .addr-clear::before, #compose-fab::before, .risk-chip::before, .g1-w-link::before, .sc-info::before, .sc-tab::before { animation: none !important; }
}
html.motion-off .btn::before, html.motion-off .react-btn::before, html.motion-off .feed-tab::before, html.motion-off .dtab::before, html.motion-off .oc-tf::before, html.motion-off .np-seg::before, html.motion-off .np-vs-btn::before, html.motion-off .mp-btn::before, html.motion-off .copy-btn::before, html.motion-off .nav-toggle::before, html.motion-off .sc-hop::before, html.motion-off .np-row-call::before, html.motion-off .motion-btn::before, html.motion-off .npm-item::before, html.motion-off .auth-seg::before, html.motion-off .auth-tab::before, html.motion-off .profile-link::before, html.motion-off .np-caret-btn::before, html.motion-off .swap-choice::before, html.motion-off .file-label::before, html.motion-off .vote-btn::before, html.motion-off .sort-btn::before, html.motion-off .linklike::before, html.motion-off .oauth-btn::before, html.motion-off .btn-follow::before, html.motion-off .gobj-link::before, html.motion-off .wc-item::before, html.motion-off .wc-deep::before, html.motion-off .np-search-clear::before, html.motion-off .np-tickcopy::before, html.motion-off .tm-x::before, html.motion-off .pin-chip-open::before, html.motion-off .pin-chip-rm::before, html.motion-off .np-pin::before, html.motion-off .np-sort::before, html.motion-off .np-more::before, html.motion-off .np-refresh::before, html.motion-off .np-hidden-link::before, html.motion-off .np-status button::before, html.motion-off .np-newbar::before, html.motion-off .np-lookup-clear::before, html.motion-off .ab-chip::before, html.motion-off .np-chip::before, html.motion-off .np-den::before, html.motion-off .np-sv-apply::before, html.motion-off .np-sv-del::before, html.motion-off .np-runner-pin::before, html.motion-off .np-runner-chart::before, html.motion-off .np-rail-btn::before, html.motion-off .np-feed-fresh::before, html.motion-off .np-watch::before, html.motion-off .np-wl-remove::before, html.motion-off .notif-bell::before, html.motion-off .notif-clearall::before, html.motion-off .notif-x::before, html.motion-off .sc-btn::before, html.motion-off .sc-senders-toggle::before, html.motion-off .wall-tab::before, html.motion-off .lb-win::before, html.motion-off .ll-toggle button::before, html.motion-off .comm-tab::before, html.motion-off .ge-info::before, html.motion-off .cmp-mode::before, html.motion-off .np-chain-btn::before, html.motion-off .oc-mk::before, html.motion-off .ll-info::before, html.motion-off .arena-tab::before, html.motion-off .np-social-btn::before, html.motion-off .cw-tab::before, html.motion-off .np-strat::before, html.motion-off .np-fclose::before, html.motion-off .pillar > summary::before, html.motion-off .oc-data > summary::before, html.motion-off .b0-conn summary::before, html.motion-off .modal-x::before, html.motion-off .wc-x::before, html.motion-off .media-preview-rm::before, html.motion-off .intro-skip::before, html.motion-off .gif-toggle::before, html.motion-off .oc-reset::before, html.motion-off .addr-clear::before, html.motion-off #compose-fab::before, html.motion-off .risk-chip::before, html.motion-off .g1-w-link::before, html.motion-off .sc-info::before, html.motion-off .sc-tab::before { animation: none !important; }
@media (forced-colors: active) {
  .btn::before, .btn::after, .react-btn::before, .react-btn::after, .feed-tab::before, .feed-tab::after, .dtab::before, .dtab::after, .oc-tf::before, .oc-tf::after, .np-seg::before, .np-seg::after, .np-vs-btn::before, .np-vs-btn::after, .mp-btn::before, .mp-btn::after, .copy-btn::before, .copy-btn::after, .nav-toggle::before, .nav-toggle::after, .sc-hop::before, .sc-hop::after, .np-row-call::before, .np-row-call::after, .motion-btn::before, .motion-btn::after, .npm-item::before, .npm-item::after, .auth-seg::before, .auth-seg::after, .auth-tab::before, .auth-tab::after, .profile-link::before, .profile-link::after, .np-caret-btn::before, .np-caret-btn::after, .swap-choice::before, .swap-choice::after, .file-label::before, .file-label::after, .vote-btn::before, .vote-btn::after, .sort-btn::before, .sort-btn::after, .linklike::before, .linklike::after, .oauth-btn::before, .oauth-btn::after, .btn-follow::before, .btn-follow::after, .gobj-link::before, .gobj-link::after, .wc-item::before, .wc-item::after, .wc-deep::before, .wc-deep::after, .np-search-clear::before, .np-search-clear::after, .np-tickcopy::before, .np-tickcopy::after, .tm-x::before, .tm-x::after, .pin-chip-open::before, .pin-chip-open::after, .pin-chip-rm::before, .pin-chip-rm::after, .np-pin::before, .np-pin::after, .np-sort::before, .np-sort::after, .np-more::before, .np-more::after, .np-refresh::before, .np-refresh::after, .np-hidden-link::before, .np-hidden-link::after, .np-status button::before, .np-status button::after, .np-newbar::before, .np-newbar::after, .np-lookup-clear::before, .np-lookup-clear::after, .ab-chip::before, .ab-chip::after, .np-chip::before, .np-chip::after, .np-den::before, .np-den::after, .np-sv-apply::before, .np-sv-apply::after, .np-sv-del::before, .np-sv-del::after, .np-runner-pin::before, .np-runner-pin::after, .np-runner-chart::before, .np-runner-chart::after, .np-rail-btn::before, .np-rail-btn::after, .np-feed-fresh::before, .np-feed-fresh::after, .np-watch::before, .np-watch::after, .np-wl-remove::before, .np-wl-remove::after, .notif-bell::before, .notif-bell::after, .notif-clearall::before, .notif-clearall::after, .notif-x::before, .notif-x::after, .sc-btn::before, .sc-btn::after, .sc-senders-toggle::before, .sc-senders-toggle::after, .wall-tab::before, .wall-tab::after, .lb-win::before, .lb-win::after, .ll-toggle button::before, .ll-toggle button::after, .comm-tab::before, .comm-tab::after, .ge-info::before, .ge-info::after, .cmp-mode::before, .cmp-mode::after, .np-chain-btn::before, .np-chain-btn::after, .oc-mk::before, .oc-mk::after, .ll-info::before, .ll-info::after, .arena-tab::before, .arena-tab::after, .np-social-btn::before, .np-social-btn::after, .cw-tab::before, .cw-tab::after, .np-strat::before, .np-strat::after, .np-fclose::before, .np-fclose::after, .pillar > summary::before, .pillar > summary::after, .oc-data > summary::before, .oc-data > summary::after, .b0-conn summary::before, .b0-conn summary::after, .modal-x::before, .modal-x::after, .wc-x::before, .wc-x::after, .media-preview-rm::before, .media-preview-rm::after, .intro-skip::before, .intro-skip::after, .gif-toggle::before, .gif-toggle::after, .oc-reset::before, .oc-reset::after, .addr-clear::before, .addr-clear::after, #compose-fab::before, #compose-fab::after, .risk-chip::before, .risk-chip::after, .g1-w-link::before, .g1-w-link::after, .sc-info::before, .sc-tab::before, .sc-info::after, .sc-tab::after { display: none; }
}

/* ===== The age gate (agegate.js) ==================================================================
   One question, once per device, before the site opens: are you 18 or older. It wears the site's own
   look — the matte green-biased black, the brand green, the matrix grid — because it is the first thing
   anybody sees. z-index 9960: above every modal (the ticket is 9000, the sign-in confirm 9500) and the
   toasts, below the tip bubbles (9990) so its buttons can still describe themselves, and below the
   rocket cursor (9998/9999), which hides the native pointer — painting over it would leave no cursor. */

/* Until the question is built, a plain cover, so the page never flashes before it. On the homepage the
   loading screen (z 999) sits above this, and entry.js drops the cover the moment that screen is up. */
html.age-pending::after {
  content: ''; position: fixed; inset: 0; z-index: 998; pointer-events: none;
  background: var(--ink);
}
html.age-open, html.age-open body { overflow: hidden; }

#age-gate {
  position: fixed; inset: 0; z-index: 9960;
  display: grid; place-items: center;
  padding: max(1rem, env(safe-area-inset-top, 0px)) 1rem max(1rem, env(safe-area-inset-bottom, 0px));
  overflow-y: auto; overscroll-behavior: contain;
  color: var(--text);
  background:
    radial-gradient(90% 70% at 50% 42%, color-mix(in srgb, var(--green) 14%, transparent), transparent 70%),
    repeating-linear-gradient(to right, color-mix(in srgb, var(--green) 7%, transparent) 0 1px, transparent 1px 28px),
    repeating-linear-gradient(to bottom, color-mix(in srgb, var(--green) 7%, transparent) 0 1px, transparent 1px 28px),
    color-mix(in srgb, var(--ink) 94%, transparent);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  animation: age-in var(--dur-3, 320ms) var(--ease-out, ease) both;
}
#age-gate.age-leaving { animation: age-out 240ms ease both; pointer-events: none; }
@keyframes age-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes age-out { from { opacity: 1; } to { opacity: 0; } }

.age-card {
  width: min(100%, 30rem); margin: auto;
  display: flex; flex-direction: column; align-items: center; gap: 0.85rem;
  padding: clamp(1.25rem, 5vw, 2.1rem);
  text-align: center;
  background: linear-gradient(180deg, var(--ink-3), var(--ink-2));
  border: 1.5px solid color-mix(in srgb, var(--green) 38%, transparent);
  border-radius: var(--r-4, 22px);
  box-shadow: 0 30px 80px -24px rgba(0,0,0,0.9), 0 0 48px color-mix(in srgb, var(--green) 16%, transparent);
  animation: age-card-in var(--dur-4, 600ms) cubic-bezier(0.2, 1.4, 0.4, 1) both;
}
.age-card[hidden] { display: none !important; }
@keyframes age-card-in { from { transform: translateY(14px) scale(0.97); } to { transform: none; } }

.age-brand { display: inline-flex; align-items: center; gap: 0.5rem; }
.age-brand img { width: 48px; height: 48px; filter: drop-shadow(0 0 12px color-mix(in srgb, var(--green) 50%, transparent)); }
.age-brand span { font-family: 'Luckiest Guy', cursive; font-size: max(var(--text-floor), 1.35rem); letter-spacing: 0.02em; color: var(--green-bright); }

.age-kicker {
  margin: 0.2rem 0 0; padding: 0.2rem 0.65rem 0.2rem calc(0.65rem + 0.22em); border-radius: var(--r-pill, 999px);   /* the tracking after the last letter, matched on the left */
  font-size: max(var(--text-floor), 0.72rem); font-weight: 800; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--on-green); background: var(--green-bright);
}
.age-title {
  margin: 0; font-family: 'Luckiest Guy', cursive; font-weight: 400; letter-spacing: 0.02em;
  font-size: max(var(--text-floor), clamp(1.7rem, 7vw, 2.4rem)); line-height: 1.05; color: var(--text);
  text-wrap: balance;
}
.age-title:focus { outline: none; }
.age-title:focus-visible { outline: 3px solid var(--focus); outline-offset: 4px; border-radius: 6px; }
.age-sub { margin: 0; max-width: 40ch; color: var(--text-dim); font-size: max(var(--text-floor), 0.95rem); line-height: 1.55; }

/* the box itself: a real checkbox, large, inside a row the whole of which is the label */
.age-check {
  width: 100%; margin-top: 0.3rem;
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.8rem 0.95rem; min-height: 56px; border-radius: var(--r-2, 14px);
  text-align: left; font-size: max(var(--text-floor), 0.98rem); line-height: 1.4; cursor: pointer;
  background: color-mix(in srgb, var(--ink) 70%, transparent);
  border: 1.5px solid var(--edge-ctl);
  transition: border-color var(--dur-2, 180ms) ease, background var(--dur-2, 180ms) ease;
}
.age-check:hover { border-color: var(--green); }
.age-check:has(input:checked) { border-color: var(--green-bright); background: color-mix(in srgb, var(--green) 12%, var(--ink)); }
.age-check input {
  flex: 0 0 auto; width: 24px; height: 24px; margin: 0; cursor: pointer;
  accent-color: var(--green-bright);
}
.age-check input:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.age-check b { color: var(--text); }

.age-err { margin: 0; min-height: 1.3em; font-size: max(var(--text-floor), 0.88rem); font-weight: 600; color: var(--red-soft); }
.age-actions { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 0.7rem; }
.age-enter { width: 100%; }
.age-fine { margin: 0.2rem 0 0; font-size: max(var(--text-floor), 0.8rem); color: var(--text-mute); line-height: 1.5; }
.age-fine a { color: var(--green-bright); }

@media (max-width: 380px) {
  .age-enter { font-size: max(var(--text-floor), 1rem); padding: 0.85rem 1rem; }
  .age-brand span { font-size: max(var(--text-floor), 1.15rem); }
}
@media (prefers-reduced-motion: reduce) {
  #age-gate, #age-gate.age-leaving, .age-card { animation: none; }
}
html.motion-off #age-gate, html.motion-off #age-gate.age-leaving, html.motion-off .age-card { animation: none; }
@media print {
  #age-gate, html.age-pending::after { display: none !important; }
  html.age-open, html.age-open body { overflow: visible !important; }
}
@media (forced-colors: active) {
  .age-card, .age-check { border: 2px solid CanvasText; }
  html.age-pending::after { background: Canvas; }
}

/* where a price came from, when it is not the index (chain.js) */
.price-src { margin: 0.35rem 0 0; font-size: max(var(--text-floor), 0.78rem); color: var(--text-dim); }

/* the Diamond line in the homepage OG banner wears the Diamond OG colour, not the gold of the rest */
.og-banner .og-diamond-word { color: var(--og-diamond-mid); }

/* Form controls do not inherit the page's size (the browser gives them 13.33px): floored like everything else.
   Element selectors, so any class rule for a control still wins. */
button, input, select, textarea { font-size: max(var(--text-floor), 1em); }
/* A button's line is a fixed 1.2, not 'normal': with 'normal' an emoji in the label (Apple Color Emoji is taller than
   Rubik) grows the line box at the top and pushes the words about 2px below the button's middle on a phone. */
button { line-height: 1.2; font-family: inherit; }   /* and the page's typeface, which a <button> does not inherit on its own (every button without one of its own was drawn in Arial) */

/* a finger does the pointing: every control in the bar grows to the 44px touch target */
@media (pointer: coarse) { :root { --nav-ctl: 44px; } }

/* ===== The token dashboard (newpairs.js: NPCard.dashboardHTML) ======================================
   The default view of a token wherever someone reads more about one — the Scanner's result, the token
   popup, a radar row, a Hot Feed slide, a call's detail, a watchlist row. Header, one strip of headline
   figures, the actions (caveat first), then three columns of cards with the chart in the middle.

   The columns follow the dashboard's OWN width (a container query), not the window's: the same markup
   is a page on the Scanner, fills the popup, and stacks on a phone. The breakpoints are in em because
   every size on this site starts from the text floor (14px on a phone, 19pt from 1280px up), so a
   column is only wide enough when it holds enough words, not enough pixels.
     < 40em  one column, in source order — the order focus and a screen reader take: chart, activity, safety,
             contract, market, holders, block 0, community, links, then the score breakdown
     ≥ 40em  the chart column (chart and activity, the score breakdown under them) beside the side column
     ≥ 52em  three columns: safety + contract | the chart column | market, holders, block 0, community, links
   The side pair spans both rows of the chart column, and the second row is 1fr: in a grid of auto height an item
   spanning a flexible row sizes only that row, so the score breakdown starts right under the activity card whatever
   the height of the columns beside it. */
.tkd { container: tkd / inline-size; text-align: left; }
.tkd-in { display: flex; flex-direction: column; gap: 0.85rem; }

/* header: who it is · what it trades at · what our checks make of it */
.tkd-head {
  display: grid; gap: 0.9rem 1.4rem; align-items: center; grid-template-columns: minmax(0, 1fr);
  padding: 1rem 1.1rem; border: 1.5px solid var(--ink-4); border-radius: 16px;
  background: linear-gradient(120deg, var(--tok-soft, transparent), transparent 55%), var(--ink-2);
}
.tkd-id { display: flex; align-items: center; gap: 0.85rem; min-width: 0; }
.tkd-idt { min-width: 0; display: grid; gap: 0.3rem; justify-items: start; }
/* the logo disc: the team's image when there is one, the ticker's first letter under it either way (a failed
   image is removed by newpairs.js and the letter shows through). The letter is sized from the disc. */
.tkd-logo {
  --ava: calc(var(--text-floor) * 3);
  position: relative; flex: 0 0 auto; width: var(--ava); height: var(--ava); border-radius: 50%; overflow: hidden;
  display: grid; place-content: center; background: var(--tok-soft, var(--ink-3)); border: 2px solid var(--tok, var(--green));
}
.tkd-mono { font-family: 'Luckiest Guy', cursive; font-size: calc(var(--ava) * 0.46); line-height: 1; color: var(--tok, var(--green-bright)); }
.tkd-logo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.tkd-kicker { margin: 0; font-size: max(var(--text-floor), 0.72rem); font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-mute); overflow-wrap: anywhere; }
.tkd-kicker code { letter-spacing: 0; text-transform: none; font-size: max(var(--text-floor), 0.8rem); }
.tkd-h { margin: 0; font-family: 'Luckiest Guy', cursive; font-weight: 400; letter-spacing: 0.02em; line-height: 1.1; color: var(--text); overflow-wrap: anywhere; font-size: max(var(--text-floor), clamp(1.45rem, 4.2cqi, 2.3rem)); }
.tkd-h:focus:not(:focus-visible) { outline: none; }
.tkd-sym { color: var(--green-bright); }
.tkd-sub { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.9rem; font-size: max(var(--text-floor), 0.84rem); color: var(--text-dim); }
.tkd-addr { display: inline-flex; align-items: center; gap: 0.3rem; }
.tkd-addr code { font-size: max(var(--text-floor), 0.84rem); color: var(--text); }
.tkd-idt .np-badges { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.tkd-price { display: grid; gap: 0.25rem; justify-items: start; min-width: 0; }
.tkd-price-l { font-size: max(var(--text-floor), 0.72rem); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-dim); }
.tkd-price-v { font-size: max(var(--text-floor), 1.9rem); font-weight: 800; line-height: 1.1; font-variant-numeric: tabular-nums; color: var(--text); overflow-wrap: anywhere; }
.tkd-moves { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.tkd-verdict { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.35rem 0.75rem; align-items: center; min-width: 0; }
.tkd-verdict .np-gauge { --ava: calc(var(--text-floor) * 3.1); width: var(--ava); height: var(--ava); }
.tkd-verdict .np-gauge-svg { width: 100%; height: 100%; }
.tkd-verdict-t { display: flex; flex-direction: column; align-items: flex-start; gap: 0.3rem; min-width: 0; }
.tkd-verdict .np-verdict { white-space: normal; }
.tkd-health { font-size: max(var(--text-floor), 0.84rem); font-weight: 700; color: var(--text-dim); }
.tkd-health b { font-size: max(var(--text-floor), 1rem); }
.tkd-verdict-why { grid-column: 1 / -1; margin: 0; font-size: max(var(--text-floor), 0.78rem); line-height: 1.45; color: var(--text-dim); }
@container tkd (min-width: 40em) {
  .tkd-head { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "id price" "verdict verdict"; }
  .tkd-id { grid-area: id; } .tkd-price { grid-area: price; justify-items: end; text-align: right; } .tkd-verdict { grid-area: verdict; }
  .tkd-moves { justify-content: flex-end; }
}
@container tkd (min-width: 52em) {
  .tkd-head { grid-template-columns: minmax(0, 1.35fr) auto minmax(0, 1fr); grid-template-areas: "id price verdict"; }
}
.tkd-meta .sc-hit-s { margin: 0; text-align: left; }
.tkd .np-flagstrip { padding: 0; }

/* the headline figures: 2 or 4 across, so a row is never left with one tile on its own (the page caps the dashboard
   near 66em at the 19pt floor, too narrow for eight readable tiles in a row) */
.tkd-stats { margin: 0; display: grid; gap: 0.5rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@container tkd (min-width: 30em) { .tkd-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.tkd-stat { min-width: 0; background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 12px; padding: 0.6rem 0.75rem; }
.tkd-stat dt { font-size: max(var(--text-floor), 0.72rem); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-dim); }
.tkd-stat dd { margin: 0.15rem 0 0; display: grid; gap: 0.1rem; }
.tkd-stat-v { font-size: max(var(--text-floor), 1.15rem); font-weight: 800; line-height: 1.2; font-variant-numeric: tabular-nums; color: var(--text); overflow-wrap: anywhere; }
.tkd-stat-sub { font-size: max(var(--text-floor), 0.74rem); line-height: 1.35; color: var(--text-mute); overflow-wrap: anywhere; }
.tkd-stat.is-bad { border-color: color-mix(in srgb, var(--red) 55%, transparent); }
.tkd-stat.is-bad .tkd-stat-v, .tkd-stat.is-bad .tkd-stat-flag { color: var(--red); }
.tkd-stat.is-warn { border-color: color-mix(in srgb, var(--gold) 55%, transparent); }
.tkd-stat.is-warn .tkd-stat-v, .tkd-stat.is-warn .tkd-stat-flag { color: var(--gold); }
.tkd-stat-flag { font-size: max(var(--text-floor), 0.74rem); font-weight: 800; line-height: 1.35; overflow-wrap: anywhere; }
/* "not read yet": an unknown, set apart from a figure — never a 0 and never a dash beside real numbers */
.tkd-unread { font-size: max(var(--text-floor), 0.86rem); font-weight: 700; font-style: italic; color: var(--text-mute); }

/* the actions: the caveat is read first, then the buttons */
.tkd-actbar { display: grid; gap: 0.6rem; padding: 0.8rem 0.9rem; background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 14px; }
.tkd-caveat { margin: 0; font-size: max(var(--text-floor), 0.78rem); line-height: 1.45; color: var(--text-dim); }
.tkd-acts { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.tkd-acts .call-row { display: contents; }
.tkd-acts .btn, .tkd-acts .np-pin { flex: 0 1 auto; min-height: 44px; }
.tkd-acts .np-pin { border-radius: 999px; padding: 0.5rem 1.1rem; font-size: max(var(--text-floor), 0.95rem); }
@container tkd (max-width: 26em) {
  .tkd-acts .btn, .tkd-acts .np-pin, .tkd-acts .np-watch-wide { flex: 1 1 100%; justify-content: center; }
  .tkd-acts > a.btn { flex-basis: calc(50% - 0.25rem); }   /* the two outside links share a row; the actions keep theirs */
}

/* the columns */
.tkd-grid { display: grid; gap: 0.85rem; grid-template-columns: minmax(0, 1fr); align-items: start; }
.tkd-col, .tkd-side { display: grid; gap: 0.85rem; align-content: start; min-width: 0; grid-template-columns: minmax(0, 1fr); }
@container tkd (min-width: 40em) {
  .tkd-grid { grid-template-columns: minmax(0, 1.65fr) minmax(0, 1fr); grid-template-rows: auto 1fr; }
  .tkd-col--c { grid-column: 1; grid-row: 1; }
  .tkd-col--c2 { grid-column: 1; grid-row: 2; }
  .tkd-side { grid-column: 2; grid-row: 1 / span 2; }
}
@container tkd (min-width: 52em) {
  .tkd-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr) minmax(0, 1fr); }
  .tkd-side { display: contents; }
  .tkd-col--l { grid-column: 1; grid-row: 1 / span 2; }
  .tkd-col--c { grid-column: 2; grid-row: 1; }
  .tkd-col--c2 { grid-column: 2; grid-row: 2; }
  .tkd-col--r { grid-column: 3; grid-row: 1 / span 2; }
}

/* a card: heading, what matters at a glance, and the rest one click down */
.tkd-card { min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.6rem; align-content: start; padding: 0.85rem 0.95rem; background: var(--ink-2); border: 1.5px solid var(--ink-4); border-radius: 14px; }
.tkd-card-h { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.25rem 0.6rem; font-size: max(var(--text-floor), 0.98rem); font-weight: 800; line-height: 1.3; color: var(--text); }
.tkd-card-aside { font-size: max(var(--text-floor), 0.8rem); font-weight: 700; color: var(--text-dim); }
.tkd-card-b { min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.6rem; }   /* minmax(0, …): a wide child (the chart's controls, a table) scrolls or wraps inside, never widens the card */
.tkd-card-b > p, .tkd-card-b > section, .tkd-card-b > div { margin: 0; }
.tkd-card .np-why { margin: 0; padding: 0; }   /* a <section>: the page-level section padding is not for a card */
.tkd-card .np-why-clean { margin: 0; }
.tkd-card .np-audit-lead { margin: 0; }
.tkd-card .np-audit-row { grid-template-columns: minmax(0, 1fr); gap: 0.15rem; }   /* the label over its answer: a side column is too narrow for both across */
.tkd-card .np-audit-row dd { overflow-wrap: anywhere; }
.tkd-card .np-flow, .tkd-card .np-conc, .tkd-card .np-contract { margin: 0; }
.tkd-card .np-reserves { margin: 0; }
.tkd-card .np-holders { max-height: none; margin: 0; }
.tkd-card .np-holder { flex-wrap: wrap; }
.tkd-card .np-holder code { white-space: nowrap; }   /* a short address never breaks mid-way: the share wraps under it instead */
.tkd-card .np-brandstat { padding: 0; }
.tkd-card .np-socials { margin: 0; }
.tkd-card .np-kv { grid-template-columns: repeat(auto-fit, minmax(min(8em, 100%), 1fr)); }
.tkd-card--chart .oc-canvas { height: clamp(230px, min(46vh, 70cqi), 540px); }
.tkd-line { margin: 0; line-height: 1.5; font-size: max(var(--text-floor), 0.9rem); color: var(--text); }
.tkd-line.tkd-bad { color: var(--red); }
.tkd-line.tkd-warn { color: var(--gold); }
.tkd-gaps { margin: 0; font-size: max(var(--text-floor), 0.84rem); line-height: 1.45; color: var(--gold); }
/* a neutral note for what we could not read — deliberately not the green "clean" box, which reads as a pass */
.tkd-note, .tkd-card--chart .np-why-clean, .tkd-card--activity .np-why-clean {
  margin: 0; font-size: max(var(--text-floor), 0.86rem); line-height: 1.45; color: var(--text-dim);
  background: var(--ink); border: 1px dashed var(--ink-5); border-radius: 10px; padding: 0.55rem 0.7rem;
}
.tkd-mini { margin: 0; display: grid; gap: 0.4rem; grid-template-columns: repeat(auto-fit, minmax(min(9em, 100%), 1fr)); }   /* three across, or one per row — never two and a lone third */
.tkd-mini > div { min-width: 0; background: var(--ink); border-radius: 10px; padding: 0.45rem 0.6rem; }
.tkd-mini dt { font-size: max(var(--text-floor), 0.7rem); font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-dim); }
.tkd-mini dd { margin: 0.1rem 0 0; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--text); overflow-wrap: anywhere; }
.tkd-slot .tok-comm-panel { margin: 0; }

/* "More" — a pop-down at the foot of a card. The caret is drawn, not typed, so it sits in the middle of its disc. */
.tkd-more { border-top: 1px solid var(--ink-4); }
.tkd-more-s {
  list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; min-height: 44px;
  padding: 0.4rem 0 0; cursor: pointer; border-radius: 8px;
  font-size: max(var(--text-floor), 0.86rem); font-weight: 800; color: var(--green-bright);
}
.tkd-more-s::-webkit-details-marker { display: none; }
.tkd-more-s:hover .tkd-more-lbl { text-decoration: underline; text-underline-offset: 0.2em; }
.tkd-more-s:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.tkd-more-caret { position: relative; flex: 0 0 auto; width: 1.75em; height: 1.75em; border-radius: 50%; background: var(--ctl-fill-lo); transition: transform 0.2s ease, background 0.15s ease; }
.tkd-more-caret::before { content: ''; position: absolute; left: 50%; top: 50%; translate: -50% -50%; width: 0.62em; height: 0.36em; background: var(--ctl-ink); clip-path: polygon(0 0, 100% 0, 50% 100%); }
.tkd-more-s:hover .tkd-more-caret { background: var(--ctl-fill-hi); }
.tkd-more[open] > .tkd-more-s .tkd-more-caret { transform: rotate(180deg); }
.tkd-more-b { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.6rem; padding: 0.5rem 0 0.1rem; min-width: 0; }
.tkd-more-b > p, .tkd-more-b > div { margin: 0; }
.tkd-more--in { margin-top: 0.5rem; }
.tkd .np-honest { margin: 0; }
@media (prefers-reduced-motion: reduce) { .tkd-more-caret { transition: none; } }
html.motion-off .tkd-more-caret { transition: none; }
@media (forced-colors: active) {
  .tkd-more-caret { background: ButtonFace; border: 1px solid ButtonText; }
  .tkd-more-caret::before { forced-color-adjust: none; background: ButtonText; }
  .tkd-card, .tkd-stat, .tkd-head, .tkd-actbar { border: 1px solid CanvasText; }
}

/* On the Scanner page the result breaks out of the 900px column so three columns have room; the other
   controls keep their width. Same centre as the column, never wider than the window less 1rem a side. */
.sc-result:has(> .tkd) { width: min(1680px, calc(100vw - 2rem)); margin-left: calc(50% - min(840px, 50vw - 1rem)); }

/* ===== Full-screen charts (app.js, ChartFull — owner, 2026-10-14: "Allow a user to expand any chart to full screen pop up and
   easily be able to close it") =====
   The ⤢ on every chart, and the pop-up it opens. In the pop-up the chart takes the room there is: its plot grows to fill what
   the head and the controls leave, and never shrinks under a readable height (with a table opened below it, the view
   scrolls instead). */
.cf-open { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; padding: 0; border: 1.5px solid var(--ctl-fill-lo); border-radius: 10px; background: var(--ctl-fill-lo); color: var(--ctl-ink); font-size: max(var(--text-floor), 1rem); line-height: 1; cursor: pointer; }
.cf-open:hover { background: var(--ctl-fill-hi); border-color: var(--ctl-fill-hi); }
.cf-open:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
@media (pointer: coarse) { .cf-open { width: 44px; height: 44px; } }
/* four corners pointing out: drawn, so it is centred and the same on every device (no font has to carry it) */
.cf-ico { display: block; width: 1em; height: 1em; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M1 1h7v2.5H3.5V8H1zM12 1h7v7h-2.5V3.5H12zM1 12h2.5v4.5H8V19H1zM16.5 12H19v7h-7v-2.5h4.5z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M1 1h7v2.5H3.5V8H1zM12 1h7v7h-2.5V3.5H12zM1 12h2.5v4.5H8V19H1zM16.5 12H19v7h-7v-2.5h4.5z'/%3E%3C/svg%3E") center / 100% 100% no-repeat; }
@media (forced-colors: active) { .cf-ico { background: ButtonText; } }
/* where the ⤢ sits: the price chart's head (last, after the live price); beside the source buttons when the switch has them */
.chart-src-row { display: none; }
.chart-switch.has-src > .chart-src-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.5rem; min-width: 0; }   /* the ⤢ stays top right; the source buttons wrap beside it */
.chart-src-row > .chart-src { flex: 0 1 auto; min-width: 0; }
.chart-switch.has-src .oc-head .cf-open { display: none; }
.np-vol-lbl { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
/* the admin day chart: the ⤢ beside its caption, everything else full width under them */
.adm-chart { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 1rem; align-items: start; }
.adm-chart > * { grid-column: 1 / -1; }
.adm-chart > figcaption { grid-column: 1; grid-row: 1; }
.adm-chart > .cf-open { grid-column: 2; grid-row: 1; }
.ll-head-r { display: inline-flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.wc-head-r { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }

/* the pop-up */
.cf { position: fixed; inset: 0; z-index: 460; display: flex; justify-content: center; padding: clamp(0px, 1.6vw, 1.25rem); }
.cf[hidden] { display: none; }   /* closed means no box at all: agegate.js and arcade.js look for an open dialog by its box */
.cf-backdrop { position: absolute; inset: 0; background: rgba(4, 7, 4, 0.82); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.cf-dialog { position: relative; display: flex; flex-direction: column; width: 100%; max-width: 1920px; min-width: 0; min-height: 0; background: var(--ink); border: 1.5px solid var(--ink-4); border-radius: 16px; overflow: hidden; box-shadow: 0 24px 80px rgba(0, 0, 0, 0.55); }
.cf-dialog:focus { outline: none; }   /* it takes focus only so a press on the chart keeps Esc inside it; the ✕ shows the ring */
.cf-head { flex: 0 0 auto; display: flex; align-items: center; gap: 0.5rem 1rem; padding: 0.55rem 0.7rem 0.55rem 1.1rem; border-bottom: 1.5px solid var(--ink-4); }
.cf-title { flex: 1 1 auto; min-width: 0; margin: 0; font-family: 'Luckiest Guy', cursive; font-weight: 400; letter-spacing: 0.02em; color: var(--green-bright); font-size: max(var(--text-floor), 1.3rem); line-height: 1.2; overflow-wrap: anywhere; }
.cf-x { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 0.35rem 1.05rem; border: 1.5px solid var(--edge-ctl); border-radius: 999px; background: var(--ctl-fill-lo); color: var(--ctl-ink); font-weight: 800; font-size: max(var(--text-floor), 0.95rem); line-height: 1.1; white-space: nowrap; cursor: pointer; }
.cf-x:hover { background: var(--red); border-color: var(--red); color: var(--on-red); }
.cf-x:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.cf-turn { display: none; margin: 0; padding: 0.35rem 1rem; border-bottom: 1px solid var(--hair); color: var(--text-dim); font-size: max(var(--text-floor), 0.82rem); line-height: 1.4; }
@media (orientation: portrait) and (max-width: 640px) and (pointer: coarse) { .cf.has-turn .cf-turn { display: block; } }   /* a phone, not a narrow desktop window, and only for something wide (a chart, a banner) */
.cf-stage { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; padding: 0.8rem 1rem 1rem; }
.cf .cf-ctx { flex: 1 0 auto; display: flex; flex-direction: column; min-width: 0; }   /* .cf .cf-ctx: above .trk-dash's own display */
.cf .cf-ctx > [data-cf-unit] { flex: 1 0 auto; display: flex; flex-direction: column; min-width: 0; margin: 0; }
.cf .cf-open { display: none; }   /* already full screen */
.cf-ph { display: block; min-width: 0; }
@media (max-width: 640px) {
  .cf { padding: 0; }
  .cf-dialog { border: 0; border-radius: 0; }
  .cf-head { padding-left: 0.8rem; }
  .cf-stage { padding: 0.5rem 0.5rem 0.75rem; }
}
@media (prefers-reduced-motion: no-preference) {
  .cf:not([hidden]) .cf-dialog { animation: cf-in 0.16s ease-out; }   /* a fade only: a scale would hand the chart a shrunken box to measure */
}
html.motion-off .cf .cf-dialog { animation: none; }
@keyframes cf-in { from { opacity: 0; } to { opacity: 1; } }

/* each chart in the pop-up: the plot takes the room; at least 55% of the screen even with a table open under it */
.cf .chart-switch > .onchain-chart, .cf .chart-switch > .chart-embed { flex: 1 0 auto; }
.cf .onchain-chart { display: flex; flex-direction: column; }
.cf .oc-plot { flex: 1 1 auto; min-height: 240px; min-height: max(240px, 55vh); min-height: max(240px, 55dvh); }
.cf .oc-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.cf .chart-embed { position: relative; height: auto; min-height: 380px; min-height: max(380px, 60vh); min-height: max(380px, 60dvh); }
.cf .chart-embed-frame { position: absolute; inset: 0; }
.cf .cf-ctx > .wc { display: flex; flex-direction: column; }
.cf .trk-dash .wc-plot { flex: 1 1 auto; aspect-ratio: auto; min-height: 240px; min-height: max(240px, 55vh); min-height: max(240px, 55dvh); }
.cf .trk-dash .wc-canvas { position: absolute; inset: 0; }
.cf .adm-chart-plot { flex: 1 1 auto; height: auto; min-height: 220px; min-height: max(220px, 55vh); min-height: max(220px, 55dvh); }
.cf .np-vol { flex: 1 1 auto; height: auto; min-height: 200px; min-height: max(200px, 50vh); min-height: max(200px, 50dvh); }
.cf .cf-ctx > .loot { width: 100%; max-width: 1100px; margin: 0 auto; }   /* a ranked list reads best at a line length, not the full width of a big screen */
/* a short screen (a phone held sideways): edge to edge, a slimmer head, and each chart sized to the room left under it, so
   its time axis is on screen without scrolling — the floors above are for screens with height to spare */
@media (max-height: 520px) {
  .cf { padding: 0; }
  .cf-dialog { border: 0; border-radius: 0; }
  .cf-head { padding-block: 0.2rem; }
  .cf-stage { padding: 0.4rem 0.6rem 0.6rem; }
  .cf .oc-src { display: none; }
  .cf .oc-plot { min-height: 150px; min-height: max(150px, calc(100vh - 205px)); min-height: max(150px, calc(100dvh - 205px)); }
  .cf .chart-embed { min-height: 180px; min-height: max(180px, calc(100vh - 130px)); min-height: max(180px, calc(100dvh - 130px)); }
  .cf .trk-dash .wc-plot { min-height: 150px; min-height: max(150px, calc(100vh - 190px)); min-height: max(150px, calc(100dvh - 190px)); }
  .cf .adm-chart-plot { min-height: 140px; min-height: max(140px, calc(100vh - 150px)); min-height: max(140px, calc(100dvh - 150px)); }
  .cf .np-vol { min-height: 130px; min-height: max(130px, calc(100vh - 170px)); min-height: max(130px, calc(100dvh - 170px)); }
}

/* ===== The pop-up as a sheet (size 'panel': the Wall Style editor) =====
   Centred and sized to its content on a middling screen, the whole screen on a phone, and at the side of a wide one — with a
   lighter veil, so your wall stays in view beside it and shows each change as you make it. */
.cf.is-panel { align-items: center; }
.cf.is-panel .cf-dialog { max-width: 640px; height: auto; max-height: 100%; }
@media (min-width: 1100px) {
  .cf.is-panel { justify-content: flex-end; align-items: stretch; padding: 0; }
  .cf.is-panel .cf-dialog { max-width: 520px; height: 100%; max-height: none; border-width: 0 0 0 1.5px; border-radius: 0; }
  .cf.is-panel .cf-backdrop { background: rgba(4, 7, 4, 0.35); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
@media (max-width: 640px) { .cf.is-panel .cf-dialog { height: 100%; } }

/* ===== A wall's profile picture and banner, full screen (upage.js — owner, 2026-10-15: "Allow a user to pull up a full screen
   size view of a profile picture and banner by clicking on it") =====
   A see-through button over each: the picture keeps its look, the button takes the press and the keyboard. The banner's sits
   under the avatar (z 1 against the avatar's 2) and under the row of actions beside it, so neither loses a press to it. */
.wall-id-top { position: relative; z-index: 2; }
/* ...and the row's empty strip over the banner's foot lets presses through to the banner; the avatar and the buttons keep theirs */
.wall-id-top, .wall-id-actions { pointer-events: none; }
.wall-avatar, .wall-id-actions > * { pointer-events: auto; }
.wall-view { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; border: 0; border-radius: inherit; background: transparent; color: #fff; cursor: zoom-in; display: grid; place-items: center; }
.wall-view--banner { z-index: 1; }
.wall-view--avatar { z-index: 3; border-radius: 50%; }
.wall-view::after { content: ''; width: 30px; height: 30px; opacity: 0; transition: opacity 0.15s; background: currentColor; filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.8));
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M1 1h7v2.5H3.5V8H1zM12 1h7v7h-2.5V3.5H12zM1 12h2.5v4.5H8V19H1zM16.5 12H19v7h-7v-2.5h4.5z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M1 1h7v2.5H3.5V8H1zM12 1h7v7h-2.5V3.5H12zM1 12h2.5v4.5H8V19H1zM16.5 12H19v7h-7v-2.5h4.5z'/%3E%3C/svg%3E") center / 100% 100% no-repeat; }
.wall-view:hover, .wall-view:focus-visible { background: rgba(0, 0, 0, 0.28); }
.wall-view:hover::after, .wall-view:focus-visible::after { opacity: 1; }
.wall-view:focus-visible { outline: 3px solid var(--focus); outline-offset: -3px; }
.wall-view--add::after { content: '＋'; width: auto; height: auto; -webkit-mask: none; mask: none; background: none; font-size: max(var(--text-floor), 1.6rem); font-weight: 800; }   /* your own wall with no banner yet: add one */
@media (prefers-reduced-motion: reduce) { .wall-view::after { transition: none; } }
@media (forced-colors: active) { .wall-view::after { background: ButtonText; } }
/* the full view itself: the picture as large as the screen allows, never cropped */
.mv { flex: 1 0 auto; margin: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1rem; min-width: 0; }
.mv-media { display: block; max-width: 100%; max-height: calc(100vh - 12rem); max-height: calc(100dvh - 12rem); width: auto; height: auto; object-fit: contain; border-radius: 12px; }
.mv-emoji { display: grid; place-items: center; width: min(70vmin, 22rem); aspect-ratio: 1; border-radius: 50%; line-height: 1; font-size: max(var(--text-floor), min(38vmin, 12rem)); background: radial-gradient(circle at 30% 28%, var(--ink-4), var(--ink)); border: 4px solid var(--accent, var(--green)); }
.mv-cap { margin: 0; text-align: center; color: var(--text-dim); font-size: max(var(--text-floor), 0.9rem); }
.mv-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.6rem; }

/* ===== The Wall Style editor (wallstyle.js) in the pop-up ===== */
.ws { display: grid; gap: 0.9rem; min-width: 0; }
.ws-lead { margin: 0; color: var(--text-dim); font-size: max(var(--text-floor), 0.9rem); line-height: 1.45; }
.ws-sec { min-width: 0; padding: 0.8rem 0.9rem 0.9rem; border: 1.5px solid var(--ink-4); border-radius: 14px; background: var(--ink-2); scroll-margin-top: 0.5rem; }
.ws-sec:focus { outline: none; }
.ws-sec:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.ws-h { margin: 0 0 0.2rem; font-size: max(var(--text-floor), 1.05rem); font-weight: 800; color: var(--text); }
.ws .f-label span { font-weight: 400; }
.ws .f-label { margin-top: 0.6rem; }
.ws-emoji { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.ws .addr-input { width: 100%; }
.ws-save-row { display: flex; align-items: center; gap: 0.4rem 0.8rem; flex-wrap: wrap; margin-top: 0.8rem; }
.ws-save-row .modal-note { margin: 0; }
.ws-more { margin: 0; }

