/* ============================================================
   Pax Monero - System 6 / classic Macintosh look
   Monochrome desktop, white menu bar, windowed panels,
   beveled buttons. Fully monochrome (grayscale): even the coin
   glyphs and status dots are black / white / gray.
   ============================================================ */

:root {
  color-scheme: light;
  --desktop: #b7b7b7;
  --window: #ffffff;
  --bevel: #d8d5d0;
  --bevel-2: #ecebe8;
  --shade: #9a9a9a;
  --ink: #000000;
  --soft: #444444;
  --faint: #6b6b6b;
  /* Surface + line tokens: the few non-variable colors left in the light
     stylesheet live here so the dark theme can flip them from one place.
     `--bar` is the menu bar / brand / badge; `--fill` the light-gray panel
     fills; `--line*` the hairline borders; the bevel shadows encode the
     classic recessed/highlighted edge and flip with the theme. */
  --bar: #ffffff;
  --fill: #f2f2f2;
  --fill-hover: #e8e6df;
  --line: #c4c4c4;
  --line-soft: #cfcfcf;
  --checker-a: #bdbdbd;
  --checker-b: #b5b5b5;
  --btn-bevel: inset -1px -1px 0 #7f7f7f, inset 1px 1px 0 #ffffff,
               inset -2px -2px 0 #b3b3b3, inset 2px 2px 0 #efefef;
  --btn-bevel-active: inset 1px 1px 0 #7f7f7f, inset -1px -1px 0 #ffffff;
  --switch-bevel: inset 1px 1px 0 #ffffff, inset -1px -1px 0 #7f7f7f;
  --timer-bevel: inset -2px -2px 0 #b3b3b3, inset 2px 2px 0 #efefef;
  --input-inset: inset 1px 1px 0 rgba(0, 0, 0, 0.18);
  /* Amber + green accents (verification, risk, extensions, remaining). */
  --amber-border: #9a6700;
  --amber-text: #8a5a00;
  --amber-bg: #fff8e1;
  --amber-rail: #b08020;
  --amber-wash: rgba(176, 128, 32, 0.08);
  --green: #1a7f37;
  /* Misc one-offs. */
  --mock-page: #f7f7f5;
  --wallet-mid: #9a9a9a;
  --font-ui: "Chicago", "Geneva", system-ui, "Segoe UI", "DejaVu Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-body: "Geneva", system-ui, "Segoe UI", "DejaVu Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-mono: "Monaco", "Menlo", "Courier New", "DejaVu Sans Mono", "Liberation Mono", monospace;
}

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

html { scroll-behavior: smooth; }

body {
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
  background-color: var(--desktop);
  /* subtle desktop checker */
  background-image: repeating-conic-gradient(var(--checker-a) 0% 25%, var(--checker-b) 0% 50%);
  background-size: 4px 4px;
  min-height: 100vh;
}

a { color: var(--ink); text-decoration: underline; }
a:hover { color: var(--ink); }
code { font-family: var(--font-mono); font-size: 0.9em; }

.container { max-width: 1000px; margin: 4px auto; padding: 0 12px; container-type: inline-size; }

/* ---------- White menu bar ---------- */

.menu-bar {
  position: sticky; top: 0; z-index: 50;
  background: var(--bar); color: var(--ink);
  display: flex; align-items: center; gap: 12px;
  justify-content: center;
  padding: 0 10px;
  border-bottom: 1px solid var(--ink);
  box-sizing: border-box;
}

.brand { display: flex; align-items: center; gap: 7px; text-decoration: none; color: var(--ink); font-family: var(--font-ui); font-size: 13px; font-weight: 700; }
.brand:hover { background: transparent; color: var(--ink); }
.brand-mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; background: var(--bar); color: var(--ink);
  font-size: 11px; line-height: 1; border-radius: 2px;
  border: 1px solid var(--ink);
}
.brand-text { letter-spacing: 0.02em; }

.main-nav { display: flex; align-items: start; gap: 2px; }
.menu-bar a, .menu-right a, .menu-form button, #notify-toggle {
  font-family: var(--font-ui); font-size: 12px; color: var(--ink);
  font-weight: bolder;
  text-decoration: none; padding: 2px 8px; border: none; background: none;
  cursor: pointer; display: inline-block;
}
.main-bar a:hover, .menu-right a:hover, .menu-form button:hover, #notify-toggle:hover {
  background: var(--ink); color: var(--window);
}


/* ---------- Notification tray (dropdown below the bell) ---------- */

.notify-wrap { position: relative; display: inline-block; }
#notify-toggle {
  position: relative;
  /* The tray is a native <details> element: drop the disclosure triangle
     so the summary looks exactly like the old plain button. */
  list-style: none;
}
#notify-toggle::-webkit-details-marker { display: none; }
#notify-toggle::marker { content: ""; }

.notify-badge {
  position: absolute; top: 2px; right: -6px; z-index: 5;
  min-width: 12px; height: 14px; padding: 0 3px;
  background: var(--bar); color: var(--ink);
  border: 1px solid var(--ink); border-radius: 999px;
  font-family: var(--font-ui); font-size: 10px; font-weight: 700;
  line-height: 13px; text-align: center; vertical-align: top;
}


.notify-panel {
  position: absolute; top: calc(100% + 6px); left: 50%; z-index: 80;
  transform: translateX(-50%);
  width: 340px; max-width: calc(100vw - 24px);
  background: var(--window); color: var(--ink);
  border: 1px solid var(--ink);
  box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.5);
  font-family: var(--font-body); font-size: 12px;
  display: flex; flex-direction: column;
}
.notify-panel[hidden] { display: none; }

.notify-grip { display: none; }

/* Sponsored notification ads live in their own strip at the very top of
   the tray - above the sound switch - never inside the notification list.
   Filled by notify.js; hidden while empty (or before JS runs). */
.notify-sponsored {
  display: flex; flex-direction: column;
  border-bottom: 1px solid var(--ink);
  background: var(--fill);
}
.notify-sponsored[hidden] { display: none; }
.notify-sponsored .notify-item { border-bottom: none; }

.notify-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 10px; border-bottom: 1px solid var(--ink);
  background: var(--bevel-2);
}
.notify-head b {
  font-family: var(--font-ui); font-size: 12px; letter-spacing: 0.04em;
  text-transform: unset;
}
/* The tray header's controls (sound + clear all) sit inline on the right,
   one row, sharing the switch look. */
.notify-head form { margin: 0; display: inline-flex; }
.notify-head .notify-switch { margin: 0; }

.notify-switch {
  font-family: var(--font-ui); font-size: 10px; font-weight: 700;
  text-align: center; color: var(--ink);
  background: var(--bevel); border: 1px solid var(--ink);
  margin: 8px 0 8px 8px; padding: 4px 8px; cursor: pointer;
  width: fit-content;
  box-shadow: var(--switch-bevel);
}
.notify-switch:hover, .notify-switch:focus-visible { filter: invert(1); outline: none; }

.notify-list {
  display: flex; flex-direction: column;
  max-height: 430px; overflow-y: auto;
}
.notify-empty {
  padding: 26px 14px; text-align: center; color: var(--soft); font-size: 12px;
}


.notify-item {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 12px; cursor: pointer;
  border-bottom: 1px solid var(--line-soft);
  text-align: left; background: var(--window);
  width: 100%;
}
.notify-item:hover, .notify-item:focus-visible {
  background: var(--bevel-2); outline: none;
}
.notify-item.fresh { box-shadow: inset 3px 0 0 var(--ink); }

.notify-ico {
  flex-shrink: 0; width: 20px; text-align: center;
  font-size: 15px; line-height: 1.4;
}
.notify-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.notify-main b { font-size: 12px; line-height: 1.35; }
.notify-item.fresh .notify-main b { text-decoration: underline; }
.notify-sub { color: var(--soft); font-size: 11px; line-height: 1.35; }
.notify-time { color: var(--faint); font-size: 10px; }

.menu-right { margin-left: auto; display: flex; align-items: center; gap: 4px; }
.menu-user {
  font-family: var(--font-ui); font-size: 12px; color: var(--ink);
  padding: 2px 6px; text-decoration: none;
}
.menu-user:hover {   background: var(--ink); color: var(--window); }
.menu-form { display: inline; }

/* ---------- LAN admin panel ---------- */

/* The LAN admin port serves the whole site plus the admin pages, so the
   admin pages get their own compact bar: brand and admin navigation on the
   left, then the site shortcut and sign-out pushed right. No notification
   tray, no "+ Listing", no ad/FAQ footer. */
.admin-bar { justify-content: flex-start; gap: 4px; }
.admin-bar .admin-spacer { flex: 1 1 auto; }
.admin-bar a:hover, .admin-bar .menu-form button:hover {
  background: var(--ink); color: var(--window);
}
.admin-container { max-width: 1120px; }

/* The admin username/password door (LAN admin port): a centered, compact
   card sitting below the admin bar, with the CAPTCHA widget inline. */
.admin-login-card { margin-top: 56px; }

/* ---------- Classic windows ---------- */

.panel, .hero, .offer-card, .deposit-card {
  position: relative;
  background: var(--window);
  border: 1px solid var(--ink);
  box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.45);
}

/* ---------- Platform report ---------- */

/* The footer's Report / Sponsor / FAQ buttons sit side by side in a
   centered row. FAQ is a native <details>: its summary is styled like the
   other two buttons, and its questions still open right there in the
   footer - `display: contents` lets the summary join the row while the
   question list wraps to its own full-width line below when opened. */
.site-footer .foot-links {
  margin: 12px 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  max-width: 33%;
}
.report-link {
  display: inline-block; font-family: var(--font-ui); font-size: 12px; font-weight: 700;
  border: 1px solid var(--ink); padding: 4px 12px; background: var(--window);
  color: var(--ink); text-decoration: none; text-transform: unset; letter-spacing: 0.08em;
}
.report-link:hover { background: var(--fill-hover); }
/* The report form, scrolled to when any sponsor's hover "!" button is clicked:
   the anchor clears the sticky menu bar. No frame or outline - the form
   itself is enough; the "Sponsor report" category is pre-selected instead. */
#new-report { scroll-margin-top: 64px; }
.page-title { margin-bottom: 4px; }
.lead { margin-bottom: 22px; }
.report-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px; margin: 26px 0; border: 1px solid var(--ink);
  box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.45); background: var(--window); padding: 16px;
}
.report-card { display: flex; flex-direction: column; gap: 2px; }
.report-label { font-size: 10px; text-transform: unset; letter-spacing: 0.08em; color: var(--soft); }
.report-card b { font-size: 18px; }
.report-panels { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 0 26px; }
/* Grid items, like flex items, refuse to shrink below their content's
   min-content width by default - the wide ledger tables in the report
   panels must be allowed to shrink so their .table-wrap scrolls instead
   of pushing the page off-screen. */
