/* ================================================================
   bitFlyer Mobile-First Clone — style.css
   Breakpoints: base = mobile (<480px), sm ≥480px, md ≥768px, lg ≥1024px
   ================================================================ */

/* ── Reset & base ── */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  -webkit-tap-highlight-color: transparent;
}

:root {
  /* Colors */
  --bg-0:       #080a10;
  --bg-1:       #0d0f17;
  --bg-2:       #131620;
  --bg-3:       #1a1d2a;
  --bg-card:    #10131c;
  --border:     #1e2230;
  --border-2:   #252a3a;

  --text-1:     #f0f2f7;
  --text-2:     #c8cdd8;
  --text-3:     #9ca3af;
  --text-muted: #4b5563;
  --text-dim:   #374151;

  --green:      #22c55e;
  --green-bg:   #14532d;
  --red:        #ef4444;
  --red-bg:     #7f1d1d;
  --blue:       #3b82f6;
  --amber:      #fbbf24;

  /* Nav heights — used for sticky offsets. The top safe-area inset is
     folded in so the sticky ticker/section-nav still line up directly
     under the header once it grows to clear a status bar / notch in the
     installed PWA. env() resolves to 0px in a normal browser tab, so
     this is a no-op there rather than a standalone-only special case. */
  --header-h: calc(52px + env(safe-area-inset-top, 0px));
  --ticker-h: 38px;

  /* Spacing */
  --pad-xs: 4px;
  --pad-sm: 8px;
  --pad-md: 12px;
  --pad-lg: 16px;

  /* Type */
  --font: 'Inter', system-ui, -apple-system, sans-serif;
  --radius-sm: 4px;
  --radius:    6px;
  --radius-lg: 10px;
}

html {
  height: 100%;
  overscroll-behavior: none;
  /* Chrome colour, not page colour, and deliberately different from
     <body>.
     In an iOS home-screen app the system reserves the status-bar and
     home-indicator strips and paints them itself with the canvas
     background — the page never gets to draw there, so no amount of
     .bottom-nav styling can reach it. Taking the canvas background from
     <html> and matching it to the header/nav (--bg-2) makes those strips
     continue the app's chrome instead of showing the darker page
     background, so the nav reads as running to the physical bottom edge.
     <body> is pinned over the whole viewport with its own --bg-0, so
     this is only ever visible in those reserved strips (and behind an
     overscroll bounce). */
  background: var(--bg-2);
}

body {
  font-family: var(--font);
  font-size: 13px;
  background: var(--bg-0);
  color: var(--text-2);
  overscroll-behavior: none;
  display: flex;
  flex-direction: column;

  /* The shell is pinned to the visual viewport rather than sized with
     viewport units.
     100vh/100dvh and -webkit-fill-available all disagree with each other
     inside an iOS home-screen app: with a translucent status bar the web
     view is full-screen, but -webkit-fill-available reports the height
     *minus* the status bar, so the column came up short and the bottom
     nav floated well above the screen edge. Anchoring all four sides
     sidesteps the whole question — the box is whatever the viewport
     currently is, and it re-resolves for free when Android's URL bar
     slides away or the keyboard opens.
     Nothing scrolls <body> itself (every scrollable region is an inner
     container), so taking it out of flow costs nothing. Fixed
     positioning here does NOT become the containing block for the
     modals — only transform/filter/perspective do that — so they stay
     anchored to the viewport as before.
     The bottom safe-area inset deliberately lives on .bottom-nav, not
     here: as padding on <body> it shrinks the column and leaves a strip
     of page background under the nav instead of letting the bar reach
     the physical bottom edge like a native tab bar. */
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

/* ================================================================
   ICON SPRITE — sized/colored via the parent's font-size/color
   ================================================================ */
.icon {
  width: 1em;
  height: 1em;
  display: inline-block;
  vertical-align: middle;
  flex-shrink: 0;
}

/* Prevent accidental text-selection / callout menu when tapping or
   long-pressing repeatedly-tapped pill/tab controls on mobile */
.pair-btn, .coin-chip, .bs-tab, .ot-btn, .tf-btn, .ob-view-btn,
.trade-filter-btn, .snav-item, .bnav-item, .pct-btn, .qa-btn,
.settings-item, .kyc-doc-option, .kyc-upload-slot, .submit-btn,
.auth-btn, .modal-submit, .toggle-slider, .deposit-sim-btn {
  user-select: none;
  -webkit-user-select: none;
}

/* ================================================================
   SCROLLBAR
   ================================================================ */
::-webkit-scrollbar { width: 3px; height: 3px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 2px; }

/* ================================================================
   TOP HEADER
   ================================================================ */
.header {
  background: var(--bg-2);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  /* Top padding clears the status bar when installed; box-sizing is
     border-box, so the usable header content stays its nominal height. */
  padding: env(safe-area-inset-top, 0px) var(--pad-md) 0;
  height: var(--header-h);
  flex-shrink: 0;
  gap: 10px;
  position: sticky;
  top: 0;
  z-index: 100;
}

.logo {
  font-size: 17px;
  font-weight: 800;
  color: var(--text-1);
  letter-spacing: -0.5px;
  flex-shrink: 0;
}
.logo span { color: var(--blue); }

.pair-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 5px 10px;
  cursor: pointer;
  touch-action: manipulation;
}
.pair-btn:active { background: var(--border-2); }
.pair-name {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-1);
}
.pair-arrow {
  font-size: 10px;
  color: var(--text-muted);
}

/* Header price (mobile only) */
.header-price-block {
  margin-left: auto;
  text-align: right;
}
.header-price {
  font-size: 16px;
  font-weight: 700;
  color: var(--green);
  line-height: 1.2;
}
.header-change {
  font-size: 10px;
  color: var(--green);
}

/* Hamburger / menu icon */
.menu-btn {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 32px;
  height: 32px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px;
  flex-shrink: 0;
}
.menu-btn span {
  display: block;
  height: 2px;
  background: var(--text-3);
  border-radius: 1px;
  transition: transform 0.2s, opacity 0.2s;
}

/* ================================================================
   TICKER STRIP (scrollable stats bar)
   ================================================================ */
.ticker-strip {
  background: var(--bg-1);
  border-bottom: 1px solid var(--border);
  display: flex;
  overflow-x: auto;
  scrollbar-width: none;
  padding: 0 var(--pad-md);
  gap: 20px;
  flex-shrink: 0;
  height: var(--ticker-h);
  align-items: center;
  position: sticky;
  top: var(--header-h);
  z-index: 99;
}
.ticker-strip::-webkit-scrollbar { display: none; }

.ticker-stat {
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
}
.ticker-label {
  font-size: 9px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  white-space: nowrap;
}
.ticker-value {
  font-size: 11px;
  color: var(--text-3);
  font-weight: 500;
  white-space: nowrap;
}

/* ================================================================
   SECTION NAV (tabs: Chart / Book / Trade / Orders)
   ================================================================ */
.section-nav {
  background: var(--bg-1);
  border-bottom: 1px solid var(--border);
  display: flex;
  overflow-x: auto;
  scrollbar-width: none;
  flex-shrink: 0;
  position: sticky;
  top: calc(var(--header-h) + var(--ticker-h));
  z-index: 99;
}
.section-nav::-webkit-scrollbar { display: none; }

.snav-item {
  flex-shrink: 0;
  padding: 10px 16px;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: color 0.15s, border-color 0.15s;
  touch-action: manipulation;
  white-space: nowrap;
}
.snav-item.active {
  color: var(--blue);
  border-bottom-color: var(--blue);
}
.snav-item:active { background: rgba(255,255,255,0.05); }

/* ================================================================
   MAIN CONTENT — mobile single-column stack, desktop grid
   ================================================================ */
