/* ===========================================================================
   Swap desk (/swap/) — page styles layered on app.css + shell.css.
   ITEMS ONLY: values with the .vicon, never $. Owner rules: borderless surfaces
   (tone + shadow, no outlines — only list hairlines, the focus ring, the item
   card selected ring and rarity edge), no mascot in the desk, no idle loops,
   global custom scrollbars (never set scrollbar-width/-color here), shine only
   on "Send swap offer".
   Desktop (> 900px): full-viewport 3 columns (inventory | controls | stock).
   Phones (<= 900px): stacked, segmented "Your items | Stock", sticky swap bar,
   summary + filters in a bottom sheet.
   =========================================================================== */

.swap-page { position: relative; }
.sw-screen { isolation: isolate; }
.sw-screen .swap-glow { background: radial-gradient(55% 38% at 50% 0%, rgba(139, 92, 246, .12) 0%, transparent 70%), radial-gradient(40% 30% at 0% 100%, rgba(124, 58, 237, .05), transparent 70%); }
.sw-v { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.sw-v .vicon { width: 12px; height: 12px; vertical-align: 0; }

/* ---------------------------------------------------------------- layout */
/* The desk is the page column of /swap: the same --container / --gutter tokens and formula as the header bar, which
   app.css gives the same values on this page (body.swap-body :is(.site-header, #toasts)) — so the wordmark starts
   at the inventory panel's left edge and the account chip ends at the stock panel's right edge. Change both together. */
.sw-screen { --container: 1848px; --gutter: 16px; }
/* app.css' panel entrances are finished on arrival anyway (rule 17); a panel shown again later (crossing 900px on a
   resize or rotation, the phone Your items | Stock switch) must not replay them — the phone switch has its own
   short .sw-panel-in */
.sw-layout > * { animation: none; }
@media (min-width: 900.02px) {
  .sw-screen { height: 100dvh; min-height: 700px; overflow: hidden; }
  .sw-layout { grid-template-columns: minmax(0, 1fr) 300px minmax(0, 1fr); gap: 12px; padding: 10px 0 16px; width: min(var(--container), calc(100% - 2 * var(--gutter))); margin: 0 auto; }
  .sw-panel { min-height: 0; }
  .sw-controls { order: initial; }
}
@media (min-width: 900.02px) and (max-width: 1180px) {
  .sw-screen { --gutter: 10px; }
  .sw-layout { grid-template-columns: minmax(0, 1fr) 256px minmax(0, 1fr); gap: 8px; padding: 8px 0 10px; }
}

/* ---------------------------------------------------------------- panels */
.sw-panel { position: relative; border-radius: 20px; background: var(--surface-1); box-shadow: var(--shadow-card); }
.sw-panel::before { content: ''; position: absolute; inset: 0 0 auto 0; height: 220px; pointer-events: none; z-index: 0; border-radius: 20px 20px 0 0; background: radial-gradient(70% 100% at 50% 0%, rgba(139, 92, 246, .08), transparent 72%); }
#panel-get::before { background: radial-gradient(70% 100% at 50% 0%, rgba(5, 202, 98, .05), transparent 72%); }
.sw-panel.sw-panel-in { animation: panel-in 420ms var(--ease-out-quart) backwards; }

.sw-phead { position: relative; z-index: 2; flex: none; display: flex; align-items: center; justify-content: space-between; gap: 12px; height: 62px; padding: 0 16px; }
#panel-get .sw-phead { flex-direction: row-reverse; }
.sw-ptitle { display: flex; align-items: center; gap: 10px; min-width: 0; }
#panel-get .sw-ptitle { flex-direction: row-reverse; text-align: right; }
.sw-pico { width: 32px; height: 32px; flex: none; border-radius: 10px; display: grid; place-items: center; transition: transform 300ms var(--ease-out-quart); }
.sw-pico-give { color: #c9b8ff; background: rgba(139, 92, 246, .18); box-shadow: 0 0 18px rgba(139, 92, 246, .16); }
.sw-pico-get { color: #6ee7a8; background: rgba(5, 202, 98, .14); box-shadow: 0 0 18px rgba(5, 202, 98, .12); }
.sw-phead:hover .sw-pico-give { transform: translateY(-2px); }
.sw-phead:hover .sw-pico-get { transform: translateY(2px); }
.sw-ptext { display: flex; flex-direction: column; min-width: 0; }
.sw-eyebrow { font-size: 10px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: rgba(255, 255, 255, .4); line-height: 1.3; }
.sw-ptext h2 { font-size: 15.5px; font-weight: 700; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-dep-link { position: relative; flex: none; display: inline-flex; align-items: center; justify-content: center; gap: 4px; height: 28px; padding: 0 11px 0 9px; border-radius: 999px; font-size: 11.5px; font-weight: 700; color: #d6c9ff; background: rgba(139, 92, 246, .16); transition: transform 200ms var(--ease-out-quart), background-color 150ms; }
.sw-dep-link::after { content: ''; position: absolute; inset: -6px -4px; } /* 40px tap area around the small pill */
.sw-dep-link:not([aria-disabled]):hover { background: rgba(139, 92, 246, .28); transform: translateY(-1px); color: #fff; }
.sw-dep-link:not([aria-disabled]):active { transform: scale(.96); }
/* the desk's game isn't live (staff console → Controls): it takes no deposits — the pill stays where it is, dimmed and
   inert, with the reason in its title (a tap says it in a toast: phones have no hover) */
.sw-dep-link[aria-disabled] { opacity: .45; cursor: not-allowed; }
/* the count + total column takes the header's spare width and its count line spans it, so "0 selected" turning
   into "0 of 7 selected" when your items land moves no box */
.sw-ptotal { flex: 1 1 auto; display: flex; flex-direction: column; align-items: stretch; gap: 1px; min-width: 0; text-align: right; }
.sw-ptotal .sw-total { align-self: flex-end; }
#panel-get .sw-ptotal { text-align: left; }
#panel-get .sw-ptotal .sw-total { align-self: flex-start; }
.sw-selc { max-width: 100%; font-size: 11px; font-weight: 500; color: rgba(255, 255, 255, .42); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; }
.sw-total { display: inline-flex; align-items: center; gap: 6px; font-size: 17px; font-weight: 800; font-variant-numeric: tabular-nums; }
.sw-total .vicon { width: 15px; height: 15px; vertical-align: 0; }

/* ---------------------------------------------------------------- cart zones (no mascot) */
.sw-cart { position: relative; z-index: 1; flex: none; height: 138px; margin: 0 12px; border-radius: 16px; background: rgba(0, 0, 0, .22); transition: background-color 300ms var(--ease-out); }
.sw-cart.side-offer::after, .sw-cart.side-get::after { content: none; } /* app.css edge lines: borderless desk */
.sw-cart.has-items { background: rgba(139, 92, 246, .06); }
.sw-cart-empty { flex-direction: column; gap: 8px; padding: 0 20px; text-align: center; animation: fade-in 320ms var(--ease-out) both; }
.sw-cart-empty .cart-copy { align-items: center !important; text-align: center !important; padding: 0 !important; max-width: 340px; }
.sw-cart .cart-copy p { font-size: 13px; font-weight: 500; color: rgba(255, 255, 255, .52); }
.sw-cart .cart-copy small { font-size: 11px; color: rgba(255, 255, 255, .32); }
.sw-cart-ico { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; color: rgba(255, 255, 255, .5); background: rgba(255, 255, 255, .06); }
.side-get .sw-cart-ico { color: #6ee7a8; background: rgba(5, 202, 98, .1); }
.side-offer .sw-cart-ico { color: #c9b8ff; background: rgba(139, 92, 246, .14); }
/* a game that isn't live: the muted clock alone, no words, no "+" (swap.js cartEmptyHtml) */
.sw-cart-empty.is-off .sw-cart-ico { color: rgba(255, 255, 255, .42); background: rgba(255, 255, 255, .05); }

.sw-chips { gap: 8px; padding: 10px 12px; }
/* a touch-only screen keeps proximity snapping for its swipes; with a mouse or trackpad the row stays where the wheel
   or a drag leaves it (a re-snap after every wheel tick or glide would jump the row back) */
@media (hover: none) and (pointer: coarse) { .sw-chips { scroll-snap-type: x proximity; } }
/* a row wider than the cart scrolls sideways: the cut side fades out (swap.js edgeFade), so a chip half under the
   edge reads as "more this way", not as a broken card */
.sw-chips.fade-r { -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent); }
.sw-chips.fade-l { -webkit-mask-image: linear-gradient(90deg, transparent, #000 28px); mask-image: linear-gradient(90deg, transparent, #000 28px); }
.sw-chips.fade-l.fade-r { -webkit-mask-image: linear-gradient(90deg, transparent, #000 28px, #000 calc(100% - 28px), transparent); mask-image: linear-gradient(90deg, transparent, #000 28px, #000 calc(100% - 28px), transparent); }
.sw-chip {
  --rc: 139, 92, 246;
  position: relative; flex: none; width: 94px; height: 118px; padding: 0; border-radius: 14px; overflow: hidden; cursor: pointer; scroll-snap-align: end;
  background: linear-gradient(180deg, var(--surface-2) 0%, #10131b 55%, rgba(var(--rc), .16) 100%);
  box-shadow: inset 0 -2px 0 rgb(var(--rc)), 0 6px 16px rgba(0, 0, 0, .3);   /* rarity edge (allowed) */
  animation: sw-chip-in 420ms var(--ease-out-quart) backwards;
  transition: transform 260ms var(--ease-out-quart), box-shadow 260ms var(--ease-out);
}
@keyframes sw-chip-in { 0% { opacity: 0; transform: translateY(14px) scale(.7); } 60% { opacity: 1; transform: translateY(-2px) scale(1.04); } 100% { transform: none; } }
/* an entrance plays once (swap.js marks it .sw-in when it ends): a cart shown again — crossing 900px, the phone
   Your items | Stock switch — doesn't pop its chips in again */
.sw-chip.sw-in { animation: none; }
.sw-chip::before { content: ''; position: absolute; inset: 14% 16% 38%; border-radius: 50%; background: radial-gradient(circle, rgba(var(--rc), .3), transparent 70%); filter: blur(8px); }
.sw-chip:hover { transform: translateY(-3px); box-shadow: inset 0 -2px 0 rgb(var(--rc)), 0 14px 26px rgba(0, 0, 0, .45), 0 0 18px rgba(var(--rc), .16); }
.sw-chip:active { transform: scale(.95); }
.sw-chip img { position: absolute; inset: 9px 14px 40px; width: calc(100% - 28px); height: calc(100% - 49px); object-fit: contain; filter: drop-shadow(0 4px 8px rgba(0, 0, 0, .45)); transition: transform 260ms var(--ease-out-quart); }
.sw-chip:hover img { transform: scale(1.06) rotate(-3deg); }
.sw-chip-name { position: absolute; left: 7px; right: 7px; bottom: 22px; font-size: 9.5px; font-weight: 700; text-transform: uppercase; text-align: left; color: rgba(255, 255, 255, .88); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-chip-price { position: absolute; left: 7px; right: 7px; bottom: 7px; display: flex; align-items: center; gap: 4px; font-size: 11px; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums; }
.sw-chip-price .vicon { width: 11px; height: 11px; vertical-align: 0; }
.sw-chip .cc-x { position: absolute; top: 5px; right: 5px; z-index: 3; width: 20px; height: 20px; border-radius: 7px; display: grid; place-items: center; background: rgba(0, 0, 0, .55); color: rgba(255, 255, 255, .8); opacity: 0; transform: scale(.7); transition: opacity 150ms, transform 250ms var(--ease-out-quart), background-color 150ms; }
.sw-chip:hover .cc-x, .sw-chip:focus-visible .cc-x { opacity: 1; transform: none; background: var(--danger); color: #fff; }
.sw-chip-n { position: absolute; top: 5px; left: 5px; z-index: 3; min-width: 22px; height: 18px; padding: 0 6px; border-radius: 999px; display: grid; place-items: center; font-size: 10px; font-weight: 800; color: #fff; background: var(--accent); box-shadow: 0 0 10px rgba(139, 92, 246, .6); }
.sw-chip.chip-out { animation: chip-out 170ms var(--ease-out) both; pointer-events: none; }
/* wheel + click-and-drag scrolling (ui/dragscroll.js; mouse / pen — touch swipes natively): a row wider than its cart
   shows the grab hand (the remove × keeps the pointer). Dragged, it follows the pointer: the chips' hover lift and
   press dip are off and nothing gets selected; where the row snaps (touch screens: a pen, a mouse plugged in) snapping
   is off while it is dragged, glides on or eases after a wheel tick, so it never pulls the row back mid-move */
.sw-chips.is-scrollable, .sw-chips.is-scrollable .sw-chip { cursor: grab; }
.sw-chips.is-scrollable .sw-chip .cc-x { cursor: pointer; }
.sw-chips.is-dragging, .sw-chips.is-dragging .sw-chip { cursor: grabbing; -webkit-user-select: none; user-select: none; }
.sw-chips.is-dragging, .sw-chips.is-gliding { scroll-snap-type: none; }
.sw-chips.is-dragging .sw-chip { pointer-events: none; transform: none; }
.sw-chips.is-dragging .sw-chip img { transform: none; }
.sw-tick { animation: sw-tick 320ms var(--ease-out-quart); }
@keyframes sw-tick { 0% { transform: scale(.6); } 60% { transform: scale(1.25); } 100% { transform: scale(1); } }
@media (hover: none) { .sw-chip .cc-x { opacity: 1; transform: none; } }

/* ---------------------------------------------------------------- toolbar */
.sw-tool { position: relative; z-index: 3; flex: none; display: flex; align-items: center; gap: 8px; padding: 12px 12px 4px; }
.sw-search { position: relative; flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; height: 38px; padding: 0 6px 0 12px; border-radius: 12px; background: var(--surface-2); color: rgba(255, 255, 255, .38); transition: background-color 150ms, box-shadow 200ms var(--ease-out); cursor: text; }
.sw-search:hover { background: var(--surface-3); }
.sw-search:focus-within { background: var(--surface-3); box-shadow: 0 0 0 2px var(--accent); color: var(--accent-hover); } /* the one field focus ring */
.sw-search svg { flex: none; }
.sw-search input { flex: 1; min-width: 0; height: 100%; padding: 0; border: 0; outline: 0; background: transparent; font-size: 13px; color: #fff; }
.sw-search input::placeholder { color: rgba(255, 255, 255, .34); }
/* the field draws the focus ring; the global :focus-visible ring on the bare input would double it */
.sw-search input:focus-visible, .sw-card .numfield input:focus-visible { box-shadow: none; }
.sw-clear { position: relative; flex: none; width: 26px; height: 26px; border-radius: 8px; display: grid; place-items: center; color: rgba(255, 255, 255, .6); background: rgba(255, 255, 255, .06); transition: background-color 150ms, color 150ms; }
.sw-clear::after { content: ''; position: absolute; inset: -7px; } /* 40px tap area */
.sw-clear:hover { color: #fff; background: rgba(255, 255, 255, .12); }
.sw-sortbox { position: relative; flex: none; min-width: 0; }
.sw-tool-off .sw-search, .sw-tool-off .sw-sortbox, .sw-tool-off .sw-filter-btn { opacity: .45; pointer-events: none; } /* nothing to search or filter (swap.js) */
.sw-sort-ico { display: none; }
.sw-tool .csel-trigger { height: 38px; padding: 0 10px 0 12px; border-radius: 12px; font-size: 12.5px; font-weight: 600; background: var(--surface-2); color: rgba(255, 255, 255, .85); }
.sw-tool .csel-trigger:hover, .sw-tool .csel-trigger[aria-expanded="true"] { background: var(--surface-3); }
.sw-filter-btn { display: none; position: relative; width: 44px; height: 40px; flex: none; border-radius: 12px; place-items: center; color: rgba(255, 255, 255, .8); background: var(--surface-2); transition: transform 150ms, background-color 150ms; }
.sw-filter-btn:active { transform: scale(.94); }
.sw-fcount { position: absolute; top: -5px; right: -5px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; display: grid; place-items: center; font-size: 10px; font-weight: 800; color: #fff; background: var(--accent); box-shadow: 0 0 10px rgba(139, 92, 246, .7); animation: pop-spring 300ms var(--ease-out-quart) both; }

/* ---------------------------------------------------------------- grids */
.sw-grid {
  position: relative; z-index: 1; flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); grid-auto-rows: max-content; gap: 8px; padding: 8px 12px 12px; align-content: start;
}
/* cards and placeholders keep the scrollbar's room (its track is transparent): the cards arriving over 12 placeholders
   overflow where the placeholders didn't, and a scrollbar appearing then would narrow every column under them (Chrome
   logs it as a layout shift of the grid's contents). A message fills the whole grid, as before. Phones don't scroll
   the grid (no gutter there) */
.sw-grid:not(.is-state) { scrollbar-gutter: stable; }
/* a message / the sign-in card: one cell across every column, stretched to the grid's height. The grid stays a grid
   (never another display mode): switching it rebuilds its box, which Chrome logs as a layout shift of the whole panel
   even where nothing moves (swap.js stateOver toggles this class to lay a late message out over the placeholders) */
.sw-grid.is-state { grid-auto-rows: auto; align-content: stretch; }
.sw-grid.is-state > * { grid-column: 1 / -1; }
.sw-sentinel { grid-column: 1 / -1; height: 1px; }
/* placeholder cards (shell.css .skc.icard-sm: the card's own art box 1 / .86 + its 64px name strip) are exactly as tall
   as the cards that replace them, so the grid doesn't grow when your items land (phones: the band below moved);
   their tone reads on the panel (--surface-1) */

/* empty / error states: icon tile, no mascot */
.sw-state { flex: 1; display: grid; place-items: center; padding: 16px; min-height: 280px; animation: slide-fade-in 360ms var(--ease-out) both; }
.sw-es { display: flex; flex-direction: column; align-items: center; gap: 8px; max-width: 340px; text-align: center; }
.sw-es h3 { font-size: 17px; font-weight: 800; }
.sw-es p { margin: 0 0 6px; font-size: 13.5px; line-height: 1.55; color: var(--muted); }
.sw-es-ico { width: 56px; height: 56px; margin-bottom: 4px; border-radius: 18px; display: grid; place-items: center; color: #c9b8ff; background: rgba(139, 92, 246, .14); box-shadow: 0 10px 30px rgba(139, 92, 246, .14); }
.sw-es-warn .sw-es-ico { color: #ffd48a; background: rgba(248, 183, 77, .14); box-shadow: 0 10px 30px rgba(248, 183, 77, .1); }
.sw-es-bad .sw-es-ico { color: #ff9a9c; background: rgba(219, 59, 62, .14); box-shadow: 0 10px 30px rgba(219, 59, 62, .1); }
.sw-state .btn { height: 40px; padding: 0 16px; }
/* a message replacing placeholders the visitor sees: the one content step over them while they fade out (swap.js
   stateOver: held in its own place, then into the flow when the step is over) */
.sw-state.ps-in { z-index: 1; animation: ps-in 160ms var(--ease-out) both; }
.sw-soft { background: var(--surface-2); }
.sw-soft:hover { background: var(--surface-3); }
.sw-deposit-btn { height: 42px; }

/* item card tweaks inside the desk */
.sw-grid .icard { animation-duration: 420ms; }
.sw-grid .icard.ps-in { animation-duration: 160ms; } /* the content step over placeholders stays the shared 160 ms */
/* ...nor its cards rise again (a background re-sync renders them .sw-in from the start); the pop / shake of a pick
   below still play */
.icard.sw-in, .sw-state.sw-in, .sw-signin-card.sw-in, .sw-cart-empty.sw-in { animation: none; }
/* a faint light rim around plain art: black art (Adopt Me's Neon Black Scooter) keeps its outline on the dark card
   (art with a variant effect has its own glow, .fx-*) */
.sw-grid .icard .ic-art:not([class*="fx-"]) img, .sw-chip img { filter: drop-shadow(0 0 1px rgba(255, 255, 255, .5)) drop-shadow(0 0 8px rgba(255, 255, 255, .1)) drop-shadow(0 6px 12px rgba(0, 0, 0, .45)); }
.sw-grid .icard.is-disabled:hover { transform: none; box-shadow: inset 0 -2px 0 rgb(var(--rc)); }
.sw-grid .icard.is-disabled:hover .ic-art img { transform: none; }
.sw-grid .icard .ic-disabled { animation: fade-in 200ms var(--ease-out) both; }
.icard.st-over .ic-disabled span { color: #ffd48a; background: rgba(60, 42, 10, .92); }
.icard.st-listed .ic-disabled span { color: #e2d8ff; background: rgba(46, 30, 88, .92); }
.icard.st-wd .ic-disabled span { color: #b5e2ff; background: rgba(12, 44, 64, .92); }
.icard.st-novalue .ic-disabled span { color: rgba(255, 255, 255, .65); }
.sw-val { display: inline-flex; align-items: center; gap: 5px; min-width: 0; font-size: 13px; font-weight: 700; white-space: nowrap; }
.sw-val .vicon { width: 12px; height: 12px; vertical-align: 0; }
.sw-val-none { color: rgba(255, 255, 255, .35); }
.icard.sw-pop { animation: sw-pop 420ms var(--ease-out-quart); }
@keyframes sw-pop { 0% { transform: scale(.93); } 55% { transform: scale(1.035); } 100% { transform: scale(1); } }
.icard.sw-shake { animation: sw-shake 380ms var(--ease-out); }
@keyframes sw-shake { 20%, 60% { transform: translateX(-4px); } 40%, 80% { transform: translateX(4px); } }
.icard.selected .ic-art::before { background: radial-gradient(circle, rgba(139, 92, 246, .35), transparent 70%); }
/* keyboard focus (allowed exception): shell's .icard shadow would otherwise hide the global ring */
.sw-grid .icard:focus-visible { box-shadow: var(--ring-focus), inset 0 -2px 0 rgb(var(--rc)); }
.sw-grid .icard.selected:focus-visible { box-shadow: var(--ring-focus), inset 0 0 0 2px var(--accent), inset 0 -2px 0 rgb(var(--rc)); }
.sw-chip:focus-visible { box-shadow: var(--ring-focus), inset 0 -2px 0 rgb(var(--rc)); }

/* stock stepper (− n +) on selected stock cards */
.sw-step {
  position: absolute; left: 50%; bottom: 2px; z-index: 6;
  display: flex; align-items: center; gap: 2px; padding: 3px;
  border-radius: 999px; background: rgba(12, 14, 21, .95);
  box-shadow: 0 6px 16px rgba(0, 0, 0, .5), 0 0 16px rgba(139, 92, 246, .22);
  visibility: hidden; opacity: 0; pointer-events: none; transform: translate(-50%, 8px) scale(.8);
  transition: opacity 180ms var(--ease-out), transform 260ms var(--ease-out-quart), visibility 0s linear 260ms;
}
.icard.sw-has-n .sw-step { visibility: visible; opacity: 1; pointer-events: auto; transform: translate(-50%, 0); transition: opacity 180ms var(--ease-out), transform 260ms var(--ease-out-quart), visibility 0s; }
.sw-step button { position: relative; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; color: #fff; }
.sw-step button::before { content: ''; position: absolute; inset: 2px; z-index: -1; border-radius: 50%; background: rgba(255, 255, 255, .1); transition: background-color 150ms, transform 150ms; }
.sw-step button:hover::before { background: var(--accent); }
.sw-step button:active::before { transform: scale(.88); }
.sw-step { isolation: isolate; }
.sw-step b { min-width: 18px; text-align: center; font-size: 12px; font-weight: 800; font-variant-numeric: tabular-nums; }
.icard.sw-maxed .sw-step button[data-d="1"] { opacity: .35; }

/* ---------------------------------------------------------------- sign-in gate (static, no mascot) */
.sw-signin { flex: 1; position: relative; min-height: 380px; display: grid; place-items: center; overflow: hidden; border-radius: 14px; }
.sw-signin-skel { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); grid-auto-rows: max-content; gap: 8px; align-content: start; opacity: .55; filter: blur(5px) saturate(.8); pointer-events: none; -webkit-mask-image: linear-gradient(to bottom, #000 25%, transparent 92%); mask-image: linear-gradient(to bottom, #000 25%, transparent 92%); }
.sw-signin-skel .skc::after { animation: none; }
.sw-ghost { --rc: 139, 92, 246; position: relative; aspect-ratio: 1 / 1.3; border-radius: 12px; overflow: hidden; background: linear-gradient(180deg, #121622 0%, #0e1119 55%, rgba(var(--rc), .14) 100%); }
.sw-ghost img { position: absolute; left: 14%; top: 8%; width: 72%; height: 58%; object-fit: contain; }
.sw-ghost i { position: absolute; left: 10%; height: 7px; border-radius: 4px; background: rgba(255, 255, 255, .14); }
.sw-ghost i:nth-of-type(1) { bottom: 22%; width: 66%; }
.sw-ghost i:nth-of-type(2) { bottom: 10%; width: 40%; background: rgba(248, 183, 77, .3); }
.sw-signin-card { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; width: min(400px, 100%); padding: 26px 24px 22px; border-radius: 22px; text-align: center; background: rgba(14, 17, 24, .88); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); box-shadow: var(--shadow-pop), 0 0 60px rgba(139, 92, 246, .1); animation: slide-fade-in 420ms var(--ease-out) 80ms backwards; }
.sw-signin-card h3 { font-size: 19px; font-weight: 800; margin: 4px 0 8px; }
.sw-signin-card p { font-size: 13.5px; font-weight: 400; color: rgba(255, 255, 255, .62); max-width: 330px; margin: 0 auto 16px; line-height: 1.6; }
.sw-signin-btn { width: 100%; }
.sw-signin-fine { display: block; margin-top: 10px; font-size: 11.5px; color: var(--muted); }

/* ---------------------------------------------------------------- control column */
.sw-controls { display: flex; flex-direction: column; gap: 10px; min-height: 0; padding: 0; overflow: hidden; }
.sw-games { position: relative; flex: none; display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 4px; border-radius: 16px; background: var(--surface-1); box-shadow: var(--shadow-card); }
.sw-gt { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; height: 56px; border-radius: 12px; font-size: 12px; font-weight: 700; color: rgba(255, 255, 255, .55); transition: color 200ms var(--ease-out), background-color 200ms; }
.sw-gt img { width: 22px; height: 22px; opacity: .6; transition: opacity 200ms, transform 300ms var(--ease-out-quart); }
.sw-gt:hover { color: #fff; }
.sw-gt:not(.on):hover { background: rgba(255, 255, 255, .04); }
.sw-gt:hover img { opacity: .95; transform: translateY(-2px) rotate(-8deg) scale(1.08); }
.sw-gt:active { transform: scale(.96); }
.sw-gt.on { color: #fff; }
.sw-gt.on img { opacity: 1; }
/* a game that isn't live (staff console → Controls): ONE small "Soon" / "Paused" capsule, the game tabs' own marker on
   every page (app.css game states: the count capsule's size and neutral tone, the selected tab's lighter one; no border,
   no animation) — here in the icon's place (the deposit sheet's tiles do the same: the names stay in line and the
   capsule never covers the art), beside the name on tablets, a 6px dot in the corner on phones */
.sw-gt span { white-space: nowrap; }
.sw-gt em { flex: none; font-style: normal; font-size: 9.5px; font-weight: 800; letter-spacing: .05em; line-height: 18px; text-transform: uppercase; padding: 0 7px; border-radius: 999px; color: rgba(255, 255, 255, .7); background: rgba(255, 255, 255, .08); }
.sw-gt.on em { color: #fff; background: rgba(255, 255, 255, .22); }
@media (min-width: 900.02px) {
  .sw-gt em { order: -1; margin: 2px 0; }
  .sw-gt:has(> em:not([hidden])) > img { display: none; }
}
.sw-gt-pill { position: absolute; z-index: 0; top: 4px; bottom: 4px; left: 4px; width: calc((100% - 16px) / 3); border-radius: 12px; background: var(--grad-accent); box-shadow: 0 6px 22px rgba(139, 92, 246, .4); transform: translateX(calc(var(--gi, 0) * (100% + 4px))); transition: transform 460ms var(--ease-out-fluid); }

.sw-seg { display: none; }

/* the one call to action (shine only while it reads "Send swap offer") */
.sw-cta-wrap { flex: none; }
.sw-cta { height: 52px; border-radius: 15px; font-size: 15.5px; font-weight: 700; gap: 10px; box-shadow: 0 8px 26px rgba(139, 92, 246, .38); }
.sw-cta .sw-cta-ico { flex: none; transition: transform 300ms var(--ease-out-quart); }
.sw-cta:hover:not(:disabled) .sw-cta-ico { transform: rotate(180deg); }
.sw-cta[data-state="signin"]:hover .sw-cta-ico { transform: translateX(2px) scale(1.08); }
.sw-cta:disabled { opacity: 1; background: var(--surface-2); background-image: none; box-shadow: none; color: rgba(255, 255, 255, .42); filter: none; }
.sw-cta-label { display: inline-block; }
/* The desktop button keeps the painted sweep (background-position on the 250% gradient, under the label: app.css's
   sweep before it moved to the compositor). As a composited layer it turned the text painted after it — the summary
   and the whole "You get" column — from subpixel to greyscale antialiasing on 1x screens. The phone button
   (#sw-cta-m, no subpixel text on phones) keeps the compositor sweep. */
.sw-cta-wrap .btn-shine > .glare { z-index: -1; }
.sw-cta-wrap .btn-shine > .glare::after { inset: 0; width: auto; height: auto; background-size: 250% 250%; background-position: -100% -100%; transform: none; animation-name: glare-sweep; will-change: auto; }
.sw-swapin { animation: sw-label-in 320ms var(--ease-out-quart); }
@keyframes sw-label-in { from { opacity: 0; transform: translateY(7px); } to { opacity: 1; transform: none; } }

.sw-sheet { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
/* a session cookie but no remembered account, /api/me on its way (swap.js acctWait): like the header's account slot,
   the summary + filters column waits unseen instead of painting the signed-out desk first (phones: the swap bar's
   content, below); shown after 2.5 s regardless (late-show, app.css) */
@media (min-width: 900.02px) { .sw-screen.sw-acct-wait .sw-sheet { visibility: hidden; animation: late-show 0s 2.5s forwards; } }
.sw-screen.sw-acct-wait .sw-dep-link { visibility: hidden; animation: late-show 0s 2.5s forwards; }
.sw-sheet-head { display: none; }
.sw-sheet-scroll { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; display: flex; flex-direction: column; gap: 10px; padding-bottom: 2px; }
/* the open Filters card scrolls inside the column: the cut edge fades (swap.js edgeFade), no sliced text line */
.sw-sheet-scroll.fade-b { -webkit-mask-image: linear-gradient(#000 calc(100% - 28px), transparent); mask-image: linear-gradient(#000 calc(100% - 28px), transparent); }
.sw-sheet-scroll.fade-t { -webkit-mask-image: linear-gradient(transparent, #000 24px); mask-image: linear-gradient(transparent, #000 24px); }
.sw-sheet-scroll.fade-t.fade-b { -webkit-mask-image: linear-gradient(transparent, #000 24px, #000 calc(100% - 28px), transparent); mask-image: linear-gradient(transparent, #000 24px, #000 calc(100% - 28px), transparent); }
.sw-filters { flex: 1 0 auto; display: flex; flex-direction: column; gap: 10px; }

.sw-card { flex: none; padding: 0 14px; border-radius: 16px; background: var(--surface-1); box-shadow: var(--shadow-card); }
.sw-card .cacc-trigger { min-height: 44px; padding: 10px 0; font-size: 13px; font-weight: 700; color: rgba(255, 255, 255, .88); }
.sw-card .cacc-content { display: flex; flex-direction: column; gap: 8px; padding: 0 0 14px; }

/* summary: two totals, a coverage bar, ONE status line, swap credit (only when you have some), the button */
.sw-sum { display: flex; flex-direction: column; gap: 10px; padding: 14px; }
.sw-sum-top { display: flex; align-items: center; gap: 8px; }
.sw-sum-side { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.sw-sum-side > span { font-size: 11.5px; font-weight: 600; color: var(--muted); }
.sw-sum-side b { display: inline-flex; align-items: center; gap: 6px; min-width: 0; font-size: 19px; font-weight: 800; line-height: 1.2; color: #fff; font-variant-numeric: tabular-nums; }
.sw-sum-side b .vicon { width: 14px; height: 14px; vertical-align: 0; }
.sw-sum-r { align-items: flex-end; text-align: right; }
.sw-sum-ico { flex: none; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 10px; color: var(--accent-hover); background: rgba(139, 92, 246, .14); }
.sw-meter { height: 6px; border-radius: 6px; background: rgba(255, 255, 255, .07); overflow: hidden; }
.sw-meter[hidden] { display: none; }
.sw-meter.is-idle { visibility: hidden; } /* signed in, nothing picked: the bar's place is kept, nothing drawn */
.sw-meter i { display: block; height: 100%; width: 0; border-radius: inherit; transition: width 420ms var(--ease-out-quart), background-color 300ms; }
.sw-meter[data-sign="pos"] i { background: linear-gradient(90deg, #22c55e, #3ee48b); box-shadow: 0 0 10px rgba(62, 228, 139, .45); }
.sw-meter[data-sign="bad"] i { background: linear-gradient(90deg, #db3b3e, #ff8587); box-shadow: 0 0 10px rgba(255, 133, 135, .4); }
.sw-net { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 53px; padding: 9px 12px; border-radius: 12px; background: var(--surface-2); transition: background-color 300ms var(--ease-out); } /* two lines of label reserved: the hint, "Leftover → … swap credit" or a shortfall never grow the card */
.sw-net.flash { animation: verdict-pop 340ms var(--ease-out-quart); }
/* the label box fills the reserved two lines; the words (a fresh inner span per status, swap.js) are centred in it,
   so a one-line status replacing a two-line hint moves no box */
.sw-net-label { align-self: stretch; display: flex; align-items: center; min-width: 0; font-size: 12.5px; font-weight: 600; line-height: 1.4; color: rgba(255, 255, 255, .6); text-wrap: balance; }
.sw-net-label > span { min-width: 0; }
.sw-net-label .sw-v { color: #fff; font-weight: 700; }
.sw-net-label .sw-v .vicon { width: 11px; height: 11px; }
.sw-net-val { flex: none; display: inline-flex; align-items: center; gap: 5px; font-size: 16px; font-weight: 800; font-variant-numeric: tabular-nums; }
.sw-net-val[hidden] { display: none; }
.sw-net-val .vicon { width: 12px; height: 12px; vertical-align: 0; }
.sw-net[data-sign="zero"] .sw-net-label { text-align: center; flex: 1; justify-content: center; }
.sw-net[data-sign="pos"] { background: rgba(5, 202, 98, .11); }
.sw-net[data-sign="pos"] .sw-net-label, .sw-net[data-sign="pos"] .sw-net-val { color: #3ee48b; }
.sw-net[data-sign="neg"] { background: rgba(139, 92, 246, .12); }
.sw-net[data-sign="neg"] .sw-net-label, .sw-net[data-sign="neg"] .sw-net-val { color: #cbbdff; }
.sw-net[data-sign="bad"] { background: rgba(219, 59, 62, .11); }
.sw-net[data-sign="bad"] .sw-net-label, .sw-net[data-sign="bad"] .sw-net-val { color: #ff9a9c; }
.sw-net[data-sign="warn"] { background: rgba(248, 183, 77, .1); }
.sw-net[data-sign="warn"] .sw-net-label { color: #ffd48a; }
.sw-credit { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 0 4px; font-size: 12px; font-weight: 600; color: var(--muted); cursor: help; }
.sw-credit[hidden] { display: none; }
.sw-credit b { display: inline-flex; align-items: center; gap: 5px; color: #fff; font-variant-numeric: tabular-nums; }
.sw-credit b .vicon { width: 11px; height: 11px; vertical-align: 0; }
/* "Checking live values…": its slot is always kept, tucked into the card's bottom padding (the line coming and going
   never moves the Filters card below) */
.sw-qstate { display: flex; align-items: center; justify-content: center; gap: 6px; height: 14px; margin: -4px 0 -8px; font-size: 11px; font-weight: 500; line-height: 14px; color: rgba(255, 255, 255, .42); visibility: hidden; opacity: 0; transition: opacity 160ms var(--ease-out), visibility 160ms; }
.sw-qstate.is-on { visibility: visible; opacity: 1; }
.sw-qstate:not(.is-on) .sw-qdot { animation: none; }
.sw-qdot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent-hover); animation: pulse 1s var(--ease-in-out) infinite; } /* status indicator */

/* filters: one card; sections inside */
.sw-ftitle { display: inline-flex; align-items: center; gap: 8px; }
.sw-ftitle .sw-fcount { display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px; font-style: normal; font-size: 11px; font-weight: 800; color: #fff; background: var(--grad-accent); }
.sw-ftitle .sw-fcount[hidden] { display: none; }
.sw-fsec { display: flex; flex-direction: column; gap: 8px; }
.sw-fsec[hidden] { display: none; }
.sw-fsec + .sw-fsec { padding-top: 12px; border-top: 1px solid var(--hairline); }
.sw-fl { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: rgba(255, 255, 255, .45); }
.sw-reset { height: 40px; margin-top: 4px; border-radius: 12px; background: var(--surface-2); }
.sw-reset:hover { background: var(--surface-3); }

/* value range */
.sw-card .price-pair { gap: 8px; }
.sw-card .numfield { height: 38px; padding: 0 10px; border-radius: 11px; gap: 7px; background: var(--surface-2); }
.sw-card .numfield:focus-within { background: var(--surface-3); }
.sw-card .numfield .vicon { width: 12px; height: 12px; vertical-align: 0; }
.sw-card .numfield input { font-size: 13px; color: #fff; }
.sw-card .numfield.bad { background: rgba(219, 59, 62, .18); animation: shake 360ms; }
.sw-card .numfield.bad input { color: #ffb3b4; }
.sw-range { position: relative; height: 32px; margin: 0 8px; cursor: pointer; touch-action: pan-y; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent; }
.sw-range.dragging { cursor: grabbing; }
/* the end thumbs sit flush with the box: its hit area reaches into the 8px side margins, so a finger on a thumb's ring still grabs it */
.sw-range::before { content: ""; position: absolute; top: 0; bottom: 0; left: -8px; right: -8px; }
.sw-range-track { position: absolute; left: 9px; right: 9px; top: 50%; height: 4px; margin-top: -2px; border-radius: 4px; background: rgba(255, 255, 255, .08); }
.sw-range-fill { position: absolute; top: 0; bottom: 0; left: 0; right: 0; border-radius: 4px; background: var(--grad-accent); box-shadow: 0 0 10px rgba(139, 92, 246, .55); }
/* the thumbs are drawn by the two native inputs (focus + keyboard); pointer drags go to .sw-range (swap.js bindRange) */
.sw-range input[type="range"] { position: absolute; left: 0; top: 50%; width: 100%; height: 26px; margin: -13px 0 0; padding: 0; background: none; pointer-events: none; -webkit-appearance: none; appearance: none; }
.sw-range input[type="range"]:focus-visible { box-shadow: none; z-index: 1; }
.sw-range input[type="range"]::-webkit-slider-runnable-track { height: 26px; background: none; }
.sw-range input[type="range"]::-moz-range-track { height: 26px; background: none; }
.sw-range input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; pointer-events: none; width: 18px; height: 18px; margin-top: 4px; border-radius: 50%; background: #fff; box-shadow: 0 0 0 4px rgba(139, 92, 246, .35), 0 2px 10px rgba(0, 0, 0, .5); transition: transform 150ms var(--ease-out-quad), box-shadow 150ms; }
.sw-range input[type="range"]::-moz-range-thumb { pointer-events: none; width: 18px; height: 18px; border: 0; border-radius: 50%; background: #fff; box-shadow: 0 0 0 4px rgba(139, 92, 246, .35), 0 2px 10px rgba(0, 0, 0, .5); transition: transform 150ms var(--ease-out-quad), box-shadow 150ms; }
.sw-range input.near::-webkit-slider-thumb { transform: scale(1.12); }
.sw-range input.near::-moz-range-thumb { transform: scale(1.12); }
.sw-range input.drag::-webkit-slider-thumb { transform: scale(1.2); box-shadow: 0 0 0 6px rgba(139, 92, 246, .4), 0 2px 10px rgba(0, 0, 0, .5); }
.sw-range input.drag::-moz-range-thumb { transform: scale(1.2); box-shadow: 0 0 0 6px rgba(139, 92, 246, .4), 0 2px 10px rgba(0, 0, 0, .5); }
/* keyboard focus ring (not after a press: .ptr) */
.sw-range:not(.ptr) input[type="range"]:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px var(--accent), 0 2px 10px rgba(0, 0, 0, .5); }
.sw-range:not(.ptr) input[type="range"]:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 4px var(--accent), 0 2px 10px rgba(0, 0, 0, .5); }
.sw-card .filter-hint { font-size: 11px; color: rgba(255, 255, 255, .36); }

/* rarity + category checklists (real checkboxes, custom-styled globally) */
.sw-checks { display: flex; flex-direction: column; gap: 2px; }
/* rows are updated in place (swap.js syncChecks): no entrance animation, so a game switch doesn't replay one */
.sw-check { display: flex; align-items: center; gap: 9px; min-height: 36px; padding: 0 8px; border-radius: 10px; cursor: pointer; transition: background-color 150ms var(--ease-smooth); }
.sw-check:hover { background: rgba(255, 255, 255, .035); }
.sw-check.on { background: rgba(var(--rc), .08); }
.sw-check-sw { width: 10px; height: 10px; flex: none; border-radius: 3px; background: linear-gradient(135deg, rgb(var(--rc)), rgba(var(--rc), .85)); box-shadow: 0 0 8px rgba(var(--rc), .3); }
.sw-check-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12.5px; font-weight: 500; color: rgba(255, 255, 255, .6); transition: color 150ms; }
.sw-check:hover .sw-check-name, .sw-check.on .sw-check-name { color: #fff; }
.sw-check-n { flex: none; font-size: 10.5px; color: rgba(255, 255, 255, .32); font-variant-numeric: tabular-nums; }
.sw-check input { margin-left: auto; }
.sw-fempty { padding: 4px 2px 2px; }
/* a game switch in progress: the previous game's filters stay put (dimmed by swap.js) until the new ones are ready */
.sw-fbusy .cacc-content { pointer-events: none; }

.sw-foot { display: none; }
.reset-filters.on { color: #fff; background: rgba(139, 92, 246, .18); }
.reset-filters:active { transform: scale(.97); }
.sw-sheet-done { display: none; margin-top: 8px; }

.sw-mbar, .sw-backdrop { display: none; }

/* ---------------------------------------------------------------- how it works */
.sw-seo { position: relative; padding: 76px 0 84px; background: linear-gradient(180deg, var(--surface-1), var(--background)); overflow: hidden; }
/* the band fades into the canvas and its own bottom padding is the gap: no bare 90px strip between two tone seams */
body.swap-body .site-footer { margin-top: 0; }
/* the footer's column (.container: the root --container / --gutter), so the band's text lines up with the footer */
.sw-seo .seo-inner { width: min(var(--container), calc(100% - 2 * var(--gutter))); max-width: none; gap: 28px; }
/* the head is the title alone (no kicker pill, no intro: owner, Oct 17 — less text) */
.sw-seo-head { text-align: center; max-width: 680px; margin: 0 auto; }
.sw-seo-head h2 { font-size: clamp(24px, 3vw, 34px); font-weight: 800; margin: 0; letter-spacing: -.01em; text-wrap: balance; }
.sw-seo h3 { text-wrap: balance; }
.sw-seo p { text-wrap: pretty; }
/* four one-line steps: the number tile beside a title and one short line */
.sw-steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.sw-steps li { position: relative; display: flex; align-items: center; gap: 14px; padding: 18px 18px; border-radius: 18px; background: var(--surface-2); box-shadow: var(--shadow-card); transition: transform 300ms var(--ease-out-quart), box-shadow 300ms var(--ease-out); overflow: hidden; }
.sw-steps li > div { min-width: 0; }
.sw-steps li::after { content: ''; position: absolute; right: -40px; top: -40px; width: 120px; height: 120px; border-radius: 50%; background: radial-gradient(circle, rgba(139, 92, 246, .16), transparent 70%); transition: transform 400ms var(--ease-out-quart); }
.sw-steps li:hover { transform: translateY(-4px); box-shadow: 0 18px 40px rgba(0, 0, 0, .4); }
.sw-steps li:hover::after { transform: scale(1.4); }
.sw-step-n { flex: none; width: 34px; height: 34px; border-radius: 11px; display: grid; place-items: center; font-size: 15px; font-weight: 800; color: #fff; background: var(--grad-accent); box-shadow: 0 6px 18px rgba(139, 92, 246, .42); }
.sw-steps h3 { font-size: 15px; margin-bottom: 2px; }
.sw-steps p { margin: 0; font-size: 13.5px; font-weight: 400; line-height: 1.5; color: var(--muted); }
/* one link to the FAQ's swap-credit answer replaces the two explainer columns */
.sw-seo-more { margin: -10px 0 0; text-align: center; font-size: 14px; }
.sw-seo-more a { display: inline-flex; align-items: center; min-height: 40px; padding: 0 6px; color: var(--accent-hover); font-weight: 600; }
.sw-seo-more a:hover { text-decoration: underline; }
.sw-cta-band { position: relative; display: flex; align-items: center; gap: 20px; min-height: 150px; padding: 28px 230px 28px 30px; border-radius: 22px; overflow: hidden; background: radial-gradient(60% 140% at 85% 100%, rgba(139, 92, 246, .3), transparent 70%), linear-gradient(120deg, #141026, #0f0d1c); box-shadow: var(--shadow-card); }
.sw-cta-copy { flex: 0 1 auto; min-width: 0; } /* the button sits right after the copy, not adrift mid-card */
.sw-cta-copy h3 { font-size: 22px; font-weight: 800; margin-bottom: 6px; }
.sw-cta-copy p { margin: 0; font-size: 14px; color: rgba(255, 255, 255, .65); }
.sw-cta-band .btn { flex: none; }
.sw-cta-mascot { position: absolute; right: 26px; bottom: -34px; width: auto; height: 210px; pointer-events: none; filter: drop-shadow(0 10px 30px rgba(139, 92, 246, .35)); } /* static (owner rule) */
@media (max-width: 1180px) { .sw-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); } } /* 4 x ~215px cards were cramped up to here */

/* ---------------------------------------------------------------- confirm modal */
.sw-confirm .modal-head { margin-bottom: 2px; }
.sw-cf-game { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px 0 8px; margin: 0 0 12px; border-radius: 999px; font-size: 12px; font-weight: 600; color: rgba(255, 255, 255, .7); background: var(--surface-2); }
.sw-cf-cols { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); gap: 10px; align-items: stretch; }
.sw-cf-col { min-width: 0; padding: 12px; border-radius: 16px; background: var(--surface-2); }
.sw-cf-col h4 { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: rgba(255, 255, 255, .5); }
.sw-cf-col h4 > span::before { content: ''; display: inline-block; width: 7px; height: 7px; margin-right: 7px; border-radius: 50%; vertical-align: 1px; background: var(--accent); box-shadow: 0 0 8px rgba(139, 92, 246, .7); }
.sw-cf-col.get h4 > span::before { background: var(--success); box-shadow: 0 0 8px rgba(5, 202, 98, .6); }
.sw-cf-col h4 b { display: inline-flex; align-items: center; gap: 5px; font-size: 15px; font-weight: 800; letter-spacing: 0; text-transform: none; color: #fff; }
.sw-cf-col ul { list-style: none; margin: 0; padding: 0 2px 0 0; display: grid; gap: 6px; max-height: 280px; overflow-y: auto; }
.sw-cf-col li { display: flex; align-items: center; gap: 10px; min-width: 0; padding: 6px 8px 6px 6px; border-radius: 12px; background: rgba(255, 255, 255, .035); animation: slide-fade-in 320ms var(--ease-out) backwards; }
.sw-cf-col li:nth-child(2) { animation-delay: 50ms; } .sw-cf-col li:nth-child(3) { animation-delay: 100ms; } .sw-cf-col li:nth-child(4) { animation-delay: 150ms; } .sw-cf-col li:nth-child(n+5) { animation-delay: 200ms; }
.sw-cf-thumb { width: 42px; height: 42px; flex: none; display: grid; place-items: center; border-radius: 11px; background: radial-gradient(circle at 50% 45%, rgba(var(--rc), .3), rgba(var(--rc), .07) 70%); }
.sw-cf-thumb img { width: 34px; height: 34px; object-fit: contain; }
.sw-cf-name { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.sw-cf-name b { font-size: 13px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-cf-sub { display: flex; align-items: center; gap: 5px; min-width: 0; }
.sw-cf-name small { min-width: 0; font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-cf-badges { display: flex; gap: 3px; flex: none; }
.sw-cf-badges:empty { display: none; }
.sw-cf-badges .vb { min-width: 16px; height: 16px; padding: 0 5px; font-size: 8.5px; }
.sw-cf-n { flex: none; font-style: normal; font-size: 11px; font-weight: 800; padding: 2px 7px; border-radius: 999px; color: #d6c9ff; background: rgba(139, 92, 246, .2); }
.sw-cf-price { flex: none; display: inline-flex; align-items: center; gap: 4px; font-size: 13px; font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }
.sw-cf-none { margin: 8px 0 4px; font-size: 13px; color: var(--muted); }
.sw-cf-mid { display: grid; place-items: center; }
.sw-cf-mid svg { width: 40px; height: 40px; padding: 10px; border-radius: 50%; color: #fff; background: var(--grad-accent); box-shadow: 0 6px 20px rgba(139, 92, 246, .45); animation: sw-spin-in 600ms var(--ease-out-quart) 200ms backwards; }
@keyframes sw-spin-in { from { transform: rotate(-180deg) scale(.4); opacity: 0; } }
.sw-cf-net { display: flex; flex-direction: column; align-items: center; gap: 4px; margin-top: 12px; padding: 14px 16px; border-radius: 16px; text-align: center; background: var(--surface-2); }
.sw-cf-net.pos { background: rgba(5, 202, 98, .1); }
.sw-cf-net.neg { background: rgba(139, 92, 246, .12); }
.sw-cf-net-label { font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: rgba(255, 255, 255, .5); }
.sw-cf-settle { display: inline-flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 4px; font-size: 18px; font-weight: 800; }
.sw-cf-settle .vicon { width: 14px; height: 14px; }
.sw-cf-net.pos .sw-cf-settle { color: #3ee48b; }
.sw-cf-net.neg .sw-cf-settle { color: #d6c9ff; }
.sw-cf-net small { font-size: 12px; color: var(--muted); }
.sw-cf-credit { display: inline-flex; align-items: center; gap: 8px; margin-top: 2px; font-size: 13px; color: rgba(255, 255, 255, .6); }
.sw-cf-credit strong { color: #fff; font-weight: 800; }
.sw-cf-arrow { opacity: .6; }
.sw-cf-note { margin: 12px 0 0; text-align: center; font-size: 12px; font-weight: 500; line-height: 1.55; color: var(--muted); }
.sw-cf-actions .btn { min-width: 120px; }
.sw-cf-go { min-width: 170px; }

/* ---------------------------------------------------------------- processing / success / failure */
.sw-proc .proc-head { margin-bottom: 14px; }
.sw-proc-out:empty { display: none; }
.sw-proc-out { margin-top: 10px; animation: slide-fade-in 300ms var(--ease-out) both; }
.sw-fail-mascot { width: 104px; margin: 0 auto 6px; filter: drop-shadow(0 10px 26px rgba(139, 92, 246, .3)); }
.sw-fail-title { justify-content: center; margin-bottom: 12px; font-size: 20px; animation: slide-fade-in 320ms var(--ease-out) 80ms backwards; }
.sw-proc-failed .proc-head, .sw-proc-failed .proc-steps { display: none; }
.sw-proc-failed .sw-proc-out { margin-top: 0; }
.sw-proc-failed .proc-error { animation: slide-fade-in 320ms var(--ease-out) 140ms backwards; }
.sw-proc-out .proc-error .sw-v, .sw-proc-out .proc-line .sw-v { color: #fff; font-weight: 800; }
.sw-proc-out .proc-line { font-size: 13px; }
.sw-muted { color: var(--muted) !important; font-size: 12px !important; }
.sw-stale { display: grid; gap: 0; margin: 0 0 10px; padding: 4px 12px; border-radius: 12px; background: var(--surface-2); text-align: left; }
.sw-stale-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 7px 0; font-size: 12.5px; color: var(--muted); }
.sw-stale-row + .sw-stale-row { border-top: 1px solid var(--hairline); }
.sw-stale-row > span:last-child { display: inline-flex; align-items: center; gap: 6px; }
.sw-stale-row b { color: #fff; }
.sw-fail-actions { justify-content: center; }
.sw-fail-actions .btn { min-width: 130px; }
.modal.sw-proc-done { overflow: hidden; }
.sw-done { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; }
.sw-done > * { animation: slide-fade-in 380ms var(--ease-out) backwards; }
.sw-done > :nth-child(3) { animation-delay: 80ms; } .sw-done > :nth-child(4) { animation-delay: 120ms; } .sw-done > :nth-child(5) { animation-delay: 160ms; }
.sw-done > :nth-child(6) { animation-delay: 200ms; } .sw-done > :nth-child(7) { animation-delay: 240ms; } .sw-done > :nth-child(8) { animation-delay: 280ms; }
.sw-done > :nth-child(9) { animation-delay: 320ms; } .sw-done > :nth-child(10) { animation-delay: 360ms; }
.sw-done-mascot { width: 124px; margin: -6px 0 4px; filter: drop-shadow(0 12px 30px rgba(139, 92, 246, .4)); }
.sw-done-burst { position: absolute; left: 50%; top: 70px; width: 0; height: 0; animation: none !important; }
.sw-done-burst i { position: absolute; left: -4px; top: -4px; width: 8px; height: 8px; border-radius: 2px; background: #a78bfa; opacity: 0; animation: sw-burst 1000ms var(--ease-out) var(--d, 0ms) both; }
.sw-done-burst i:nth-child(3n + 2) { background: #3ee48b; border-radius: 50%; }
.sw-done-burst i:nth-child(3n) { background: #f8c46d; width: 6px; height: 10px; }
@keyframes sw-burst { 0% { opacity: 1; transform: rotate(var(--a)) translateY(0) scale(.4); } 70% { opacity: 1; } 100% { opacity: 0; transform: rotate(var(--a)) translateY(-130px) scale(1) rotate(200deg); } }
.sw-done-title { font-size: 25px; font-weight: 800; }
.sw-done-sub { margin: 2px 0 0; font-size: 12px; font-weight: 500; color: var(--muted); }
.sw-done-label { margin: 16px 0 0; font-size: 13px; font-weight: 700; color: rgba(255, 255, 255, .8); }
.sw-done-items { margin: 8px 0 6px; }
.sw-done-more { display: grid; place-items: center; width: 52px; height: 52px; border-radius: var(--radius-md); font-size: 13px; font-weight: 800; color: #d6c9ff; background: rgba(139, 92, 246, .16); }
.sw-done-vals:empty { display: none; }
.sw-done-vals { display: flex; gap: 14px; margin: 0; font-size: 12.5px; color: var(--muted); }
.sw-done-vals > span { display: inline-flex; align-items: center; gap: 5px; }
.sw-done-vals .sw-v { color: #fff; font-weight: 700; }
.sw-done-delta { display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 220px; margin: 12px 0 4px; padding: 12px 20px; border-radius: 16px; background: var(--surface-2); }
.sw-done-delta b { display: inline-flex; align-items: center; gap: 4px; font-size: 26px; font-weight: 800; font-variant-numeric: tabular-nums; }
.sw-done-delta b .vicon { width: 18px; height: 18px; }
.sw-done-delta small { font-size: 12px; color: var(--muted); }
.sw-done-delta.pos { background: rgba(5, 202, 98, .1); }
.sw-done-delta.pos b { color: #3ee48b; }
.sw-done-delta.neg { background: rgba(139, 92, 246, .12); }
.sw-done-delta.neg b { color: #fff; }
.sw-done-bal { display: inline-flex; align-items: center; gap: 6px; margin: 4px 0 0; font-size: 13px; color: var(--muted); }
.sw-done-bal .sw-v { color: #fff; font-weight: 700; }
.sw-done-actions { width: 100%; justify-content: center; margin-top: 18px; }
.sw-done-actions .btn { flex: 1; max-width: 190px; }

/* ===========================================================================
   PHONES (<= 900px)
   =========================================================================== */
@media (max-width: 900px) {
  body.swap-body { padding-bottom: calc(146px + env(safe-area-inset-bottom)); }
  /* no stacking contexts here: the sheet/backdrop must layer against the header + tab bar. At least a screen tall: the
     band below starts under the fold, so your items landing (12 placeholder cards -> "No MM2 items yet") never pull it
     up into view (rule 17) */
  .sw-screen { height: auto; min-height: 100dvh; overflow: visible; padding-top: calc(var(--header-h) + 4px); isolation: auto; }
  .sw-layout { display: flex; flex-direction: column; gap: 12px; padding: 4px var(--gutter) 20px; z-index: auto; }
  .sw-controls { display: contents; }
  .sw-games { order: 0; }
  .sw-gt { flex-direction: row; gap: 8px; height: 44px; font-size: 13px; }
  .sw-gt img { width: 20px; height: 20px; }
  .sw-gt em { position: static; margin-left: -2px; }

  .sw-seg { order: 1; display: grid; position: relative; grid-template-columns: 1fr 1fr; padding: 4px; border-radius: 14px; background: var(--surface-1); box-shadow: var(--shadow-card); }
  .sw-seg button { position: relative; z-index: 1; height: 42px; border-radius: 10px; display: flex; align-items: center; justify-content: center; gap: 8px; font-size: 14px; font-weight: 700; color: rgba(255, 255, 255, .55); transition: color 250ms; }
  .sw-seg button.on { color: #fff; }
  .sw-seg em { min-width: 22px; height: 20px; padding: 0 6px; border-radius: 999px; display: grid; place-items: center; font-style: normal; font-size: 11px; font-weight: 800; background: rgba(255, 255, 255, .08); transition: background-color 250ms; }
  .sw-seg button.on em { background: rgba(255, 255, 255, .22); }
  .sw-seg em:empty { display: none; } /* a count only once something is picked ("Stock 0" read as an empty stock) */
  .sw-seg-pill { position: absolute; z-index: 0; top: 4px; bottom: 4px; left: 4px; width: calc(50% - 4px); border-radius: 10px; background: var(--grad-accent); box-shadow: 0 6px 18px rgba(139, 92, 246, .4); transition: transform 420ms var(--ease-out-fluid); }
  .sw-screen[data-view="get"] .sw-seg-pill { transform: translateX(100%); }

  .sw-panel { order: 2; display: none; min-height: 0; overflow: visible; border-radius: 18px; }
  .sw-screen[data-view="give"] #panel-give, .sw-screen[data-view="get"] #panel-get { display: flex; }
  .sw-phead { height: 58px; padding: 0 14px; }
  .sw-cart { height: 128px; margin: 0 10px; }
  .sw-chips { padding: 9px 10px; }
  .sw-chip { width: 86px; height: 110px; }
  .sw-tool { padding: 10px 10px 2px; }
  .sw-search, .sw-tool .csel-trigger { height: 40px; }           /* tap targets >= 40px */
  .sw-filter-btn { display: grid; }
  .sw-grid { overflow: visible; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 8px; padding: 8px 10px 12px; }
  .sw-state { min-height: 340px; }
  .sw-signin { min-height: 440px; }
  .sw-signin-skel { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); }
  .sw-signin-card { padding: 22px 18px 18px; }
  /* stepper: 40px hit boxes, the visible circles stay small */
  .sw-step { padding: 0 2px; gap: 0; height: 34px; }
  .sw-step button { width: 40px; height: 40px; margin: -3px 0; }
  .sw-step button::before { inset: 7px; }

  .sw-cta-wrap { display: none; }

  /* summary + filters become a bottom sheet */
  .sw-sheet {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 96; max-height: 88dvh;
    max-width: 560px; margin-inline: auto; /* tablets: a centred sheet, not checkboxes 680px from their labels */
    border-radius: 24px 24px 0 0; background: var(--surface-1);
    box-shadow: 0 -24px 60px rgba(0, 0, 0, .6);
    padding-bottom: env(safe-area-inset-bottom);
    transform: translateY(105%); visibility: hidden;
    transition: transform 380ms var(--ease-out-fluid), visibility 0s linear 380ms;
  }
  .sw-sheet.open { transform: none; visibility: visible; transition: transform 420ms var(--ease-out-fluid), visibility 0s; }
  .sw-sheet-head { display: flex; align-items: center; justify-content: space-between; position: relative; padding: 18px 16px 10px; flex: none; }
  .sw-sheet-head h3 { font-size: 18px; font-weight: 800; }
  .sw-sheet-head .modal-close { width: 40px; height: 40px; }
  .sw-sheet-grab { position: absolute; left: 50%; top: 7px; width: 40px; height: 4px; margin-left: -20px; border-radius: 4px; background: rgba(255, 255, 255, .16); }
  /* no bottom padding on the scroller: the sticky footer would stick 16px above the sheet's edge and rows would
     scroll through the gap under it — the footer carries that space itself */
  .sw-sheet-scroll { padding: 0 16px; scrollbar-width: none; overscroll-behavior: contain; }
  .sw-sheet-scroll.fade-b { -webkit-mask-image: none; mask-image: none; } /* the sticky footer is the bottom edge here */
  .sw-sheet-scroll.fade-t.fade-b { -webkit-mask-image: linear-gradient(transparent, #000 24px); mask-image: linear-gradient(transparent, #000 24px); }
  .sw-sheet-scroll::-webkit-scrollbar { display: none; }
  .sw-card { background: var(--surface-2); box-shadow: none; }
  .sw-card .numfield, .sw-net, .sw-cf-col { background: var(--surface-3); }
  .sw-card .numfield { height: 40px; }
  .sw-card .numfield input { height: 100%; } /* the field itself is the 40px tap target */
  .sw-check { min-height: 42px; }
  .sw-range { height: 40px; }
  .sw-sheet-done { display: flex; height: 44px; }
  .sw-foot { display: block; position: sticky; bottom: 0; z-index: 2; background: linear-gradient(to top, var(--surface-1) calc(100% - 14px), transparent); padding: 16px 0; }
  .sw-reset { height: 44px; background: var(--surface-3); }
  .sw-sheet[data-mode="filters"] #acc-summary { display: none; }
  .sw-sheet[data-mode="summary"] #acc-filters { display: none !important; }
  .sw-sheet[data-mode="filters"] #acc-filters > .cacc-trigger { display: none; }
  .sw-sheet[data-mode="filters"] #acc-filters .cacc-body { grid-template-rows: 1fr; }
  .sw-sheet[data-mode="filters"] #acc-filters .cacc-content { padding-top: 14px; }
  .sw-sheet[data-mode="summary"] .sw-sheet-done { margin-top: 0; }
  /* Swap details has no Filters card above the foot: its box (.sw-filters) is then the foot's only room, so it sticks
     to the sheet's bottom itself — a short window (a phone held sideways) never cuts "Back to items" in half */
  .sw-sheet[data-mode="summary"] .sw-filters { position: sticky; bottom: 0; z-index: 2; }
  .sw-backdrop { display: block; position: fixed; inset: 0; z-index: 95; background: rgba(3, 4, 8, .6); backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(5px); opacity: 0; transition: opacity 300ms var(--ease-out); }
  .sw-backdrop[hidden] { display: none !important; }
  .sw-backdrop.on { opacity: 1; }
  body.sw-sheet-open { overflow: hidden; }

  /* sticky swap bar above the tab bar: credit change + the CTA */
  .sw-mbar {
    display: flex; align-items: center; gap: 8px; position: fixed; z-index: 49;
    left: calc(10px + env(safe-area-inset-left)); right: calc(10px + env(safe-area-inset-right)); bottom: calc(56px + env(safe-area-inset-bottom) + 8px);
    padding: 6px; border-radius: 18px;
    background: rgba(18, 21, 30, .95); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    box-shadow: 0 14px 40px rgba(0, 0, 0, .6);
    animation: sw-bar-in 520ms var(--ease-out-quart) 200ms backwards;
    transition: box-shadow 300ms var(--ease-out);
  }
  .sw-mbar.has-picks { box-shadow: 0 14px 40px rgba(0, 0, 0, .6), 0 0 32px rgba(139, 92, 246, .2); }
  .sw-screen.sw-acct-wait .sw-mbar > * { visibility: hidden; animation: late-show 0s 2.5s forwards; }
  @keyframes sw-bar-in { from { opacity: 0; transform: translateY(24px); } }
  .sw-mbar-info { flex: 1; min-width: 0; min-height: 48px; display: flex; flex-direction: column; justify-content: center; align-items: flex-start; gap: 1px; padding: 4px 8px; border-radius: 12px; text-align: left; transition: background-color 150ms; }
  .sw-mbar-info:active { background: rgba(255, 255, 255, .05); }
  .sw-mbar-top { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 600; color: var(--muted); }
  .sw-mbar-top svg { color: var(--accent-hover); }
  .sw-mbar-row { display: flex; align-items: center; gap: 4px; min-width: 0; max-width: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 14px; font-weight: 700; color: rgba(255, 255, 255, .8); font-variant-numeric: tabular-nums; }
  .sw-mbar-row .sw-v { font-size: 16px; font-weight: 800; }
  .sw-mbar-row small { font-size: 11px; font-weight: 600; color: rgba(255, 255, 255, .5); }
  /* a state's words ("Pick items to swap", "Back shortly"): their own box, so a line longer than the bar ends in "…" —
     the row is a flex box, where text-overflow never shows (swap.js updateSummary) */
  .sw-mbar-row > .sw-mb-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  /* a quiet line (no swap can go through and the panel on screen already says when: swap.js panelSaysWhen) keeps its
     line box, so the counts above it never move between Your items and Stock */
  .sw-mbar-row:empty::before { content: '\a0'; }
  .sw-mbar-row[data-sign="pos"] { color: #3ee48b; }
  .sw-mbar-row[data-sign="neg"] { color: #d6c9ff; }
  .sw-mbar-row[data-sign="bad"] { color: #ff9a9c; }
  /* one width for every label ("Pick items" … "Send swap offer"): the bar doesn't reflow when the picks land */
  .sw-cta-m { width: 160px; flex: none; height: 48px; padding: 0 12px; border-radius: 14px; font-size: 14.5px; }

  .sw-seo { padding: 56px 0 60px; }
  .sw-seo .seo-inner { gap: 28px; }
  .sw-cta-band { padding: 24px 190px 24px 24px; }
  .sw-cta-mascot { right: 16px; height: 180px; bottom: -30px; }
}
/* large phones / small tablets: the mascot keeps its side, the button goes under the copy (beside it the copy had
   ~150px at 561: a 3-line heading, a 4-line text and the mascot past the band's bottom edge) */
@media (min-width: 561px) and (max-width: 767px) {
  .sw-cta-band { flex-direction: column; align-items: flex-start; gap: 16px; }
}
@media (max-width: 560px) {
  /* a game's "Soon" / "Paused" capsule is a 6px dot in the tab's corner here, as on every page's phone tabs (it never
     takes room from the name: "Adopt Me" stays on one line at 320); the tab keeps a title */
  .sw-gt em { position: absolute; top: 6px; right: 5px; width: 6px; height: 6px; margin: 0; padding: 0; font-size: 0; background: rgba(255, 255, 255, .42); }
  .sw-gt.on em { background: #fff; }
  .sw-steps { grid-template-columns: 1fr; }
  /* small phones: copy, button, then the mascot under them (the band is too narrow for a side mascot) */
  .sw-cta-band { flex-direction: column; align-items: flex-start; padding: 24px 20px 150px; }
  .sw-cta-mascot { right: 50%; margin-right: -80px; height: 170px; bottom: -26px; }
  /* the sort is an icon button (its list still names every option): the search keeps the room */
  .sw-sort-ico { display: block; position: absolute; left: 50%; top: 50%; z-index: 1; margin: -8px 0 0 -8px; color: rgba(255, 255, 255, .8); pointer-events: none; }
  .sw-tool .csel-trigger { width: 44px; padding: 0; justify-content: center; }
  .sw-tool .csel-trigger .csel-value { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .sw-tool .csel-trigger > svg { display: none; }
  .sw-cf-cols { grid-template-columns: 1fr; }
  .sw-cf-mid { height: 30px; }
  .sw-cf-mid svg { width: 34px; height: 34px; padding: 8px; transform: rotate(90deg); animation: none; }
  .sw-cf-col ul { max-height: 190px; }
  .sw-cf-actions .btn { flex: 1; min-width: 0; height: 44px; }
  .sw-cf-go { min-width: 0; }
  .sw-done-vals { flex-direction: column; gap: 2px; }
  .sw-done-actions .btn, .sw-fail-actions .btn { height: 44px; }
}
/* crowded panel headers: the Deposit pill turns into a round "+" (label stays for screen readers via aria-label) */
@media (max-width: 480px), (min-width: 900.02px) and (max-width: 1180px) {
  /* a 40px box (the tap target, rule 11) that paints a 30px round button: the tone is clipped to the content box and
     the negative margin keeps the header row's 30px footprint */
  .sw-dep-link { width: 40px; height: 40px; margin: -5px; padding: 5px; background-clip: content-box; }
  .sw-dep-link::after { content: none; }
  .sw-dep-link span { display: none; }
  .sw-dep-link svg { width: 14px; height: 14px; }
}
@media (max-width: 400px) {
  .sw-ptitle { gap: 8px; }
  .sw-pico { width: 28px; height: 28px; border-radius: 9px; }
  .sw-phead { gap: 8px; padding: 0 12px; }
}
/* small phones: the panel title and its count keep their words — the decorative arrow tile goes first, then (at 320)
   the stock count after "N selected"; three cart chips fit the cart */
@media (max-width: 374px) {
  .sw-pico { display: none; }
}
@media (max-width: 360px) {
  .sw-chip { width: 76px; height: 106px; }
}
@media (max-width: 339px) {
  .sw-selc .sw-of { display: none; }
}
@media (min-width: 900.02px) and (max-width: 1060px) {
  .sw-pico { display: none; }
}
/* the 256px middle column: "Leftover → swap credit" (the game is in the tabs right above), not a 3-line wrap */
@media (min-width: 900.02px) and (max-width: 1180px) {
  .sw-net-g { display: none; }
}
@media (min-width: 900.02px) and (max-width: 1180px) {
  .sw-grid, .sw-signin-skel { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 6px; padding: 8px 10px 10px; }
  .sw-cart .cart-copy p { font-size: 12px; }
  .sw-phead { padding: 0 12px; }
  .sw-tool { padding: 10px 10px 4px; gap: 6px; }
  .sw-tool .csel-trigger { padding: 0 8px 0 10px; font-size: 12px; }
}
@media (max-width: 380px) {
  .sw-cta-m { width: 136px; padding: 0 10px; font-size: 13.5px; }
  .sw-mbar-info { padding: 4px 6px; } /* 132px of words at 320: "Pick items to swap" whole */
  .sw-grid { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
}
/* toasts: the desk's panel titles, carts and game tabs sit right under the header, never under a toast ("YOU GET /
   BloxyShop Stock"). Phones: a toast drops over the header band (as app.css does below 900px). Desktop, where the
   header's right end is the account chip (its menu must stay reachable): a toast rises at the foot of the middle
   column, as wide as it — under the summary and the (usually closed) Filters card, its bottom on the panels' bottom
   edge (its own 8px margin below); with a dialog open it goes to the top edge, as everywhere (app.css) */
@media (max-width: 900px) { body.swap-body #toasts { top: calc(8px + env(safe-area-inset-top)); } }
@media (min-width: 900.02px) {
  /* a fixed-height stack (it doesn't block clicks): a toast coming in grows upwards inside it, nothing moves */
  body.swap-body:not(.modal-open) #toasts { top: auto; bottom: calc(var(--gutter) - 8px); left: 0; right: 0; margin-inline: auto; width: 300px; height: 260px; justify-content: flex-end; }
  body.swap-body:not(.modal-open) .toast { transform-origin: bottom center; }
}
@media (min-width: 900.02px) and (max-width: 1180px) { body.swap-body:not(.modal-open) #toasts { width: 256px; } }
/* touch screens wider than the phone layout (an iPad held sideways): the panels' search fields are 40px tap targets
   (rule 11; their sort dropdowns: shell.css .csel-sm) */
@media (pointer: coarse) and (min-width: 900.02px) {
  .sw-search, .sw-tool .csel-trigger { height: 40px; }
  /* the picked card's stepper: 40px hit boxes, the visible circles stay small (as on phones) */
  .sw-step { padding: 0 2px; gap: 0; height: 34px; }
  .sw-step button { width: 40px; height: 40px; margin: -3px 0; }
  .sw-step button::before { inset: 7px; }
}
@media (prefers-reduced-motion: reduce) {
  .sw-chip, .icard.sw-pop, .sw-net.flash, .sw-mbar, .sw-state { animation: none !important; }
}

/* narrow stock cards: the selected check sits top-left, so the qty pill moves under it
   (next to it, it collided with the variant badge on the right) */
@media (max-width: 560px) {
  .sw-grid .icard.selected .ic-qty { top: 31px; left: 7px; }
}