.report-panels > * { min-width: 0; }
.report-tally td:last-child, .report-nodes td.num, .report-flow td.num { color: var(--ink); font-weight: 700; }
.report-empty { margin: 4px 0; }
.report-card-solo { border-top: 1px dashed var(--ink); padding: 10px 0 2px; }
.report-card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.report-subject { font-weight: 700; }
.report-message { margin: 6px 0 2px; white-space: pre-wrap; }
.report-solution {
  margin: 8px 0 2px; padding: 8px 10px;
  background: var(--fill); border: 1px solid var(--ink);
}
.report-solution b { display: block; font-size: 10px; text-transform: unset; letter-spacing: 0.08em; margin-bottom: 4px; }
.report-solution p { margin: 0; white-space: pre-wrap; }
.report-resolve { margin: 0 0 14px; padding: 10px 12px; border: 1px dashed var(--soft); }

/* ---------- Classic windows ---------- */

.panel, .hero { margin: 24px 0; padding: 20px 22px 22px; }

/* Every titled element draws its data-title tab 19px above its box
   (see the [data-title]::before rules below), so each one needs that much
   room above it or the tab covers whatever sits above. The base panel
   margin leaves ~13px of visible air; the tighter containers below
   (grids, swap-grid, danger-panel) get their own minimums so a titled
   element never hides the element above it. */

/* The swap fragment's ledger lives in a native <details> so the default
   view stays compact (no internal scroll area) and expands without
   JavaScript. Defined after .panel so its padding/margin win. */
.ledger-details { margin: 10px 0; padding: 0; }
.ledger-details summary {
  list-style: none; cursor: pointer;
  padding: 9px 12px;
  border-bottom: 1px solid var(--ink);
  font-family: var(--font-ui); font-size: 12px; font-weight: 700;
  letter-spacing: 0.04em; text-transform: unset;
}
.ledger-details summary::-webkit-details-marker { display: none; }
.ledger-details summary::marker { content: ""; }
.ledger-details[open] summary { background: var(--bevel); }
.ledger-details[open] .table-wrap { margin: 10px; }

.panel[data-title]::before,
.hero[data-title]::before,
.offer-card[data-title]::before,
.deposit-card[data-title]::before {
  content: attr(data-title);
  position: absolute; top: -19px; left: -1px; right: -1px; height: 17px;
  background: var(--window);
  border: 1px solid var(--ink); border-bottom: none;
  font-family: var(--font-ui); font-size: 12px; line-height: 17px;
  text-align: center; color: var(--ink);
  padding: 0 12px;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}

/* ---------- Buttons (classic bevel) ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  font-family: var(--font-ui); font-size: 13px; font-weight: 600;
  color: var(--ink); background: var(--bevel);
  border: 1px solid var(--ink); border-radius: 0;
  padding: 5px 16px; cursor: pointer; text-decoration: none;
  box-shadow: var(--btn-bevel);
  transition: none;
}
.btn:hover { text-decoration: none; filter: invert(1); }
.btn:active {
  transform: translate(1px, 1px);
  box-shadow: var(--btn-bevel-active);
}
.btn-primary { background: var(--bevel); color: var(--ink); }
.btn-ghost { background: var(--bevel-2); }
.btn-block { width: 100%; }
.btn-sm { padding: 3px 10px; font-size: 12px; }
/* Destructive action: same beveled look, but white-on-black so it reads
   as the "destructive" choice in the dialog. */
.btn-danger { background: var(--ink); color: var(--window); }

/* ---------- Danger zone (owner listing delete) ---------- */

.danger-panel { margin-top: 26px; }
.danger-reason {
  border: 1px solid var(--ink); background: var(--window);
  color: var(--ink); padding: 8px 12px; margin-top: 14px;
  font-weight: 700; font-size: 13px;
}

/* Admin actions panel */
.admin-actions { margin-top: 16px; margin-bottom: 8px; }

/* ---------- Fields ---------- */

input, select, textarea {
  font-family: var(--font-body); font-size: 13px; color: var(--ink);
  background: var(--window); border: 1px solid var(--ink); border-radius: 0;
  padding: 6px 8px; outline: none; width: 100%;
  box-shadow: var(--input-inset);
}
input:focus, select:focus, textarea:focus {
  box-shadow: var(--input-inset), 0 0 0 1px var(--ink);
}
textarea { resize: vertical; }
.check {
  flex-direction: row!important;
  align-items: flex-start;
}
.check input[type="checkbox"] {
  width: min-content!important;
  height: min-content!important;
  margin: 2px 0 0 0;
  padding: 0;
  border: none;
  box-shadow: none;
  flex-shrink: 0;
}
.checkbox{
  margin: auto 0;
  width: min-content!important;
  height: min-content!important;
}
.stack-form { display: flex; flex-direction: column; gap: 15px; margin-top: 12px; }
.stack-form label { display: flex; flex-direction: column; gap: 6px; font-weight: 600; font-size: 13px; }

/* The listing form's "Advanced" group: a native <details> so the essentials
   (currencies, amounts, wallets) stay up front and the optional extras -
   conditions, lucky code, open/private flags - sit one tap away, no JS. */
.advanced-box { margin-top: 2px; border: 1px solid var(--ink); background: var(--window); }
.advanced-box summary {
  list-style: none; cursor: pointer;
  padding: 8px 12px;
  font-family: var(--font-ui); font-size: 12px; font-weight: 700;
  letter-spacing: 0.04em; text-transform: unset;
}
.advanced-box summary::-webkit-details-marker { display: none; }
.advanced-box summary::marker { content: ""; }
.advanced-box[open] summary { background: var(--bevel); }
.advanced-fields {
  display: flex; flex-direction: column; gap: 14px;
  padding: 12px; border-top: 1px solid var(--ink);
}
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 560px) { 
.field-row { grid-template-columns: 1fr; }
.site-footer .foot-links {
max-width:70%;
} 
}
.form-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 8px; flex-wrap: wrap; }

/* The swap pair - the same coin-chip ⇄ coin-chip look as the offer cards
   (offer-pair), with the chip contents replaced by interactive controls:
   coin icon · currency select · amount input on each side, and a clickable
   ⇄ that swaps the directions. The icons swap when a currency select
   changes. On the post-a-listing form each chip carries a "You send" /
   "You receive" caption above it. */
.offer-pair > .coin-chip, .swap-pair > .coin-chip { flex: 1 1 0; min-width: 0; }
.swap-side { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.swap-cap {
  font-family: var(--font-ui); font-size: 11px; font-weight: 700;
  letter-spacing: 0.04em; text-transform: unset;
}
.swap-pair .swap-side .coin-chip { width: 100%; }
.swap-pair .coin-chip select { width: auto; flex: 0 0 auto; }
.swap-pair .coin-chip input {
  flex: 1 1 auto; min-width: 0;
  border: none; box-shadow: none; background: transparent; padding: 0;
}
.swap-pair .coin-chip input:focus { box-shadow: none; outline: none; }
.arrow-btn {
  align-self: center; flex-shrink: 0;
  font-family: var(--font-ui); font-size: 15px; font-weight: 700;
  line-height: 1; padding: 7px 9px; cursor: pointer;
  border: 1px solid var(--ink); background: var(--bevel);
  box-shadow: 1px 1px 0 rgba(0, 0, 0, 0.5);
}
form .swap-mid{
	margin-top: 18px; 
}
.swap-pair{
	margin-bottom: 8px;
}
.arrow-btn:hover { background: var(--bevel-2); }
.arrow-btn:active { box-shadow: none; transform: translate(1px, 1px); }
/* The swap pair's middle column: the ⇄ (or the swap-direction button) with
   the live commission hint tucked right under it. */
.swap-mid {
  display: flex; flex-direction: column-reverse; align-items: center; align-self: flex-end; gap: 4px;
  flex-shrink: 0;
}
.swap-mid .price-hint { margin: 0; font-size: 11px; white-space: nowrap; }
/* Tooltip for the price/commission details (the ⓘ next to the pay figure on
   the accept / request boards): a CSS-only popover shown on hover or focus
   (keyboard: the ⓘ is focusable). */
.tip-wrap { position: relative; flex-shrink: 0; }
.tip-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border: 1px solid var(--ink); border-radius: 50%;
  font-size: 11px; font-weight: 700; line-height: 1; cursor: help;
  background: var(--window); color: var(--ink);
}
.tip {
  position: absolute; right: 0; bottom: calc(100% + 8px); z-index: 20;
  width: max-content; max-width: 260px; min-width: 170px;
  background: var(--window); border: 1px solid var(--ink);
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.5);
  padding: 8px 10px; font-size: 11px; font-weight: 400; line-height: 1.45;
  display: none; text-align: left; white-space: normal;
}
.tip-wrap:hover .tip, .tip-ico:focus + .tip { display: block; }
.tip .price-hint { margin: 4px 0 0; }
@media (max-width: 376px) {
 .site-footer .foot-links{max-width:80%;}
 .swap-pair { flex-direction: column; align-items: stretch; }
  .arrow-btn { transform: rotate(90deg); }
  .arrow-btn:active { transform: rotate(90deg) translate(1px, 1px); }
  .offer-pair{
    flex-direction: column!important;
    gap: 0!important;
  }
    .route-arrow{
    rotate: 90deg;
  }
    .swap-mid {
    flex-direction: row;
    align-self: center;
    margin: 4px 0;: 
  }
}

/* Narrower main column for the listings home and the post-a-listing form:
   on large screens the content column stops well short of the full 1000px
   container, keeping the swap UI compact. On smaller viewports the column
   is already narrower than the cap, so nothing changes. */
.container { max-width: 860px; }
.muted { color: var(--soft); font-weight: 400; }
.foot-sub { font-size: 12px; }

/* Random-credential helpers (the legacy sign-up form): the buttons and the
   generated-value note were injected by the removed /static/signup.js. The
   styles are kept in case the layout reappears, but nothing injects them
   anymore. */
.gen-tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.gen-tools .btn { align-self: flex-start; }
.gen-note { font-size: 12px; color: var(--soft); font-weight: 400; word-break: break-all; }

/* The self-hosted captcha (no third-party tracker): a math, word or picture
   challenge. Math/word widgets put the prompt inline; the image widget shows
   a locally-rendered PNG. No JavaScript involved. */
.captcha-widget { display: flex; flex-direction: column; gap: 8px; margin-top: 2px; }
.captcha-widget .captcha-prompt { font-weight: 600; font-size: 13px; }

.captcha-widget .captcha-img {
  border: 1px solid var(--ink); background: #fff; padding: 4px;
  image-rendering: pixelated; max-width: 220px; height: auto;
}
.captcha-widget .captcha-unavailable { font-size: 12px; }

.crumb { font-size: 12px; margin: 8px 0 4px; color: var(--soft); }
.crumb a { color: var(--ink); }

/* ---------- Hero ---------- */