.main {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Each tab "page" hidden by default */
.tab-page {
  display: none;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
.tab-page.active {
  display: flex;
}

/* ================================================================
   PANEL SHARED
   ================================================================ */
.panel-title {
  font-size: 9px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  padding: 6px var(--pad-md);
  background: var(--bg-card);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

/* ================================================================
   CHART PAGE
   ================================================================ */
.chart-page-inner {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}

.chart-timeframes {
  display: flex;
  gap: 0;
  background: var(--bg-card);
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  scrollbar-width: none;
  flex-shrink: 0;
}
.chart-timeframes::-webkit-scrollbar { display: none; }

.tf-btn {
  padding: 8px 14px;
  font-size: 11px;
  color: var(--text-muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  flex-shrink: 0;
  touch-action: manipulation;
  transition: color 0.15s;
}
.tf-btn.active {
  color: var(--blue);
  border-bottom-color: var(--blue);
}
.tf-btn:active { background: rgba(255,255,255,0.05); }

/* Candle/Line toggle, pinned to the end of the same scrollable toolbar
   row as the timeframe pills — matches bitFlyer's real chart toolbar
   layout (timeframes + chart-type control together on one strip). */
.chart-type-toggle {
  display: flex;
  gap: 2px;
  margin-left: auto;
  padding: 4px 8px;
  flex-shrink: 0;
  align-self: center;
}
.ct-btn {
  padding: 4px 10px;
  font-size: 10px;
  font-weight: 600;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border-2);
  cursor: pointer;
  touch-action: manipulation;
  transition: color 0.15s, background-color 0.15s, border-color 0.15s;
}
.ct-btn:first-child { border-radius: 6px 0 0 6px; border-right: none; }
.ct-btn:last-child  { border-radius: 0 6px 6px 0; }
.ct-btn.active { color: #fff; background: var(--blue); border-color: var(--blue); }

/* Moving-average legend, overlaid top-left of the price chart itself
   (TradingView/Binance-style) rather than a separate legend row that
   would eat into the chart's own height. */
.chart-ma-legend {
  position: absolute;
  top: 6px;
  left: 10px;
  z-index: 2;
  display: flex;
  gap: 10px;
  font-size: 9px;
  font-weight: 600;
  pointer-events: none;
}
.ma-tag b { font-weight: 700; margin-left: 3px; }

.chart-area {
  flex: 1 1 auto;
  min-height: 120px;
  display: flex;
  flex-direction: column;
  background: var(--bg-0);
}
.price-chart-wrap {
  flex: 1 1 auto;
  min-height: 0;
  position: relative;
}
.volume-chart-wrap {
  flex: 0 0 56px;
  min-height: 0;
  position: relative;
  border-top: 1px solid var(--border);
}
.chart-area canvas {
  width: 100% !important;
  height: 100% !important;
  display: block;
}

/* Stats row below chart */
.chart-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--border);
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}
.chart-stat-cell {
  background: var(--bg-card);
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.cs-label {
  font-size: 9px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.3px;
}
.cs-value {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-2);
}
.cs-value.up   { color: var(--green); }
.cs-value.down { color: var(--red); }

/* ================================================================
   ORDER BOOK PAGE
   ================================================================ */
.ob-controls {
  display: flex;
  gap: var(--pad-sm);
  padding: var(--pad-sm) var(--pad-md);
  background: var(--bg-card);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  align-items: center;
}
.ob-view-btn {
  padding: 4px 10px;
  font-size: 10px;
  font-weight: 500;
  background: var(--bg-3);
  color: var(--text-muted);
  border-radius: var(--radius-sm);
  cursor: pointer;
  border: 1px solid var(--border-2);
  touch-action: manipulation;
}
.ob-view-btn.active {
  border-color: var(--blue);
  color: var(--blue);
}
.ob-view-btn:active { background: var(--bg-3); }
.ob-precision {
  margin-left: auto;
  font-size: 10px;
  color: var(--text-muted);
}
/* The precision picker sits inline in a compact toolbar, not a full
   modal field — override the custom-select trigger's default full-width
   button styling down to the same small pill the native <select> used. */
.ob-precision .cs-trigger-wrap { display: inline-block; }
.ob-precision .cs-trigger {
  width: auto;
  background: var(--bg-3);
  border: 1px solid var(--border-2);
  color: var(--text-2);
  border-radius: var(--radius-sm);
  font-size: 10px;
  padding: 2px 6px;
  gap: 4px;
}
.ob-precision .cs-trigger-chevron { width: 10px; height: 10px; }

.ob-headers {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  padding: 4px var(--pad-md);
  font-size: 9px;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  background: var(--bg-card);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.ob-headers span:nth-child(2),
.ob-headers span:nth-child(3) { text-align: right; }

.ob-scroll {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  flex: 1 1 auto;
  min-height: 0;
}

.ob-row {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  padding: 3px var(--pad-md);
  position: relative;
  cursor: pointer;
  touch-action: manipulation;
}
.ob-row:active { background: #1a1e2a; }

.ob-bar {
  position: absolute;
  right: 0; top: 0; bottom: 0;
  opacity: 0.12;
  pointer-events: none;
}
.ob-row.ask .price-col { color: var(--red); }
.ob-row.bid .price-col { color: var(--green); }
.ob-row .ob-right  { text-align: right; }
.ob-row .ob-muted  { text-align: right; color: var(--text-muted); }

.ob-spread {
  text-align: center;
  padding: 5px;
  font-size: 10px;
  color: var(--amber);
  background: #141720;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.spread-mid {
  font-size: 15px;
  font-weight: 700;
  color: var(--green);
}

/* ================================================================
   TRADE PAGE (order form)
   ================================================================ */
.trade-page {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: var(--pad-md);
  display: flex;
  flex-direction: column;
  gap: var(--pad-md);
}

/* ── Coin selector chips ── */
.coin-select-row {
  display: flex;
  flex-wrap: nowrap;
  gap: 8px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  flex-shrink: 0;
  padding-bottom: 2px;
}
.coin-select-row::-webkit-scrollbar { display: none; }

.coin-chip {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  padding: 8px 14px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 20px;
  cursor: pointer;
  touch-action: manipulation;
  transition: all 0.15s;
  white-space: nowrap;
}
.coin-chip.active {
  border-color: var(--blue);
  background: rgba(59,130,246,0.1);
}
.coin-chip:active { background: var(--bg-3); }
.coin-chip-icon {
  font-size: 14px;
  width: 18px;
  text-align: center;
  flex-shrink: 0;
}
.coin-chip-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-3);
}
.coin-chip.active .coin-chip-label { color: var(--blue); }

@media (max-width: 380px) {
  .coin-chip {
    padding: 7px 10px;
    gap: 4px;
  }
  .coin-chip-label { font-size: 11px; }
}

.bs-tabs {
  flex-shrink: 0;
  display: flex;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--border);
}
.bs-tab {
  flex: 1;
  padding: 11px;
  text-align: center;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  background: var(--bg-card);
  color: var(--text-muted);
  transition: all 0.15s;
  touch-action: manipulation;
}
.bs-tab.buy.active  { background: var(--green-bg); color: var(--green); }
.bs-tab.sell.active { background: var(--red-bg);   color: var(--red); }
.bs-tab:active { filter: brightness(1.2); }

.order-type-row {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  flex-shrink: 0;
}
.ot-btn {
  padding: 6px 14px;
  font-size: 11px;
  font-weight: 500;
  background: var(--bg-card);
  color: var(--text-muted);
  border-radius: var(--radius-sm);
  cursor: pointer;
  border: 1px solid var(--border-2);
  touch-action: manipulation;
  transition: all 0.12s;
}
.ot-btn.active {
  border-color: var(--blue);
  color: var(--blue);
  background: rgba(59,130,246,0.08);
}
.ot-btn:active { background: var(--bg-3); }

.field { display: flex; flex-direction: column; gap: 5px; flex-shrink: 0; }
.field-label {
  font-size: 10px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.4px;
}
.input-wrap {
  display: flex;
  align-items: center;
  background: var(--bg-card);
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  padding: 0 var(--pad-md);
  height: 44px;
  transition: border-color 0.15s;
}
.input-wrap:focus-within { border-color: var(--blue); }
.input-wrap input {
  background: none;
  border: none;
  outline: none;
  color: var(--text-1);
  /* 16px avoids iOS Safari's zoom-on-focus (anything under 16px triggers it) */
  font-size: 16px;
  flex: 1;
  font-family: var(--font);
  min-width: 0;
}
.input-unit {
  font-size: 11px;
  color: var(--text-muted);
  flex-shrink: 0;
}

.pct-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
  flex-shrink: 0;
}
.pct-btn {
  padding: 8px 0;
  text-align: center;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-muted);
  background: var(--bg-card);
  border-radius: var(--radius-sm);
  cursor: pointer;
  border: 1px solid var(--border-2);
  touch-action: manipulation;
  transition: all 0.12s;
}
.pct-btn:active {
  background: var(--bg-3);
  color: var(--text-2);
}

.fee-row {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: var(--text-muted);
  padding: 2px 0;
  flex-shrink: 0;
}
.fee-row span:last-child { color: var(--text-3); }

.submit-btn {
  width: 100%;
  padding: 14px;
  border-radius: var(--radius);
  font-size: 15px;
  font-weight: 700;
  border: none;
  cursor: pointer;
  transition: filter 0.15s, transform 0.1s;
  touch-action: manipulation;
  letter-spacing: 0.2px;
  flex-shrink: 0;
}
.submit-btn:active { transform: scale(0.98); }
.submit-btn.buy  { background: #16a34a; color: #fff; }
.submit-btn.sell { background: #dc2626; color: #fff; }
.submit-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: none;
  transform: none;
}

.balance-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--pad-md);
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex-shrink: 0;
  /* extra breathing room so the card never sits flush against
     the bottom edge / safe-area on short screens */
  margin-bottom: var(--pad-md);
}
.balance-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
}
.balance-label { color: var(--text-muted); }
.balance-value { color: var(--text-2); font-weight: 600; }

/* ================================================================
   TRADES PAGE (recent trades)
   ================================================================ */
.trades-filters {
  display: flex;
  gap: var(--pad-sm);
  padding: var(--pad-sm) var(--pad-md);
  background: var(--bg-card);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.trade-filter-btn {
  padding: 4px 10px;
  font-size: 10px;
  background: var(--bg-3);
  color: var(--text-muted);
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-2);
  cursor: pointer;
  touch-action: manipulation;
}
.trade-filter-btn.active {
  border-color: var(--blue);
  color: var(--blue);
}
.trade-filter-btn:active { background: var(--bg-3); }

.trade-headers {
  display: grid;
  grid-template-columns: 70px 1fr 1fr;
  padding: 4px var(--pad-md);
  font-size: 9px;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  background: var(--bg-card);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.trade-headers span:nth-child(2),
.trade-headers span:nth-child(3) { text-align: right; }

.trades-list {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  flex: 1 1 auto;
  min-height: 0;
}

.trade-row {
  display: grid;
  grid-template-columns: 70px 1fr 1fr;
  padding: 4px var(--pad-md);
  border-bottom: 1px solid #0d0f17;
  align-items: center;
}
.trade-row .tr-time  { font-size: 11px; color: var(--text-dim); }
.trade-row .tr-price { text-align: right; font-size: 12px; font-weight: 600; }
.trade-row .tr-size  { text-align: right; font-size: 11px; color: var(--text-muted); }
.tr-price.buy  { color: var(--green); }
.tr-price.sell { color: var(--red); }

/* ================================================================
   BOTTOM NAV (mobile)
   ================================================================ */
.bottom-nav {
  background: var(--bg-2);
  border-top: 1px solid var(--border);
  display: flex;
  flex-shrink: 0;
  position: sticky;
  bottom: 0;
  z-index: 100;
  /* Carries the bottom safe area itself (see body) — the bar's
     background then runs to the physical bottom of the screen while its
     icons/labels stay clear of the iOS home indicator. 0 in a browser
     tab and on Android, so nothing changes there. */
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

.bnav-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 8px 4px;
  cursor: pointer;
  touch-action: manipulation;
  transition: color 0.15s;
  color: var(--text-muted);
}
.bnav-item.active { color: var(--blue); }
.bnav-item:active { background: rgba(255,255,255,0.05); }
.bnav-icon { font-size: 20px; line-height: 1; }
.bnav-label { font-size: 9px; font-weight: 500; letter-spacing: 0.3px; }

/* ================================================================
   PAIR SELECTOR DRAWER
   ================================================================ */
.drawer-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.7);
  z-index: 200;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s;
}
.drawer-overlay.open {
  opacity: 1;
  pointer-events: all;
}
.drawer {
  position: fixed;
  bottom: 0;
  left: 0; right: 0;
  background: var(--bg-2);
  border-radius: 16px 16px 0 0;
  z-index: 201;
  transform: translateY(100%);
  transition: transform 0.3s cubic-bezier(0.4,0,0.2,1);
  max-height: 80dvh;
  display: flex;
  flex-direction: column;
}
.drawer.open { transform: translateY(0); }

.drawer-handle {
  width: 36px;
  height: 4px;
  background: var(--border-2);
  border-radius: 2px;
  margin: 10px auto 0;
  flex-shrink: 0;
}
.drawer-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--text-1);
  padding: 14px var(--pad-lg) 10px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.drawer-search {
  margin: var(--pad-md);
  background: var(--bg-card);
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  padding: 10px 12px;
  color: var(--text-1);
  /* 16px avoids iOS Safari's zoom-on-focus (anything under 16px triggers it) */
  font-size: 16px;
  font-family: var(--font);
  outline: none;
  flex-shrink: 0;
}
.drawer-search:focus { border-color: var(--blue); }
.drawer-search::placeholder { color: var(--text-muted); }

.pair-list {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  flex: 1 1 auto;
  min-height: 0;
  padding-bottom: 16px;
}
/* Deliberately its own rule rather than grouped with .pair-list — that
   class is also targeted by SCROLL_LOCK_CONTAINERS (app.js) to freeze
   background scroll areas the instant any modal opens. Sharing the class
   here meant the picker's own list got inline overflow:hidden'd the
   moment the parent modal opened, silently beating this rule and making
   the list unscrollable no matter how tall the option list was. */
.cs-list {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  flex: 1 1 auto;
  min-height: 0;
  padding-bottom: 16px;
}
.pair-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px var(--pad-lg);
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  touch-action: manipulation;
}
.pair-item:active { background: var(--bg-3); }
.pair-item-name  { font-size: 14px; font-weight: 600; color: var(--text-1); }
.pair-item-full  { font-size: 11px; color: var(--text-muted); margin-top: 1px; }
.pair-item-price { text-align: right; }
.pair-item-pv    { font-size: 13px; font-weight: 600; color: var(--text-2); }
.pair-item-chg   { font-size: 11px; margin-top: 1px; }
.pair-item-chg.up { color: var(--green); }
.pair-item-chg.dn { color: var(--red); }

/* ================================================================
   CUSTOM SELECT — replaces every native <select> with a button that
   opens this same bottom-sheet picker (see enhanceCustomSelect() in
   app.js), so every dropdown in the app shares one on-brand
   interaction instead of each OS's native <select> UI.
   ================================================================ */
/* Triggers live inside modals (z-index 201), so the picker itself needs
   to sit above whatever modal opened it, not at the shared .drawer/.modal
   level — otherwise the parent modal (later in DOM order, same z-index)
   paints on top and the picker opens invisibly behind it. */
.cs-overlay { z-index: 310; }
.cs-drawer { z-index: 311; }

/* Deliberately not position:relative — nothing inside needs it as an
   absolute-positioning context, and doing so would promote this above
   the leading icon (.modal-input-icon, itself position:absolute) in
   stacking order, covering it. The plain <select> it replaces was never
   positioned either, which is why the icon painted on top before. */
