/* ===========================================================================
   PetSwap v6 shell — shared components layered on app.css (the base design
   system). Loaded on every page right after app.css.
   Borderless: surfaces separate by tone (--surface-1/2/3/pop) + soft shadow.
   The only lines allowed are --hairline dividers inside lists/tables, the
   focus ring, the selected-state ring and the rarity bottom edge of item cards.
   =========================================================================== */

:root {
  --gold: #f8b74d;
  --grad-accent: linear-gradient(135deg, #9d6bff 0%, #8b5cf6 45%, #7c3aed 100%);
  --panel: #0e1118;          /* legacy alias of --surface-1 */
  --panel-2: #131722;
  --line: rgba(255, 255, 255, .06);   /* legacy — use --hairline for dividers, never for outlines */
}

body.modal-open { overflow: hidden; }
.muted { color: var(--muted); }
.pos { color: var(--success); }
.neg { color: #ff6b6e; }
.accent { color: var(--accent-hover); }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .92em; }
.break { word-break: break-all; }
.text-danger { color: #ff6b6e; }
.link-btn { color: var(--accent-hover); font-weight: 600; font-size: inherit; padding: 0; }
.link-btn:hover { text-decoration: underline; }
.field-label { display: block; font-size: 13px; font-weight: 600; color: var(--foreground); margin: 14px 0 7px; }
.form-error { margin: 10px 0 0; padding: 9px 12px; border-radius: var(--radius-md); font-size: 13px; font-weight: 500; color: #ff9092; background: rgba(219, 59, 62, .12); animation: slide-fade-in 220ms var(--ease-out) both; }
.pill { display: inline-flex; align-items: center; height: 22px; padding: 0 9px; border-radius: 999px; font-size: 11px; font-weight: 600; background: rgba(255, 255, 255, .06); color: rgba(255, 255, 255, .7); white-space: nowrap; }
.pill-ok { background: rgba(5, 202, 98, .14); color: #3ee48b; }
.pill-warn { background: rgba(248, 183, 77, .14); color: #f8c46d; }
.pill-bad { background: rgba(219, 59, 62, .15); color: #ff8587; }
.pill-mute { background: rgba(255, 255, 255, .05); color: rgba(255, 255, 255, .45); }
.btn-danger-solid { background: #c53033; color: #fff; }
.btn-danger-solid:hover { background: #d83a3d; }
.btn.is-loading { color: transparent !important; pointer-events: none; }
.btn.is-loading > * { visibility: hidden; }
.btn.is-loading::after { content: ''; position: absolute; left: 50%; top: 50%; width: 18px; height: 18px; margin: -9px 0 0 -9px; border-radius: 50%; border: 2px solid rgba(255, 255, 255, .25); border-top-color: #fff; animation: spin 700ms linear infinite; }
.announce-bar { position: relative; z-index: 60; padding: 8px 16px; text-align: center; font-size: 13px; font-weight: 500; background: linear-gradient(90deg, #5b21b6, #7c3aed, #5b21b6); color: #fff; }

/* the PetSwap value icon (values, swap totals, swap credit) — never next to $ */
.vicon { display: inline-block; width: 13px; height: 13px; flex: none; vertical-align: -2px;
  background: url('../img/brand/bloxyshop-coin-64.webp') center / contain no-repeat; } /* the gold BloxyShop "BS" coin */

/* ---------------------------------------------------------------- header */
/* the BloxyShop text wordmark: a fixed 137x26 box (the old logo image's size), so the header and the footer mascot
   never move, whatever font is up */
.logo-word { display: block; width: 137px; height: 26px; white-space: nowrap; font-family: var(--font); font-size: 25px; font-weight: 800; line-height: 26px; letter-spacing: -.01em; color: #fff; filter: drop-shadow(0 2px 10px rgba(139, 92, 246, .25)); }
.logo-acc { color: #c4b5fd; }
.site-header .bar { gap: 14px; }
/* the nav row is as wide on every page: each link reserves its label's bold width (data-label, an invisible line of
   no height; the "/ ''" alt text keeps it out of the link's name), so the row never shifts when the active link
   (bold) changes. The accent ink under the active link is an element of its own (shell.mjs; chrome.js moves it under
   the clicked page's link on the click), so the link may not clip it */
.main-nav .nav-link { flex-direction: column; justify-content: center; overflow: visible; }
.main-nav .nav-link::before { content: attr(data-label); content: attr(data-label) / ""; display: block; height: 0; overflow: hidden; visibility: hidden; font-weight: 600; pointer-events: none; }
.nav-ink { position: absolute; left: 12px; right: 12px; bottom: 3px; height: 2px; border-radius: 2px; background: var(--accent); box-shadow: 0 0 10px rgba(139, 92, 246, .8); transform-origin: 0 50%; pointer-events: none; }
/* a click answers at once, in the page being left: the clicked link lights up while the next page loads, on the
   next frame (no colour transition) — and so does the header link (or tab) of the page it opens, the ink with it
   (chrome.js); the page's own link steps back meanwhile. No tap rectangle on phones */
.mobile-nav a, .main-nav a, .site-footer a, .site-header .logo { -webkit-tap-highlight-color: transparent; }
.main-nav .nav-link.is-pending { color: var(--foreground); transition: none; }
.main-nav .nav-link.is-pending::after { transition: none; } /* its hover underline goes at once: the ink is there */
.main-nav:has(.is-pending) .nav-link.active:not(.is-pending) { color: rgba(255, 255, 255, .8); transition: none; }
/* any other link to another page (chrome.js): a footer link takes the accent, a header menu item (its menu stays open
   until the page changes) a light accent tone, the wordmark dims a little, a button link stays pressed */
#site-footer .footer-col a.is-pending { color: var(--accent-hover); transition: none; }
#site-header .hdr-pop a.is-pending { background: rgba(139, 92, 246, .16); color: #fff; transition: none; }
.site-header .logo.is-pending .logo-word { opacity: .7; }
a.btn.is-pending, a.btn.is-pending:hover { transform: scale(.97); filter: brightness(1.12); transition: none; }
/* the account side never runs past the column: it may shrink (a long name ellipsizes) and the steps at the end of
   the header section drop parts of it on narrow screens */
.header-actions, .auth-slot, .user-menu { min-width: 0; }
.auth-slot { display: flex; align-items: center; gap: 8px; }
/* "Log in" matches the 40px / 12px-corner header chips beside it at every width */
.btn.hdr-login { height: 40px; padding: 0 16px; border-radius: 12px; font-size: 14px; font-weight: 600; }
/* wallet pill: the balance (dropdown trigger) and the "+" Add funds button share one background */
.bal-group { display: flex; align-items: center; gap: 2px; height: 40px; padding: 3px; border-radius: 12px; background: rgba(255, 255, 255, .06); transition: background-color 150ms var(--ease-smooth); }
.bal-group:hover { background: rgba(255, 255, 255, .085); }
.wallet-menu, .user-menu { position: relative; }

/* balance chip = wallet dropdown trigger */
.bal-chip { display: inline-flex; align-items: center; gap: 8px; height: 34px; padding: 0 8px 0 10px; border-radius: 9px; font-size: 14px; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums;
  background: transparent; transition: background-color 150ms var(--ease-smooth); }
.bal-chip:hover { background: rgba(255, 255, 255, .07); }
.bal-chip[aria-expanded="true"] { background: rgba(139, 92, 246, .2); }
.bal-chip .bc-ico { width: 18px; height: 18px; flex: none; color: var(--accent-hover); }
.bal-chip .bc-chev { flex: none; color: rgba(255, 255, 255, .45); transition: transform 200ms var(--ease-out-quart); }
.bal-chip[aria-expanded="true"] .bc-chev { transform: rotate(180deg); }
.bal-chip.bump { animation: bal-bump 520ms var(--ease-out-quart); }
@keyframes bal-bump { 30% { transform: scale(1.08); box-shadow: 0 0 22px rgba(139, 92, 246, .45); } }
.bal-plus { flex: none; width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center; color: #fff; background: var(--grad-accent); box-shadow: 0 3px 12px rgba(139, 92, 246, .4); transition: transform 200ms var(--ease-out-quart), filter 150ms; }
.bal-plus:hover { filter: brightness(1.12); }
.bal-plus:hover svg { transform: rotate(90deg); }
.bal-plus svg { transition: transform 220ms var(--ease-out-quart); }
.bal-plus:active { transform: scale(.92); }

.user-chip { height: 40px; max-width: 100%; padding: 0 10px 0 6px; gap: 8px; border-radius: 12px; }
.user-chip img, .user-chip .user-avatar { flex: none; border-radius: 8px; }
.discord-chip { flex: none; height: 40px; border-radius: 12px; }
.discord-chip svg { flex: none; }
.user-chip img, .user-chip .user-avatar { width: 28px; height: 28px; }
.uc-name { min-width: 0; max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.uc-chev { flex: none; color: rgba(255, 255, 255, .45); transition: transform 200ms; }
.user-chip[aria-expanded="true"] { background: rgba(255, 255, 255, .1); }
.user-chip[aria-expanded="true"] .uc-chev { transform: rotate(180deg); }

/* header popovers (wallet dropdown + user menu): borderless, tone + shadow */
.hdr-pop { position: absolute; right: 0; top: calc(100% + 10px); z-index: 70; min-width: 220px; padding: 6px; border-radius: 16px;
  background: var(--surface-pop); box-shadow: var(--shadow-pop); transform-origin: top right; animation: hdr-pop-in 170ms var(--ease-out-quart) both; }
@keyframes hdr-pop-in { from { opacity: 0; transform: translateY(-6px) scale(.97); } }
.hdr-pop a, .hdr-pop button:not(.btn) { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 40px; padding: 8px 10px; border-radius: 10px; font-size: 13.5px; font-weight: 500; color: rgba(255, 255, 255, .85); text-align: left; transition: background-color 120ms var(--ease-smooth), color 120ms var(--ease-smooth); }
.hdr-pop a:not(.btn):hover, .hdr-pop button:not(.btn):hover, .hdr-pop a:not(.btn):focus-visible, .hdr-pop button:not(.btn):focus-visible { background: rgba(255, 255, 255, .06); color: #fff; box-shadow: none; }
.hdr-pop svg { flex: none; color: rgba(255, 255, 255, .5); }
.hdr-sep { height: 1px; margin: 4px 8px; background: var(--hairline); }

.um-pop { min-width: 232px; }
.um-head { display: flex; flex-direction: column; padding: 8px 10px 10px; }
.um-head b { font-size: 14px; }
.um-head span { font-size: 12px; color: var(--muted); }
.um-credit { margin: 2px 2px 4px; padding: 9px 10px 8px; border-radius: 12px; background: rgba(139, 92, 246, .09); }
.um-credit-h { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 3px; font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: rgba(255, 255, 255, .5); }
.hdr-pop a.um-credit-row { display: flex; align-items: center; gap: 8px; min-height: 34px; margin: 0 -6px; padding: 4px 6px; border-radius: 8px; font-size: 13px; color: rgba(255, 255, 255, .8); }
.hdr-pop a.um-credit-row:hover, .hdr-pop a.um-credit-row:focus-visible { background: rgba(139, 92, 246, .12); }
.um-credit-row img { width: 16px; height: 16px; opacity: .75; }
.um-credit-row b { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums; }
.um-credit-note { margin: 3px 0 0; font-size: 11px; line-height: 1.4; color: rgba(255, 255, 255, .42); }

.wm-pop { width: 290px; padding: 8px; }
.wm-head { padding: 8px 8px 12px; }
.wm-label { display: block; font-size: 12px; font-weight: 600; color: var(--muted); }
.wm-bal { display: block; margin-top: 2px; font-size: 28px; font-weight: 800; line-height: 1.15; color: #fff; font-variant-numeric: tabular-nums; }
.wm-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; padding: 0 0 6px; }
/* two buttons side by side: "Open inventory" (the desk's menu) is the longest label, and it fits inside its padding
   from 320px (13px; under 360px 12.5px with a little less padding) */
.wm-actions .btn { height: 40px; padding: 0 8px; gap: 6px; font-size: 13px; font-weight: 600; white-space: nowrap; }
@media (max-width: 360px) { .wm-actions .btn { padding: 0 6px; gap: 5px; font-size: 12.5px; } }
.wm-actions .btn svg { color: currentColor; }
.hdr-pop .wm-go { margin-left: auto; width: 14px; height: 14px; opacity: .45; }
/* the swap desk's box (owner, Oct 15): the BloxyShop value of the user's items in the desk's game — the value coin as
   the chip's glyph + fmtValue, never $ — and its menu: "Your MM2 items", the total, that game's swap credit, Deposit
   items / Open inventory. A total the desk hasn't told yet keeps the chip's size with a quiet bar (rule 17): the value
   box is as wide as the widest fmtValue answer ("88.8M": 43.4px at 14px, 40.3px at 13px <= 440px), so the total
   that replaces the bar never moves the header */
.bc-val { min-width: 44px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bc-wait { display: inline-block; width: 44px; height: 10px; border-radius: 5px; vertical-align: middle; background: rgba(255, 255, 255, .1); }
.wm-val { display: flex; align-items: center; gap: 8px; min-width: 0; }
.wm-val .vicon { width: 22px; height: 22px; }
.wm-val .bc-wait { width: 76px; height: 20px; border-radius: 8px; }
.wm-note { display: block; margin-top: 3px; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.wm-note:empty { display: none; }
.wm-credit { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 0 0 8px; padding: 9px 10px; border-radius: 12px; font-size: 12.5px; color: rgba(255, 255, 255, .72); background: rgba(139, 92, 246, .09); }
.wm-credit[hidden] { display: none; }
.wm-credit b { display: inline-flex; align-items: center; gap: 5px; color: #fff; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* signed in on a narrow desktop (a 20-character Roblox name and a 5-digit balance need ~1060px): the Discord chip
   turns icon-only, a long name ellipsizes as the bar narrows (min-width: 0 above), and up to 1040px the name steps
   aside (the avatar chip still opens the account menu) and the five nav links sit 2px apart, so "Market · Swap ·
   Inventory · Values · FAQ" keeps its room beside the swap desk's box and the Discord chip down to 901px */
@media (min-width: 900.02px) and (max-width: 1180px) {
  .header-actions:has(.user-menu) .discord-chip { width: 40px; padding: 0; justify-content: center; }
  .header-actions:has(.user-menu) .discord-chip span { display: none; }
}
@media (min-width: 900.02px) and (max-width: 1040px) { .uc-name { display: none; } .main-nav { gap: 2px; } }
@media (max-width: 900px) {
  .discord-chip { display: none; }
  .uc-name, .uc-chev { display: none; }
  .user-chip { padding: 0 5px; }
  .site-header .logo { margin-right: 0; } /* no nav beside it: the bar gap is the spacing */
}
@media (max-width: 480px) {
  .hdr-pop { position: fixed; left: var(--gutter); right: var(--gutter); top: calc(var(--header-h) + 2px); width: auto; min-width: 0; transform-origin: top center; }
}
@media (max-width: 440px) { .bal-chip { padding: 0 6px 0 8px; gap: 6px; font-size: 13px; } .bal-chip .bc-chev { display: none; } .bc-val { min-width: 41px; } .bal-chip .bc-wait { width: 41px; } }
@media (max-width: 420px) { .logo-word { width: 116px; height: 22px; font-size: 21px; line-height: 22px; } }
/* the header's wordmark follows the page's header size (app.css: --logo-w/-h/-fs, <html data-hdr>); the footer's
   keeps the box above */
.site-header .logo-word { width: var(--logo-w); height: var(--logo-h); font-size: var(--logo-fs); line-height: var(--logo-h); }
/* small phones, signed in: wordmark + wallet box + avatar don't fit with even 16px gutters, so the avatar chip steps
   aside (Inventory and Wallet are in the tab bar; Inventory → Settings has Log out and, for staff, the console) — on the
   swap desk too, where the box shows the desk's item value (Oct 15). At 340px and under the box's glyph (the wallet,
   the desk's value coin) goes too. */
@media (max-width: 400px) { .auth-slot > .bal-group + .user-menu { display: none; } }
@media (max-width: 340px) { .bal-chip .bc-ico { display: none; } .bal-chip { padding-left: 10px; } }
/* last resort for a balance too long for any of the steps above: it ellipsizes inside the box, never off-screen
   (and only after the user chip's name has given way: the box barely shrinks while anything else can) */
.bal-group, .wallet-menu { min-width: 0; }
.auth-slot > .bal-group { flex-shrink: .001; }
.bal-chip { max-width: 100%; }
#bal-amt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bc-val { flex: 0 1 auto; }

/* mobile tab bar: 5 columns */
.mobile-nav { grid-template-columns: repeat(5, 1fr); background: rgba(10, 12, 18, .96); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); }
.mobile-nav a { position: relative; }
.tab-ink { position: absolute; top: 0; left: 30%; right: 30%; height: 2px; border-radius: 2px; background: var(--accent); box-shadow: 0 0 10px var(--accent); transform-origin: 0 50%; pointer-events: none; }
/* the tapped tab takes the active colour at once (the page's own tab steps back meanwhile); the icon gives a little */
.mobile-nav a.is-pending { color: var(--accent); }
.mobile-nav:has(a.is-pending) a.active:not(.is-pending) { color: var(--muted); }
.mobile-nav a svg { transition: transform 100ms var(--ease-out); }
.mobile-nav a:active svg { transform: scale(.92); }

/* ---------------------------------------------------------------- footer */
.site-footer { overflow: hidden; }
.footer-beam { display: none; } /* legacy markup: the footer is separated by tone, not a line */
.site-footer::before { content: ''; position: absolute; inset: 0; background: radial-gradient(40% 80% at 10% 0%, rgba(139, 92, 246, .12), transparent 70%); pointer-events: none; }
/* the brand column is never under 256px (901-1090px); the link columns need ~110px. The blurb is one short line
   ("Swap, buy and sell Roblox items at live values.") wherever the column is wide enough for it */
.footer-grid { grid-template-columns: minmax(256px, 1.6fr) repeat(4, 1fr); }
.footer-brand { position: relative; }
.footer-brand .logo { display: inline-flex; }
.footer-mascot { position: absolute; left: 150px; top: -22px; height: 64px; width: auto; }
/* the mascot (top -22px, 64px tall) ends 42px down: the blurb starts below it, not under its feet */
.footer-brand .footer-blurb { margin-top: 20px; max-width: 340px; }
.footer-col h4 { position: relative; font-size: 15px; margin-bottom: 14px; }
.footer-col { display: flex; flex-direction: column; gap: 11px; font-size: 14px; }
.footer-col a { align-self: flex-start; color: rgba(255, 255, 255, .7); transition: color 150ms; }
.footer-col a:hover { color: #fff; }
.footer-pay { display: flex; gap: 8px; margin-top: 16px; opacity: .85; }
@media (max-width: 900px) { .footer-grid { grid-template-columns: 1fr 1fr; gap: 28px; } .footer-brand { grid-column: 1 / -1; } }

/* ---------------------------------------------------------------- game tabs */
.game-tabs { display: inline-flex; gap: 4px; padding: 4px; border-radius: 14px; background: rgba(255, 255, 255, .04); }
.game-tabs .gt { display: inline-flex; align-items: center; gap: 8px; height: 38px; padding: 0 14px; border-radius: 10px; font-size: 13.5px; font-weight: 600; color: rgba(255, 255, 255, .6); transition: color 150ms, background-color 150ms; white-space: nowrap; }
.game-tabs .gt img { width: 20px; height: 20px; opacity: .7; transition: opacity 150ms, transform 250ms var(--ease-out-quart); }
.game-tabs .gt:hover { color: #fff; background: rgba(255, 255, 255, .04); }
.game-tabs .gt:hover img { transform: rotate(-8deg) scale(1.08); }
.game-tabs .gt.on { color: #fff; background: var(--grad-accent); box-shadow: 0 4px 18px rgba(139, 92, 246, .35); }
.game-tabs .gt.on img { opacity: 1; }
.game-ico { display: inline-block; vertical-align: middle; }
.seg-tabs { display: inline-flex; gap: 2px; padding: 4px; border-radius: 999px; background: rgba(255, 255, 255, .05); }
.seg-tabs button, .seg-tabs a { height: 36px; padding: 0 18px; border-radius: 999px; font-size: 14px; font-weight: 600; color: rgba(255, 255, 255, .6); transition: all 180ms var(--ease-out-quad); }
.seg-tabs .on { color: #fff; background: var(--grad-accent); box-shadow: 0 4px 16px rgba(139, 92, 246, .4); }

/* ---------------------------------------------------------------- item card */
.icard-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
@media (max-width: 560px) { .icard-grid { grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 8px; } }
.icard {
  --rc: 139, 92, 246;
  position: relative; min-width: 0; display: flex; flex-direction: column;
  border-radius: 12px; overflow: hidden; isolation: isolate;
  background: linear-gradient(180deg, #0f121a 0%, #0c0f16 55%, rgba(var(--rc), .10) 100%);
  box-shadow: inset 0 -2px 0 rgb(var(--rc));                       /* rarity bottom edge (allowed) */
  transition: transform 260ms var(--ease-out-quart), box-shadow 260ms var(--ease-out);
  animation: card-rise 360ms var(--ease-out-quart) backwards; animation-delay: var(--rd, 0ms);
}
@keyframes card-rise { from { opacity: 0; transform: translateY(10px) scale(.97); } }
/* a card built while its page arrives (market.js / swap.js): it comes with the page, so no rise (app.js settleArrival
   would finish it on its first frame anyway — and finishing dozens of them took a frame of its own) */
.icard.ic-now { animation: none; }
/* reduced motion: cards that land later just appear too (the desk's stock, your items — the market and the inventory
   already cut theirs to 1 ms: market.css, profile.css) */
@media (prefers-reduced-motion: reduce) { .icard { animation: none; } }
.icard.clickable { cursor: pointer; }
/* hover-capable screens only: a tap leaves :hover stuck on the tapped card, which would lift it 4px and tilt its art
   the moment it is picked on a phone (and its hover shadow would cover the selected ring) */
@media (hover: hover) {
  .icard.clickable:hover { transform: translateY(-4px); box-shadow: inset 0 -2px 0 rgb(var(--rc)), 0 18px 36px rgba(0, 0, 0, .45), 0 0 26px rgba(var(--rc), .14); z-index: 2; }
  /* a selected card under the pointer keeps its ring (the hover shadow alone would hide it right after the click) */
  .icard.selected.clickable:hover:not(:focus-visible) { box-shadow: inset 0 0 0 2px var(--accent), inset 0 -2px 0 rgb(var(--rc)), 0 18px 36px rgba(0, 0, 0, .45), 0 0 24px rgba(139, 92, 246, .35); }
}
.icard.clickable:active { transform: translateY(-1px) scale(.98); }
/* min-height 0: the box doesn't grow when the art loads. The single minmax(0, 1fr) track is definite (the box's
   height comes from aspect-ratio), so the image's 100% height resolves to the content box: square art is
   contained in it instead of rendering width-tall and spilling over the tier label below. */
.ic-art { position: relative; aspect-ratio: 1 / .86; min-height: 0; display: grid; grid-template: minmax(0, 1fr) / minmax(0, 1fr); place-items: center; padding: 14px 14px 4px; }
/* the glow behind the art carries a faint light core, so dark art (a black scooter) still reads on the dark tile */
.ic-art::before { content: ''; position: absolute; inset: 18% 18% 10%; border-radius: 50%; background: radial-gradient(circle, rgba(var(--rc), .22), rgba(255, 255, 255, .05) 45%, transparent 70%); filter: blur(8px); z-index: -1; }
.ic-art img { width: 100%; height: 100%; min-width: 0; min-height: 0; object-fit: contain; transition: opacity 160ms var(--ease-out), transform 300ms var(--ease-out-quart); filter: drop-shadow(0 6px 12px rgba(0, 0, 0, .45)); }
@media (hover: hover) { .icard.clickable:hover .ic-art img { transform: scale(1.07) rotate(-2deg); } }
/* the labels paint above the art's drop shadow */
.ic-strip { position: relative; z-index: 1; display: flex; flex-direction: column; gap: 1px; padding: 6px 10px 10px; min-width: 0; }
/* a card label left empty because the name already says it (PS99 tiers): no line for it, the name may use two */
.ic-type:empty { display: none; }
.ic-type:empty + .ic-name { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; white-space: normal; overflow-wrap: break-word; }
.ic-type { font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: rgb(var(--rc)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ic-name { font-size: 12px; font-weight: 700; line-height: 1.3; text-transform: uppercase; color: rgba(255, 255, 255, .92); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* centred, not baseline: a value chip that starts with its coin (.vicon, an empty box) would put its baseline at
   the coin's bottom edge and ride ~2px above the price */
.ic-meta { display: flex; align-items: center; justify-content: space-between; gap: 6px; margin-top: 3px; min-height: 18px; }
.ic-price { font-size: 13.5px; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums; }
.ic-value { font-size: 11px; font-weight: 500; color: rgba(255, 255, 255, .45); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ic-foot { padding: 0 10px 10px; display: flex; gap: 6px; align-items: center; }
.ic-qty { position: absolute; top: 7px; left: 7px; z-index: 3; font-size: 10.5px; font-weight: 700; padding: 2px 7px; border-radius: 999px; background: rgba(0, 0, 0, .55); color: rgba(255, 255, 255, .9); }
.ic-badges { position: absolute; top: 7px; right: 7px; z-index: 3; display: flex; gap: 3px; flex-wrap: wrap; justify-content: flex-end; max-width: 75%; }
.ic-sel { position: absolute; top: 7px; left: 7px; z-index: 4; width: 20px; height: 20px; border-radius: 6px; display: grid; place-items: center; color: #fff; background: var(--accent); opacity: 0; transform: scale(.5); transition: all 200ms var(--ease-out-quart); }
.ic-sel svg { width: 12px; height: 12px; }
/* selected-state ring (allowed exception) */
.icard.selected { box-shadow: inset 0 0 0 2px var(--accent), inset 0 -2px 0 rgb(var(--rc)), 0 0 24px rgba(139, 92, 246, .35); }
.icard.selected .ic-sel { opacity: 1; transform: none; }
/* keyboard focus ring (the card's own box-shadow would otherwise hide the global :focus-visible ring) */
.icard.clickable:focus-visible { box-shadow: var(--ring-focus), inset 0 -2px 0 rgb(var(--rc)); }
.icard.selected:focus-visible { box-shadow: var(--ring-focus), inset 0 0 0 2px var(--accent), inset 0 -2px 0 rgb(var(--rc)); }
.icard.selected .ic-qty { left: 32px; }
.ic-selcount { position: absolute; bottom: 8px; right: 8px; z-index: 4; font-size: 11px; font-weight: 800; padding: 2px 7px; border-radius: 999px; background: var(--accent); color: #fff; }
.ic-disabled { position: absolute; inset: 0; z-index: 5; display: grid; place-items: center; background: rgba(6, 8, 13, .62); backdrop-filter: grayscale(1); -webkit-backdrop-filter: grayscale(1); }
.ic-disabled span { font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; padding: 4px 9px; border-radius: 999px; background: rgba(0, 0, 0, .6); color: rgba(255, 255, 255, .75); }
.icard.is-disabled { cursor: not-allowed; }
.icard-sm .ic-art { padding: 10px 10px 2px; }
.icard-sm .ic-strip { padding: 4px 8px 8px; }
.icard-sm .ic-name { font-size: 11px; }
.icard-sm .ic-price { font-size: 12px; }
/* the smallest phones (2 columns of ~120px names): a long name may take a second line instead of losing the part
   that tells items apart ("GREEN PUMPKIN (2021)"); the price line keeps the row's common bottom edge */
@media (max-width: 340px) {
  .icard-grid .icard > .ic-strip { flex: 1 1 auto; }
  .icard-grid .ic-name { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; white-space: normal; overflow-wrap: break-word; }
  .icard-grid .ic-meta { margin-top: auto; padding-top: 3px; }
}

/* variant badges */
.vb { display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 6px; border-radius: 999px; font-size: 9.5px; font-weight: 800; letter-spacing: .02em; color: #fff; background: rgba(0, 0, 0, .55); text-transform: uppercase; }
.vb-golden { background: linear-gradient(135deg, #f7d774, #d39e1a); color: #3b2800; }
/* variant badges and art effects are STATIC: dozens sit on every grid, and idle loops are for status
   only (live dot, spinners, confirmation bars). Only hover/focus on a card may animate the art. */
.vb-rainbow { background: linear-gradient(90deg, #ff5f6d, #ffc371, #7cff6b, #4fd1ff, #b36bff); color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, .5); }
.vb-shiny { background: linear-gradient(135deg, #e0f2ff, #9ad7ff); color: #0b3a5b; position: relative; overflow: hidden; }
.vb-shiny::after { content: ''; position: absolute; inset: 0; background: linear-gradient(115deg, transparent 38%, rgba(255, 255, 255, .6) 50%, transparent 62%); pointer-events: none; }
.vb-neon { background: #16a34a; box-shadow: 0 0 10px rgba(74, 222, 128, .7); }
.vb-mega { background: linear-gradient(135deg, #a855f7, #ec4899); box-shadow: 0 0 10px rgba(217, 70, 239, .7); }
.vb-fly { background: #0ea5e9; }
.vb-ride { background: #ec4899; }
.vb-chroma { background: linear-gradient(90deg, #22d3ee, #a78bfa, #f472b6); }

/* variant art effects (only when no dedicated art exists): a static tinted glow; the colour cycle
   plays ONCE when the card is hovered / focused (an interaction, not an idle loop) */
.fx-rainbow img { filter: drop-shadow(0 6px 12px rgba(0, 0, 0, .45)) drop-shadow(0 0 5px rgba(255, 95, 109, .55)) drop-shadow(0 0 11px rgba(79, 209, 255, .45)) saturate(1.2); }
.fx-chroma img { filter: drop-shadow(0 6px 12px rgba(0, 0, 0, .45)) drop-shadow(0 0 5px rgba(34, 211, 238, .6)) drop-shadow(0 0 11px rgba(244, 114, 182, .45)); }
.icard.clickable:hover .fx-rainbow img, .icard.clickable:focus-visible .fx-rainbow img { animation: fx-hue 1.4s linear 1; }
.icard.clickable:hover .fx-chroma img, .icard.clickable:focus-visible .fx-chroma img { animation: fx-hue 1.6s linear 1; }
@keyframes fx-hue { from { filter: drop-shadow(0 6px 12px rgba(0, 0, 0, .45)) hue-rotate(0deg); } to { filter: drop-shadow(0 6px 12px rgba(0, 0, 0, .45)) hue-rotate(360deg); } }
.fx-shiny::after { content: ''; position: absolute; inset: 10%; pointer-events: none; background:
  radial-gradient(circle at 20% 30%, #fff 0 1.5px, transparent 2.5px), radial-gradient(circle at 75% 20%, #fff 0 1.2px, transparent 2.2px),
  radial-gradient(circle at 80% 70%, #fff 0 1.5px, transparent 2.5px), radial-gradient(circle at 30% 80%, #fff 0 1px, transparent 2px);
  opacity: .85; }
.fx-neon img { filter: drop-shadow(0 0 6px rgba(74, 222, 128, .9)) drop-shadow(0 0 14px rgba(74, 222, 128, .45)); }
.fx-mega img { filter: drop-shadow(0 0 7px rgba(236, 72, 153, .85)) drop-shadow(0 0 14px rgba(168, 85, 247, .5)); }

/* ---------------------------------------------------------------- mascots + empty states */
/* The mascot never loops (float/bob/bounce/breathe/sway/spin are banned); app.css
   forces a single fade-in on every mascot <img>. */
.mascot { display: block; height: auto; user-select: none; -webkit-user-drag: none; pointer-events: none; }
.empty-state { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 36px 18px; gap: 8px; }
.empty-state.compact { padding: 12px 8px 4px; }
.empty-state .es-mascot { width: 128px; margin-bottom: 4px; filter: drop-shadow(0 10px 24px rgba(139, 92, 246, .25)); }
/* icon tile (cards.js iconTile): empty states and success marks where the mascot was taken out */
.ic-tile { width: 56px; height: 56px; flex: none; display: grid; place-items: center; border-radius: 18px; background: rgba(139, 92, 246, .15); color: #b9a5ff; }
.ic-tile svg { width: 26px; height: 26px; }
.ic-tile.is-warn { background: rgba(248, 183, 77, .14); color: #f8c46d; }
.ic-tile.is-ok { background: rgba(5, 202, 98, .15); color: #3ee48b; }
.empty-state .es-icon { margin-bottom: 6px; }
.empty-state h3 { font-size: 17px; }
.empty-state p { margin: 0 0 8px; max-width: 360px; font-size: 13.5px; color: var(--muted); line-height: 1.55; }

/* ---------------------------------------------------------------- modals */
.overlay { position: fixed; inset: 0; z-index: 100; display: grid; place-items: center; padding: 16px; background: rgba(3, 4, 8, .62); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.overlay.closing { animation: fade-out 180ms var(--ease-out) both; }
.overlay.closing .modal { animation: modal-out 180ms var(--ease-out) both; }
@keyframes modal-out { to { opacity: 0; transform: translateY(10px) scale(.97); } }
.modal { width: min(440px, 100%); max-height: calc(100dvh - 32px); overflow-y: auto; overscroll-behavior: contain; padding: 22px; border-radius: 24px; background: var(--surface-1); box-shadow: 0 30px 80px rgba(0, 0, 0, .6); }
.modal-wide { width: min(760px, 100%); }
.modal-head { align-items: center; }
.modal-title { display: flex; align-items: center; gap: 10px; font-size: 19px; font-weight: 800; }
.modal-close { width: 40px; height: 40px; border-radius: 11px; display: grid; place-items: center; background: rgba(255, 255, 255, .06); color: rgba(255, 255, 255, .7); flex: none; }
.modal-close:hover { background: rgba(255, 255, 255, .1); color: #fff; transform: rotate(90deg); }
.confirm-body { font-size: 14px; color: rgba(255, 255, 255, .8); line-height: 1.6; }
.confirm-body p { margin: 0 0 10px; }
.confirm-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 16px; }
@media (max-width: 640px) {
  .overlay { place-items: end center; padding: 0; }
  .modal, .modal-wide { width: 100%; max-height: 92dvh; border-radius: 22px 22px 0 0; padding: 20px 16px calc(18px + env(safe-area-inset-bottom)); animation: sheet-up 340ms var(--ease-out-quart) both; }
  .modal::before { content: ''; display: block; width: 40px; height: 4px; border-radius: 4px; background: rgba(255, 255, 255, .15); margin: -8px auto 12px; }
  .overlay.closing .modal { animation: sheet-down 200ms var(--ease-out) both; }
}
@keyframes sheet-up { from { transform: translateY(100%); } }
@keyframes sheet-down { to { transform: translateY(100%); } }

/* ---------------------------------------------------------------- custom select (ui/select.js)
   Every native <select> (unless [data-native]) is kept in the DOM, visually hidden,
   and paired with a .csel-trigger button + a .csel-pop listbox portalled to <body>. */
.csel-native { position: absolute !important; width: 1px !important; height: 1px !important; margin: 0 !important; padding: 0 !important; border: 0 !important;
  opacity: 0 !important; pointer-events: none !important; overflow: hidden !important; clip-path: inset(50%) !important; white-space: nowrap !important; }
.csel-trigger { position: relative; display: inline-flex; align-items: center; gap: 8px; height: 40px; min-width: 0; max-width: 100%; padding: 0 12px 0 14px;
  border: none; border-radius: 12px; background: var(--surface-2); color: var(--foreground); font: inherit; font-size: 14px; font-weight: 500; line-height: 1.2;
  text-align: left; cursor: pointer; user-select: none; -webkit-tap-highlight-color: transparent;
  transition: background-color 150ms var(--ease-smooth), box-shadow 150ms var(--ease-out), transform 200ms var(--ease-out-quart); }
.csel-trigger:hover { background: var(--surface-3); }
.csel-trigger:active { transform: scale(.985); }
.csel-trigger[aria-expanded="true"] { background: var(--surface-3); }
.csel-trigger:disabled { opacity: .5; cursor: not-allowed; transform: none; }
.csel-value { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.csel-value.is-placeholder { color: var(--muted); }
.csel-chev { flex: none; color: rgba(255, 255, 255, .5); transition: transform 220ms var(--ease-out-quart), color 150ms var(--ease-smooth); }
.csel-trigger:hover .csel-chev { color: rgba(255, 255, 255, .8); }
.csel-trigger[aria-expanded="true"] .csel-chev { transform: rotate(180deg); color: var(--accent-hover); }
.csel-block { display: flex; width: 100%; }
.csel-sm { height: 34px; padding: 0 10px 0 12px; border-radius: 10px; font-size: 13px; }
/* bare: the page's container provides the chrome (e.g. a pill with an icon) */
.csel-bare { align-self: stretch; height: auto; min-height: 36px; padding: 0 2px; border-radius: 8px; background: none; }
.csel-bare:hover, .csel-bare[aria-expanded="true"] { background: none; }
.csel-bare:active { transform: none; }
.csel-bare:focus-visible { box-shadow: none; }
.csel-bare:focus-visible .csel-value { text-decoration: underline; text-decoration-color: var(--accent); text-underline-offset: 4px; }
.csel-bare:focus-visible .csel-chev { color: var(--accent-hover); }

.csel-pop { position: fixed; z-index: 300; box-sizing: border-box; width: max-content; padding: 6px; border-radius: 14px;
  background: var(--surface-pop); box-shadow: var(--shadow-pop); overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain;
  opacity: 0; transform: translateY(-6px) scale(.98); transform-origin: top center;
  transition: opacity 140ms var(--ease-out), transform 200ms var(--ease-out-quart); }
.csel-pop.is-up { transform-origin: bottom center; transform: translateY(6px) scale(.98); }
.csel-pop.is-in { opacity: 1; transform: none; }
.csel-pop.is-out { pointer-events: none; }
.csel-opt { display: flex; align-items: center; gap: 10px; min-height: 40px; padding: 8px 10px 8px 12px; border-radius: 10px;
  font-size: 14px; font-weight: 500; line-height: 1.3; color: rgba(255, 255, 255, .78); cursor: pointer; user-select: none; -webkit-tap-highlight-color: transparent; }
.csel-opt-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.csel-check { flex: none; margin-left: auto; color: var(--accent-hover); opacity: 0; transform: scale(.6); transition: opacity 150ms var(--ease-out), transform 200ms var(--ease-out-quart); }
/* highlight: arrow keys move .is-active; with a mouse/pen the row under the cursor is lit by :hover (no transition, no
   waiting for a pointermove, so it never trails the cursor — also while the list scrolls under a still cursor) */
.csel-opt.is-active, .csel-pop.by-pointer .csel-opt:hover:not([aria-disabled="true"]) { background: rgba(255, 255, 255, .06); color: #fff; }
.csel-pop.by-pointer .csel-opt.is-active:not(:hover) { background: none; color: rgba(255, 255, 255, .78); }
.csel-opt[aria-selected="true"] { color: #fff; font-weight: 600; background: rgba(139, 92, 246, .14); }
.csel-opt[aria-selected="true"].is-active, .csel-pop.by-pointer .csel-opt[aria-selected="true"]:hover { background: rgba(139, 92, 246, .22); }
.csel-pop.by-pointer .csel-opt[aria-selected="true"].is-active:not(:hover) { background: rgba(139, 92, 246, .14); color: #fff; }
.csel-opt[aria-selected="true"] .csel-check { opacity: 1; transform: none; }
.csel-opt[aria-disabled="true"] { opacity: .4; cursor: not-allowed; background: none; }
.csel-group { padding: 10px 12px 4px; font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: rgba(255, 255, 255, .4); }
.csel-group-opt { padding-left: 20px; }
.csel-empty { padding: 10px 12px; font-size: 13px; color: var(--muted); }
/* option extras (data-dot / data-dot-class / data-count) */
.csel-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; background: rgb(var(--dot, 139, 92, 246)); box-shadow: 0 0 8px rgba(var(--dot, 139, 92, 246), .45); }
.csel-count { flex: none; margin-left: auto; font-style: normal; font-size: 11.5px; font-weight: 600; color: rgba(255, 255, 255, .4); font-variant-numeric: tabular-nums; }
.csel-count + .csel-check { margin-left: 0; }
.csel-icon { flex: none; width: 20px; height: 20px; border-radius: 50%; }

/* ---------------------------------------------------------------- login */
.login-body.step-in { animation: slide-fade-in 280ms var(--ease-out) both; }
.login-sub { margin: 0 0 4px; font-size: 13.5px; color: var(--muted); }
.login-sub b { color: #fff; }
.login-reason { margin: 0 0 10px; padding: 9px 12px; border-radius: 10px; font-size: 13px; background: rgba(139, 92, 246, .12); color: #d9ccff; }
.login-fine { margin: 14px 0 0; text-align: center; font-size: 11.5px; font-weight: 600; color: var(--muted); }
.login-body .input-wrap svg { position: absolute; left: 12px; width: 15px; height: 15px; color: rgba(255, 255, 255, .45); }
.login-body .input { padding-left: 34px; }
.login-body .input:focus { box-shadow: inset 0 0 0 1.5px var(--accent); }
.login-body #lg-go { margin-top: 18px; }
.lg-open { margin-bottom: 10px; }
.login-confirm { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 6px 0 2px; }
.lc-avatar { width: 88px; height: 88px; border-radius: 22px; overflow: hidden; display: grid; place-items: center; background: #1a1f2b; box-shadow: 0 0 34px rgba(139, 92, 246, .45); margin-bottom: 14px; animation: pop-spring 420ms var(--ease-out-quart) both; }
.lc-avatar img { width: 100%; height: 100%; object-fit: cover; }
.lc-avatar span { font-size: 32px; font-weight: 800; }
.login-confirm h3 { font-size: 20px; }
.lc-handle { margin: 2px 0 16px; font-size: 13.5px; color: var(--muted); }
.lc-q { margin: 0 0 16px; font-weight: 700; }
.lc-actions { display: flex; gap: 10px; }
.login-success { display: flex; flex-direction: column; align-items: center; text-align: center; }
.ls-avatar { position: relative; width: 88px; height: 88px; margin: 2px 0 16px; border-radius: 22px; display: grid; place-items: center; background: #1a1f2b; box-shadow: 0 0 34px rgba(139, 92, 246, .45); animation: pop-spring 420ms var(--ease-out-quart) both; }
.ls-avatar img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; }
.ls-avatar > span { font-size: 32px; font-weight: 800; }
.ls-ok { position: absolute; right: -7px; bottom: -7px; width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; color: #fff; background: #22c55e; box-shadow: 0 0 0 4px var(--surface-1), 0 0 14px rgba(34, 197, 94, .6); }
.login-success h3 { font-size: 20px; }
.login-success p { margin: 6px 0 16px; color: var(--muted); font-size: 14px; }

/* ---------------------------------------------------------------- Add funds (ui/deposit.js)
   Every user has a permanent address per coin. Two steps, in the deposit sheet's Crypto tab (the header "+"; a bottom
   sheet on phones) and on /wallet/ (Add funds tab, embedded, beside "Recent deposits"):
     1. Deposit amount: big custom $ field, quick amounts, "Pay with" dropdown, USDT / USDC network
     2. Complete Payment: headline, centered QR, live status card, label/value rows with copy
        buttons, "How deposits are credited" disclosure, Close
   Borderless: tone + shadow; hairline dividers only between list rows. */
.deposit-modal { width: min(460px, 100%); }
.deposit-modal .modal-close { width: 40px; height: 40px; }
.dp-flow { display: flex; flex-direction: column; min-width: 0; }
.dp-head { align-items: center; gap: 10px; }
.dp-head .modal-title { flex: 1; min-width: 0; }
.dp-back { flex: none; display: grid; place-items: center; width: 40px; height: 40px; margin-left: -6px; border-radius: 12px; color: rgba(255, 255, 255, .7);
  transition: background-color 150ms var(--ease-smooth), color 150ms var(--ease-smooth), transform 150ms var(--ease-out-quad); }
.dp-back:hover { color: #fff; background: rgba(255, 255, 255, .07); }
.dp-back:active { transform: scale(.92); }
.dp-step { display: flex; flex-direction: column; gap: 12px; min-width: 0; animation: slide-fade-in 260ms var(--ease-out) both; }

/* step 1: amount, quick amounts, coin + network. The two labels share one top line and "You send" sits on the
   amount's line (its line box is the big number's), so neither half floats lower than the other. */
.dp-big { display: flex; align-items: flex-start; gap: 10px; min-width: 0; padding: 12px 16px; border-radius: 16px;
  background: linear-gradient(90deg, var(--surface-2) 0%, rgba(139, 92, 246, .16) 100%); --dp-big-lh: 34.5px; }
.dp-big small { display: block; margin-bottom: 2px; font-size: 11.5px; line-height: 16px; font-weight: 600; color: var(--muted); }
.dp-big-in { flex: 1 1 0; min-width: 0; cursor: text; }
.dp-big-v { display: flex; align-items: baseline; gap: 2px; font: 800 30px/1.15 var(--font); color: #fff; }
.dp-cur { flex: none; }
.dp-amt-box { position: relative; flex: 1 1 auto; display: flex; min-width: 0; overflow: hidden; }
/* the input's own text is transparent (its caret, selection and keyboard are real); .dp-amt-mirror draws the same
   characters on top so each one can animate in: typed characters pop in, a quick amount rolls in digit by digit */
.dp-big-v input { width: 100%; min-width: 0; padding: 0; border: 0; outline: 0; background: none; color: transparent; caret-color: #fff; font: inherit; font-variant-numeric: tabular-nums; font-kerning: none; }
/* the field is a 40px tap target (rule 11) in the 34.5px line: the negative margin keeps the line where it was */
.dp-big-v input { height: 40px; margin: calc((var(--dp-big-lh) - 40px) / 2) 0; }
.dp-big-v input:focus-visible { box-shadow: none; }
.dp-big-v input::placeholder { color: rgba(255, 255, 255, .3); }
.dp-big-v input::selection { color: transparent; background: rgba(139, 92, 246, .35); }
.dp-amt-mirror { position: absolute; left: 0; top: 0; bottom: 0; display: flex; align-items: center; white-space: pre; pointer-events: none; color: #fff; font-variant-numeric: tabular-nums; font-kerning: none; }
.dp-amt-mirror span { display: inline-block; }
.dp-amt-mirror .in { animation: dp-digit-in 260ms var(--ease-out-quart) both; animation-delay: calc(var(--i, 0) * 32ms); }
@keyframes dp-digit-in { from { opacity: 0; transform: translateY(.32em) scale(.82); } }
.dp-big-out b.dp-out-in { animation: dp-out-in 220ms var(--ease-out) both; }
@keyframes dp-out-in { from { opacity: .3; transform: translateY(3px); } }
@media (prefers-reduced-motion: reduce) { .dp-amt-mirror .in, .dp-big-out b.dp-out-in { animation: none; } }
.dp-chevs { flex: none; align-self: flex-end; margin-bottom: calc((var(--dp-big-lh) - 32px) / 2); color: var(--accent-hover); }
.dp-big-out { flex: 1 1 0; min-width: 0; text-align: left; }
.dp-big-out b { display: block; font-size: 15px; line-height: var(--dp-big-lh); font-weight: 700; color: #c4b5fd; font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dp-big-out b.is-empty { color: rgba(255, 255, 255, .3); } /* like the field's "0" placeholder */
.dp-presets { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.dp-preset { height: 44px; border-radius: 12px; background: var(--surface-2); font-size: 14px; font-weight: 700; color: rgba(255, 255, 255, .8); font-variant-numeric: tabular-nums;
  transition: background-color 150ms var(--ease-smooth), color 150ms var(--ease-smooth), transform 150ms var(--ease-out-quad), box-shadow 200ms; }
.dp-preset:hover { background: var(--surface-3); color: #fff; }
.dp-preset:active { transform: scale(.96); }
.dp-preset.on { color: #fff; background: rgba(139, 92, 246, .24); box-shadow: 0 6px 18px rgba(139, 92, 246, .18); }
.dp-field-l { margin: 4px 2px -4px; font-size: 13px; font-weight: 600; color: rgba(255, 255, 255, .8); }
.dp-amount .csel-trigger { height: 48px; padding: 0 14px 0 12px; border-radius: 14px; background: var(--surface-2); font-size: 14px; font-weight: 600; }
.dp-amount .csel-trigger:hover, .dp-amount .csel-trigger[aria-expanded="true"] { background: var(--surface-3); }
/* network choice (USDT: TRON · BNB Chain · Ethereum) — also used by the Withdraw tab */
.dp-nets-wrap { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.dp-nets-wrap[hidden], .wd-nets[hidden] { display: none; }
.dp-nets { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 8px; }
.dp-net-opt { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 1px; min-width: 0; min-height: 50px; padding: 7px 12px; border-radius: 12px; text-align: left; background: var(--surface-2); color: rgba(255, 255, 255, .78);
  transition: background-color 150ms var(--ease-smooth), color 150ms var(--ease-smooth), transform 150ms var(--ease-out-quad), box-shadow 200ms; }
.dp-net-opt:hover { background: var(--surface-3); color: #fff; }
.dp-net-opt:active { transform: scale(.97); }
.dp-net-opt.on { color: #fff; background: rgba(139, 92, 246, .24); box-shadow: 0 6px 18px rgba(139, 92, 246, .18); }
.dp-net-opt b { font-size: 13.5px; font-weight: 700; white-space: nowrap; }
.dp-net-opt em { font-style: normal; font-size: 11.5px; font-weight: 600; color: var(--muted); }
.dp-net-opt.on em { color: #c4b5fd; }
.dp-net-opt small { font-size: 11px; color: var(--muted); }
.dp-amt-err { margin: -2px 2px 0; font-size: 12.5px; line-height: 1.5; color: #ff9092; }
.dp-amt-err.is-info { color: #f8c46d; }
.dp-continue { gap: 8px; margin-top: 2px; }
.dp-continue:disabled { opacity: .5; cursor: not-allowed; }
.dp-amount .dp-fine { text-align: center; }
/* an account on hold: the reason sits right above the disabled Continue / Request withdrawal */
.dp-hold { display: flex; gap: 8px; margin: 0; padding: 10px 12px; border-radius: 12px; font-size: 12.5px; line-height: 1.5; color: #ffc2c3; background: rgba(219, 59, 62, .1); text-wrap: pretty; }
.dp-hold svg { flex: none; margin-top: 2px; color: #ff8587; }
.dp-hold a { font-weight: 700; color: #fff; text-decoration: underline; text-underline-offset: 2px; white-space: nowrap; }
.wadd-card .dp-hold { margin-bottom: 12px; }
/* on /wallet/ the notice under the balance card says it (with Contact support): here only a quiet line, not a 2nd red box */
.dp-hold.is-quiet { display: block; padding: 0 2px; border-radius: 0; text-align: center; text-wrap: balance; color: var(--muted); background: none; }

/* step 2: complete payment (balanced lines: no lone "below" / "Policy." on a line of its own) */
.dp-send { margin: 0; text-align: center; font-size: 14px; line-height: 1.5; color: rgba(255, 255, 255, .72); text-wrap: balance; }
.dp-send b { color: #fff; font-weight: 700; font-variant-numeric: tabular-nums; }
.dp-send .muted { font-weight: 500; white-space: nowrap; } /* "(≈ $50.00)" stays in one piece */
.dp-qr { align-self: center; flex: none; width: 188px; height: 188px; padding: 12px; border-radius: 18px; background: #fff; box-shadow: 0 10px 30px rgba(0, 0, 0, .35); }
.dp-qr svg { display: block; width: 100%; height: 100%; }
/* live status: waiting / seen on the blockchain (x / y confirmations) / received / held */
.dp-status { display: flex; align-items: flex-start; gap: 12px; padding: 14px; border-radius: 14px; background: var(--surface-2); animation: slide-fade-in 240ms var(--ease-out) both; }
.dp-spin { flex: none; width: 26px; height: 26px; margin-top: 1px; border-radius: 50%; border: 3px solid rgba(139, 92, 246, .22); border-top-color: var(--accent-hover); animation: spin 900ms linear infinite; } /* status indicator: idle loop allowed */
.dp-st-badge { flex: none; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; }
.dp-st-badge.ok { color: #3ee48b; background: rgba(5, 202, 98, .16); }
.dp-st-badge.bad { color: #ff8587; background: rgba(219, 59, 62, .15); }
.dp-st-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.dp-st-title { font-size: 14px; font-weight: 700; color: var(--accent-hover); }
.dp-status.st-wait .dp-st-title { color: #fff; }
.dp-status.st-credited .dp-st-title { color: #3ee48b; }
.dp-status.st-below_min .dp-st-title, .dp-status.st-failed .dp-st-title { color: #ff8587; }
.dp-status.st-review .dp-st-title, .dp-status.st-dropped .dp-st-title, .dp-status.st-ignored .dp-st-title { color: #f8c46d; }
.dp-st-line { font-size: 13px; line-height: 1.45; color: rgba(255, 255, 255, .75); }
.dp-st-line b { color: #fff; font-variant-numeric: tabular-nums; }
.dp-st-line b.pos { color: #3ee48b; }
/* meta parts are spaced by the gap (no "·" text that would dangle at a line end when the line wraps) */
.dp-st-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 12px; font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }
.dp-st-meta a, .dp-st-more a { display: inline-flex; align-items: center; gap: 3px; font-weight: 600; color: var(--accent-hover); white-space: nowrap; }
.dp-st-meta .link-btn { display: inline-flex; align-items: center; gap: 5px; min-height: 40px; margin: -5px 0; font-size: 12.5px; } /* 40px tap target in the 30px line */
.dp-st-meta .link-btn:disabled { color: var(--muted); text-decoration: none; cursor: default; }
.dp-st-more { display: flex; flex-wrap: wrap; gap: 2px 12px; font-size: 12px; color: var(--muted); }
.dp-status .dp-bar { margin: 5px 0 3px; }
.dp-status.st-seen .dp-bar i { animation: bar-pulse 1.6s var(--ease-in-out) infinite; } /* status indicator: idle loop allowed */
/* label / value rows */
.dp-rows { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.dp-row { display: flex; align-items: center; gap: 10px; min-width: 0; min-height: 46px; padding: 6px 6px 6px 14px; border-radius: 12px; background: var(--surface-2); }
.dp-pay .dp-row-pid[hidden] { display: none; }
.dp-k { flex: none; width: 104px; font-size: 13px; font-weight: 500; color: var(--muted); }
/* values start on one left edge after the labels (rows with and without a copy button line up) */
.dp-v { flex: 1 1 auto; min-width: 0; font-size: 13px; font-weight: 600; color: #fff; text-align: left; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.dp-v:last-child { padding-right: 8px; }
.dp-v .muted { font-weight: 500; }
.dp-stv.tone-warn { color: #f8c46d; }
.dp-stv.tone-ok { color: #3ee48b; }
.dp-stv.tone-bad { color: #ff8587; }
.dp-stv.tone-mute { color: var(--muted); }
/* a long address breaks anywhere, in even lines (no 4-character tail on a line of its own) */
.dp-addr-text { font: 600 12.5px/1.45 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; word-break: break-all; text-wrap: balance; user-select: all; }
.dp-icon-btn { flex: none; display: grid; place-items: center; width: 36px; height: 36px; border-radius: 10px; color: rgba(255, 255, 255, .72); background: var(--surface-3);
  transition: background-color 150ms var(--ease-smooth), color 150ms var(--ease-smooth), transform 150ms var(--ease-out-quad); }
.dp-icon-btn:hover { color: #fff; background: rgba(139, 92, 246, .32); }
.dp-icon-btn:active { transform: scale(.92); }
.dp-icon-btn.done { color: #3ee48b; background: rgba(5, 202, 98, .18); }
/* the coin icon stays in front of the network name; a long name wraps beside it (never the icon alone on a line) */
.dp-net { display: flex; align-items: flex-start; gap: 6px; color: #ffd48a; }
.dp-net img { flex: none; margin-top: 1.5px; }
.dp-net-t { min-width: 0; text-wrap: balance; }
.dp-contract { display: block; font: 500 11px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: rgba(255, 212, 138, .7); }
.dp-warn { display: flex; gap: 8px; margin: 0; padding: 10px 12px; border-radius: 12px; font-size: 12.5px; line-height: 1.5; color: #f6d59a; background: rgba(248, 183, 77, .08); }
.dp-warn svg { flex: none; margin-top: 1px; color: #f8b74d; }
.dp-more { border-radius: 12px; background: var(--surface-2); }
.dp-more summary { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 44px; padding: 0 14px; list-style: none; cursor: pointer; font-size: 13px; font-weight: 600; color: rgba(255, 255, 255, .8); border-radius: 12px; transition: color 150ms; }
.dp-more summary::-webkit-details-marker { display: none; }
.dp-more summary::after { content: ''; flex: none; width: 7px; height: 7px; margin-top: -3px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg); opacity: .6; transition: transform 200ms var(--ease-out-quart); }
.dp-more[open] summary::after { transform: rotate(-135deg); margin-top: 3px; }
.dp-more summary:hover { color: #fff; }
.dp-more p { margin: 0; padding: 0 14px 12px; font-size: 12.5px; line-height: 1.55; color: rgba(255, 255, 255, .7); }
.dp-more p b { color: #fff; }
.dp-done { margin-top: 2px; height: 46px; }
/* the desktop modal: "Complete Payment" fits a 1440x900 laptop without an inner scroll (tighter steps, and a
   slightly smaller QR / rows when the window is under ~960px tall) */
@media (min-width: 641px) {
  .deposit-modal .dp-step { gap: 10px; }
  .deposit-modal .dp-done { margin-top: 0; height: 44px; }
}
@media (min-width: 641px) and (max-height: 960px) {
  .deposit-modal .dp-qr { width: 164px; height: 164px; padding: 10px; border-radius: 16px; }
  .deposit-modal .dp-row { min-height: 44px; padding-top: 4px; padding-bottom: 4px; }
}

/* /wallet/ Add funds: the two steps in a card | recent deposits. Step 1 has no title here (the selected "Add funds" tab
   right above names it); step 2's "‹ Complete Payment" and "Recent deposits" share one head style (40px row, 16px
   title, same padding), so they line up side by side. */
.dp-page-grid { display: grid; grid-template-columns: minmax(0, 480px) minmax(0, 1fr); align-items: start; gap: 18px; }
.dp-embed { padding: 18px; border-radius: 20px; background: var(--surface-1); box-shadow: var(--shadow-card); }
/* no config snapshot yet (a first visit): the card keeps step 1's height (406-440px under the tabs) until the config
   answers (rule 17) */
.dp-embed .dp-flow:empty { min-height: 387px; }
.dp-card .dps-tabs { margin-bottom: 12px; }
.dp-embed .modal-head { min-height: 40px; margin-bottom: 12px; }
.dp-embed .modal-title, .dp-recent-head h3 { font-size: 16px; font-weight: 800; line-height: 1.3; }
.dp-recent { display: flex; flex-direction: column; gap: 12px; min-width: 0; padding: 18px; border-radius: 20px; background: var(--surface-1); box-shadow: var(--shadow-card); }
.dp-recent-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 40px; }
.dp-recent-head h3 { margin: 0; }
.dp-recent-head .link-btn { min-height: 40px; font-size: 13px; }

/* transfer rows (Add funds recent list, Transactions, staff) */
.dp-list { display: flex; flex-direction: column; min-width: 0; border-radius: 14px; background: var(--surface-2); overflow: hidden; }
.dp-tx { display: flex; align-items: flex-start; gap: 12px; width: 100%; min-width: 0; padding: 12px 14px; text-align: left; color: inherit; }
.dp-tx.is-new { animation: slide-fade-in 240ms var(--ease-out) both; }
.dp-tx + .dp-tx { border-top: 1px solid var(--hairline); }
.dp-tx-coin { flex: none; margin-top: 1px; }
.dp-tx-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.dp-tx-top { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 8px; }
.dp-tx-top b { font-size: 14px; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.dp-tx-net { display: inline-flex; align-items: center; height: 20px; padding: 0 7px; border-radius: 6px; font-size: 10.5px; font-weight: 700; letter-spacing: .02em; color: #c4b5fd; background: rgba(139, 92, 246, .14); }
.dp-tx-line { font-size: 12.5px; line-height: 1.45; color: rgba(255, 255, 255, .72); text-wrap: pretty; } /* no lone last word ("… to have it / reviewed.") */
/* date · address · link: spaced by the gap (no "·" left dangling at a line end); the short address never splits */
.dp-tx-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 12px; font-size: 11.5px; color: var(--muted); overflow-wrap: anywhere; }
.dp-tx-meta .mono { white-space: nowrap; overflow-wrap: normal; }
.dp-tx-meta a { display: inline-flex; align-items: center; gap: 3px; font-weight: 600; color: var(--accent-hover); white-space: nowrap; }
/* a steady amount column: the confirmation bars of neighbouring rows end at the same x */
.dp-tx-side { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 6px; min-width: 84px; }
.dp-tx-usd { font-size: 14px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.wd-row.st-cancelled .dp-tx-usd, .wd-row.st-rejected .dp-tx-usd { font-size: 13px; font-weight: 600; }
.dp-tx-side .btn { height: 34px; }
/* Cancel on a pending withdrawal: a soft button with a visible shape (not grey ghost text) */
.dp-tx-side .wd-cancel { padding: 0 14px; font-size: 13px; font-weight: 600; color: #fff; background: rgba(255, 255, 255, .08); }
.dp-tx-side .wd-cancel:hover { background: rgba(255, 255, 255, .13); }
.dp-bar { height: 5px; margin: 4px 0 2px; border-radius: 5px; background: rgba(255, 255, 255, .08); overflow: hidden; }
.dp-bar i { display: block; height: 100%; border-radius: inherit; background: var(--grad-accent); box-shadow: 0 0 12px rgba(139, 92, 246, .7); transition: width 600ms var(--ease-out-quart); }
.dp-tx.st-seen .dp-bar i { animation: bar-pulse 1.6s var(--ease-in-out) infinite; } /* status indicator: idle loop allowed */
@keyframes bar-pulse { 50% { opacity: .45; } }
.dp-empty { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 22px 16px; text-align: center; font-size: 13px; line-height: 1.5; color: var(--muted); border-radius: 14px; background: var(--surface-2); }
.dp-empty b { font-size: 14px; color: #fff; }
.dp-empty svg { color: rgba(255, 255, 255, .35); margin-bottom: 2px; }
.dp-list .dp-empty { background: none; }
.dp-skel { display: grid; gap: 8px; padding: 12px; }
.dp-skel .skel { display: block; height: 44px; border-radius: 10px; }
.dp-fine { margin: 2px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--muted); text-wrap: pretty; }
.dp-fine a { color: var(--accent-hover); }
.dp-off .empty-state { padding: 20px 8px 8px; }

@media (max-width: 899px) {
  .dp-page-grid { grid-template-columns: minmax(0, 1fr); }
}
/* phones: a transfer row is a grid — coin | title (+ status pill on its own line, the same in every row) | amount —
   and the status line, bar and meta run under the amount too, so text isn't squeezed into a narrow column and the
   bars of neighbouring rows are the same length. Cancel sits at the row's end. */
@media (max-width: 480px) {
  .dp-tx:not(.w-legacy-row) { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto; column-gap: 12px; row-gap: 3px; align-items: start; }
  .dp-tx:not(.w-legacy-row) > .dp-tx-main, .dp-tx:not(.w-legacy-row) > .dp-tx-side { display: contents; }
  .dp-tx:not(.w-legacy-row) .dp-tx-coin { grid-column: 1; grid-row: 1 / span 2; }
  .dp-tx:not(.w-legacy-row) .dp-tx-top { grid-column: 2; grid-row: 1; row-gap: 0; }
  .dp-tx:not(.w-legacy-row) .dp-tx-usd { grid-column: 3; grid-row: 1; justify-self: end; line-height: 20px; }
  .dp-tx:not(.w-legacy-row) .dp-tx-line, .dp-tx:not(.w-legacy-row) .dp-bar, .dp-tx:not(.w-legacy-row) .dp-tx-meta { grid-column: 2 / -1; }
  .dp-tx:not(.w-legacy-row) .dp-tx-side .btn { grid-column: 2 / -1; justify-self: end; margin-top: 4px; }
  .dp-tx-top b { line-height: 20px; }
  .dp-tx-top::after { content: ''; order: 1; flex-basis: 100%; }
  .dp-tx-top .pill { order: 2; margin-top: 4px; }
}
@media (max-width: 640px) {
  .dp-big { padding: 10px 12px; gap: 6px; --dp-big-lh: 29.9px; } /* the 26px amount's line box (26 x 1.15) */
  .dp-big-v { font-size: 26px; }
  .dp-big-out b { font-size: 13.5px; }
  .dp-qr { width: 172px; height: 172px; }
  .dp-k { width: 86px; font-size: 12.5px; }
  .dp-row { padding-left: 12px; }
  .dp-icon-btn { width: 40px; height: 40px; }
  .dp-embed, .dp-recent { padding: 14px; border-radius: 18px; }
}
@media (max-width: 380px) {
  .dp-k { width: 74px; }
  .dp-nets { grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); }
  .dp-net-opt { padding: 7px 9px; }
}
@keyframes shake { 20%, 60% { transform: translateX(-5px); } 40%, 80% { transform: translateX(5px); } }

/* ---------------------------------------------------------------- the deposit sheet (ui/deposit.js openDepositModal)
   ONE sheet, two tabs under its head row: Crypto (the Add funds steps above) | Items (the trade-bot window below). The
   head row follows the tab (Crypto's step 2: "‹ Complete Payment"); the panes take the shown tab's own height on every
   switch, eased both ways (ui/deposit.js sizePanes) — a block, so the box never stretches a pane and a pane's height is
   its own. The same tab row and panes sit in the /wallet/ Add funds card. */
.dps-head { margin-bottom: 12px; }
.dp-back[hidden] { display: none; }
.dps-tabs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px; margin-bottom: 14px; padding: 4px; border-radius: 14px; background: var(--surface-2); }
.dps-tab { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-width: 0; height: 40px; padding: 0 12px; border-radius: 10px; font-size: 14px; font-weight: 700; color: rgba(255, 255, 255, .6); white-space: nowrap;
  transition: color 160ms var(--ease-smooth), background-color 160ms var(--ease-smooth), box-shadow 200ms var(--ease-out), transform 150ms var(--ease-out-quad); }
.dps-tab svg { flex: none; }
.dps-tab:hover { color: #fff; background: rgba(255, 255, 255, .04); }
.dps-tab.on, .dps-tab.on:hover { color: #fff; background: var(--grad-accent); box-shadow: 0 4px 16px rgba(139, 92, 246, .35); }
.dps-tab:active { transform: scale(.97); }
.dps-panes { display: block; min-width: 0; }
.dps-pane { display: flex; flex-direction: column; min-width: 0; }
.dps-pane[hidden] { display: none; }
/* the swap desk's sheet is Items only (rule 7): no tab row, its one pane takes the focus when it opens */
.dps-pane:focus, .dps-pane:focus-visible { outline: none; box-shadow: none; }
/* /wallet/: the page's selected "Add funds" tab is the purple pill right above the card, so the card's own Crypto |
   Items switch marks its selected tab quietly (a lighter tone, no glow); "Recent deposits" (crypto) steps aside while
   Items shows */
.dp-card .dps-tab.on, .dp-card .dps-tab.on:hover { background: rgba(255, 255, 255, .1); box-shadow: 0 2px 8px rgba(0, 0, 0, .22); }
.dp-recent[hidden] { display: none; }

/* ---------------------------------------------------------------- Deposit items (ui/itemdeposit.js)
   The trade-bot window (moved from the profile, Oct 15; class names unchanged): game tiles (MM2 · Adopt Me · PS99 ·
   BGSI · BGS, rule 15), the bot card, its steps, the live panel, the calm messages, the success view. Tone + shadow
   only, no outlines, no idle motion (rule 3, rule 2). */
.bd { display: flex; flex-direction: column; min-width: 0; }
.bd .btn > span:not(.glare) { display: inline-flex; align-items: center; gap: 7px; }
.bd .btn svg { flex: none; }
.bd .btn-primary:active { transform: scale(.97); }
/* a tab switched to Items for the first time: a quiet wait while its settings load (the panes hold their height) */
.bd-wait { display: grid; place-items: center; min-height: 220px; }
.bd-held .empty-state { padding: 26px 8px 10px; }
.bd-held .empty-state p a { color: var(--accent-hover); font-weight: 600; white-space: nowrap; }
/* shared with the profile page (its withdraw sheets, Transfers rows) */
.pf-btn-soft { background: rgba(255, 255, 255, .06); color: #fff; font-weight: 600; }
.pf-btn-soft:hover { background: rgba(255, 255, 255, .1); }
.pf-btn-soft:active { transform: scale(.97); }
.pf-done-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 16px; }
.pf-done-actions .btn { height: 46px; font-weight: 600; }
.pf-swap-in { animation: pf-fade 240ms var(--ease-out) both; }
@keyframes pf-fade { from { opacity: 0; } } /* the profile's own (profile.css has the same) */
.pf-thumbs { display: inline-flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.pf-tchip { position: relative; width: 38px; height: 38px; flex: none; display: grid; place-items: center; border-radius: 10px; background: rgba(255, 255, 255, .05); }
.pf-tchip-th { width: 32px; height: 32px; object-fit: contain; }
.pf-tchip em { position: absolute; right: -5px; bottom: -5px; padding: 1px 5px; border-radius: 999px; font-style: normal; font-size: 9.5px; font-weight: 800; color: #fff; background: var(--accent); box-shadow: 0 2px 6px rgba(0, 0, 0, .5); }
.pf-tmore { padding: 0 4px; font-size: 11.5px; font-weight: 700; color: var(--muted); }
/* PS99 Diamonds: the small gem, never the value coin and never $ */
.pf-gem { flex: none; display: inline-block; vertical-align: -2px; }

/* game tiles: five equal tiles, icon over name; phone sheets (<= 380px) a row of names. Every tap target >= 40px */
.dm-games { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; margin-bottom: 14px; }
.dm-game { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; height: 60px; padding: 0 4px; border-radius: 14px; background: var(--surface-2); font-size: 12.5px; font-weight: 700; color: rgba(255, 255, 255, .7); min-width: 0;
  transition: background-color 160ms, color 160ms, box-shadow 200ms, transform 200ms var(--ease-out-quart); }
.dm-game img { width: 20px; height: 20px; flex: none; }
.dm-game span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dm-game:hover:not(:disabled) { color: #fff; background: var(--surface-3); }
.dm-game:active:not(:disabled) { transform: scale(.97); }
.dm-game.on, .dm-game.on:hover:not(:disabled) { color: #fff; background: rgba(139, 92, 246, .24); box-shadow: 0 6px 20px rgba(139, 92, 246, .2); }
.dm-game:disabled { opacity: .45; cursor: not-allowed; }
.dm-game em { display: none; }
@media (max-width: 760px) { .dm-game { height: 58px; } }
@media (max-width: 380px) {
  .dm-games { display: flex; gap: 4px; }
  .dm-game { flex: 1 1 auto; flex-direction: row; min-width: 40px; height: 44px; padding: 0 5px; }
  .dm-game img { display: none; } /* whole names ("Adopt Me") at 320 */
}

/* the bot card */
.bd-body { display: flex; flex-direction: column; }
.bd-body:focus, .bd-body:focus-visible { outline: none; box-shadow: none; }
.bd-card { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; padding: 18px 16px 16px; border-radius: 20px; overflow: hidden; isolation: isolate;
  background: var(--surface-2); }
/* a soft accent wash on the top of the card */
.bd-card::before { content: ''; position: absolute; inset: 0; z-index: -1; background: radial-gradient(110% 95% at 50% 0%, rgba(139, 92, 246, .2), transparent 66%); }
/* the avatar: the bot's Roblox headshot over a plain tile with a user glyph (what shows until it loads, until a PS99 /
   MM2 bot is set, and if the file is missing — same box). 72px and the card's 18/16px padding: BGSI's window (steps, the
   hatches note, the quick chats, the status line, the shield line) fits a 1440x900 laptop without an inner scroll */
.bd-av { position: relative; width: 72px; height: 72px; flex: none; border-radius: 22px; display: grid; place-items: center;
  background: var(--surface-3); box-shadow: 0 14px 30px rgba(0, 0, 0, .34); }
.bd-pic { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: inherit; object-fit: cover; }
.bd-pic-fb { display: grid; place-items: center; color: rgba(255, 255, 255, .3); background: linear-gradient(150deg, #262c40, #1b2030); }
.bd-dot { position: absolute; right: -4px; bottom: -4px; width: 20px; height: 20px; border-radius: 50%; background: #22c55e; box-shadow: 0 0 0 4px var(--surface-2), 0 0 14px rgba(34, 197, 94, .75); }
/* the name and the status are one line each, so the card keeps its height when a bot fills in. The status has no dot
   of its own: the avatar's dot says online */
.bd-name { margin-top: 16px; font-size: 19px; font-weight: 800; line-height: 1.25; white-space: nowrap; font-variant-numeric: tabular-nums; }
.bd-status { max-width: 100%; margin-top: 5px; overflow: hidden; text-overflow: ellipsis; font-size: 13px; font-weight: 600; white-space: nowrap; color: var(--muted); font-variant-numeric: tabular-nums; }
.bd-body.is-on .bd-status { color: #8ee8b2; }
.bd-join { margin-top: 14px; height: 50px; gap: 8px; font-weight: 700; }
.bd-join svg { flex: none; }
.bd-steps { margin-top: 14px; }
.bd-fine { display: flex; align-items: flex-start; gap: 8px; margin: 12px 2px 0; font-size: 12px; line-height: 1.5; color: var(--muted); }
.bd-fine svg { flex: none; margin-top: 1px; color: #3ee48b; }
/* a game's own trading rule under the steps (BGSI: 8,000 hatches); it steps aside with them while a trade is on screen */
.bd-note { margin-top: 10px; }
.bd-note svg { color: var(--accent-hover); }
/* BGSI's verification phrase (ui/cards.js quickChats; the deposit window, the withdrawal card, Transfers): the three
   quick chats the real bot sends in the trade window — the game's own icons, in order, numbered. It stays on screen
   while a trade is (that is when the player checks it). (.qc-scoped: a card's own `p` / `span` rules never restyle it) */
.bd-qc { margin-top: 10px; }
.qc { padding: 12px 12px 11px; border-radius: 13px; text-align: center; background: var(--surface-2); }
.qc .qc-t { margin: 0; font-size: 12.5px; font-weight: 600; line-height: 1.45; color: rgba(255, 255, 255, .8); text-wrap: pretty; }
.qc .qc-list { list-style: none; display: flex; justify-content: center; gap: 12px; margin: 10px 0 0; padding: 0; }
.qc .qc-tile { position: relative; width: 58px; height: 58px; flex: none; border-radius: 14px; background: rgba(255, 255, 255, .05); }
.qc .qc-tile img { display: block; width: 100%; height: 100%; padding: 3px; object-fit: contain; }
.qc .qc-n { position: absolute; left: -5px; top: -5px; z-index: 1; width: 20px; height: 20px; border-radius: 7px; display: grid; place-items: center;
  overflow: visible; font-size: 11px; font-weight: 800; line-height: 1; color: #fff; background: var(--grad-accent); }
.qc .qc-w { margin: 9px 0 0; font-size: 12px; font-weight: 500; line-height: 1.45; color: #f8c46d; text-wrap: pretty; }
.qc.is-compact { padding: 0; background: none; }
.qc.is-compact .qc-list { justify-content: flex-start; margin: 8px 0 0 5px; }
.qc.is-compact .qc-tile { width: 56px; height: 56px; }
/* numbered steps */
.dm-steps { list-style: none; counter-reset: s; display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; margin: 14px 0 0; padding: 0; }
.dm-steps li { position: relative; counter-increment: s; padding: 8px 12px 8px 46px; border-radius: 13px; background: var(--surface-2); font-size: 13px; line-height: 1.55; color: rgba(255, 255, 255, .8); text-wrap: pretty; }
.dm-steps li::before { content: counter(s); position: absolute; left: 12px; top: 8px; width: 23px; height: 23px; border-radius: 8px; display: grid; place-items: center; font-size: 12px; font-weight: 800; color: #fff; background: var(--grad-accent); }
.dm-steps b { color: #fff; }
/* "Join bot's server" while bot deposits aren't open yet, and the paused / no bot / error messages */
.bd-soon { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 6px 4px 0; }
.bd-soon-ic { width: 64px; height: 64px; margin-bottom: 14px; border-radius: 20px; }
.bd-soon-ic svg { width: 30px; height: 30px; }
.bd-soon h3 { font-size: 20px; }
.bd-soon p { max-width: 340px; margin: 7px 0 0; font-size: 14px; line-height: 1.55; color: rgba(255, 255, 255, .72); }
.bd-soon p b { color: #fff; }
.bd-soon .pf-done-actions { width: 100%; margin-top: 20px; }
.bd-soon .pf-done-actions.is-one { grid-template-columns: minmax(0, 1fr); }

/* PS99 / MM2 / Adopt Me / BGSI live: [Join bot's server | Open profile], four steps, the live panel */
.bd-joinrow { display: flex; gap: 8px; margin-top: 14px; }
.bd-joinrow .bd-join { flex: 1 1 auto; min-width: 0; margin-top: 0; }
.bd-prof { flex: none; height: 50px; padding: 0 16px; font-weight: 600; }
.bd-join.is-off, .bd-prof.is-off { opacity: .45; pointer-events: none; }
/* the trade is on screen: the how-to steps step aside and the bot card turns into one compact row, so the offer has the room */
.bd-body.is-live .bd-steps, .bd-body.is-live .bd-note { display: none; }
.bd-body.is-live .bd-card { display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "av name" "av status"; column-gap: 14px; justify-items: start; align-items: center;
  padding: 12px 14px; text-align: left; }
.bd-body.is-live .bd-av { grid-area: av; width: 52px; height: 52px; border-radius: 16px; box-shadow: none; }
.bd-body.is-live .bd-dot { right: -3px; bottom: -3px; width: 14px; height: 14px; box-shadow: 0 0 0 3px var(--surface-2); }
.bd-body.is-live .bd-name { grid-area: name; align-self: end; margin-top: 0; font-size: 16px; }
.bd-body.is-live .bd-status { grid-area: status; align-self: start; margin-top: 2px; }
.bd-body.is-off .bd-dot { background: #6b7280; box-shadow: 0 0 0 4px var(--surface-2); }
.bd-body.is-on.is-off .bd-status { color: var(--muted); }
.bd-live { margin-top: 12px; }
.bd-live:empty { display: none; }
.bd-lstat { display: flex; align-items: flex-start; gap: 8px; margin: 0; padding: 11px 12px; border-radius: 13px; font-size: 13px; font-weight: 600; line-height: 1.45; text-wrap: pretty;
  background: var(--surface-2); color: rgba(255, 255, 255, .8); }
.bd-lstat svg { flex: none; margin-top: 1px; }
.bd-lstat.is-wait, .bd-lstat.is-mute { font-weight: 500; color: var(--muted); }
.bd-lstat.is-ok { background: rgba(5, 202, 98, .1); color: #8ee8b2; }
.bd-lstat.is-warn { background: rgba(248, 183, 77, .1); color: #f8c46d; }
.bd-lstat.is-busy { background: rgba(139, 92, 246, .12); color: #c9b8ff; }
.bd-offer { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; max-height: 284px; margin-top: 8px; padding-right: 2px; overflow-y: auto; }
.bd-pet { display: flex; align-items: center; gap: 10px; min-width: 0; min-height: 46px; padding: 5px 12px 5px 6px; border-radius: 12px; background: var(--surface-2); }
.bd-pet-th { width: 34px; height: 34px; flex: none; display: grid; place-items: center; padding: 3px; border-radius: 10px; object-fit: contain; background: rgba(255, 255, 255, .05); }
.bd-pet-n { flex: 1 1 auto; min-width: 0; font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* MM2 items stack: a count beside the name ("x2") */
.bd-pet-x { flex: none; padding: 2px 7px; border-radius: 999px; font-size: 11.5px; font-weight: 800; line-height: 1.35; color: #c9b8ff; background: rgba(139, 92, 246, .16);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.bd-pet-v { flex: 0 1 auto; max-width: 55%; text-align: right; font-size: 12px; font-weight: 600; line-height: 1.35; color: #f8c46d; text-wrap: pretty; }
/* BGSI: the pet's enchants on a quiet line under its name (shown, never priced) */
.bd-pet-m { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.bd-pet-m .bd-pet-n { flex: none; }
.bd-pet-e { font-size: 11.5px; font-weight: 500; line-height: 1.3; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bd-pet.is-bad .bd-pet-th { opacity: .5; filter: saturate(.4); }
.bd-pet.is-bad .bd-pet-n { color: rgba(255, 255, 255, .6); }
.bd-pet.is-gems .bd-pet-th { background: rgba(56, 189, 248, .1); }
.bd-ok { display: inline-grid; place-items: center; width: 26px; height: 26px; border-radius: 8px; color: #3ee48b; background: rgba(5, 202, 98, .15); }
.bd-done h3 { max-width: 360px; text-wrap: balance; }
.bd-done-th { margin-top: 14px; }
.bd-done-th .pf-thumbs { justify-content: center; }
@media (max-width: 640px) {
  .pf-done-actions { grid-template-columns: 1fr; }
  .pf-done-actions :is([data-close], [data-inv]) { order: -1; } /* the primary one on top */
}
@media (max-width: 480px) {
  .bd .bd-prof > span:not(.glare) { display: none; }
  .bd-prof { width: 50px; padding: 0; justify-content: center; }
}
@media (prefers-reduced-motion: reduce) {
  .bd, .bd *, .dps-panes { animation-duration: 1ms !important; animation-iteration-count: 1 !important; animation-delay: 0ms !important; transition-duration: 1ms !important; }
}

/* ---------------------------------------------------------------- payment rows (retired order view, profile transfers) */
.payment-modal { width: min(440px, 100%); }
.pay-rows { display: grid; gap: 6px; margin-bottom: 14px; }
.pay-row { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 12px; background: var(--surface-2); min-width: 0; }
.pr-label { flex: none; width: 82px; font-size: 12.5px; color: var(--muted); }
.pr-val { flex: 1; min-width: 0; font-size: 13px; font-weight: 600; overflow-wrap: anywhere; }
.pr-val.mono { word-break: break-all; }
.pr-val a { color: var(--accent-hover); display: inline-flex; align-items: center; gap: 4px; }
.pr-copy { width: 34px; height: 34px; flex: none; border-radius: 10px; display: grid; place-items: center; background: rgba(255, 255, 255, .06); color: rgba(255, 255, 255, .7); transition: all 150ms; }
.pr-copy:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.pr-copy.done { background: rgba(5, 202, 98, .2); color: #3ee48b; }
.payment-modal .dp-fine { margin: 0 0 14px; }

/* ---------------------------------------------------------------- wallet panel (mountWallet)
   Tabs on top (Add funds · Withdraw · Transactions), content below. */
.wallet-shell { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.wallet-nav { display: inline-flex; align-self: flex-start; gap: 4px; max-width: 100%; padding: 4px; border-radius: 16px; background: var(--surface-1); overflow-x: auto; scrollbar-width: none; }
.wallet-nav::-webkit-scrollbar { display: none; }
.wn-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 40px; padding: 0 16px; border-radius: 12px; font-size: 14px; font-weight: 600; color: rgba(255, 255, 255, .55); white-space: nowrap; transition: color 160ms var(--ease-smooth), background-color 160ms var(--ease-smooth), box-shadow 200ms var(--ease-out); }
.wn-btn svg { width: 16px; height: 16px; flex: none; }
.wn-btn:hover { color: #fff; background: rgba(255, 255, 255, .04); }
.wn-btn.on { color: #fff; background: var(--grad-accent); box-shadow: 0 4px 16px rgba(139, 92, 246, .35); }
.wn-btn:active { transform: scale(.97); }
.wallet-main { min-width: 0; }
.wallet-main.wm-in { animation: slide-fade-in 260ms var(--ease-out) both; }
.w-h { font-size: 15px; font-weight: 700; margin: 0 0 12px; }
.w-h-gap { margin-top: 26px; }
.w-loading { display: grid; place-items: center; padding: 60px 0; }
#wlt-panel .w-loading { min-height: 483px; } /* about the Add funds card (tabs + step 1) it turns into: the page doesn't jump */
.wadd { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 20px; align-items: start; }
.wadd-left { min-width: 0; }
.wrow { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 10px 2px; border-bottom: 1px solid var(--hairline); font-size: 14px; color: var(--muted); }
.wrow b { color: #fff; font-variant-numeric: tabular-nums; text-align: right; }
.wrow b.accent { color: var(--accent-hover); }
.wrow[hidden], .dep-note[hidden] { display: none; }
.coin-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.coin-tile { display: flex; align-items: center; gap: 10px; height: 50px; padding: 0 14px; border-radius: 14px; background: var(--surface-2); font-size: 14px; font-weight: 700; color: rgba(255, 255, 255, .85); transition: background-color 160ms var(--ease-out-quad), transform 160ms var(--ease-out-quad), color 160ms; }
.coin-tile em { margin-left: auto; font-style: normal; font-size: 10px; font-weight: 700; color: var(--muted); }
.coin-tile:hover { background: var(--surface-3); transform: translateY(-1px); }
.coin-tile.on { background: rgba(139, 92, 246, .22); color: #fff; }
.coin-tile.on em { color: rgba(255, 255, 255, .7); }
.coin-tile[disabled] { opacity: .35; cursor: not-allowed; transform: none; }
.dep-note { margin: 12px 0; font-size: 12px; line-height: 1.5; color: rgba(255, 255, 255, .5); font-weight: 600; }
.wd-addr-hint { margin: 8px 0 0; font-size: 12px; font-weight: 600; color: #ff9092; }
.input.is-bad { background: rgba(219, 59, 62, .1); }
.wadd-card { position: sticky; top: calc(var(--header-h) + 16px); display: flex; flex-direction: column; padding: 18px; border-radius: 18px; background: var(--surface-1); box-shadow: var(--shadow-card); }
.wc-label { font-size: 12.5px; color: var(--muted); font-weight: 600; }
.wc-bal { font-size: 28px; font-weight: 800; margin: 4px 0 6px; font-variant-numeric: tabular-nums; }
.wc-est { margin: 10px 0 12px; font-size: 12px; line-height: 1.5; color: var(--muted); }
.wc-demo { margin: 0 0 8px; padding: 9px 11px; border-radius: 12px; background: rgba(139, 92, 246, .1); font-size: 12px; line-height: 1.5; color: rgba(255, 255, 255, .72); }
.wc-demo b { color: #fff; font-variant-numeric: tabular-nums; }
.wc-fine { margin: 10px 0 0; font-size: 11.5px; text-align: center; color: var(--muted); font-weight: 600; line-height: 1.5; }
.amt-wrap .amt-prefix { position: absolute; left: 13px; color: rgba(255, 255, 255, .5); font-weight: 700; }
.amt-wrap .input { padding-left: 28px; padding-right: 56px; }
.amt-max { position: absolute; right: 4px; height: 40px; min-width: 44px; padding: 0 10px; border-radius: 10px; font-size: 12px; }
.wd-open { margin-top: 24px; }
/* Transactions: deposits, withdrawals and the balance history stacked full width at every size (side-by-side
   lists of different lengths left a tall empty column beside the shorter one) */
.w-rec-cols { display: grid; grid-template-columns: minmax(0, 1fr); gap: 26px; }
.w-rec-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.w-rec-head .link-btn { display: inline-flex; align-items: center; min-height: 40px; margin: -10px -8px; padding: 0 8px; font-size: 13px; } /* a 40px tap target, the negative margin keeps the head */
.w-legacy { margin-top: 18px; }
.w-legacy summary { cursor: pointer; font-size: 13px; font-weight: 600; color: var(--muted); padding: 6px 0; }
.w-legacy summary:hover { color: #fff; }
.w-legacy .dp-list { margin-top: 8px; }
.w-legacy-row:hover { background: var(--surface-3); }
/* Balance history: the same list look as the deposit / withdrawal lists above it (surface-2, 1px hairlines between
   rows); one column grid shared by every row (subgrid) so the side columns size to their content and the
   details get the rest; a header names the columns (the last one is the balance after each change) */
.ledger { display: grid; grid-template-columns: minmax(96px, max-content) minmax(0, 1fr) max-content max-content max-content; column-gap: 16px; border-radius: 14px; background: var(--surface-2); overflow: hidden; }
.lg-row { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; align-items: center; padding: 11px 14px; font-size: 13px; }
.lg-row + .lg-row { border-top: 1px solid var(--hairline); }
.lg-head { padding-top: 9px; padding-bottom: 9px; font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: rgba(255, 255, 255, .45); }
.lg-kind { font-weight: 600; }
.lg-memo { color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lg-time { color: var(--muted); font-size: 12px; white-space: nowrap; }
.lg-row b, .lg-head .lg-amt { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.lg-bal { text-align: right; color: rgba(255, 255, 255, .55); font-variant-numeric: tabular-nums; white-space: nowrap; }
.lg-head .lg-memo, .lg-head .lg-bal { color: inherit; }
@media (max-width: 980px) {
  .wadd { grid-template-columns: 1fr; }
  .wadd-card { position: static; }
}
@media (max-width: 760px) {
  /* the three tabs size to their labels and share the rest: "Transactions" is never cut ("Transacti…") */
  .wallet-nav { display: flex; align-self: stretch; }
  .wn-btn { flex: 1 1 auto; min-width: 0; padding: 0 10px; gap: 6px; font-size: 13px; }
  .wn-btn span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .coin-tiles { grid-template-columns: repeat(2, 1fr); }
  .ledger { display: block; }
  .lg-row { grid-template-columns: minmax(0, 1fr) auto; column-gap: 10px; row-gap: 1px; }
  .lg-head, .lg-memo, .lg-bal { display: none; }
  .lg-kind, .lg-time { grid-column: 1; }
  .lg-row b { grid-column: 2; grid-row: 1 / span 2; }
}
@media (max-width: 460px) { .wn-btn svg { display: none; } }
@media (max-width: 340px) { .wn-btn { padding: 0 8px; } }
/* small phones: a USDT / USDC tile puts "3 networks" under the ticker instead of squeezing it in beside it */
@media (max-width: 420px) {
  .coin-tile { display: grid; grid-template-columns: 26px minmax(0, 1fr); align-items: center; align-content: center; justify-items: start; column-gap: 10px; padding: 0 12px; text-align: left; }
  .coin-tile img { grid-row: 1 / span 2; }
  .coin-tile em { grid-column: 2; margin: 0; font-size: 10.5px; line-height: 1.2; white-space: nowrap; }
}

/* ---------------------------------------------------------------- page scaffolding */
.page { padding-top: calc(var(--header-h) + 28px); padding-bottom: 24px; }
/* a page that is still filling in keeps the footer below the fold (no footer flashing up, then pushed away): with
   the footer's 90px top margin it starts exactly at the fold, no further down */
main.page { min-height: calc(100vh - 90px); }
main.swap-page { min-height: 100vh; }
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 20px; }
.page-title { font-size: clamp(28px, 4vw, 44px); font-weight: 800; letter-spacing: -.01em; }
.page-sub { margin: 6px 0 0; color: var(--muted); font-size: 14.5px; }
.panel-card { border-radius: 18px; background: var(--surface-1); padding: 18px; }
.skeleton-card { border-radius: 12px; aspect-ratio: 1 / 1.25; background: linear-gradient(100deg, #10131a 30%, #161a24 50%, #10131a 70%); background-size: 300% 100%; animation: skel-sweep 1.4s linear 600ms infinite; }
@keyframes skel-sweep { to { background-position: -150% 0; } }
/* A sweep repaints its placeholder on every frame (a background-position animation runs on the page's thread): the
   inventory's, the values' and the FAQ's placeholders sweep only when a load takes a while (600 ms, as .skc). */
/* The placeholder card of a card grid (the market's listings, the swap desk's stock and your items): the real card's
   own anatomy — .icard > .ic-art + .ic-strip (type · name · price line) [+ .ic-foot on the market] — so it is as tall
   as the one-line-name card that replaces it (in the market's subgrid rows too) and nothing moves when the cards
   land. Its bars sit inside the real line boxes (type 15px, name 15.6px / 14.3px small, price line 23.5px / 21px
   small); a quiet light tone that reads on the page and on the desk's panels (--surface-1), no rarity colour, no
   entrance; the sheen starts only when a load takes a while (600 ms). Markup: market.js / swap.js skeletons(), and
   the static copies in market/ and swap/index.html (the first frame in every browser). They are cheap to paint —
   they are a page's first frame: their art circle is a soft gradient without the real card's blur filter, and the
   sheen layer isn't painted at all (opacity 0) until it starts. */
.icard.skc { pointer-events: none; animation: none; box-shadow: none; background: rgba(255, 255, 255, .028); }
.skc .ic-art::before { background: radial-gradient(circle, rgba(255, 255, 255, .07), rgba(255, 255, 255, .03) 45%, transparent 72%); filter: none; }
.skc i { display: block; border-radius: 6px; background: rgba(255, 255, 255, .06); }
.skc .sk-t { width: 38%; height: 9px; margin: 3px 0; }
.skc .sk-n { width: 72%; height: 11px; margin: 2.3px 0; }
.skc .sk-p { width: 46%; height: 12px; margin: 7.25px 0 4.25px; }
.icard-sm.skc .sk-n { margin: 1.65px 0; }
.icard-sm.skc .sk-p { margin: 6px 0 3px; }
.skc::after { content: ''; position: absolute; inset: 0; pointer-events: none; opacity: 0; background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, .04) 50%, transparent 70%); background-size: 300% 100%; animation: skc-sheen 1.4s linear 600ms infinite; }
@keyframes skc-sheen { from { opacity: 1; background-position: 0 0; } to { opacity: 1; background-position: -150% 0; } }
/* real cards replacing placeholders the visitor saw: one quiet step over them, no rise, no stagger (market.js /
   swap.js add it and keep the placeholders under the cards until it is over — crossIn — so the grid is never empty;
   a placeholder without a card fades out meanwhile; app.js settleArrival finishes neither early). Cards that are
   there on arrival get none. */
@keyframes ps-in { from { opacity: 0; } }
@keyframes ps-out { to { opacity: 0; } }
.icard.ps-in { animation: ps-in 160ms var(--ease-out) both; z-index: 1; }
.icard.skc.ps-out { animation: ps-out 160ms var(--ease-out) both; }
/* item art not in the cache yet fades in once it has loaded (cards.js; art that comes at once just shows) */
.ic-art img.is-wait { opacity: 0; }
.ic-art img.is-instant { transition: transform 300ms var(--ease-out-quart); }

/* reduced motion: stop the few remaining idle loops (shine sweep, live dot, placeholder sheens); art appears as it
   loads */
@media (prefers-reduced-motion: reduce) {
  .btn-shine > .glare, .live-dot { animation: none !important; }
  .skc::after, .skeleton-card, .sk, .skel, .pf-skel-text, .pf-skel-block, .qa-skel { animation: none !important; }
  .ic-art img { transition: transform 300ms var(--ease-out-quart); }
}

/* ---------------------------------------------------------------- phones: shared chrome tap targets >= 40px */
@media (max-width: 899px) {
  .bal-group { height: 44px; padding: 2px; }
  .bal-chip { height: 40px; }
  .bal-plus { width: 40px; height: 40px; }
  .user-chip { height: 40px; min-width: 40px; }
  .hdr-pop a.um-credit-row { min-height: 40px; }
  .site-header .logo, .site-footer .logo { display: inline-flex; align-items: center; min-height: 40px; }
  .footer-col { gap: 0; }
  .footer-col a { display: inline-flex; align-items: center; min-height: 40px; min-width: 40px; }
  /* "View transaction" in deposit / withdrawal rows and the Add funds status card: a 40px hit area without growing
     the row; Cancel on a pending withdrawal is 40px tall */
  .dp-tx-meta a, .dp-st-meta a, .dp-st-more a { padding: 12px 0; margin: -12px 0; }
  .dp-tx-side .wd-cancel { height: 40px; }
}