.hero { text-align: center; }
.hero-title {
  font-family: var(--font-ui);
  font-size: clamp(1.55rem, 4vw, 2.3rem); font-weight: 800;
  color: var(--ink); letter-spacing: -0.01em; line-height: 1.15; margin: 4px 0 14px;
}
.grad { font-style:italic; font-size: clamp(1.8rem, 4vw, 2.6rem); }
.hero-actions { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }

.hero-stats { display: flex; justify-content: center; gap: 12px; flex-wrap: wrap; margin-top: 18px; }
.stat {
  justify-content:center;
  background: var(--window); border: 1px solid var(--ink);
  padding: 10px 18px; min-width: 120px;
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.4);
}
.stat b { display: block; font-family: var(--font-ui); font-size: 1.4rem; font-weight: 800; color: var(--ink); }
.stat span { font-size: 0.72rem; color: var(--soft); text-transform: unset; letter-spacing: 0.05em; }

/* "Coins supported" stat: PNG icons with the ticker as alt text - a browser
   that can't show the image simply renders the alt string instead (no JS).
   A broken <img> paints its alt as ordinary content, so flex-centring the
   img itself keeps the fallback centred; the window-coloured backing stops
   the page showing through while loading / through transparent pixels. */
.stat-coins { display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 28px; margin-top:8px; margin-bottom:-8px; }
.stat-coin {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  background: var(--window); border-radius: 50%;
  overflow: hidden;
  font-family: var(--font-ui); font-size: 9px; font-weight: 800;
  letter-spacing: 0.03em; color: var(--ink);
  margin: 0 -3px;
}

/* Sponsor stat: matches .stat but contains a sponsor link */
.stat-sponsor {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px 18px;
  min-width: 120px;
}
.stat-sponsor .home-sidebar-sponsor {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: var(--ink);
  width: 100%
}
.stat-sponsor .sponsor-title {
  display: block;
  font-family: var(--font-ui);
  font-size: 21px;
  font-weight: 800;
  color: var(--ink);
  text-align: center;
}
.stat-sponsor .sponsor-sub {
  display: block;
  font-size: 0.72rem;
  color: var(--soft);
  text-transform: unset;
  letter-spacing: 0.05em;
  text-align: center;
}
.stat-sponsor .sponsor-badge {
  display: inline-block;
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: unset;
  color: var(--soft);
  
}
.stat-sponsor .sponsor-report {
font-size:10px;
right: -17px;
bottom: -8px;
border:none;
box-shadow:none;
}

/* ---------- Account page ---------- */

.account-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
}
.account-head h1 {
  font-family: var(--font-ui); font-size: 1.9rem; font-weight: 800;
  letter-spacing: -0.01em; color: var(--ink); margin: 0;
}
/* The account code is the account's only credential - present it in the
   same dashed code box the listing page uses, never as inline text. */
.account-code-box { margin-top: 14px; }
.account-stats {
  display: flex; flex-wrap: wrap; gap: 12px;
  margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--bevel-2);
}
.account-stats .stat { flex: 1 1 150px; min-width: 130px; }
.account-tx-panel h2 {
  font-family: var(--font-ui); font-size: 1.4rem; font-weight: 800;
  letter-spacing: -0.01em; color: var(--ink); margin: 0 0 4px;
}

/* ---------- Sections ---------- */

.section-head { display: flex; justify-content: flex-end; margin-bottom: 28px; }
.offers-section, .how { margin: 0 0; }
/* The offers section carries its own data-title tab, so its first child
   must start below that tab. A hair of padding-top stops the grid's top
   margin from collapsing into the section's - without it, the first-row
   card tabs (also 19px above each card) land exactly on top of the
   section's "Open listings" tab and hide it. */
.offers-section { padding-top: 6px; }
.empty-state {
  text-align: center; padding: 40px 20px;
  border: 1px dashed var(--ink); background: var(--window);
  color: var(--soft);
}
.empty-state p + p { margin-top: 6px; }

/* ---------- Offer cards ---------- */

.offer-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 32px 20px; margin-top: 0;
}
/* On mobile the card grids collapse to full-width columns so every card
   lines up with the other panels - a minmax(300px)/minmax(320px) track
   would otherwise overflow the container on narrow screens and make the
   cards a different size than the panels around them. */
@media (max-width: 640px) {
  .offer-grid, .deposit-grid { grid-template-columns: 1fr; }
}
.offer-card { margin: 0; padding: 18px 18px 16px; display: flex; flex-direction: column; gap: 14px; min-width: 0; overflow-wrap: anywhere; }
.offer-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.offer-top .status-badge { flex-shrink: 0; }

.offer-pair { display: flex; align-items: center; gap: 10px; flex-direction: row; min-width: 0; }
.coin-chip {
  width: 100%;
  display: flex; align-items: center; gap: 10px;
  background: var(--fill); border: 1px solid var(--ink);
  padding: 8px 12px; min-width: 0;
      box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.5);

}
.chip-text { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.chip-text b { font-size: 14px; }
.chip-text small { color: var(--soft); font-size: 12px; }
.route-arrow { color: var(--ink); font-size: 16px; font-weight: 700; }
/* Coin icon wrapper - holds the coin image and a text fallback.
   When the <img> loads it covers the fallback; when it fails the
   onerror handler hides the <img> so the centred abbreviation shows.
   The backing is var(--window), not white: it must match the theme
   while the PNG loads and behind its transparent pixels. */
.coin-ico-wrap {
  margin: auto 0;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  background: var(--fill);
}
.deposit-card .coin-ico-wrap  {background: var(--window);}
.deposit-card .coin-ico-img {background: var(--window);}
/* A failed <img> paints its alt text as ordinary content - flex-centre it
   with the fallback's exact font so no-JS browsers (where onerror never
   fires, e.g. Tor Safest) land the alt dead-centre over .coin-fallback
   instead of showing a second, misaligned string. The img carries its own
   opaque var(--window) backing: once the PNG loads, that backing paints
   over .coin-fallback so the text stays invisible even through the
   transparent pixels of the logo. */
.coin-ico-img {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  object-fit: contain;
  background: var(--fill);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink);
}
.coin-fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink);
  border-radius: 50%;
  pointer-events: none;
}
/* The listing form's coin icons are a live preview that follows the
   currency <select> - driven entirely by CSS, no JavaScript. Every coin
   icon is server-rendered inline inside the chip and :has() shows the one
   whose data-coin matches the selected <option>, so changing the dropdown
   swaps the icon even with JS disabled. Browsers without :has() support
   (e.g. Tor Browser Safest / Firefox ESR < 121) show the first icon as
   a static fallback - it matches the first <option> and never changes,
   but at least the user sees *something*. */
.coin-chip .swap-ico .coin-ico-wrap { display: none; }
/* Fallback: always show the first icon (matches the default <option>).
   When :has() is supported, the rules below override this and show only
   the matching icon. */
.coin-chip .swap-ico .coin-ico-wrap:first-of-type {
  display: flex;
}
/* Progressive enhancement: show the icon matching the selected currency. */
.coin-chip:has(select option[value="XMR"]:checked) .swap-ico [data-coin="XMR"],
.coin-chip:has(select option[value="BTC"]:checked) .swap-ico [data-coin="BTC"],
.coin-chip:has(select option[value="LTC"]:checked) .swap-ico [data-coin="LTC"],
.coin-chip:has(select option[value="BCH"]:checked) .swap-ico [data-coin="BCH"] {
  display: flex;
}
/* When :has() is supported and a non-first option is selected, hide the
   first-of-type fallback so only the matching icon shows. */
.coin-chip:has(select option:not([value="XMR"]):checked) .swap-ico .coin-ico-wrap:first-of-type,
.coin-chip:has(select option[value="LTC"]:checked) .swap-ico .coin-ico-wrap:first-of-type,
.coin-chip:has(select option[value="BCH"]:checked) .swap-ico .coin-ico-wrap:first-of-type,
.coin-chip:has(select option[value="BTC"]:checked) .swap-ico .coin-ico-wrap:first-of-type {
  display: none;
}

/* Keep old class for compatibility but use image instead */
.coin-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  font-size: 20px;
  color: var(--coin, #000);
  border: 1px solid #000;
  background: var(--window);
  border-radius: 50%;
}

.offer-meta { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.results-line { padding-bottom: 12px; }

/* ---------- Pills, badges, presence ---------- */
/* Every pill shares the status-badge look: square corners, small unset
   Chicago text with a leading dot. Variants (presence, network, ghost)
   keep their own dot or colors but match the same base shape. */

.pill, .status-badge {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--font-ui); font-size: 10px; font-weight: 700;
  letter-spacing: 0.05em; text-transform: unset;
  padding: 2px 8px; border: 1px solid var(--ink);
  background: var(--window); color: var(--ink); white-space: nowrap;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.5);

}
.pill { max-width: 100%; }
.pill::before, .status-badge::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; flex-shrink: 0;
}
.pill.ghost { background: transparent; border-style: dashed; color: var(--soft); }
.pill.ghost::before { display: none; }
.code-pill { font-family: var(--font-mono); letter-spacing: 0.06em; background: var(--ink); color: var(--window); white-space: normal; overflow-wrap: anywhere; }

/* Network backend pills: simulated (demo) vs live node. */
.net-sim { border-style: dashed; color: var(--faint); border-color: var(--faint); }
.net-live { background: var(--ink); color: var(--window); }
.net-live::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--window); box-shadow: 0 0 0 1px #000;
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.5);
}

.presence::before {
  content: ""; width: 9px; height: 9px; border: 1px solid var(--ink);
  border-radius: 50%; display: inline-block; flex-shrink: 0;
}
.presence.on::before { background: var(--ink); }
.presence.off::before { background: var(--window); }

/* A username that links to its public profile page. */
.user-link {
  color: inherit;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 2px;
}
.pill .user-link { color: var(--ink); }
.pill .user-link:hover { text-decoration-style: solid; }
.muted .user-link { color: var(--soft); }

.s-open { background: var(--window); }
.s-completed { background: var(--ink); color: var(--window); }
.s-matched { background: var(--bevel); }
.s-verifying { background: var(--window); border-style: double; }
.s-cancelled { color: var(--faint); border-color: var(--faint); }
.s-neutral { color: var(--soft); border-color: var(--soft); }

/* ---------- Listing detail ---------- */

.listing-code-box {
  margin-top: 16px; padding: 12px 16px;
  background: var(--fill); border: 1px dashed var(--ink);
  display: flex; flex-direction: column; gap: 4px;
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.5);
}
.listing-code-box .muted { font-size: 11px; text-transform: unset; letter-spacing: 0.07em; }
.listing-code {
  font-family: var(--font-mono); font-size: 1.35rem; font-weight: 800;
  letter-spacing: 0.14em; color: var(--ink);
}

/* ---------- Masked private codes ---------- */