.cs-native { display: none !important; }
.cs-trigger {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: #0d0f17;
  border: 1px solid #252a3a;
  border-radius: 8px;
  padding: 12px 14px;
  color: #f0f2f7;
  font-size: 14px;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
  transition: border-color 0.15s;
}
.cs-trigger:active, .cs-trigger.cs-open { border-color: #3b82f6; }
.cs-trigger.has-icon { padding-left: 42px; }
.cs-trigger-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cs-trigger-placeholder .cs-trigger-label { color: #374151; }
.cs-trigger-chevron {
  width: 16px; height: 16px;
  color: #6b7280;
  flex-shrink: 0;
  transition: transform 0.2s;
}
.cs-trigger.cs-open .cs-trigger-chevron { transform: rotate(180deg); }
.cs-trigger.cs-disabled { opacity: 0.5; pointer-events: none; }

.cs-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 13px var(--pad-lg);
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  touch-action: manipulation;
}
.cs-item:active { background: var(--bg-3); }
.cs-item-label { font-size: 14px; color: var(--text-1); }
.cs-item.selected .cs-item-label { color: var(--blue); font-weight: 600; }
.cs-item-check { width: 18px; height: 18px; color: var(--blue); flex-shrink: 0; visibility: hidden; }
.cs-item.selected .cs-item-check { visibility: visible; }
.cs-drawer-empty { padding: 28px var(--pad-lg); text-align: center; font-size: 12px; color: var(--text-muted); }

/* ================================================================
   TOAST NOTIFICATION
   ================================================================ */
.toast {
  position: fixed;
  bottom: 90px;
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: var(--bg-3);
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  padding: 10px 18px;
  font-size: 12px;
  color: var(--text-1);
  z-index: 300;
  opacity: 0;
  transition: opacity 0.2s, transform 0.2s;
  pointer-events: none;
  /* wrap instead of nowrap — dynamic messages (e.g. insufficient-balance
     amounts) can be longer than the screen is wide */
  max-width: min(340px, calc(100vw - 32px));
  white-space: normal;
  text-align: center;
  line-height: 1.4;
}
.toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ================================================================
   DESKTOP BREAKPOINT — md (≥768px) two-column layout
   ================================================================ */
@media (min-width: 768px) {
  :root { --header-h: calc(48px + env(safe-area-inset-top, 0px)); }

  body { font-size: 12px; }

  /* height comes from --header-h above — no override needed here */

  /* Hide mobile bottom nav on desktop */
  .bottom-nav { display: none; }

  /* Top section-nav becomes persistent */
  .section-nav { display: flex; }
  .snav-item { padding: 10px 20px; }

  /* Main switches to 2-column: book | chart+order */
  .main {
    flex-direction: row;
    overflow: hidden;
    flex: 1;
  }

  /* All tab pages visible at once in desktop grid */
  .tab-page {
    display: flex !important;
    overflow: hidden;
  }

  /* Book column */
  #page-book {
    width: 240px;
    flex-shrink: 0;
    border-right: 1px solid var(--border);
    flex-direction: column;
  }

  /* Chart takes remaining space */
  #page-chart {
    flex: 1;
    min-width: 0;
  }

  /* Trade form becomes right column */
  #page-trade {
    width: 220px;
    flex-shrink: 0;
    border-left: 1px solid var(--border);
    overflow-y: auto;
  }

  /* Trades panel merges below chart */
  #page-trades {
    display: none !important; /* merged into chart page on desktop */
  }

  .trade-page {
    padding: var(--pad-md);
    gap: 10px;
  }

  .submit-btn { padding: 11px; font-size: 13px; }
  .bs-tab { padding: 8px; font-size: 12px; }
  .input-wrap { height: 36px; }
  .input-wrap input { font-size: 12px; }
  .pct-btn { padding: 5px 0; }

  /* No bottom-nav on desktop, so the toast shouldn't float 90px up
     with nothing beneath it */
  .toast { bottom: 24px; }
}

/* ================================================================
   DESKTOP BREAKPOINT — lg (≥1024px) three-column layout
   ================================================================ */
@media (min-width: 1024px) {
  #page-book { width: 230px; }
  #page-trade { width: 230px; }

  /* Show inline trades at bottom of chart area */
  .inline-trades {
    display: flex !important;
    flex-direction: column;
    height: 150px;
    flex-shrink: 0;
    border-top: 1px solid var(--border);
    overflow: hidden;
  }
}

/* Hide desktop-only elements on mobile */
.desktop-only { display: none; }
@media (min-width: 768px) {
  .desktop-only { display: flex; }
  .mobile-only  { display: none !important; }
}


/* ================================================================
   ACCOUNT PAGE
================================================================ */
.account-guest {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 48px 24px 32px;
  gap: 14px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  flex: 1 1 auto;
  min-height: 0;
}
.guest-logo {
  font-size: 28px;
  font-weight: 800;
  color: #f0f2f7;
  letter-spacing: -1px;
}
.guest-logo span { color: #3b82f6; }
.guest-sub {
  font-size: 13px;
  color: #6b7280;
  text-align: center;
  max-width: 280px;
  line-height: 1.5;
}
.auth-btn {
  width: 100%;
  max-width: 320px;
  padding: 14px;
  border-radius: 8px;
  font-size: 15px;
  font-weight: 700;
  border: none;
  cursor: pointer;
  transition: filter 0.15s;
  flex-shrink: 0;
}
.auth-btn:active { filter: brightness(0.9); }
.auth-btn.primary  { background: #3b82f6; color: #fff; }
.auth-btn.secondary {
  background: transparent;
  color: #3b82f6;
  border: 1.5px solid #3b82f6;
}
.guest-features { width: 100%; max-width: 320px; display: flex; flex-direction: column; gap: 14px; margin-top: 10px; flex-shrink: 0; }
.guest-feature { display: flex; align-items: center; gap: 14px; }
.gf-icon { font-size: 22px; }
.gf-title { font-size: 13px; font-weight: 600; color: #c8cdd8; }
.gf-desc  { font-size: 11px; color: #6b7280; margin-top: 2px; }

/* logged in dashboard — this is the critical fix: must scroll
   independently within the tab-page's bounded height */
.account-dashboard {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  gap: 0;
  /* extra bottom padding so the last settings item clears the
     iOS home-indicator / safe area and isn't flush to the edge */
  padding-bottom: calc(var(--pad-lg) + env(safe-area-inset-bottom));
}

.profile-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: #131620;
  border-bottom: 1px solid #1e2230;
  flex-shrink: 0;
}
/* A tappable badge (see openAvatarPicker() in app.js) showing one of the
   illustrated avatar SVGs — background color is set per-avatar in JS.
   The chrome here (ring + drop shadow + glossy highlight) stays the same
   regardless of which avatar/color is picked. */
.profile-avatar {
  width: 64px; height: 64px;
  border-radius: 50%;
  border: none;
  padding: 0;
  cursor: pointer;
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  position: relative;
  z-index: 0; /* establishes its own stacking context so ::after's negative
                 z-index below stays contained instead of escaping behind
                 sibling elements in .profile-bar */
  overflow: hidden;
  box-shadow: 0 0 0 3px rgba(255,255,255,0.05), 0 4px 12px rgba(0,0,0,0.35);
  touch-action: manipulation;
}
.profile-avatar:active { filter: brightness(0.92); }
.profile-avatar::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(160deg, rgba(255,255,255,0.28), rgba(255,255,255,0) 55%);
  pointer-events: none;
}
#profile-avatar-icon { width: 64px; height: 64px; }
/* Uploaded photo sits on top of the illustrated avatar; whichever is in
   use is toggled in applyProfilePhoto(). object-fit keeps a non-square
   photo from stretching inside the circular badge. */
#profile-avatar-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}
/* Monogram fallback — the default for a new account, and the same
   treatment most exchange apps use before a photo is set. Sized off the
   badge so it scales with it rather than being hard-coded twice. */
.avatar-initials {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  font-weight: 700;
  letter-spacing: 0.5px;
  color: #fff;
  border-radius: 50%;
  user-select: none;
}
/* Preview swatch inside the picker grid uses the same rules at a
   smaller size. */
.avatar-option .avatar-initials { font-size: 20px; position: static; }

/* Small camera chip — makes "you can change this" discoverable without
   a text label. Sits above the photo but inside the badge's clip. */
.avatar-cam-badge {
  position: absolute;
  right: -1px;
  bottom: -1px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--blue);
  border: 2px solid #131620;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  pointer-events: none;
}
.avatar-cam-badge svg { width: 10px; height: 10px; }
/* The badge would otherwise be clipped by the circular overflow:hidden
   on .profile-avatar, so let it show while the photo stays clipped. */
.profile-avatar { overflow: visible; }
.profile-avatar > #profile-avatar-icon,
.profile-avatar > #profile-avatar-photo { border-radius: 50%; }
.profile-avatar::after { border-radius: 50%; }

/* Upload / remove rows at the top of the avatar picker */
.photo-upload-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  cursor: pointer;
  text-align: left;
  margin-bottom: 8px;
  touch-action: manipulation;
}
.photo-upload-row:active { background: var(--bg-3); }
.pur-icon {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: rgba(59,130,246,0.14);
  color: #60a5fa;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.pur-icon svg { width: 16px; height: 16px; }
.photo-upload-row.danger .pur-icon { background: rgba(206,79,79,0.14); color: var(--red); }
.pur-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pur-title { font-size: 13px; font-weight: 700; color: var(--text-1); }
.pur-sub { font-size: 11px; color: var(--text-3); }

/* "or choose an avatar" rule */
.avatar-picker-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 6px 0 12px;
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}
.avatar-picker-divider::before,
.avatar-picker-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border);
}

/* Avatar picker modal — a simple 3-across grid of tappable badges,
   matching the same "colored circle + white icon" chrome as the profile
   badge itself so the picker previews look exactly like the result. */