/* Private codes (account code, swap code, tracking code) render as stars -
   one `*` per character, exactly the real code's length, in the same
   font/size/class as the code itself - with a small "Reveal it" hint.
   Clicking opens a native <details> whose <summary> (the stars) is then
   hidden, so the real code takes the stars' exact place: the masked text
   turns into the code. Pure HTML/CSS, no JavaScript: a glance sees only
   stars. */
.code-reveal { display: inline-block; margin: 0 0 0 5px; vertical-align: middle; overflow:hidden; }
.code-reveal > summary {
  list-style: none; cursor: pointer; display: inline-block;
}
.code-reveal > summary::-webkit-details-marker { display: none; }
.code-reveal > summary::marker { content: ""; }
/* The stars render soft (the revealed code stays ink) and aren't
   selectable as if they were the code itself. */
.code-reveal > summary code { color: var(--soft); user-select: none; }
.code-reveal .reveal-hint {
  font-family: var(--font-ui); font-size: 10px; font-weight: 700;
  letter-spacing: 0.05em; color: var(--ink); text-decoration: underline;
}
.code-reveal > summary:hover .reveal-hint,
.code-reveal > summary:focus-visible .reveal-hint {
  background: var(--fill-hover); outline: none;
}
/* Open: the stars (summary) vanish and the real code takes their place. */
.code-reveal[open] > summary { display: none; }
.code-reveal > code { word-break: break-all; }

.detail-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; margin-top: 18px; }
.address-panel { background: var(--window); }
.address-rows { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 10px; margin-top: 14px; }
.meta-line {
  display: flex; flex-direction: column; gap: 3px;
  background: var(--fill); border: 1px solid var(--ink);
  padding: 8px 12px;
}
.meta-line .muted { font-size: 10px; text-transform: unset; letter-spacing: 0.08em; }
.meta-line b { font-size: 13px; }

.offer-note { margin-top: 16px; padding: 12px 14px; border: 1px solid var(--ink); background: var(--fill); font-size: 13px; }
.accept-panel { background: var(--window); }
.swap-link-panel p + p { margin-top: 6px; }

/* ---------- Swap page ---------- */

.swap-head { padding: 6px 0 6px; margin-bottom: 10px; }
.swap-title-row {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.swap-title { min-width: 0; }
.swap-title h1 {
  font-family: var(--font-ui); font-size: 1.9rem; font-weight: 800;
  letter-spacing: -0.01em; color: var(--ink); margin: 0 0 3px;
}
.swap-pair-line { font-weight: 700; color: var(--soft); font-size: 13px; }
.swap-head-side { display: flex; flex-direction: column; align-items: flex-end; gap: 7px; }
.hint { margin-top: 12px; color: var(--soft); max-width: 680px; }

/* Tidy one-row facts band for the swap header: dates and figures sit side
   by side in a single bordered strip instead of stacked boxes. */
.swap-meta {
  display: flex; flex-wrap: wrap; gap: 6px 26px;
  margin-top: 14px; padding: 9px 12px;
  border: 1px solid var(--ink); background: var(--fill);
  font-size: 12px;
}
.meta-item { display: inline-flex; align-items: baseline; gap: 8px; }
.meta-item .muted { font-size: 10px; text-transform: unset; letter-spacing: 0.08em; }
.meta-item b { font-size: 12.5px; }
.eyebrow {
  display: inline-block; font-family: var(--font-ui); font-size: 11px;
  font-weight: 700; letter-spacing: 0.1em; text-transform: unset;
  border: 1px solid var(--ink); padding: 3px 10px; margin-bottom: 10px; color: var(--ink);
}

.swap-parties { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }

.completed-banner {
  margin: 18px 0 0; padding: 10px 14px;
  border: 1px solid var(--ink); background: var(--window);
  font-size: 13px; color: var(--ink);
}

/* ---------- Acceptance confirmation window ---------- */

.confirm-panel { background: var(--window); }
.confirm-intro { max-width: 680px; }
.confirm-intro code { word-break: break-all; }

.confirm-timer-wrap {
  margin: 18px 0 6px;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  text-align: center;
}
.confirm-timer-label { font-size: 12px; color: var(--soft); max-width: 560px; }
.confirm-timer {
  font-family: var(--font-mono);
  font-size: 2.5rem; font-weight: 800; letter-spacing: 0.06em;
  color: var(--ink); background: var(--window);
  border: 2px solid var(--ink);
  padding: 8px 34px; min-width: 190px;
  box-shadow: var(--timer-bevel);
}
.confirm-timer.urgent {
  background: var(--ink); color: var(--window);
  animation: confirm-pulse 1s steps(2, end) infinite;
}
@keyframes confirm-pulse { 50% { opacity: 0.7; } }
.confirm-foot { font-size: 12px; max-width: 560px; }

/* Swap deposit-deadline countdown (reuses the .confirm-timer look). */
.swap-timer-wrap {
  margin: 16px 0 4px;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  text-align: center;
}
.swap-timer-label { font-size: 12px; color: var(--soft); max-width: 560px; }
.swap-timer-wrap .confirm-timer { font-size: 1.9rem; padding: 6px 24px; min-width: 160px; }

/* 1-minute extension confirmation panel (deposit not detected at deadline). */
.extension-alert {
  margin: 16px 0 4px;
  padding: 18px 22px;
  border: 1px solid var(--line);
  border-left: 4px solid var(--amber-rail);
  background: var(--amber-wash);
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  text-align: center;
  width:100%;
}
.extension-alert .confirm-timer { font-size: 1.9rem; padding: 6px 24px; min-width: 160px; }

/* The whole swap page is one uniform flex wrapper at the same gap: the info
   card, the two deposit cards, the transaction ledger and the address panel
   all sit at the same gap. The info card, the ledger and the address panel
   take the full row; the two deposit cards sit side by side on wide screens
   and wrap to a stacked column as the viewport narrows - no media query
   needed, so phones (and tablets) always read top-to-bottom. */
.swap-grid {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 20px;
  /* The first card (the Info panel) draws its data-title tab 19px above
     itself on top of its own 10px margin - this extra top margin keeps
     the tab clear of the swap head / account-code note above it. */
  margin-top: 22px;
}
.swap-grid .deposit-card {
  flex: 1 1 360px;
  min-width: 0;
  margin-top: 10px;
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.5);
}
.swap-grid .info-card,
.swap-grid .ledger-details,
.swap-grid .address-panel {
  flex: 1 1 100%;
  /* min-width: 0 lets these flex items shrink below their content's
     min-content width - without it, the wide transaction ledger (long
     txids in nowrap cells) would blow the swap page past the viewport
     instead of scrolling inside .table-wrap. */
  min-width: 0;
  margin: 10px 0;
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.5);
}

/* Swap-grid deposit cards sit in half-width columns, so addresses and
   tracking codes wrap naturally onto the next line like normal text
   (no horizontal scroll - a long XMR address just continues below). The
   verification check list stays compact too: two tight columns (half the
   checks left, half right) with a slightly smaller font, so the section
   doesn't stretch the card; phones fall back to the single column from
   the media query below. */
.swap-grid .ver-checks {
  grid-template-columns: 1fr 1fr;
  gap: 3px 12px;
  font-size: 11.5px;
}

.deposit-grid {
  display: flex;
  flex-direction: row;
  gap: 24px; margin: 32px 0;
}
/* The ad-order page's two deposit cards (payment + info) share the row
   equally: a long wallet address (XMR is ~95 chars) must not inflate the
   payment card and crush its neighbour. The payment address wraps onto
   the next line like normal text inside its box (no horizontal scroll). */
.deposit-grid > .deposit-card {
  flex: 1 1 0;
  min-width: 0;
}
.deposit-card {
  margin: 0; padding: 24px;
  display: flex; flex-direction: column; gap: 10px;
  min-width: 0;
}
.deposit-head { display: flex; align-items: center; gap: 12px; }
.deposit-title { display: flex; flex-direction: column; line-height: 1.35; flex: 1; min-width: 0; }
.deposit-title h3 { font-family: var(--font-ui); font-size: 15px; letter-spacing: 0.01em; }
.coin-sub { color: var(--soft); font-size: 11px; }

.track-code { font-size: 12px; color: var(--soft); line-height: 1.5; overflow-wrap: anywhere; }
.track-code code { font-size: 13px; font-weight: 700; color: var(--ink); letter-spacing: 0.08em; }

.flow-line {
  font-size: 12.5px; line-height: 1.55; color: var(--ink);
  background: var(--fill); border: 1px solid var(--ink);
  padding: 12px 14px; margin: 0;
}
.flow-line b { font-size: 12.5px; }

.deposit-note { font-size: 11.5px; line-height: 1.5; }

.deposit-address {
  font-family: var(--font-mono); font-size: 12.5px; line-height: 1.6; word-break: break-all;
  background: var(--fill); border: 1px solid var(--ink);
  padding: 13px 14px; letter-spacing: 0.02em; color: var(--ink);
}

/* Wallet addresses: first and last letters clearly black and bold, the rest a
   lighter gray, for quick head/tail verification at a glance. */
.wallet-addr {
  font-family: var(--font-mono); font-size: 0.9em; color: var(--wallet-mid);
  word-break: break-all;
}
.wallet-addr b { color: var(--ink); font-weight: 800; }
.wallet-addr .mid { color: var(--wallet-mid); font-weight: 400; }

/* QR code display for deposit addresses, payout addresses, and ad payments. */
.deposit-qr, .address-qr {
  margin-top: 8px;
  display: flex;
  justify-content: center;
  background: var(--fill);
  border: 1px solid var(--ink);
  padding: 8px;
}
.deposit-qr .qr-code, .deposit-qr .qr-code-img, .address-qr .qr-code, .address-qr .qr-code-img {
  width: 150px;
  height: 150px;
  max-width: 150px;
  max-height: 150px;
  background: white;
  flex-shrink: 0;
  display: block;
}

/* Collapsible QR code toggle */
.qr-toggle > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
  background: var(--bevel);
  border: 1px solid var(--ink);
  padding: 4px 10px;
  box-shadow: var(--btn-bevel);
}
.qr-toggle > summary::-webkit-details-marker { display: none; }
.qr-toggle > summary::marker { content: ""; }
.qr-toggle > summary:hover { filter: invert(1); }
.qr-toggle[open] > summary { background: var(--ink); color: var(--window); }
.qr-toggle .deposit-qr { margin-top: 8px; }

/* Admin view: QR codes next to addresses in address-rows */
.address-rows .address-qr {
  margin-top: 4px;
  background: transparent;
  border: none;
  padding: 0;
  box-shadow: none;
}
.address-rows .address-qr .qr-code, .address-rows .address-qr .qr-code-img {
  width: 140px;
  height: 140px;
  max-width: 140px;
  max-height: 140px;
  display: block;
}

.deposit-amounts { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.deposit-amounts > div { display: flex; flex-direction: column; gap: 3px; min-width: 0; background: var(--fill); border: 1px solid var(--ink); padding: 11px 14px; }
.deposit-amounts .muted { font-size: 10px; text-transform: unset; letter-spacing: 0.08em; }
.deposit-amounts b { font-size: 13.5px; overflow-wrap: anywhere; }

.deposit-remaining { margin-top: 8px; padding: 10px 14px; background: var(--amber-bg); border: 1px solid var(--ink); border-radius: 4px; }
.deposit-remaining .muted { font-size: 10px; text-transform: unset; letter-spacing: 0.08em; color: var(--soft); }
.deposit-remaining b { font-size: 13.5px; color: var(--ink); overflow-wrap: anywhere; }

.progress { height: 14px; border: 1px solid var(--ink); background: var(--window); }
.progress-bar { height: 100%; background: var(--ink); }
.progress-label { font-size: 12px; color: var(--ink); font-weight: 600; }
.progress-label.ghost { color: var(--soft); font-weight: 400; }

.utxo-list { display: flex; flex-direction: column; gap: 10px; margin-top: 0; }
.utxo-row { display: flex; flex-direction: column; gap: 4px; }
.utxo-row .progress-label { font-size: 11px; font-weight: 400; color: var(--soft); }

/* ---------- Deep deposit verification (verifier service) ---------- */

.verification-section {
  padding-top: 12px; border-top: 1px dashed var(--line);
  display: flex; flex-direction: column; gap: 10px;
}
.verification-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 11px; text-transform: unset; letter-spacing: 0.08em;
}
.ver-status {
  font-weight: 700; font-size: 11px; padding: 2px 8px;
  border: 1px solid var(--ink); background: var(--window);
}
.ver-status.ver-critical { border-color: var(--amber-border); color: var(--amber-text); }
.ver-status.ver-warning { border-color: var(--amber-border); color: var(--amber-text); }
.ver-status.ver-unverified { border-color: var(--soft); color: var(--soft); }
.ver-checks { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 14px; font-size: 12px; }
.ver-check { display: flex; justify-content: space-between; gap: 8px; }
.ver-label { color: var(--soft); }
.ver-value { color: var(--ink); font-weight: 600; white-space: nowrap; }
.ver-check.bad .ver-value { color: var(--amber-text); }
.ver-flags { display: flex; flex-wrap: wrap; gap: 4px; }
.ver-flag {
  font-size: 10px; font-weight: 700; letter-spacing: 0.02em;
  border: 1px solid var(--amber-border); color: var(--amber-text); padding: 1px 6px;
}
.ver-error { font-size: 11px; color: var(--amber-text); overflow-wrap: anywhere; }
.ver-meta { font-size: 10px; }
@media (max-width: 640px) { .ver-checks { grid-template-columns: 1fr; } }

/* Dirty-money risk screen verdict (attached to a deposit's verification
   snapshot; deliberately conservative - high-risk only on overwhelming
   evidence, single weak signals stay "review"). */
.risk-badge {
  font-weight: 700; font-size: 11px; padding: 2px 8px;
  border: 1px solid var(--green); color: var(--green); background: var(--window);
}
.risk-badge.risk-review { border-color: var(--amber-border); color: var(--amber-text); }
.risk-badge.risk-high { border-color: var(--amber-border); color: var(--amber-text); }
.risk-evidence { font-size: 11px; color: var(--soft); overflow-wrap: anywhere; }

.tx-line { font-size: 12px; color: var(--soft); overflow-wrap: anywhere; }

/* ---------- Tables ---------- */

.table-wrap { overflow-x: auto; }
.ledger { width: 100%; border-collapse: collapse; font-size: 13px; }
.ledger th {
  text-align: left; font-size: 10px; text-transform: unset; letter-spacing: 0.08em;
  color: var(--ink); font-weight: 700; padding: 8px 10px; border-bottom: 2px solid var(--ink);
}
.ledger td { padding: 8px 10px; border-bottom: 1px solid var(--line); vertical-align: top; white-space: nowrap; }
.ledger td:last-child { white-space: normal; }
.ledger td code { word-break: break-all; }

.dir-in { color: var(--ink); font-weight: 700; }
.dir-out { color: var(--soft); font-weight: 700; }
.kind-fee, .kind-payout, .kind-deposit { color: var(--ink); }
.kind-refund { color: var(--ink); }
.kind-refund::before { content: "↩\FE0E "; }

/* ---------- Search ---------- */

.search-panel { margin-top: 26px; }
.search-form { margin-top: 16px; display: flex; flex-direction: column; gap: 14px; }
.results-line { color: var(--soft); }

/* ---------- Pagination (homepage / search results) ---------- */

.pagination {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  margin: 24px 0 36px; flex-wrap: wrap;
}
.page-info {
  font-family: var(--font-ui); font-size: 12px; font-weight: 700;
  border: 1px solid var(--ink); background: var(--window);
  padding: 3px 14px;
}
.page-disabled {
  font-family: var(--font-ui); font-size: 12px; color: var(--faint);
  border: 1px dashed var(--faint); padding: 3px 10px;
}

/* ---------- Track swaps ---------- */
.track-section{
  margin: 32px 0 0 0;
}
.track-form { display: flex; gap: 10px; flex-wrap: wrap; }
.track-form input {
  flex: 1; min-width: 220px;
  text-transform: unset; letter-spacing: 0.08em; font-family: var(--font-mono);
}

.results { margin: 8px 0 30px; display: flex; flex-direction: column; gap: 12px; }

/* ---------- Public profile page ---------- */

.profile-head { margin-bottom: 26px; }
.profile-top { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.profile-avatar {
  width: 64px; height: 64px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-ui); font-size: 2rem; font-weight: 800;
  color: var(--window); background: var(--ink);
  border: 1px solid var(--ink); box-shadow: inset 2px 2px 0 rgba(255,255,255,0.25),
    inset -2px -2px 0 rgba(0,0,0,0.35);
}
.profile-id { min-width: 0; }
.profile-id h1 { margin: 0 0 2px; font-size: 1.5rem; }
.profile-actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }
.profile-stats {
  display: flex; gap: 12px; flex-wrap: wrap;
  margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--bevel-2);
}
.profile-stats .stat { min-width: 110px; }

/* Two-party confirmation window: status line + confirmed state. */
.confirm-status { margin: 10px 0 0; font-weight: 600; }
.confirm-terms { margin: 0 0 2px; max-width: 640px; text-align: center; }
.confirm-done {
  margin-top: 12px; padding: 8px 12px;
  border: 1px dashed var(--ink); background: var(--bevel);
  font-weight: 700; color: var(--ink);
}

.swap-row {
  display: flex; flex-direction: column; gap: 6px;
  background: var(--window); border: 1px solid var(--ink);
  padding: 12px 16px; color: var(--ink); text-decoration: none;
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.4);
}
.swap-row:hover { text-decoration: none; background: var(--bevel-2); }
.swap-row-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.swap-row-head b { font-size: 0.95rem; }
.swap-row a { color: var(--ink); }
.swap-row-title { text-decoration: none; color: inherit; }
.swap-row-title:hover { text-decoration: underline; }
.swap-row-meta {
  display: flex; flex-direction: column; gap: 2px;
  font-size: 0.85rem; line-height: 1.45;
}
.swap-row-pair { font-weight: 700; }
.row-arrow {
  color: var(--soft); align-self: flex-end; font-weight: 600;
  text-decoration: none;
}
.row-arrow:hover { text-decoration: underline; }

/* A listing code that links to the listing's own page. */
.code-link {
  font-family: var(--font-mono); letter-spacing: 0.04em;
  color: var(--ink); text-decoration: underline dotted;
  text-underline-offset: 2px; overflow-wrap: anywhere;
}
.code-link:hover { text-decoration-style: solid; }
.pill .code-link { color: var(--ink); }

/* ---------- Auth ---------- */

.auth-panel { max-width: 460px; margin-left: auto; margin-right: auto; }
.auth-error {
  border: 1px solid var(--ink); background: var(--window);
  color: var(--ink); padding: 8px 12px; margin-top: 14px; font-weight: 700;
  font-size: 13px;
}
.recovery-box { margin-top: 16px; }

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

.error-panel { text-align: center; padding: 50px 30px; }
.error-panel h1 { font-family: var(--font-ui); font-size: 2rem; margin-bottom: 10px; color: var(--ink); }
.error-panel p { color: var(--soft); margin-bottom: 20px; }

.site-footer {
   padding: 12px 0 24px;
  color: var(--soft); font-size: 12px;
}
.foot-sub { opacity: 0.85; }

.faq-details { margin: 0; display: contents; }
.faq-details > summary {
  list-style: none; cursor: pointer;
  font-family: var(--font-ui); font-size: 12px; font-weight: 700;
  border: 1px solid var(--ink); padding: 4px 12px;
  background: var(--window); color: var(--ink);
  text-decoration: none; text-transform: unset; letter-spacing: 0.08em;
}
.faq-details > summary:hover, .faq-details > summary:focus-visible {
  background: var(--fill-hover); outline: none;
}
.faq-details > summary::-webkit-details-marker { display: none; }
.faq-details > summary::marker { content: ""; }
/* When the FAQ opens, the question list takes its own full-width line
   below the centered buttons instead of cramming into the row. The
   explicit `:not([open])` hide is required: `display: contents` on the
   <details> (so its summary joins the button row) makes Chromium skip the
   UA rule that hides a closed details' content, and without this the
   questions would render expanded on every page. */
.faq-list { flex: 1 1 100%; margin: 4px 0 0; border-top: 1px solid var(--bevel); }
.faq-details:not([open]) .faq-list { display: none; }
.faq-list details { border-bottom: 1px solid var(--bevel); }
.faq-list summary {
  list-style: none; cursor: pointer;
  padding: 8px 2px; font-size: 12px; font-weight: 600; color: var(--ink);
}
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary::marker { content: ""; }
.faq-list details p { margin: 0 0 10px; padding: 0 2px; opacity: 0.85; }

/* ---------- Open-ended & private listings ---------- */

.card-badges {
  display: flex; flex-direction: row; flex-wrap: wrap; gap: 6px;
  align-items: center; justify-content: flex-start; min-width: 0;
}
.lock-pill { background: var(--ink); color: var(--window); }
.open-pill { border-style: double; white-space: normal; text-align: right; }


.success-banner {
  border: 1px solid var(--ink); background: var(--ink); color: var(--window);
  padding: 9px 14px; margin: 16px 0 0; font-size: 13px; font-weight: 600;
}

/* Warning banner - the network-fee notice shown on the listing/request
   forms and after posting an amount close to the minimum. Same System 6
   panel treatment as the other banners, with a double border to read as a
   caution rather than success or error. */
.warn-banner {
  border: 2px solid var(--ink); background: var(--window);
  color: var(--ink); padding: 8px 12px; margin-top: 14px;
  font-weight: 600; font-size: 12px;
}