.avatar-picker-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
}
.avatar-option {
  aspect-ratio: 1;
  width: 100%;
  border-radius: 50%;
  border: 2px solid transparent;
  padding: 0;
  cursor: pointer;
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  position: relative;
  z-index: 0;
  overflow: hidden;
  touch-action: manipulation;
  box-shadow: 0 0 0 3px rgba(255,255,255,0.05), 0 4px 12px rgba(0,0,0,0.35);
}
.avatar-option::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(160deg, rgba(255,255,255,0.28), rgba(255,255,255,0) 55%);
  pointer-events: none;
}
.avatar-option .icon { width: 100%; height: 100%; }
.avatar-option.selected { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(59,130,246,0.35), 0 4px 12px rgba(0,0,0,0.35); }
.avatar-option:active { filter: brightness(0.92); }
.profile-name  { font-size: 14px; font-weight: 700; color: #f0f2f7; }
.profile-email { font-size: 11px; color: #6b7280; margin-top: 2px; }
.profile-badges { display: flex; align-items: center; gap: 6px; margin-top: 6px; flex-wrap: wrap; }
.profile-badge {
  font-size: 9px;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 10px;
  text-transform: uppercase;
  letter-spacing: 0.3px;
}
.profile-badge-vip {
  display: inline-flex;
  align-items: center;
  line-height: 0;
  filter: drop-shadow(0 1px 1.5px rgba(0,0,0,0.4));
}
.vip-shield-icon { width: 19px; height: 21px; }
.profile-badge.unverified {
  background: var(--bg-3);
  color: var(--text-muted);
  border: 1px solid var(--border-2);
}
.profile-badge.verified {
  background: #14532d;
  color: #53c27c;
}
.logout-btn {
  margin-left: auto;
  padding: 6px 12px;
  font-size: 11px;
  font-weight: 600;
  background: transparent;
  border: 1px solid #374151;
  border-radius: 6px;
  color: #9ca3af;
  cursor: pointer;
  flex-shrink: 0;
}
.logout-btn:active { background: #1a1d2a; }

/* "Complete your account" onboarding checklist — 2FA -> bank -> AI
   Trading Desk -> deposit, in that order (see initSetupChecklist() in
   app.js). Deliberately calm/professional chrome (unlike the loud promo
   banners elsewhere) — a credible-sounding official onboarding flow is
   its own, quieter kind of trust-building red flag. */
.setup-checklist {
  margin: 14px 14px 0;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px;
  flex-shrink: 0;
}
.sc-header { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 10px; }
.sc-title { font-size: 14px; font-weight: 700; color: var(--text-1); }
.sc-subtitle { font-size: 11px; color: var(--text-3); margin-top: 2px; font-weight: 600; }
.sc-dismiss {
  width: 24px; height: 24px;
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; color: var(--text-3); cursor: pointer; flex-shrink: 0;
}
.sc-dismiss svg { width: 13px; height: 13px; }

.sc-progress-track { height: 4px; background: var(--border); border-radius: 999px; overflow: hidden; margin-bottom: 4px; }
.sc-progress-fill { height: 100%; background: var(--blue); border-radius: 999px; transition: width 0.3s ease; }

.sc-items { display: flex; flex-direction: column; margin-top: 8px; }
.sc-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 4px;
  border-radius: 8px;
  cursor: pointer;
}
.sc-item:not(:last-child) { border-bottom: 1px solid var(--border); }
.sc-item:hover { background: rgba(255,255,255,0.03); }

/* Icon badge — shows the feature icon by default; swaps to a green
   checkmark once that step is verified done (see initSetupChecklist()). */
.sc-item-icon {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: rgba(255,255,255,0.06);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  transition: background 0.2s ease;
}
.sc-item-icon svg { width: 17px; height: 17px; color: var(--text-2); }
.sc-icon-done { display: none; }
.sc-item.done .sc-icon-feature { display: none; }
.sc-item.done .sc-icon-done { display: block; }
.sc-item.done .sc-item-icon { background: var(--green); }
.sc-item.done .sc-item-icon svg { color: #fff; }

.sc-item-body { flex: 1; min-width: 0; }
.sc-item-eyebrow { font-size: 9.5px; font-weight: 700; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 1px; }
.sc-item.done .sc-item-eyebrow { color: var(--green); }
.sc-item-title { font-size: 13px; font-weight: 600; color: var(--text-1); }
.sc-item-sub { font-size: 11.5px; color: var(--text-3); margin-top: 2px; }
.sc-item.done .sc-item-title { color: var(--text-2); }

/* Only the first not-yet-done item gets this — a quiet nudge toward
   what to do next, the same convention polished onboarding checklists
   (Chime/Wealthfront-style "getting started" cards) use. */
.sc-item-next {
  display: none;
  font-size: 9.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #60a5fa;
  background: rgba(59,130,246,0.14);
  border: 1px solid rgba(59,130,246,0.35);
  padding: 3px 8px;
  border-radius: 999px;
  flex-shrink: 0;
}
.sc-item.next-step .sc-item-next { display: inline-flex; }

.sc-item-chevron { width: 14px; height: 14px; color: var(--text-3); flex-shrink: 0; transform: rotate(-90deg); }

.total-balance-card {
  background: linear-gradient(135deg, #1a237e 0%, #0d47a1 100%);
  margin: 14px;
  border-radius: 12px;
  padding: 20px;
  flex-shrink: 0;
}
.tb-header { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.tb-label  { font-size: 11px; color: rgba(255,255,255,0.7); text-transform: uppercase; letter-spacing: 0.5px; }
.tb-amount { font-size: 28px; font-weight: 800; color: #fff; letter-spacing: -1px; }
.tb-change { font-size: 12px; }
.tb-change.up   { color: #86efac; }
.tb-change.down { color: #fca5a5; }

.currency-toggle {
  background: rgba(255,255,255,0.15);
  border: 1px solid rgba(255,255,255,0.3);
  border-radius: 6px;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  padding: 4px 9px;
  cursor: pointer;
  flex-shrink: 0;
}
.currency-toggle:active { background: rgba(255,255,255,0.28); }

/* Balance amount + its visibility toggle sit on their own row, eye button
   right beside the figure — a small frosted-glass circle, not a bordered
   chip, the way Nigerian fintech apps (PalmPay/Kuda/PocketApp-style
   balance cards) place the show/hide control directly next to the
   number rather than up in the header. */
.tb-amount-row { display: flex; align-items: center; gap: 10px; margin: 6px 0 4px; }
.tb-eye-btn {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255,255,255,0.16);
  border: none;
  color: #fff;
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.15s ease, transform 0.15s ease;
}
.tb-eye-btn:active { background: rgba(255,255,255,0.32); transform: scale(0.92); }
.tb-eye-btn svg { width: 16px; height: 16px; }

.wallet-section { padding: 0 14px 8px; flex-shrink: 0; }
.wallet-section-header { display: flex; align-items: center; justify-content: space-between; padding: 10px 0 8px; }
.ws-title { font-size: 13px; font-weight: 700; color: #f0f2f7; }
.ws-edit-btn {
  font-size: 11px; font-weight: 600; color: #3b82f6;
  background: none; border: none; cursor: pointer; padding: 4px 8px;
}

.wallet-list, .wallet-edit-list { display: flex; flex-direction: column; gap: 8px; }

.wallet-edit-section-title { font-size: 12px; font-weight: 700; color: #9ca3af; margin-bottom: 8px; }
.wallet-edit-divider { border: none; border-top: 1px solid #1e2230; margin: 18px 0; }

/* Add-a-coin search results — no own scroll/max-height, same reasoning
   as .faq-list: the outer .modal is the only scroll container. */
.coin-search-results { display: flex; flex-direction: column; gap: 8px; }
.coin-search-item {
  background: #10131c;
  border: 1px solid #1e2230;
  border-radius: 10px;
  padding: 10px 12px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.coin-search-icon { width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0; }
.coin-search-item .ws-edit-btn { border: 1px solid #1e2230; border-radius: 8px; flex-shrink: 0; }

/* Press-and-drag handle for reordering wallet rows inside Manage Wallets.
   touch-action:none is scoped to just this small handle (not the row or
   the list) so grabbing it to drag doesn't also fight the modal's own
   scroll — the broader touch-action rules that caused real scroll bugs
   elsewhere in this app were the mistake of applying it too widely, not
   of using it at all. */
.wallet-drag-handle {
  flex-shrink: 0;
  width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center;
  color: #6b7280;
  font-size: 16px;
  letter-spacing: -2px;
  cursor: grab;
  touch-action: none;
  user-select: none;
}
.wallet-item.dragging {
  cursor: grabbing;
  z-index: 5;
  position: relative;
  box-shadow: 0 8px 20px rgba(0,0,0,0.35);
  border-color: #3b82f6;
}
.wallet-item {
  background: #10131c;
  border: 1px solid #1e2230;
  border-radius: 10px;
  padding: 12px 14px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.wallet-icon {
  width: 36px; height: 36px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px;
  flex-shrink: 0;
}
.wallet-info { flex: 1; min-width: 0; }
.wallet-name  { font-size: 13px; font-weight: 600; color: #f0f2f7; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wallet-addr  { font-size: 10px; color: #4b5563; margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wallet-right { text-align: right; flex-shrink: 0; }
.wallet-amount { font-size: 13px; font-weight: 700; color: #f0f2f7; }
.wallet-jpy    { font-size: 10px; color: #6b7280; margin-top: 2px; }
.wallet-fix-icon-btn {
  font-size: 10px; font-weight: 600; color: #3b82f6;
  background: none; border: none; cursor: pointer; padding: 2px 0; margin-top: 2px;
}

.quick-actions {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  padding: 0 14px 14px;
  flex-shrink: 0;
}
.qa-btn {
  background: #10131c;
  border: 1px solid #1e2230;
  border-radius: 10px;
  padding: 14px 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  touch-action: manipulation;
}
.qa-btn:active { background: #1a1d2a; }
.qa-icon  { font-size: 20px; }
.qa-label { font-size: 10px; color: #9ca3af; font-weight: 500; }

.settings-list {
  margin: 0 14px 24px;
  background: #10131c;
  border: 1px solid #1e2230;
  border-radius: 10px;
  overflow: hidden;
  flex-shrink: 0;
}
.settings-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  border-bottom: 1px solid #1a1d2a;
  cursor: pointer;
  touch-action: manipulation;
}
.settings-item:last-child { border-bottom: none; }
.settings-item:active { background: #1a1d2a; }
.si-icon  { font-size: 18px; width: 24px; text-align: center; }
.si-label { font-size: 13px; color: #c8cdd8; flex: 1; }
.si-arrow { font-size: 18px; color: #374151; }
.si-notify-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--red);
  flex-shrink: 0;
}
/* Small pill on the "Install app" row — the same quiet accent the promo
   banners use, so it draws a glance without shouting. */
.si-install-badge {
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #60a5fa;
  background: rgba(59,130,246,0.14);
  border-radius: 999px;
  padding: 3px 8px;
  flex-shrink: 0;
}

/* ================================================================
   MODALS (login, signup, edit wallet)
================================================================ */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.75);
  z-index: 200;
  display: none;
}
.modal-overlay.open { display: block; }

.modal {
  position: fixed;
  bottom: 0;
  left: 0; right: 0;
  background: #131620;
  border-radius: 20px 20px 0 0;
  z-index: 201;
  padding: 20px 20px calc(20px + env(safe-area-inset-bottom));
  display: none;
  flex-direction: column;
  gap: 14px;
  max-height: 92dvh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* Swiping past the top/bottom of the modal's own scroll range would
     otherwise chain the leftover scroll delta to whatever's behind it
     (the page rubber-bands into view for a moment, then springs back).
     `contain` stops that chaining at the modal's edge — the modal can
     still bounce internally, but the page underneath never moves. */
  overscroll-behavior: contain;
}
.modal.open { display: flex; }

/* On larger screens, center modals */
@media (min-width: 480px) {
  .modal {
    top: 50%;
    left: 50%;
    bottom: auto;
    right: auto;
    transform: translate(-50%, -50%);
    border-radius: 16px;
    width: 100%;
    max-width: 420px;
    max-height: 90vh;
  }
}

.modal-header { display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; }
.modal-logo { font-size: 20px; font-weight: 800; color: #f0f2f7; }
.modal-logo span { color: #3b82f6; }
.modal-close {
  background: #1a1d2a; border: none; color: #9ca3af;
  width: 30px; height: 30px; border-radius: 50%;
  font-size: 13px; cursor: pointer; display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.modal-title { font-size: 18px; font-weight: 700; color: #f0f2f7; }
.modal-title-group { display: flex; flex-direction: column; gap: 3px; }
.support-meta-row { display: flex; align-items: center; gap: 6px; }
.support-ticket-badge {
  font-size: 10.5px; font-weight: 600; color: #6b7280;
  font-family: 'SFMono-Regular', Consolas, monospace; letter-spacing: 0.3px;
}
.support-status-badge {
  font-size: 9.5px; font-weight: 700; padding: 2px 7px; border-radius: 999px;
  text-transform: uppercase; letter-spacing: 0.3px; white-space: nowrap;
}
.support-status-badge.open      { background: rgba(59,130,246,0.14);  color: #60a5fa; }
.support-status-badge.awaiting  { background: rgba(245,158,11,0.16);  color: #fbbf24; }
.support-status-badge.resolved  { background: rgba(107,114,128,0.18); color: #9ca3af; }
.support-agent-badge { font-size: 11px; color: var(--text-muted); }

.modal-field { display: flex; flex-direction: column; gap: 5px; flex-shrink: 0; }
.modal-label { font-size: 11px; color: #6b7280; text-transform: uppercase; letter-spacing: 0.4px; }
.modal-field-hint { font-size: 10px; color: #6b7280; line-height: 1.5; margin-top: 2px; }
.modal-input-wrap { position: relative; }
.modal-input {
  width: 100%;
  /* Flex items default to min-width:auto (their content's min-content
     size), not 0 — native inputs like type="date" have a fixed intrinsic
     width (MM/DD/YYYY segments + calendar icon) that some browsers won't
     shrink below, which overrides width:100% and pushes the field past
     its container's right edge. min-width:0 lets width:100% actually win. */
  min-width: 0;
  background: #0d0f17;
  border: 1px solid #252a3a;
  border-radius: 8px;
  padding: 12px 14px;
  color: #f0f2f7;
  /* 16px avoids iOS Safari's zoom-on-focus (anything under 16px triggers it) */
  font-size: 16px;
  font-family: inherit;
  outline: none;
  transition: border-color 0.15s;
}
.modal-input:focus { border-color: #3b82f6; }
.modal-input::placeholder { color: #374151; }
.modal-input:disabled { color: #6b7280; cursor: not-allowed; opacity: 0.7; }
/* Native number-input spinner clashes with the custom dark styling */
.modal-input[type="number"]::-webkit-inner-spin-button,
.modal-input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.modal-input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
/* Safari renders a date input's internal segments as their own flex box
   that ignores width:100% entirely unless the native appearance is
   dropped — min-width:0 above isn't enough on its own for this one. */
.modal-input[type="date"] {
  -webkit-appearance: none;
  appearance: none;
  max-width: 100%;
  overflow: hidden;
  line-height: 1.25;
}
.modal-eye {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  cursor: pointer;
  font-size: 16px;
  user-select: none;
}

/* Leading icon inside a login/signup field — sits on top of the input,
   pointer-events:none so it never blocks focusing/typing or opening a
   <select>'s native dropdown underneath it. */
.modal-input-icon {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  width: 18px; height: 18px;
  color: #4b5563;
  pointer-events: none;
  transition: color 0.15s;
}
.modal-input.has-icon { padding-left: 42px; }
.modal-input-wrap:focus-within .modal-input-icon { color: #3b82f6; }
.modal-forgot { text-align: right; flex-shrink: 0; }
.modal-forgot a { font-size: 12px; color: #3b82f6; text-decoration: none; }
.modal-error {
  font-size: 12px;
  color: #ef4444;
  min-height: 18px;
  text-align: center;
  flex-shrink: 0;
}
.modal-submit {
  width: 100%;
  padding: 14px;
  background: #3b82f6;
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: filter 0.15s;
  flex-shrink: 0;
}
.modal-submit:active { filter: brightness(0.9); }
.modal-submit:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: none;
  filter: none;
}

/* Side-by-side confirm/cancel buttons (logout confirm, etc.) */
.modal-btn-row { display: flex; gap: 10px; }
.modal-btn-row .modal-submit { width: auto; flex: 1; }
.modal-submit-secondary { background: var(--bg-3); color: var(--text-2); border: 1px solid var(--border-2); }
.modal-submit-danger    { background: var(--red); }
.modal-switch { font-size: 12px; color: #6b7280; text-align: center; flex-shrink: 0; }
.modal-switch a { color: #3b82f6; text-decoration: none; }

/* AI Trading Desk tour — drives real navigation through Chart/Book/
   Trade/Trades (see openAiTour()/aiTourNext() in app.js). A small
   floating card, not a full-width bottom sheet: JS (positionAiTourBar())
   pins it just under the section-nav tabs, the one spot common to all
   four steps, so it never parks on top of the bottom-nav or the
   trade-page buy/sell buttons. Kept genuinely see-through (low-alpha
   background, modest blur) so the real screen underneath — the thing
   being explained — stays legible through and around it. */
.ai-tour-bar {
  position: fixed;
  left: 12px; right: 12px;
  bottom: 76px;
  z-index: 150;
  display: none;
  flex-direction: column;
  background: rgba(16, 19, 28, 0.44);
  backdrop-filter: blur(11px) saturate(1.3);
  -webkit-backdrop-filter: blur(11px) saturate(1.3);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 14px;
  padding: 10px 12px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.28);
  overflow: hidden;
  max-width: 420px;
  margin: 0 auto;
}
/* Thin gradient hairline instead of a flat border — echoes the promo
   banners' top accent bar so the tour reads as part of the same design
   language rather than a bolted-on component. */
.ai-tour-bar::before {
  content: '';
  position: absolute;
  top: 0; left: 12%; right: 12%;
  height: 2px;
  background: linear-gradient(90deg, transparent, #60a5fa, transparent);
  opacity: 0.9;
}
/* Soft glow blob, same decorative technique as .promo-glow — pure
   texture, tucked behind the icon, clipped by overflow:hidden above. */
.atb-glow {
  position: absolute;
  top: -24px; left: -16px;
  width: 80px; height: 80px;
  border-radius: 50%;
  background: #3b82f6;
  filter: blur(28px);
  opacity: 0.2;
  pointer-events: none;
  animation: promoGlowPulse 4.5s ease-in-out infinite;
}

.atb-top { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; position: relative; z-index: 1; }
.atb-progress-wrap { flex: 1; min-width: 0; }
.atb-step-label { font-size: 9px; font-weight: 700; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 4px; }
.atb-progress-track { height: 2.5px; background: rgba(255,255,255,0.1); border-radius: 999px; overflow: hidden; }
.atb-progress-fill { height: 100%; background: linear-gradient(90deg, #3b82f6, #60a5fa); border-radius: 999px; transition: width 0.35s ease; }
.atb-close {
  width: 18px; height: 18px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,0.06); border: none; border-radius: 50%; color: var(--text-3); cursor: pointer;
  flex-shrink: 0;
}
.atb-close svg { width: 10px; height: 10px; }

.atb-body {
  display: flex; align-items: center; gap: 9px; margin-bottom: 9px;
  position: relative; z-index: 1;
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.atb-body.atb-fade-out { opacity: 0; transform: translateY(4px); }
.atb-icon {
  position: relative;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: rgba(59,130,246,0.22);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.atb-icon::before {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(59,130,246,0.4), transparent 70%);
  filter: blur(3px);
  z-index: -1;
  animation: atbIconPulse 2.2s ease-in-out infinite;
}
@keyframes atbIconPulse {
  0%, 100% { opacity: 0.45; transform: scale(1); }
  50%      { opacity: 0.9;  transform: scale(1.18); }
}
.atb-icon svg { width: 14px; height: 14px; color: #60a5fa; }
.atb-text { flex: 1; min-width: 0; }
.atb-title { font-size: 12.5px; font-weight: 700; color: var(--text-1); margin-bottom: 2px; }
.atb-desc { font-size: 11px; color: var(--text-2); line-height: 1.45; }

/* Compact pill buttons — the shared .modal-submit is sized for
   full-width modal sheets and dwarfed this small floating card. */
.ai-tour-bar .modal-btn-row { position: relative; z-index: 1; gap: 8px; }
.atb-btn {
  padding: 7px 14px;
  font-size: 12px;
  font-weight: 700;
  border-radius: 8px;
  border: none;
  cursor: pointer;
  transition: filter 0.15s;
  flex: none;
  width: auto;
}
.atb-btn:active { filter: brightness(0.9); }
.atb-btn-primary { background: #3b82f6; color: #fff; margin-left: auto; }
.atb-btn-secondary { background: rgba(255,255,255,0.08); color: var(--text-2); border: 1px solid rgba(255,255,255,0.12); }
.ai-tour-bar .modal-btn-row { justify-content: flex-end; }

/* Sign-up 3-step wizard — only the active step's fields render, so the
   sheet stays short instead of scrolling through 7 fields at once (see
   .signup-step below); this stepper is the "you are here" indicator. */
.signup-stepper { display: flex; align-items: center; flex-shrink: 0; margin: -6px 0 2px; }
.ss-step { display: flex; flex-direction: column; align-items: center; gap: 5px; flex-shrink: 0; }
.ss-circle {
  width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700;
  background: var(--bg-3); color: var(--text-muted);
  border: 1px solid var(--border-2);
  transition: background-color 0.2s, color 0.2s, border-color 0.2s;
}
.ss-step.active .ss-circle, .ss-step.done .ss-circle {
  background: #3b82f6; color: #fff; border-color: #3b82f6;
}
.ss-label {
  font-size: 9px; font-weight: 600; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.3px;
  transition: color 0.2s;
}
.ss-step.active .ss-label, .ss-step.done .ss-label { color: #f0f2f7; }
.ss-line {
  flex: 1; height: 2px; background: var(--border-2);
  margin: 0 4px 15px; transition: background-color 0.2s;
}
.ss-line.done { background: #3b82f6; }

/* Only the active step's field group is in flow — display:none removes
   the others from the modal's own flex gap entirely, which is what
   actually shortens the sheet (fewer fields visible at once), not just
   a CSS height trick. */
.signup-step { display: none; flex-direction: column; gap: 14px; flex-shrink: 0; }
.signup-step.active { display: flex; }

/* wallet edit fields inside modal */
.wedit-field { display: flex; flex-direction: column; gap: 5px; margin-bottom: 12px; }
.wedit-label { font-size: 11px; color: #6b7280; display: flex; align-items: center; gap: 8px; }
.wedit-label span { font-size: 16px; }
.wedit-input {
  background: #0d0f17;
  border: 1px solid #252a3a;
  border-radius: 8px;
  padding: 10px 14px;
  color: #f0f2f7;
  /* 16px avoids iOS Safari's zoom-on-focus (anything under 16px triggers it) */
  font-size: 16px;
  font-family: inherit;
  outline: none;
  width: 100%;
}
.wedit-input:focus { border-color: #3b82f6; }

/* ── Language toggle button ── */
.lang-toggle {
  margin-left: 6px;
  background: #1a1d2a;
  border: 1px solid #252a3a;
  border-radius: 6px;
  color: #c8cdd8;
  font-size: 11px;
  font-weight: 700;
  padding: 5px 9px;
  cursor: pointer;
  flex-shrink: 0;
  letter-spacing: 0.5px;
  transition: background 0.15s, border-color 0.15s;
}
.lang-toggle:active { background: #252a3a; }
.lang-jp .lang-toggle {
  background: #1e3a5f;
  border-color: #3b82f6;
  color: #93c5fd;
}

/* ================================================================
   HISTORY PAGE
   ================================================================ */
#page-history {
  display: none;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
#page-history.active { display: flex; }

.history-list { padding: 0 14px 14px; display: flex; flex-direction: column; gap: 8px; }

.history-row {
  display: flex;
  align-items: center;
  gap: 12px;
  background: #10131c;
  border: 1px solid #1e2230;
  border-radius: 10px;
  padding: 12px 14px;
}
.history-icon {
  width: 36px; height: 36px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px;
  flex-shrink: 0;
}
.history-info { flex: 1; min-width: 0; }
.history-type {
  font-size: 13px;
  font-weight: 600;
  color: #f0f2f7;
}
.history-type.deposit, .history-type.buy, .history-type.receive  { color: #35af62; }
.history-type.withdraw, .history-type.sell, .history-type.send { color: #ce4f4f; }
.history-type.transfer { color: #487dd4; }
.history-sub { font-size: 10px; color: #6b7280; margin-top: 2px; }
.history-right { text-align: right; flex-shrink: 0; }
.history-amount { font-size: 13px; font-weight: 700; color: #f0f2f7; margin-bottom: 4px; }
.history-amount.deposit, .history-amount.buy, .history-amount.receive  { color: #35af62; }
.history-amount.withdraw, .history-amount.sell, .history-amount.send { color: #ce4f4f; }
.history-status {
  font-size: 9px;
  padding: 2px 7px;
  border-radius: 10px;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  width: fit-content;
  margin-left: auto;
}
.history-status.completed { background: #14532d; color: #53c27c; }
.history-status.pending   { background: #78350f; color: #d7ab37; }
.history-status.failed    { background: #7f1d1d; color: #d67070; }

.loading-spinner {
  display: flex;
  justify-content: center;
  padding: 30px;
  color: #4b5563;
  font-size: 12px;
}


/* Withdraw result modal (success/failure) — an icon badge + amount up
   top, a receipt-style detail card, and a tinted note box for the
   reason, closer to what a real exchange shows after a withdrawal
   attempt than a bare icon and a paragraph of gray text. */
.wr-close-btn {
  position: absolute;
  top: 16px;
  right: 16px;
  z-index: 1;
}

.wr-status {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 6px 0 2px;
  text-align: center;
}
.wr-icon-badge {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--red-bg);
  color: var(--red);
}
.wr-icon-badge svg { width: 30px; height: 30px; }
.wr-icon-badge.success { background: var(--green-bg); color: var(--green); }
.wr-amount { font-size: 21px; font-weight: 700; color: var(--text-1); }

.wr-receipt {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 2px 12px;
}
.wr-receipt-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--border);
}
.wr-receipt-row:last-child { border-bottom: none; }
.wr-receipt-label { font-size: 12px; color: var(--text-3); flex-shrink: 0; }
.wr-receipt-value {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-1);
  text-align: right;
  overflow-wrap: anywhere;
}
.wr-receipt-pill {
  font-size: 10.5px;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.3px;
}
.wr-receipt-pill.declined  { background: var(--red-bg);   color: var(--red); }
.wr-receipt-pill.completed { background: var(--green-bg); color: var(--green); }

.wr-note {
  display: flex;
  gap: 9px;
  align-items: flex-start;
  background: rgba(251, 191, 36, 0.08);
  border: 1px solid rgba(251, 191, 36, 0.25);
  border-radius: var(--radius);
  padding: 11px 12px;
}
.wr-note svg { width: 16px; height: 16px; color: var(--amber); flex-shrink: 0; margin-top: 1px; }
.wr-note p { font-size: 12.5px; color: var(--text-2); line-height: 1.55; }
.wr-note.success {
  background: rgba(34, 197, 94, 0.08);
  border-color: rgba(34, 197, 94, 0.25);
}
.wr-note.success svg { color: var(--green); }

.deposit-address-box {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.deposit-address-label {
  font-size: 10px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.4px;
}
.deposit-address-value {
  font-size: 12px;
  color: var(--text-1);
  font-family: monospace;
  word-break: break-all;
  background: var(--bg-0);
  padding: 8px;
  border-radius: 6px;
  border: 1px solid var(--border-2);
}

/* Smart Trading on/off switch — the "flip this and watch your balance
   grow" fraud-training centerpiece. See toggleSmartTrading()/
   checkSmartTradingCredit() in app.js and smart_trading.sql for the
   actual (fake, admin-rate-configurable) crediting logic. Card chrome
   stays as calm/professional as the setup checklist — the switch itself
   is the whole feature, no need to shout around it. */
.smart-trading-card {
  margin: 0 14px 14px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-shrink: 0;
}
.stc-left { display: flex; align-items: center; gap: 12px; min-width: 0; }
.stc-icon {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: rgba(34,197,94,0.14);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.stc-icon svg { width: 17px; height: 17px; color: var(--green); }
.stc-title { font-size: 13.5px; font-weight: 700; color: var(--text-1); }
.stc-sub { font-size: 11.5px; color: var(--text-3); margin-top: 2px; }

/* Fraud-training red flags: unrealistic-guaranteed-return / urgency /
   deposit-bonus marketing banners, placed at the same spots real
   investment-scam sites put them (landing page hero, right after a
   balance is shown, right before a deposit amount field) — intentionally
   visible and clickable (not hidden test-only markup) so they're part of
   the same "spot it in context" training as the fake decline flow /
   placeholder deposit address elsewhere in this app, not a separate
   annotated exercise.

   Design language: one strong stat per card, not a paragraph of claims —
   a big tabular-numerals hero figure (the "+45%", the "$1,000 → $2,500")
   carries the entire message, with a single quiet supporting line under
   it. A soft accent-colored glow blob + a faint upward sparkline sit
   behind the text as pure decoration (crypto-chart texture, zero real
   data behind it) for a modern "graphic investment" feel rather than a
   flat card. Chrome stays deliberately quiet — small icon, muted dot+text
   badge, thin top accent bar — so nothing about the CONTAINER shouts;
   only the one stat itself is bold. Real sophisticated scams (and
   Coinbase itself) favor exactly this restrained look because it reads as
   more credible than a gaudy banner, which is the more useful pattern to
   train against. Accent colors: blue=new-user trust, gold=VIP/exclusivity
   (echoes .profile-badge-vip elsewhere in the app), green=money/bonus.
   NEVER wire any of this to real bonus/multiplier logic — decorative only. */
.promo-banner {
  display: flex;
  flex-direction: column;
  padding: 18px;
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  border: 1px solid var(--border);
  cursor: pointer;
  text-align: left;
  position: relative;
  overflow: hidden;
  /* overflow:hidden above (needed so the accent bar/glow respect the
     rounded corners) removes this flex item's automatic content-based
     minimum height per the flexbox spec — without flex-shrink:0 it gets
     squeezed below its own content height by sibling flex items competing
     for space in .account-dashboard's column, clipping the hero text.
     Every sibling around it (.total-balance-card, .wallet-section) already
     sets this for the same reason. */
  flex-shrink: 0;
  /* Fades/slides in the moment the card actually renders — fires once at
     page load for the guest banner, and again naturally for the
     dashboard/deposit banners since a CSS animation restarts whenever an
     element goes from display:none to displayed, with zero JS needed. */
  animation: promoCardIn 0.5s ease-out;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.promo-banner:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 24px -8px rgba(0,0,0,0.35);
}
@keyframes promoCardIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.promo-banner::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  z-index: 1;
}
.promo-banner.accent-blue::before  { background: var(--blue); }
.promo-banner.accent-gold::before  { background: linear-gradient(90deg, #fbbf24, #f59e0b); }
.promo-banner.accent-green::before { background: var(--green); }

/* Decorative glow + sparkline — purely visual texture, no data behind
   either. Sit at z-index:0, below the text content (z-index:1). Glow
   breathes continuously (a slow, subtle pulse — the "alive" crypto-chart
   texture); sparkline draws itself in once via stroke-dashoffset, which
   naturally re-plays every time a hidden banner (dashboard/deposit) first
   becomes visible since CSS animations restart on display:none -> shown. */
.promo-glow {
  position: absolute;
  top: -40px; right: -30px;
  width: 140px; height: 140px;
  border-radius: 50%;
  filter: blur(30px);
  opacity: 0.25;
  pointer-events: none;
  z-index: 0;
  animation: promoGlowPulse 4.5s ease-in-out infinite;
}
.promo-banner.accent-blue  .promo-glow { background: #3b82f6; }
.promo-banner.accent-gold  .promo-glow { background: #f59e0b; }
.promo-banner.accent-green .promo-glow { background: #22c55e; }
@keyframes promoGlowPulse {
  0%, 100% { opacity: 0.2;  transform: scale(1); }
  50%      { opacity: 0.38; transform: scale(1.12); }
}

.promo-spark {
  position: absolute;
  right: 14px; bottom: 12px;
  width: 100px; height: 34px;
  opacity: 0.3;
  pointer-events: none;
  z-index: 0;
}
.promo-banner.accent-blue  .promo-spark { color: #60a5fa; }
.promo-banner.accent-gold  .promo-spark { color: #fbbf24; }
.promo-banner.accent-green .promo-spark { color: var(--green); }
.promo-spark polyline {
  stroke-dasharray: 260;
  stroke-dashoffset: 260;
  animation: promoSparkDraw 1.4s 0.15s ease-out forwards;
}
@keyframes promoSparkDraw {
  to { stroke-dashoffset: 0; }
}

.promo-banner-toprow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  position: relative;
  z-index: 1;
}
.promo-banner-icon {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  line-height: 1;
}
.promo-banner-icon svg { width: 15px; height: 15px; }
.promo-banner.accent-blue  .promo-banner-icon { background: rgba(59,130,246,0.14); }
.promo-banner.accent-gold  .promo-banner-icon { background: rgba(251,191,36,0.14); }
.promo-banner.accent-green .promo-banner-icon { background: rgba(34,197,94,0.14); }
.promo-banner.accent-blue  .promo-banner-icon svg { color: #60a5fa; }
.promo-banner.accent-gold  .promo-banner-icon svg { color: #fbbf24; }
.promo-banner.accent-green .promo-banner-icon svg { color: var(--green); }

/* One characteristic animation per banner, on top of the shared card-level
   ones above, so each reads as its own moment instead of three copies of
   the same effect:
   - blue/guest: the zap icon flickers like current, on-brand for "New" +
     the lightning-bolt icon itself.
   - gold/dash: a diagonal shine sweeps across the whole card every few
     seconds — the "premium card catching light" cue real VIP/metal-card
     marketing uses.
   - green/deposit: the check-badge icon pops/stamps periodically, like a
     bonus just got confirmed. */
.promo-banner.accent-blue .promo-banner-icon svg {
  animation: promoZapFlicker 3.5s ease-in-out infinite;
}
@keyframes promoZapFlicker {
  0%, 100%, 91% { opacity: 1; }
  93% { opacity: 0.25; }
  95% { opacity: 1; }
  97% { opacity: 0.45; }
}

.promo-banner.accent-gold {
  isolation: isolate;
}
.promo-banner.accent-gold::after {
  content: '';
  position: absolute;
  top: 0; left: -60%;
  width: 35%; height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,0.16), transparent);
  transform: skewX(-20deg);
  pointer-events: none;
  z-index: 0;
  animation: promoShimmerSweep 4.5s ease-in-out infinite;
}
@keyframes promoShimmerSweep {
  0%   { left: -60%; }
  35%  { left: 130%; }
  100% { left: 130%; }
}

.promo-banner.accent-green .promo-banner-icon svg {
  animation: promoCheckPop 3s ease-in-out infinite;
}
@keyframes promoCheckPop {
  0%, 80%, 100% { transform: scale(1); }
  85% { transform: scale(1.25); }
  90% { transform: scale(0.95); }
  95% { transform: scale(1.05); }
}

/* Quiet corner badge — a muted dot + small-caps label, not a filled pill,
   so the container's chrome stays calm even while the hero stat is loud. */
.promo-banner-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-3);
  white-space: nowrap;
}
.promo-banner-badge::before {
  content: '';
  width: 5px; height: 5px;
  border-radius: 50%;
  animation: promoDotPulse 1.8s ease-in-out infinite;
}
.promo-banner.accent-blue  .promo-banner-badge::before { background: #60a5fa; }
.promo-banner.accent-gold  .promo-banner-badge::before { background: #fbbf24; }
.promo-banner.accent-green .promo-banner-badge::before { background: var(--green); }
@keyframes promoDotPulse {
  0%, 100% { transform: scale(1);   opacity: 1; }
  50%      { transform: scale(1.8); opacity: 0.35; }
}

/* The one strong message — big tabular-numerals figure carries the whole
   claim, e.g. "+45%" or "$1,000 → $2,500". Everything else on the card is
   quiet by comparison. */
.promo-hero {
  display: flex;
  align-items: baseline;
  gap: 7px;
  flex-wrap: wrap;
  margin-top: 14px;
  position: relative;
  z-index: 1;
}
.promo-hero-figure {
  font-size: 32px;
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.promo-banner.accent-blue  .promo-hero-figure { color: #60a5fa; }
.promo-banner.accent-gold  .promo-hero-figure { color: #fbbf24; }
.promo-banner.accent-green .promo-hero-figure { color: var(--green); }
.promo-hero-unit {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-3);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.promo-banner-label {
  margin-top: 8px;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-2);
  line-height: 1.45;
  max-width: 88%;
  position: relative;
  z-index: 1;
}

/* Urgency tag (deposit banner only, for now) — deliberately an amber
   accent rather than the card's own green, the same way real countdown/
   urgency callouts contrast against a page's base palette to grab a
   second look. Classic scarcity-pressure red flag; static copy, no real
   countdown or expiry wired to it. */
.promo-urgency {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-top: 9px;
  font-size: 10.5px;
  font-weight: 700;
  color: #fbbf24;
  position: relative;
  z-index: 1;
}
.promo-urgency svg { width: 11px; height: 11px; flex-shrink: 0; }

/* Respect reduced-motion: kill the infinite loops (glow breathing, badge
   dot, per-banner zap flicker/gold shimmer/check pop) and collapse the
   one-shot entrance/sparkline animations to their end state instantly
   rather than disabling them outright. */
@media (prefers-reduced-motion: reduce) {
  .promo-banner, .promo-glow, .promo-banner-badge::before, .promo-spark polyline,
  .promo-banner.accent-blue .promo-banner-icon svg,
  .promo-banner.accent-gold::after,
  .promo-banner.accent-green .promo-banner-icon svg {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* ================================================================
   ABOUT / PARTNERS / LICENSING — Account settings pages. The About
   hero reuses the promo-banner glow/sparkline animation language
   (same keyframes) so it reads as the same "alive" visual system
   rather than a one-off.
   ================================================================ */
.about-hero {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  padding: 22px 18px;
  text-align: center;
  background: linear-gradient(160deg, #171b2a, #10131c);
  border: 1px solid var(--border);
  flex-shrink: 0;
}
.about-hero-glow {
  position: absolute;
  width: 160px; height: 160px;
  border-radius: 50%;
  filter: blur(38px);
  opacity: 0.3;
  pointer-events: none;
  z-index: 0;
  animation: promoGlowPulse 4.5s ease-in-out infinite;
}
.about-hero-glow-1 { top: -50px; left: -40px; background: #3b82f6; }
.about-hero-glow-2 { bottom: -60px; right: -30px; background: #f59e0b; animation-delay: 1.2s; }
.about-hero-logo {
  position: relative;
  z-index: 1;
  font-size: 24px;
  font-weight: 800;
  color: #f0f2f7;
  letter-spacing: -0.5px;
}
.about-hero-logo span { color: #3b82f6; }
.about-hero-tagline {
  position: relative;
  z-index: 1;
  margin-top: 6px;
  font-size: 12.5px;
  color: var(--text-2);
}
.about-chip-row {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 14px;
}
.about-chip {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text-2);
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 999px;
  padding: 5px 10px;
}

.about-section { flex-shrink: 0; }
.about-section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 700;
  color: var(--text-1);
  margin-bottom: 8px;
}
.about-section-icon {
  width: 26px; height: 26px;
  border-radius: 50%;
  background: rgba(59,130,246,0.14);
  color: #60a5fa;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.about-section-icon svg { width: 13px; height: 13px; }
.about-p {
  font-size: 12.5px;
  line-height: 1.65;
  color: var(--text-2);
  margin: 0 0 8px;
}
.about-p:last-child { margin-bottom: 0; }

/* "Performance" highlight box — deliberately reuses the promo-banner's
   gold shimmer-sweep treatment (see .promo-banner.accent-gold::after)
   since this is the same genre of claim: a loud, unverified profit
   figure dressed up in premium-card visual language. */
.about-performance-box {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(160deg, rgba(245,158,11,0.1), rgba(245,158,11,0.02));
  border: 1px solid rgba(245,158,11,0.25);
  border-radius: var(--radius-lg);
  padding: 16px;
}
.about-performance-box::after {
  content: '';
  position: absolute;
  top: 0; left: -60%;
  width: 35%; height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,0.14), transparent);
  transform: skewX(-20deg);
  pointer-events: none;
  z-index: 0;
  animation: promoShimmerSweep 5s ease-in-out infinite;
}
.about-spark {
  position: absolute;
  top: 10px; right: 12px;
  width: 90px; height: 30px;
  color: #fbbf24;
  opacity: 0.35;
  pointer-events: none;
  z-index: 0;
}
.about-spark polyline {
  stroke-dasharray: 260;
  stroke-dashoffset: 260;
  animation: promoSparkDraw 1.4s 0.15s ease-out forwards;
}
.about-counter-row {
  position: relative;
  z-index: 1;
  display: flex;
  gap: 18px;
}
.about-counter-block { flex: 1; min-width: 0; }
.about-counter {
  font-size: 24px;
  font-weight: 800;
  color: #fbbf24;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin-bottom: 4px;
}
.about-counter-label {
  font-size: 10.5px;
  color: var(--text-3);
  line-height: 1.4;
}
.about-performance-note {
  position: relative;
  z-index: 1;
  font-size: 10px;
  color: var(--text-muted);
  line-height: 1.5;
  margin: 12px 0 0;
}
.about-footer-note {
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.6;
  text-align: center;
  margin: 0;
  flex-shrink: 0;
}
@media (prefers-reduced-motion: reduce) {
  .about-hero-glow, .about-performance-box::after, .about-spark polyline {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* Partners */
.partners-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
}
.partner-card {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 12px;
}
.partner-logo {
  flex-shrink: 0;
  width: 44px; height: 44px;
  border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  color: #fff;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.02em;
}
.partner-text { min-width: 0; }
.partner-name { font-size: 13px; font-weight: 700; color: var(--text-1); margin-bottom: 2px; }
.partner-desc { font-size: 11px; color: var(--text-3); line-height: 1.4; }

/* Admin tools */
.admin-tools-section-title { font-size: 13px; font-weight: 700; color: var(--text-1); }

/* Licensing */
.license-region-title {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-3);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 4px 0 -2px;
}
.license-box { gap: 12px; }
.license-row { display: flex; flex-direction: column; gap: 3px; font-size: 12px; }
.license-row-label { color: var(--text-1); font-weight: 700; }
.license-row-value { color: var(--text-2); line-height: 1.5; }
.license-disclaimer {
  font-size: 10.5px;
  color: var(--text-muted);
  line-height: 1.6;
  text-align: center;
  margin: 2px 0 0;
  flex-shrink: 0;
}

/* Saved card summary + card-number brand badge — see the card deposit
   form in index.html. Brand colors are plain text pills (not real
   Visa/Mastercard/etc. logos) so this stays a lightweight, license-free
   "looks real" cue rather than reproducing trademarked artwork. */
.card-brand-badge {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.3px;
  padding: 3px 7px;
  border-radius: 4px;
  color: #fff;
  background: #4b5563;
  flex-shrink: 0;
}
.card-brand-badge.visa       { background: #1a56db; }
.card-brand-badge.mastercard { background: linear-gradient(90deg, #eb001b 50%, #f79e1b 50%); }
.card-brand-badge.amex       { background: #2563eb; }
.card-brand-badge.discover   { background: #f97316; }
.card-brand-badge.jcb        { background: #16a34a; }

.modal-input-wrap .card-brand-badge {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
}

.saved-card-row { display: flex; align-items: center; gap: 10px; }
.saved-card-info { display: flex; flex-direction: column; gap: 3px; }
.saved-card-number { font-size: 13px; font-weight: 600; color: #f0f2f7; letter-spacing: 0.5px; }
.saved-card-meta { font-size: 11px; color: #9ca3af; }

.card-save-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--text-2);
  cursor: pointer;
  touch-action: manipulation;
}
.card-save-row input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--blue); cursor: pointer; }
.deposit-copy-btn {
  align-self: flex-start;
  padding: 5px 12px;
  font-size: 11px;
  background: var(--bg-3);
  border: 1px solid var(--border-2);
  border-radius: 5px;
  color: var(--text-2);
  cursor: pointer;
}
.deposit-copy-btn:active { background: var(--border-2); }
.deposit-detail-grid {
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 12px;
}
.deposit-detail-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
}
.deposit-detail-label { color: var(--text-muted); }
.deposit-detail-value { color: var(--text-1); font-weight: 600; }
#deposit-address-block { display: flex; flex-direction: column; gap: 12px; }
.deposit-network-warning {
  background: #3a1d1d;
  border: 1px solid #7f1d1d;
  border-radius: var(--radius);
  padding: 12px;
  font-size: 12px;
  color: #fca5a5;
  line-height: 1.5;
}
.deposit-sim-btn {
  width: 100%;
  padding: 12px;
  background: var(--green-bg);
  color: var(--green);
  border: 1px solid var(--green);
  border-radius: var(--radius);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}
.deposit-sim-btn:active { filter: brightness(1.2); }

/* ================================================================
   COIN DETAIL MODAL — opened by tapping a wallet row
   ================================================================ */
.coin-detail-modal { gap: 16px; }
.cd-title-row { display: flex; align-items: center; gap: 10px; }
.cd-icon {
  width: 36px; height: 36px;
  border-radius: 50%;
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  background: var(--bg-3);
}
.cd-icon img { width: 100%; height: 100%; object-fit: cover; }
.cd-name { font-size: 16px; font-weight: 700; color: #f0f2f7; }
.cd-symbol { font-size: 11px; color: var(--text-muted); }

.cd-price-row { display: flex; align-items: baseline; gap: 10px; }
.cd-price { font-size: 24px; font-weight: 700; color: #f0f2f7; }
.cd-change { font-size: 13px; font-weight: 600; }
.cd-change.up   { color: var(--green); }
.cd-change.down { color: var(--red); }

.cd-balance-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.cd-balance-label { font-size: 10px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.4px; }
.cd-balance-amount { font-size: 16px; font-weight: 700; color: #f0f2f7; }
.cd-balance-jpy { font-size: 11px; color: var(--text-muted); }

.cd-stats-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.cd-stat-cell {
  background: var(--bg-card);
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.cd-ai-card {
  background: linear-gradient(135deg, rgba(59,130,246,0.12), rgba(59,130,246,0.02));
  border: 1px solid rgba(59,130,246,0.25);
  border-radius: var(--radius);
  padding: 12px;
}
.cd-ai-header {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 700;
  color: var(--blue);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  margin-bottom: 6px;
}
.cd-ai-header .icon { width: 14px; height: 14px; }
.cd-ai-text { font-size: 12.5px; color: var(--text-2); line-height: 1.6; }

.cd-action-row { display: flex; gap: 10px; }
.cd-action-btn {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 10px 8px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-2);
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  touch-action: manipulation;
}
.cd-action-btn:active { background: var(--bg-3); }
.cd-action-btn .icon { width: 18px; height: 18px; color: var(--blue); }

.send-currency-row {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 12px;
  font-size: 13px;
  font-weight: 600;
  color: #f0f2f7;
}

/* Wallet rows (main list only, not the drag-reorder Edit Wallet list) are
   tappable to open the coin detail modal above. */
.wallet-item[onclick] { cursor: pointer; touch-action: manipulation; }
.wallet-item[onclick]:active { background: #161a28; }

/* ================================================================
   TOGGLE SWITCH (notifications, 2FA)
================================================================ */
.toggle-switch {
  position: relative;
  display: inline-block;
  width: 40px;
  height: 22px;
  flex-shrink: 0;
}
.toggle-switch input {
  opacity: 0;
  width: 0;
  height: 0;
}
.toggle-slider {
  position: absolute;
  cursor: pointer;
  inset: 0;
  background: var(--bg-3);
  border: 1px solid var(--border-2);
  border-radius: 22px;
  transition: 0.2s;
}
.toggle-slider::before {
  content: "";
  position: absolute;
  height: 16px;
  width: 16px;
  left: 2px;
  bottom: 2px;
  background: var(--text-3);
  border-radius: 50%;
  transition: 0.2s;
}
.toggle-switch input:checked + .toggle-slider {
  background: rgba(59,130,246,0.25);
  border-color: var(--blue);
}
.toggle-switch input:checked + .toggle-slider::before {
  transform: translateX(18px);
  background: var(--blue);
}

/* ================================================================
   2FA STYLES
================================================================ */
.twofa-status {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: 12px;
  color: var(--text-2);
  flex-shrink: 0;
}
.twofa-status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.twofa-status-dot.on  { background: var(--green); box-shadow: 0 0 6px var(--green); }
.twofa-status-dot.off { background: var(--text-muted); }

.twofa-info-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 20px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  text-align: center;
}
.twofa-info-box p {
  font-size: 13px;
  color: var(--text-3);
  line-height: 1.6;
  margin: 0;
}

/* 2FA status badge on account settings row */
.si-2fa-badge {
  font-size: 9px;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 10px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
}
.si-2fa-badge.on  {
  background: #14532d;
  color: #4ade80;
}
.si-2fa-badge.off {
  background: var(--bg-3);
  color: var(--text-muted);
  border: 1px solid var(--border-2);
}


/* ================================================================
   IDENTITY VERIFICATION (KYC)
================================================================ */
.kyc-status-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: var(--radius);
  flex-shrink: 0;
}
.kyc-status-bar.unverified { background: var(--bg-card); border: 1px solid var(--border); }
.kyc-status-bar.pending    { background: #3a2a0a; border: 1px solid #78350f; }
.kyc-status-bar.verified   { background: #0a2a1a; border: 1px solid #14532d; }
.kyc-status-bar.rejected   { background: #2a0a0a; border: 1px solid #7f1d1d; }

.kyc-status-icon { font-size: 24px; flex-shrink: 0; }
.kyc-status-title { font-size: 13px; font-weight: 600; color: var(--text-1); }
.kyc-status-sub   { font-size: 11px; color: var(--text-muted); margin-top: 2px; }

/* Step indicator */
.kyc-steps {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  flex-shrink: 0;
  padding: 4px 0;
}
.kyc-step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.kyc-step-dot {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--bg-3);
  border: 1px solid var(--border-2);
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
}
.kyc-step-dot.active    { background: var(--blue); border-color: var(--blue); color: #fff; }
.kyc-step-dot.completed { background: var(--green); border-color: var(--green); color: #fff; }
.kyc-step-label {
  font-size: 9px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  white-space: nowrap;
}
.kyc-step-line {
  flex: 1;
  height: 1px;
  background: var(--border-2);
  min-width: 30px;
  margin-bottom: 14px;
}

/* Document type options */
.kyc-doc-options {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  flex-shrink: 0;
}
.kyc-doc-option {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 14px 8px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  cursor: pointer;
  font-size: 11px;
  color: var(--text-3);
  text-align: center;
  touch-action: manipulation;
  transition: all 0.15s;
}
.kyc-doc-option:active  { background: var(--bg-3); }
.kyc-doc-option.selected {
  border-color: var(--blue);
  background: rgba(59,130,246,0.08);
  color: var(--blue);
}
.kyc-doc-option svg { color: var(--text-muted); transition: color 0.15s; }
.kyc-doc-option.selected svg { color: var(--blue); }

/* Upload area */
.kyc-upload-area {
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 20px;
  background: var(--bg-card);
  border: 1px dashed var(--border-2);
  border-radius: var(--radius-lg);
  text-align: center;
  flex-shrink: 0;
}
.kyc-upload-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-2);
  margin: 0;
}
.kyc-upload-sub {
  font-size: 11px;
  color: var(--text-muted);
  margin: 0;
}
.kyc-upload-slots {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  width: 100%;
  margin-top: 4px;
}
.kyc-upload-slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 14px 8px;
  background: var(--bg-0);
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  cursor: pointer;
  font-size: 11px;
  color: var(--text-muted);
  touch-action: manipulation;
  transition: all 0.15s;
}
.kyc-upload-slot:active { background: var(--bg-3); }
.kyc-upload-slot.uploaded {
  border-color: var(--green);
  color: var(--green);
}
.kyc-upload-slot.uploaded svg { stroke: var(--green); }

/* Review box */
.kyc-review-box {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex-shrink: 0;
}
.kyc-review-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
}
.kyc-review-label { color: var(--text-muted); }
.kyc-review-value { color: var(--text-1); font-weight: 600; }

/* Disclaimer */
.kyc-disclaimer {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.5;
  flex-shrink: 0;
}
.kyc-disclaimer svg { flex-shrink: 0; margin-top: 1px; }

/* Submitted / verified box */
.kyc-submitted-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 24px 16px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  flex-shrink: 0;
}

/* KYC badge on settings row */
.si-kyc-badge {
  font-size: 9px;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 10px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
}
.si-kyc-badge.unverified {
  background: var(--bg-3);
  color: var(--text-muted);
  border: 1px solid var(--border-2);
}
.si-kyc-badge.pending {
  background: #78350f;
  color: #fbbf24;
}
.si-kyc-badge.verified {
  background: #14532d;
  color: #4ade80;
}
.si-kyc-badge.rejected {
  background: #7f1d1d;
  color: #fca5a5;
}

/* ================================================================
   CUSTOMER SUPPORT (chat + FAQ + admin inbox)
================================================================ */
.support-chat-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  /* Fixed height, not min/max — the message log scrolls internally
     instead of growing the modal as messages pile up. This nests fine
     inside the outer .modal's own scroll (both vertical, so the browser
     just chains from one to the other at the boundary) — that's a
     different situation from the horizontal-in-vertical touch-action
     conflict that caused real bugs elsewhere in this app. */
  height: 320px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* Explicit rather than relying on the default `auto` — a nested
     scrollable inside another scrollable (.modal) is exactly the
     situation where some mobile browsers' touch-scroll hit-testing can
     latch onto the wrong ancestor. Declaring this one as vertical-pan-
     only removes that ambiguity, and `contain` stops any residual drag
     at this list's own edges from chaining up into the modal's scroll. */
  touch-action: pan-y;
  overscroll-behavior: contain;
  padding: 4px 6px;
  background:
    radial-gradient(circle at 20% 15%, rgba(59,130,246,0.05), transparent 40%),
    radial-gradient(circle at 80% 85%, rgba(59,130,246,0.04), transparent 40%);
}

/* One row per message — holds the small avatar (received messages only)
   plus the bubble, like a real messaging app rather than a flat list. */
.support-msg-row {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  margin-top: 10px;
}
/* Consecutive messages from the same sender sit closer together, with
   the avatar only shown on the last bubble of the group (WhatsApp/iMessage
   convention) — .grouped is added by renderSupportChatBubble() when the
   previous message was from the same sender. */
.support-msg-row.grouped { margin-top: 2px; }
.support-msg-row.user { justify-content: flex-end; }
.support-msg-row.admin, .support-msg-row.ai { justify-content: flex-start; }

.support-msg-avatar {
  width: 22px; height: 22px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  color: #fff;
}
.support-msg-avatar svg { width: 13px; height: 13px; }
.support-msg-avatar.admin { background: #6366f1; }
.support-msg-avatar.ai    { background: #14b8a6; }

.support-msg {
  position: relative;
  max-width: 78%;
  padding: 8px 11px;
  border-radius: 16px;
  font-size: 13px;
  line-height: 1.4;
  word-break: break-word;
}
.support-msg-sender {
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  margin-bottom: 2px;
  opacity: 0.7;
}
.support-msg-time {
  font-size: 9px;
  opacity: 0.6;
  margin-top: 3px;
  text-align: right;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 3px;
}
.support-msg-tick { font-size: 11px; line-height: 1; letter-spacing: -1px; }
.support-msg-tick.sent { opacity: 0.8; }
.support-msg-tick.seen { color: #93c5fd; opacity: 1; }
.support-msg.user {
  background: var(--blue);
  color: #fff;
  border-bottom-right-radius: 4px;
}
.support-msg.admin {
  background: var(--bg-3);
  color: var(--text-1);
  border-bottom-left-radius: 4px;
}
.support-msg.ai {
  background: var(--bg-card);
  border: 1px solid var(--border-2);
  color: var(--text-2);
  border-bottom-left-radius: 4px;
  white-space: pre-line;
  max-width: 82%;
  padding: 6px 9px;
  font-size: 12px;
  line-height: 1.3;
}
.support-msg.ai .support-msg-sender { margin-bottom: 1px; }
.support-msg.ai .support-msg-time { margin-top: 1px; }
/* Small triangular "tail" on the last bubble of a group, like iMessage/
   WhatsApp — skipped on grouped follow-up bubbles so only one tail shows
   per group of consecutive messages. */
.support-msg-row:not(.grouped) .support-msg.user::after {
  content: '';
  position: absolute;
  right: -6px; bottom: 0;
  width: 12px; height: 12px;
  background: var(--blue);
  clip-path: polygon(0 0, 0% 100%, 100% 100%);
}
.support-msg-row:not(.grouped) .support-msg.admin::after {
  content: '';
  position: absolute;
  left: -6px; bottom: 0;
  width: 12px; height: 12px;
  background: var(--bg-3);
  clip-path: polygon(100% 0, 0 100%, 100% 100%);
}
.support-msg-row:not(.grouped) .support-msg.ai::after {
  content: '';
  position: absolute;
  left: -6px; bottom: -1px;
  width: 12px; height: 12px;
  background: var(--bg-card);
  border-left: 1px solid var(--border-2);
  border-bottom: 1px solid var(--border-2);
  clip-path: polygon(100% 0, 0 100%, 100% 100%);
}

.support-msg-img {
  display: block;
  max-width: 100%;
  max-height: 220px;
  border-radius: 10px;
  cursor: pointer;
  margin-bottom: 4px;
}
/* A customer's own submitted photo — not clickable on their side, only
   an admin reviewing the thread can enlarge it (see renderSupportChatBubble). */
.support-msg-img.locked { cursor: default; }
.support-chat-input-row {
  display: flex;
  gap: 8px;
  margin-top: 10px;
  align-items: center;
  flex-shrink: 0;
}
.support-chat-input-row .modal-input { flex: 1; }
.support-send-btn {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: var(--blue);
  color: #fff;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 16px;
  touch-action: manipulation;
}
.support-send-btn:active { filter: brightness(0.85); }
.support-attach-btn {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--bg-3);
  color: var(--text-2);
  border: 1px solid var(--border-2);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  touch-action: manipulation;
}
.support-attach-btn:active { background: var(--border-2); }
.support-empty {
  text-align: center;
  color: var(--text-muted);
  font-size: 12px;
  padding: 24px 10px;
}
.support-offline-banner {
  background: rgba(59,130,246,0.08);
  border: 1px solid rgba(59,130,246,0.25);
  color: #93c5fd;
  font-size: 11.5px;
  line-height: 1.5;
  padding: 8px 10px;
  border-radius: 8px;
  margin-bottom: 8px;
  flex-shrink: 0;
}

/* Full-size image viewer for a tapped chat attachment — sits on top of
   the shared .modal-overlay dim (no background of its own, to avoid
   double-dimming the same backdrop). */
.image-lightbox {
  position: fixed;
  inset: 0;
  z-index: 250;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.image-lightbox img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 12px;
  object-fit: contain;
}

/* FAQ accordion — no own scroll/max-height; the outer .modal already
   scrolls, and stacking two scroll containers is what caused real bugs
   elsewhere in this app (see the note on .support-chat-list) */
.faq-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.faq-item {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.faq-question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 12px 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-1);
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
}
.faq-question .faq-arrow {
  color: var(--text-muted);
  transition: transform 0.2s;
  flex-shrink: 0;
}
.faq-item.open .faq-question .faq-arrow { transform: rotate(180deg); }
.faq-answer {
  display: none;
  padding: 0 14px 14px;
  font-size: 12px;
  color: var(--text-3);
  line-height: 1.6;
}
.faq-item.open .faq-answer { display: block; }

/* Admin inbox — same reasoning as .faq-list: let the outer .modal be
   the only scroll container */
.support-admin-thread-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.support-admin-thread-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  touch-action: manipulation;
}
.support-admin-thread-item:active { background: var(--bg-3); }
.support-admin-thread-email { font-size: 13px; font-weight: 600; color: var(--text-1); }
.support-admin-thread-preview {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 220px;
}
.support-admin-thread-item .support-status-badge { flex-shrink: 0; }
.support-admin-back-btn {
  background: none;
  border: none;
  color: var(--blue);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  padding: 4px 0 4px;
  text-align: left;
  align-self: flex-start;
}
.support-admin-thread-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 12px;
  color: var(--text-2);
  font-weight: 600;
  margin-bottom: 8px;
}