/* The little confirmation badge pinned to the middle-top of the gift page:
   a big checkmark plus a short line telling the player their swap's
   confirmation finished and the gift is unlocked. Fixed so it stays put
   while the wheel spins and the page scrolls. */
.confirm-done {
  position: fixed;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 16px 7px 8px;
  background: var(--window);
  border: 2px solid var(--ink);
  box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.45);
  font-size: 13px; font-weight: 700;
  max-width: calc(100vw - 24px);
}
.confirm-done-mark {
  flex-shrink: 0;
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--ink); color: var(--window);
  font-size: 16px; font-weight: 800; line-height: 1;
}

/* ---------- Share box ---------- */

.share-panel .share-box { margin-top: 14px; }
.share-box .listing-code { font-size: 0.95rem; word-break: break-all; letter-spacing: 0.04em; }

/* ---------- Buyer request queue ---------- */

.req-list { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
.req-row {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  border: 1px solid var(--ink); background: var(--fill); padding: 10px 12px;
}
.req-main { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 220px; }
.req-main b { font-size: 13px; }
.req-payout {
  font-size: 11px; color: var(--soft);
  background: var(--window); border: 1px solid var(--ink); padding: 3px 8px;
}
.req-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.req-actions form { margin: 0; }

@media (max-width: 640px) {
    .menu-bar { flex-wrap: wrap-reverse; gap: 2px;}

  .main-nav a, .menu-right a, #notify-toggle,
  .menu-form button { white-space: nowrap; font-size: 12px; }
  .hero { padding: 16px; }
  .hero-stats { gap: 8px; }
  .stat { min-width: 100px; padding: 8px 12px; }
  /* Deposit cards: airy still, but kept inside the viewport. */
  .deposit-grid { flex-direction: column; gap: 20px 16px; margin: 22px 0; }
  .deposit-grid > .deposit-card { flex: 1 1 auto; }
  .deposit-card { padding: 20px 18px; gap: 15px; }
  .flow-line { padding: 11px 12px; }
  .deposit-address { padding: 12px 13px; }
  .deposit-amounts { gap: 10px; }
  .deposit-amounts > div { padding: 10px 12px; }
  /* ---------- Notification tray: bottom sheet on mobile ---------- */
  .notify-panel {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto;
      transform: translateX(0);

    width: 100%; max-width: 100%; max-height: 78vh;
    border-left: none; border-right: none; border-bottom: none;
    box-shadow: 0 -4px 0 rgba(0, 0, 0, 0.5);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .notify-panel .notify-list {
    flex: 1 1 auto; min-height: 0; max-height: none;
  }
  .notify-switch { font-size: 9px; padding: 3px 6px; white-space: nowrap; }
  .notify-badge { top: -5px; right: -3px; }

}


/* ---------- Submit button busy dots (CAPTCHA pending) ---------- */

.btn.is-loading {
  pointer-events: none;
  cursor: wait;
}

/* ---------- Gift roulette (completed swaps) ---------- */

.gift-note {
  margin: 10px 0 0; padding: 8px 10px;
  background: var(--fill); border: 1px solid var(--ink);
  font-size: 13px;
}
.gift-box {
  display: flex; align-items: center; gap: 10px;
  margin-top: 12px; padding: 10px 12px;
  border: 2px dashed var(--ink); background: var(--fill);
  color: var(--ink); text-decoration: none;
}
.gift-box:hover { background: var(--fill-hover); }
.gift-box-icon { font-size: 22px; line-height: 1; }
.gift-box-text { display: flex; flex-direction: column; }
.gift-box-text b { font-size: 13px; text-transform: unset; letter-spacing: 0.05em; }
.gift-box-text span { font-size: 11px; color: var(--soft); }
.gift-panel code { word-break: break-all; }
.gift-result {
  margin: 0 0 18px; padding: 14px 16px;
  font-size: 16px; font-weight: 700; border: 1px solid var(--ink);
}
.gift-result.won { background: var(--window); }
.gift-result.lost { color: var(--soft); border-color: var(--soft); }
.gift-code-box {
  margin: 0 0 18px; padding: 14px 16px;
  background: var(--window); border: 2px solid var(--ink);
  box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.45);
  display: flex; flex-direction: column; gap: 6px;
}
.gift-code-box b { font-size: 20px; letter-spacing: 0.08em; }
.gift-code-box span { font-size: 12px; color: var(--soft); }

/* The wheel: 20 numbered pockets form a continuous rim around the hub - a
   real roulette look, not free-floating squares. Every cell is placed by a
   server-computed transform; the game is pure HTML + CSS, no JS. Each pocket
   is a trapezoid drawn with clip-path: wider at the outer rim and tapered
   toward the centre, and its outer width is exactly the arc chord for 20
   pockets, so neighbours meet edge to edge and together read as one ring.
   All geometry (pockets, ball track, centre hub, rim rail) is sized off
   --wheel-r. On large screens the wheel keeps the classic capped roulette
   size (R=170); on small screens (max-width 640px) it grows to fill the
   width of the article column (.container, the page content) via cqw =
   container query units - never overflowing it. The wheel is allowed to
   overhang the slimmer .gift-wheel-frame / panel that hosts it; only the
   article bounds it. Pocket 1 sits at 12 o'clock; the ball launches from
   the round's own --ball-start angle and its CSS animation ends at the
   server-injected --spin-deg, landing exactly on the winning pocket. */
.gift-wheel {
  /* Keep the wheel at its computed size inside the flex frame instead of
     letting it shrink to the frame's width: the wheel is designed to
     overhang its slim frame, and a shrunk box misaligns the cells/rim
     (and can push the page wide on phones). */
  flex-shrink: 0;
  --wheel-r: min(170px, calc((100cqw - 34px) / 2.32));
  /* Pocket depth is a fixed fraction of the radius too, so the ring stays
     proportional (≈54px at R=170, ≈34px on a 320px phone) as it shrinks. */
  --cell-rad: calc(var(--wheel-r) * 0.318);
  /* Outer width is the rim chord for exactly 20 pockets (sin(9°) ≈
     0.156434), so they touch end to end. */
  --cell-tan: calc(2 * (var(--wheel-r) + var(--cell-rad) / 2) * 0.156434);
  /* The center disc's radius: the pockets' inner edge is a faceted 20-gon
     with tips at R − cell-rad/2, so the center extends a small overlap past
     their tips at EVERY size to keep the hub side clean. */
  --center-r: calc(var(--wheel-r) - var(--cell-rad) / 2 + 8px);
  /* The outer rail overhangs the pocket rim by this much on each side; it
     thins slightly when the wheel is small so the rail stays slim. */
  --rim-ov: min(17px, calc(8px + var(--wheel-r) * 0.055));
  position: relative;
  width: calc(2 * (var(--wheel-r) + var(--cell-rad) / 2) + 34px);
  height: calc(2 * (var(--wheel-r) + var(--cell-rad) / 2) + 34px);
  margin: 24px auto 16px;
}
.gift-cell {
  position: absolute;
  left: 50%; top: 50%;
  width: var(--cell-rad); height: var(--cell-tan);
  margin: calc(-1 * var(--cell-tan) / 2) 0 0 calc(-1 * var(--cell-rad) / 2);
  cursor: pointer;
  /* The pocket shape lives on the cell itself, which is the only element in
     the right (radially rotated) frame: wide at the rim, tapering straight
     toward the hub, so every pocket is aimed exactly at the centre. The
     12%/88% clip-points mirror the inner:outer radius ratio, so the inner
     edge also meets its neighbours and the ring stays complete. */
  clip-path: polygon(0 12%, 0 88%, 100% 100%, 100% 0);
}
.gift-cell input[type="radio"] {
  position: absolute; opacity: 0; pointer-events: none;
}
.gift-cell span {
  position: absolute;
  /* Oversized so the counter-rotation that keeps the number upright can
     never uncover a corner of the pocket; the cell's clip-path trims the
     overflow back to the trapezoid. */
  inset: -30%;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; line-height: 1;
  user-select: none;
}
.gift-cell:nth-child(even) span { background: var(--line-soft); }
.gift-cell:hover span { background: var(--bevel-2); }
.gift-cell.picked span { background: var(--ink); color: var(--window); }
/* The winning pocket's glow appears only AFTER the ball has stopped: a
   drop-shadow follows the clipped trapezoid silhouette (a box-shadow ring
   would be cut off by the clip-path), lighting the whole pocket up for the
   15s spin, then it fades in. */
.gift-cell.landed {
  --ring-color: var(--ink);
  animation: gift-ring 15s forwards;
}
.gift-cell.picked.landed {
  --ring-color: var(--shade);
}
@keyframes gift-ring {
  0%, 95% { filter: drop-shadow(0 0 0 rgba(0, 0, 0, 0)); }
  100%    { filter: drop-shadow(0 0 6px var(--ring-color, var(--ink))); }
}
/* The ball upgrade (static/gift-wheel.js): each box the ball rolls over
   turns black and fades back to its normal color - a short dark trail
   behind the ball. The class is added per crossing and removed ~0.3s
   later, so several boxes behind the ball are at different stages of the
   fade. Pure upgrade: without JavaScript the wheel simply spins silent
   and flashless. */
.gift-cell.pass span {
  animation: gift-pass 0.32s ease-out;
}
@keyframes gift-pass {
  0%, 25% { background: var(--ink); color: var(--window); }
  100%    { background: var(--window); color: var(--ink); }
}
/* The win celebration - pure HTML/CSS, so the party works with JavaScript
   switched off too. It hides inside .gift-reveal: everything appears at the
   moment the ball lands (reveal fade), matching the win sound. */
/* Full-page confetti rain: a fixed, click-through overlay of falling ASCII
   glyphs spread edge to edge. Each piece's left/delay/speed is server-set
   inline, so no JavaScript is needed. */
.gift-confetti {
  position: fixed;
  inset: 0;
  z-index: 40;
  pointer-events: none;
  overflow: hidden;
}
.gift-confetti i {
  position: absolute;
  top: -7vh;
  font-style: normal;
  font-size: 16px; line-height: 1;
  color: var(--ink);
  opacity: 0;
  animation: gift-confetti-fall var(--dur, 3.4s) linear var(--delay, 0ms) infinite;
}
@keyframes gift-confetti-fall {
  0%   { transform: translateY(-6px) rotate(0deg); opacity: 0; }
  10%  { opacity: 1; }
  100% { transform: translateY(112vh) rotate(540deg); opacity: 0; }
}
/* The lucky code - front and centre of the win. */
.gift-win-code {
  text-align: center;
  margin: 14px auto 4px;
  padding: 14px 18px;
  max-width: 430px;
  border: 2px solid var(--ink);
  background: var(--window);
  box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.35);
}
.gift-win-code span { display: block; font-size: 12px; color: var(--soft); }
.gift-win-code b {
  display: block;
  font-family: var(--font-mono);
  font-size: 26px; letter-spacing: 0.12em;
  margin: 4px 0 2px;
}
/* The won banner pulses a box-shadow halo while it sits on screen. */
.gift-result.won {
  animation: gift-won-pulse 1.1s ease-in-out infinite;
}
@keyframes gift-won-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); }
  50%      { box-shadow: 0 0 0 9px rgba(0, 0, 0, 0.16); }
}
/* The center: a solid disc that mirrors the outer rail - the pockets' inner
   edge is faceted chords too, so this disc extends a few px over the pocket
   tips and crops the hub side to one clean circle. Same footprint for the
   paid text ad. */
.gift-center-hub {
  position: absolute; left: 50%; top: 50%;
  width: calc(2 * var(--center-r));
  height: calc(2 * var(--center-r));
  margin: calc(-1 * var(--center-r)) 0 0 calc(-1 * var(--center-r));
  border-radius: 50%;
  border: 1px solid var(--faint);
  background: var(--window);
}
/* A paid text ad in the wheel's center - same area as the hub, with the
   title centered and linked. The ad sits inside a .gift-center-slot wrapper
   (a same-sized circle, positioned like the hub) so the hover "Report"
   button can be pinned to the circle's bottom-right corner; the ad link
   itself fills the slot. */
.gift-center-slot {
  position: absolute; left: 50%; top: 50%;
  width: calc(2 * var(--center-r));
  height: calc(2 * var(--center-r));
  margin: calc(-1 * var(--center-r)) 0 0 calc(-1 * var(--center-r));
  clip-path: circle(50%);
}
.gift-center-sponsor {
  position: static;
  width: 100%; height: 100%;
  border-radius: 50%;
  border: 1px solid var(--faint);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px;
  text-align: center;
  padding: 28px;
  font-size: 14px; font-weight: 700;
  color: var(--ink); text-decoration: none;
  overflow: hidden;
  background: var(--window);
  clip-path: circle(50%);
}
.gift-center-sponsor:hover { background: var(--bevel-2); }
/* The ball travels on the exact circle the boxes sit on (the same radius
   the server uses for every cell's transform), so it rolls right over the
   boxes; the boxes themselves are the track, no extra ring. Its
   rest/launch position is the server-injected --ball-start (derived from
   the round's commitment), so it never starts from the same spot. */
.gift-ball-wrap {
  position: absolute; left: 50%; top: 50%;
  width: calc(2 * var(--wheel-r));
  height: calc(2 * var(--wheel-r));
  margin: calc(-1 * var(--wheel-r)) 0 0 calc(-1 * var(--wheel-r));
  transform: rotate(var(--ball-start, 0deg));
  /* The transparent track box covers the whole wheel; without this it
     would swallow every click, making the radio boxes and the center ad
     unclickable. The ball itself inherits it. */
  pointer-events: none;
}
/* A circular rail on top of the pocket ring: the pockets end as straight
   rim chords, so their joint outline is faceted; this annulus (a solid disc
   masked down to a ring) covers that jagged outer edge and crops it to one
   clean circle, like the metal rail of a real roulette tray. It sits above
   the cells but is pointer-events: none, so picking a pocket still works. */
.gift-rim {
  position: absolute; left: 50%; top: 50%;
  width: calc(2 * (var(--wheel-r) + var(--cell-rad) / 2) + 2 * var(--rim-ov));
  height: calc(2 * (var(--wheel-r) + var(--cell-rad) / 2) + 2 * var(--rim-ov));
  margin: calc(-1 * (var(--wheel-r) + var(--cell-rad) / 2) - var(--rim-ov)) 0 0 calc(-1 * (var(--wheel-r) + var(--cell-rad) / 2) - var(--rim-ov));
  border-radius: 50%;
  background: var(--window);
  -webkit-mask: radial-gradient(circle closest-side, transparent calc(100% - 26px), #000 calc(100% - 25px));
  mask: radial-gradient(circle closest-side, transparent calc(100% - 26px), #000 calc(100% - 25px));
  z-index: 2;
  pointer-events: none;
}
.gift-ball {
  position: absolute; left: 50%; top: -9px;
  width: 18px; height: 18px; margin-left: -9px;
  background: var(--ink); border-radius: 50%;
  border: 1px solid var(--window);
}
.gift-ball-wrap.spinning {
  animation: gift-spin 17s cubic-bezier(0.15, 0.6, 0.2, 1) forwards;
}
@keyframes gift-spin {
  from { transform: rotate(var(--ball-start, 0deg)); }
  to   { transform: rotate(calc(var(--ball-start, 0deg) + var(--spin-deg))); }
}
/* Everything that names the result stays invisible while the ball spins
   and fades in only when it stops (durations match the 15s spin above).
   The reveal is a collapsed single-row grid while hidden, so the result
   never reserves blank space at the bottom of the page before it appears:
   only when the ball lands does the row expand to its content height and
   the fade bring it in. */
.gift-reveal {
  display: grid;
  grid-template-rows: 0fr;
  overflow: hidden;
  animation: gift-reveal 15s forwards;
}
.gift-reveal-inner {
  min-height: 0;
  overflow: hidden;
}
@keyframes gift-reveal {
  0%, 94%   { opacity: 0; grid-template-rows: 0fr; }
  100%      { opacity: 1; grid-template-rows: 1fr; }
}
/* Phones: tighten margins and let the wheel grow to fill the article column
   (it never overflows it - see the formula in .gift-wheel). */
@media (max-width: 440px) {
  .gift-wheel { margin: 16px auto 12px; }
  .ad-mock-wheel .gift-wheel { margin: 8px auto; }
}

/* ---------- Advertising ---------- */

/* Footer banner, rendered inline into the page footer (no iframe): a
   simple bordered strip with the ad title and optional subtitle. */
/* Tiny "Sponsored" hint shared by every paid placement - the footer banner,
   the listing-page box and the gift wheel center. Exactly like the
   notification tray's "Sponsored" time label: a small, plain, lowercase
   word that takes no visual space (no border, no padding, no uppercase).
   Placed AFTER the sponsor copy - never in front of it: on the row layouts it
   trails the text, in the wheel center it sits below the title. */
.sponsor-badge {
  font-family: var(--font-ui);
  font-size: 10px;
  color: var(--faint);
  white-space: nowrap;
}
.foot-sponsor {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 4px 10px; margin-top: 14px; padding: 8px 12px;
  border: 1px solid var(--ink); background: var(--bar); color: var(--ink);
  text-decoration: none; font-size: 12px;
  box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.45);
}
.foot-sponsor .sponsor-title { font-weight: 700; }
.foot-sponsor .sponsor-sub { color: var(--soft); }
/* The sponsor's monochrome glyph (one Unicode char, U+FE0E text
   presentation is appended server-side): sits before the sponsor title in every
   placement - banner, listing box, notification tray, wheel center, slot
   card and order page. */
.sponsor-icon {
  display: inline-block;
  font-size: 14px; line-height: 1;
  margin-right: 6px;
  vertical-align: -1px;
  color: var(--ink);
}
.gift-center-sponsor .sponsor-icon { font-size: 20px; margin-right: 0; margin-bottom: 2px; }
.sponsor-slot-card .sponsor-icon { font-size: 16px; margin-right: 8px; }
.sponsor-slot-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
overflow-x:auto;
overflow-y:auto; 
 margin: 12px 0 4px;
max-height: 320px;
}
.sponsor-slot-card {
  display: flex; flex-direction: column; gap: 6px;
  min-height: 120px;
  border: 1px solid var(--ink);
  background: var(--window);
  padding: 10px;
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.4);
}
.sponsor-slot-card.s-taken { background: var(--bevel-2); }
.sponsor-slot-card .muted { font-size: 12px; }
.sponsor-price { font-weight: 700; }
.stack-list { list-style: none; }
.stack-list li {
  padding: 6px 0;
  border-bottom: 1px solid var(--bevel);
}
@media (max-width: 640px) {
  .sponsor-slot-grid { grid-template-columns: repeat(2, 1fr); }
}
/* Phones: one slot per row - each card gets the full width and reads top to
   bottom (label, state, price) exactly like the gift-play panels do. */
@media (max-width: 560px) {
  .sponsor-slot-grid { grid-template-columns: 1fr; }
  .sponsor-slot-card { min-height: 0; }
}

/* ---------- Gift roulette polish ---------- */

.gift-steps {
  display: flex; flex-wrap: wrap; gap: 10px;
  list-style: none; margin: 0 0 18px; padding: 0;
}
.gift-steps li {
  flex: 1 1 200px;
  border: 1px solid var(--ink); background: var(--window);
  padding: 10px 12px; font-size: 12px;
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.4);
}
.gift-steps li b { display: block; font-size: 13px; text-transform: unset; letter-spacing: 0.04em; }

/* Not a sizing container itself: the wheel is sized off the article column
   (.container), so it may overhang this frame and its panel. The flex
   centering keeps a wider wheel's overhang even on both sides. */
.gift-wheel-frame {
  display: flex;
  justify-content: center;
  margin: 4px 0 14px; padding: 4px;
}
.gift-panel .gift-wheel-frame .gift-wheel { margin: 18px auto; }

.gift-result {
  margin: 0 0 18px; padding: 18px 20px;
  font-size: 20px; font-weight: 700; text-align: center;
  border: 2px solid var(--ink);
  box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.45);
}

/* ---------- /sponsors previews ("Where your sponsor appears") ---------- */

/* ---------- /ads previews ("Where your sponsor appears") ---------- */

/* Each placement preview is its own titled panel, exactly like the slot
   sections below it - the data-title tab carries the placement name and
   the preview sits in the window body. The plain heading above the grid
   names the section as a whole. */
.sponsor-mocks-head h2 {
  font-family: var(--font-ui); font-size: 15px; margin: 26px 0 4px;
}
.sponsor-mocks-head p { margin: 0 0 12px; }
.sponsor-mock-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px;
}
@media (max-width: 720px) { .sponsor-mock-grid { grid-template-columns: 1fr; } }
/* .panel supplies the window look (border, background, shadow, 20/22px
   padding); .sponsor-mock only arranges the preview content and cancels the
   panel's page-level vertical margins inside the grid. */
.sponsor-mock {
  margin: 0;
  display: flex; flex-direction: column; gap: 8px;
}
.sponsor-mock-page {
  border: 1px solid var(--faint); background: var(--mock-page);
  padding: 8px; display: flex; flex-direction: column; gap: 8px;
}
.sponsor-mock-content {
  font-size: 11px; color: var(--soft);
  border: 1px dashed var(--faint); padding: 8px;
}
.sponsor-mock-banner, .sponsor-mock-offer {
  display: flex; align-items: center; gap: 8px;
  border: 1px solid var(--ink); background: var(--bar); color: var(--ink);
  text-decoration: none; padding: 8px 10px;
}
.sponsor-mock-banner { justify-content: center; box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.5); }
.sponsor-mock-banner b, .sponsor-mock-offer b { font-size: 12px; }
.sponsor-mock-banner span, .sponsor-mock-offer span { font-size: 11px; color: var(--soft); }
/* The "Sponsored" hint keeps its real look even inside the previews, where
   the generic `.sponsor-mock-* span` rule above would otherwise restyle it. */
.sponsor-mock-banner .sponsor-sponsor, .sponsor-mock-offer .sponsor-sponsor {
  font-size: 10px; color: var(--faint);
}
.sponsor-mock-offer { box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.5); }
.sponsor-mock-tray { border: 1px solid var(--faint); box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.4); }
.sponsor-mock-tray .notify-item { cursor: default; }
/* Each placement preview is its own titled panel, exactly like the slot
   sections below it - the data-title tab carries the placement name and
   the preview sits in the window body. The plain heading above the grid
   names the section as a whole. */
.ad-mocks-head h2 {
  font-family: var(--font-ui); font-size: 15px; margin: 26px 0 4px;
}
.ad-mocks-head p { margin: 0 0 12px; }
.ad-mock-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px;
}
@media (max-width: 720px) { .ad-mock-grid { grid-template-columns: 1fr; } }
/* .panel supplies the window look (border, background, shadow, 20/22px
   padding); .ad-mock only arranges the preview content and cancels the
   panel's page-level vertical margins inside the grid. */
.ad-mock {
  margin: 0;
  display: flex; flex-direction: column; gap: 8px;
}
.ad-mock-page {
  border: 1px solid var(--faint); background: var(--mock-page);
  padding: 8px; display: flex; flex-direction: column; gap: 8px;
}
.ad-mock-content {
  font-size: 11px; color: var(--soft);
  border: 1px dashed var(--faint); padding: 8px;
}
.ad-mock-banner, .ad-mock-offer {
  display: flex; align-items: center; gap: 8px;
  border: 1px solid var(--ink); background: var(--bar); color: var(--ink);
  text-decoration: none; padding: 8px 10px;
}
.sponsor-mock-banner { justify-content: center; box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.5); }
.sponsor-mock-banner b, .sponsor-mock-offer b { font-size: 12px; }
.sponsor-mock-banner span, .sponsor-mock-offer span { font-size: 11px; color: var(--soft); }
/* The "Sponsored" hint keeps its real look even inside the previews, where
   the generic `.sponsor-mock-* span` rule above would otherwise restyle it. */
.sponsor-mock-banner .sponsor-badge, .sponsor-mock-offer .sponsor-badge {
  font-size: 10px; color: var(--faint);
}
.sponsor-mock-offer { box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.5); }
.ad-mock-tray { border: 1px solid var(--faint); box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.4); }
.ad-mock-tray .notify-item { cursor: default; }
.ad-mock-wheel .gift-wheel {
  /* Radius inherits from the shared .gift-wheel rule, so the preview wheel
     uses the exact same geometry as the real gift page (fills its card on
     phones, classic size on desktop) - no overflow, same look. */
  margin: 8px auto;
}
.ad-mock-wheel .gift-wheel-frame { padding: 0; }
/* The mock card itself is the sizing container so the preview wheel matches
   the real wheel's on-screen size (classic on desktop, filling on phones).
   No card padding: the wheel spans the card edge to edge exactly like the
   gift page's panel, so it reads identically on mobile. */
.ad-mock-wheel { container-type: inline-size; padding: 0; }
/* No card padding: the wheel spans the panel edge to edge exactly like the
   gift page's panel; the intro and hint paragraphs carry their own side
   padding so they don't touch the window border. */
.ad-mock-wheel > p.muted { margin: 0; padding: 10px 12px 0; }
.ad-mock-wheel > p.muted:last-child { padding: 0 12px 12px; }
/* The preview wheel is the real wheel markup (winning box 20, so the ball
   carries the same .spinning class and inline angles the game pages use):
   pick any box and the ball spins with the shared animation, ticking and
   flashing every box it passes as gift-wheel.js runs on this page too. It
   stops on box 20, whose ring fades in once the ball lands - so a buyer
   sees exactly how the spin looks and sounds. The ball rests hidden until
   a box is picked. */
.ad-mock-wheel .gift-ball-wrap { display: none; }
.ad-mock-wheel:has(input[type="radio"]:checked) .gift-ball-wrap {
  display: block;
  animation: gift-spin 15s cubic-bezier(0.15, 0.6, 0.2, 1) forwards;
}
.ad-mock-wheel:has(input[type="radio"]:checked) .gift-cell:nth-child(20) {
  --ring-color: var(--shade);
  animation: gift-ring 15s forwards;
}
/* Immediate visual feedback when a box is picked (real spin page too). */
.gift-cell:has(input[type="radio"]:checked) span {
  background: var(--ink); color: var(--window);
}

/* ---------- Listing-page sponsor box (offer detail) ---------- */

/* Listing-page sponsor box (offer detail), rendered inline below the listing
   content (no iframe): a bordered strip with a hard offset shadow, matching
   the System 6 panel look. */
.offer-sponsor {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px;
  margin: -18px 0 24px 0; padding: 12px 14px;
  border: 1px solid var(--ink); background: var(--bar); color: var(--ink);
  text-decoration: none; box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.5);
}
.offer-sponsor .sponsor-title { font-weight: 700; font-size: 13px; }
.offer-sponsor .sponsor-sub { color: var(--soft); font-size: 12px; }

/* ---------- "Report this sponsor" hover control ---------- */

/* Every live sponsor sits inside a positioned slot so its hover "Report" button
   can be pinned to the bottom-right corner. The button is a small beveled
   control carrying a "!" icon, hidden until the sponsor is hovered or
   keyboard-focused (so the sponsor itself reads clean), and linking to the
   report page's report form (#new-report) - sponsors are reported through that
   one form. It is a sibling of the sponsor link - an <a> cannot nest inside
   another <a> - which is why the slots wrap each placement. The slot
   wrappers inherit the sponsors' old outer margins so the pages lay out exactly
   as before. */
.sponsor-slot, .notify-slot { position: relative; }
.sponsor-slot.foot-slot { margin: 12px 0 20px 0; }
.sponsor-slot.foot-slot .foot-sponsor { margin-top: 0; }
.sponsor-slot.offer-slot { margin: -18px 0 24px 0; }
.sponsor-slot.offer-slot .offer-sponsor { margin: 0; }
.sponsor-report {
  position: absolute; right: 4px; bottom: 4px; z-index: 3;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px;
  font-family: var(--font-ui); font-size: 13px; font-weight: 700; line-height: 1;
  color: var(--ink); background: var(--window);
  border: 1px solid var(--ink); padding: 0 4px;
  text-decoration: none;
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.45);
  opacity: 0; pointer-events: none;
  transition: opacity 0.12s ease;
}

.sponsor-slot:hover .sponsor-report, .sponsor-slot:focus-within .sponsor-report,
.notify-slot:hover .sponsor-report, .notify-slot:focus-within .sponsor-report,
.gift-center-slot:hover .sponsor-report, .gift-center-slot:focus-within .sponsor-report {
  opacity: 1; pointer-events: auto;
}
.gift-center-slot .sponsor-report{
  right: 48px; bottom: 74px!important;
}
.sponsor-report:hover, .sponsor-report:focus-visible {     background: var(--ink);
  color: var(--window);  }
/* The mock banners' generic `span` rule shrinks every span; the icon keeps
   its own size. */
.sponsor-mock-banner .sponsor-icon, .sponsor-mock-offer .sponsor-icon { font-size: 14px; }

/* ---------- Inline POST forms next to buttons (e.g. Log out) ---------- */

form.inline { display: inline; margin: 0; }

/* ============================================================
   Dark theme - System 6 after dark
   Pure CSS, no JavaScript. The site defaults to the light System 6 look
   for everyone; the only way in is the navbar ☾/☀ switch - a plain form
   submit (no script) that stores the visitor's choice in the `ilv_theme`
   cookie, which the server renders as `html.theme-dark` / `html.theme-light`.
   The palette is the same monochrome System 6 look, but pure black:
   black desktop and windows, near-white ink, bevel highlights flipped.
   `color-scheme: dark` keeps the native widgets (checkboxes, selects,
   scrollbars, date pickers) dark too. The amber/green accents brighten
   for dark surfaces; the coin glyphs and the captcha keep their light
   chips on purpose - they are brand/verification art, not theme surfaces.
   ============================================================ */

/* Light palette - the visitor chose light in the navbar, or the OS default. */
html.theme-light {
  color-scheme: light;
}

/* Dark palette - the visitor chose dark in the navbar. */
html.theme-dark {
  color-scheme: dark;
  --desktop: #000000;
  --window: #000000;
  --bevel: #1c1c1c;
  --bevel-2: #101010;
  --shade: #3a3a3a;
  --ink: #f2f2f2;
  --soft: #a3a3a3;
  --faint: #666666;
  --bar: #000000;
  --fill: #0d0d0d;
  --fill-hover: #1a1a1a;
  --line: #262626;
  --line-soft: #1f1f1f;
  --checker-a: #141414;
  --checker-b: #0d0d0d;
  --btn-bevel: inset -1px -1px 0 #000000, inset 1px 1px 0 #2e2e2e,
               inset -2px -2px 0 #0a0a0a, inset 2px 2px 0 #242424;
  --btn-bevel-active: inset 1px 1px 0 #000000, inset -1px -1px 0 #2e2e2e;
  --switch-bevel: inset 1px 1px 0 #2e2e2e, inset -1px -1px 0 #000000;
  --timer-bevel: inset -2px -2px 0 #0a0a0a, inset 2px 2px 0 #242424;
  --input-inset: inset 1px 1px 0 rgba(0, 0, 0, 0.7);
  --amber-border: #c9a24a;
  --amber-text: #e0bd6a;
  --amber-bg: #2a2414;
  --amber-rail: #c9a24a;
  --amber-wash: rgba(201, 162, 74, 0.12);
  --green: #3fb950;
  --mock-page: #050505;
  --wallet-mid: #666666;
}

/* ---------- Navbar theme toggle (☾ dark / ☀ light) ---------- */

.theme-toggle {
  display: inline-flex; align-items: center;
  margin: 0;
}
.theme-toggle .theme-btn {
  font-family: var(--font-ui); font-size: 13px; line-height: 1;
  font-weight: 700; color: var(--ink);
  background: none; border: none; cursor: pointer;
  padding: 3px 6px;
  outline: 0;
  border: transparent 2px solid;
  height: 100%;
}

/* Theme button hover states */
.theme-toggle .theme-btn:hover,
.theme-toggle .theme-btn.on {
  background: var(--ink); color: var(--window);
  border: var(--ink) 2px solid;
}
