/* ========== DASHBOARD / APP LAYOUT ========== */

.app-body {
  background: var(--app-shell-bg);
  min-height: 100vh;
  display: flex;
}

/* ========== SIDEBAR ========== */
.app-sidebar {
  width: 240px;
  min-width: 240px;
  /* Mobile browsers report 100vh as the viewport height with the URL bar HIDDEN, so a
     100vh sidebar runs taller than what is actually on screen and its bottom section
     (.sidebar-bottom → user + Log Out) sits under the browser chrome, unreachable
     because .app-sidebar is overflow:hidden. 100dvh tracks the visible viewport.
     Two-line declaration (plain vh first) so non-dvh browsers keep the old value —
     same progressive-enhancement pattern as the svh rules in trade-option.css (#328). */
  height: 100vh;
  height: 100dvh;
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--z-sidebar, 1110);
  background: #15151a;
  border-right: 1px solid rgba(var(--app-content-overlay-rgb), 0.04);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.app-sidebar::-webkit-scrollbar {
  width: 4px;
}

.app-sidebar::-webkit-scrollbar-track {
  background: transparent;
}

.app-sidebar::-webkit-scrollbar-thumb {
  background: rgba(92, 184, 230, 0.3);
  border-radius: 2px;
}
.app-sidebar::-webkit-scrollbar-thumb:hover {
  background: rgba(92, 184, 230, 0.5);
}

/* Sidebar Logo */
.sidebar-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 20px 20px 24px;
  text-decoration: none;
  flex-shrink: 0;
}

.sidebar-logo .logo-mark {
  flex-shrink: 0;
}

.sidebar-logo .logo-text {
  font-size: 17px;
  font-weight: 700;
  color: var(--app-text-1);
  letter-spacing: 1.5px;
}

/* Sidebar Sections */
.sidebar-section {
  padding: 0 12px;
  margin-bottom: 4px;
}

.sidebar-section-label {
  font-size: 10px;
  font-weight: 700;
  color: #b0b0c0;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  padding: 8px 12px 6px;
}

/* Collapsible Section Header */
.sidebar-group-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px 6px;
  cursor: pointer;
  user-select: none;
  transition: all 0.15s;
  border-radius: 6px;
  background: none;
  border: none;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
}

.sidebar-group-header:hover {
  background: rgba(var(--app-content-overlay-rgb),0.02);
}

.sidebar-group-header .sidebar-section-label {
  padding: 0;
  margin: 0;
  pointer-events: none;
}

.sidebar-group-chevron {
  width: 14px;
  height: 14px;
  color: #3a3a4a;
  transition: transform 0.25s ease;
  flex-shrink: 0;
}

.sidebar-group.collapsed .sidebar-group-chevron {
  transform: rotate(-90deg);
}

/* Collapsible Group Items */
.sidebar-group-items {
  max-height: 800px;
  overflow: hidden;
  transition: max-height 0.3s ease, opacity 0.2s ease;
  opacity: 1;
}

.sidebar-group.collapsed .sidebar-group-items {
  max-height: 0;
  opacity: 0;
}

/* Sidebar Nav Items */
/* The `hidden` attribute must actually hide nav items. `.sidebar-nav-item`
   sets display:flex (author origin), which otherwise overrides the UA
   `[hidden]{display:none}` rule — so JS-gated items (Support submenu, AI
   Analysis) would stay visible. Restore hidden with a more specific rule. */
.sidebar-nav-item[hidden] { display: none !important; }

/* A gating wrapper around a run of nav items (Futures2's BTC Margin / USDT
   Margin pair, under their "Futures & Perps" parent). It exists so an
   access probe can reveal or hide the WHOLE node in one DOM write instead of
   per item — that is what keeps a gated group from flickering in one entry at
   a time. It carries no layout of its own. It DOES spend most of its life
   carrying `hidden`, so pin display:none the same way .sidebar-nav-item does
   above — and never give this class a `display` rule without keeping this one
   more specific. The element also wears .sidebar-group (it is a nested
   collapsible), which has no `display` of its own, so this rule still bites;
   check that again if .sidebar-group ever gains one. */
.sidebar-subgroup[hidden] { display: none !important; }

/* The depth ladder for this nested node, declared in ONE place so the parent
   and its children can never drift apart. .sidebar-nav-item's own padding-left
   is 12px, so the siblings of this node (Spot Trading, Futures & Perps, Equity
   Tokens) sit at 12px; the parent takes one step in from them, and the children
   take one more step in from the PARENT — derived from it, not typed again. The
   result is a strictly ascending 12 / 24 / 36 with the icons, not just the
   labels, stepping in. These are custom properties, not brand tokens: both
   brands render this same file and neither has to define anything. */
.sidebar-subgroup {
  --sidebar-indent-step: 12px;
  /* THE PARENT SITS AT THE SAME INDENT AS ITS SIBLINGS, NOT ONE STEP IN.
     "Futures & Perps" and "Spot Trading" are both children of the PROFESSIONAL
     TRADING header, so they must start at the same x. This used to be
     `12px + step`, which was right while a flat futures item still sat between
     them — the extra step told the eye that the group was subordinate to it.
     That item is gone (the two futures pages became one route), and the extra
     step now reads as though Futures & Perps were a child of Spot Trading.
     The ladder is 12 / 24: section children, then group children. */
  --sidebar-subgroup-indent: 12px;
}

/* The nested product parent: a collapsible group INSIDE a section, so the
   margin entries read as children of Futures & Perps rather than as two
   more siblings of the section. The header is a <button> (a toggle, not a
   destination) but must read as a nav row, not as the tiny uppercase section
   label .sidebar-group-header normally holds — so it carries a
   .sidebar-nav-label and matches .sidebar-nav-item's typography and box.
   It is NOT .sidebar-nav-item: the drawer handler matches that class first.
   It also carries a LEADING ICON like every row around it. Without one its
   label began where the siblings' icons begin, which put it in line with the
   PROFESSIONAL TRADING section label above rather than with the nav rows —
   so the eye read it as another section, not as a child of one. */
.sidebar-subgroup-header {
  /* .sidebar-group-header sets space-between, which with three children would
     scatter icon / label / chevron across the row. Pack them left instead and
     let the chevron take the leftover space via its own auto margin. */
  justify-content: flex-start;
  padding: 9px 12px 9px var(--sidebar-subgroup-indent);
  margin: 1px 0;
  border-radius: 8px;
  color: var(--app-text-muted-2);
  font-size: 13px;
  font-weight: 500;
  border-left: 2px solid transparent;
}
.sidebar-subgroup-header:hover { color: #b8b8c4; }

/* AI-Trading bot rows, while the one listBots call is in flight (design §5,
   2026-09-10). The sidebar caches the row COUNT and never the labels — a cached
   name went stale for five minutes after a rename and showed the old one — so
   the count paints these neutral bars instead, and the real names replace them
   when the call returns. Same geometry, nothing a reader could mistake for a
   bot's identity. Not animated: this lives for one API round trip, and a pulse
   over that span reads as breakage rather than as loading. */
.sidebar-nav-skeleton { cursor: default; opacity: 0.5; }
.sidebar-nav-label-skeleton {
  display: block;
  height: 9px;
  width: 96px;
  border-radius: 4px;
  background: currentColor;
  opacity: 0.25;
}
.sidebar-subgroup-header .sidebar-nav-label {
  pointer-events: none;
  /* The indent plus the icon costs this label 42px of a 240px sidebar. Clip
     rather than wrap: a two-line row would break the rhythm of the rows above
     and below it, which is the very alignment this change is about. */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Same 18px box and same 12px gap to the label as .sidebar-nav-item's icons,
   so the parent row is built like its siblings and only its depth differs.
   The gap is the icon's own margin rather than the flex `gap` shorthand so it
   applies to the icon/label pair only — the chevron keeps its auto margin. */
.sidebar-subgroup-header .sidebar-subgroup-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  opacity: 0.7;
  margin-right: 12px;
}
.sidebar-subgroup-header .sidebar-group-chevron { margin-left: auto; }

/* Indent the children one step past the PARENT (see the ladder above), so the
   tree reads as a tree. The icon-rail rule (.app-sidebar.collapsed
   .sidebar-nav-item) sets `padding: 12px 0` later in this file at equal
   specificity (three classes each), so it wins there and the indent is dropped
   with the labels — which is what the centered icon rail needs. Keep this
   selector at three classes or fewer, or the rail regains an indent. The
   header needs no such counterpart: .app-sidebar.collapsed
   .sidebar-group-header already hides the whole row, icon included, because
   the parent is a toggle and has no destination to offer a collapsed rail. */
.sidebar-subgroup .sidebar-group-items .sidebar-nav-item {
  padding-left: calc(var(--sidebar-subgroup-indent) + var(--sidebar-indent-step));
}

.sidebar-nav-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  margin: 1px 0;
  border-radius: 8px;
  color: var(--app-text-muted-2);
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
  transition: all 0.15s;
  cursor: pointer;
  border-left: 2px solid transparent;
}

.sidebar-nav-item:hover {
  color: #b8b8c4;
  background: rgba(var(--app-content-overlay-rgb), 0.03);
}

.sidebar-nav-item.active {
  color: var(--app-primary);
  background: rgba(92, 184, 230, 0.06);
  border-left-color: var(--app-primary);
}

.sidebar-nav-item svg {
  flex-shrink: 0;
  opacity: 0.7;
}

.sidebar-nav-item.active svg {
  opacity: 1;
}

/* GB-07: paused / disabled sidebar items (options kill-switch) */
.sidebar-nav-item.sidebar-nav-item-disabled {
  opacity: 0.5;
  pointer-events: none;
  position: relative;
}
.sidebar-nav-item-disabled .sidebar-nav-badge {
  margin-left: auto;
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 4px;
  background: rgba(224, 160, 80, 0.18);
  color: var(--app-sell);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Coin wallet items */
.sidebar-coin-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 12px;
  margin: 1px 0;
  border-radius: 8px;
  color: var(--app-text-muted-2);
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
  transition: all 0.15s;
  cursor: pointer;
  border-left: 2px solid transparent;
}

.sidebar-coin-item:hover {
  color: #c8c8d4;
  background: rgba(var(--app-content-overlay-rgb),0.04);
}

.sidebar-coin-icon {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  color: var(--app-text-white);
  flex-shrink: 0;
}

.sidebar-coin-name {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar-coin-ticker {
  font-size: 11px;
  color: #4a4a5a;
  font-weight: 400;
}

.sidebar-coin-expand {
  width: 14px;
  height: 14px;
  color: #4a4a5a;
  transition: transform 0.2s ease;
  flex-shrink: 0;
}

.sidebar-coin-item.expanded .sidebar-coin-expand {
  transform: rotate(90deg);
}

/* Coin sub-items (Send, Receive, Trade) */
.sidebar-coin-subitems {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.25s ease, opacity 0.2s ease;
  opacity: 0;
}

.sidebar-coin-subitems.open {
  max-height: 120px;
  opacity: 1;
}

.sidebar-coin-subitem {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 12px 6px 46px;
  color: #6a6a7a;
  text-decoration: none;
  font-size: 12px;
  font-weight: 400;
  transition: all 0.15s;
  cursor: pointer;
  border-radius: 6px;
}

.sidebar-coin-subitem:hover {
  color: #c8c8d4;
  background: rgba(var(--app-content-overlay-rgb),0.03);
}

.sidebar-coin-subitem svg {
  flex-shrink: 0;
  opacity: 0.5;
}

/* Sidebar Spacer */
.sidebar-spacer {
  flex: 1;
  min-height: 8px;
}

/* Sidebar nav scrollable area */
.sidebar-nav-scroll {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  /* #529 (4): 8px left the last nav item ("History") sitting flush against the
     fixed user-footer's top border once scrolled fully down — bumped for
     breathing room between the last link and the footer. */
  padding-bottom: 24px;
}

.sidebar-nav-scroll::-webkit-scrollbar {
  width: 4px;
}

.sidebar-nav-scroll::-webkit-scrollbar-track {
  background: transparent;
}

.sidebar-nav-scroll::-webkit-scrollbar-thumb {
  background: rgba(var(--app-content-overlay-rgb), 0.06);
  border-radius: 2px;
}

/* Sidebar Bottom Section */
.sidebar-bottom {
  padding: 4px 0 12px;
  border-top: 1px solid rgba(var(--app-content-overlay-rgb),0.06);
  flex-shrink: 0;
}

.sidebar-user {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 8px;
  border-radius: 8px;
  margin-bottom: 4px;
}

.sidebar-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--app-primary), var(--app-primary-grad-end));
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 600;
  color: var(--app-text-white);
  letter-spacing: 0.5px;
  flex-shrink: 0;
}

.sidebar-user-info {
  flex: 1;
  min-width: 0;
}

.sidebar-user-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--app-text-1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar-user-email {
  font-size: 11px;
  color: #6a6a7a;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 1px;
}

.sidebar-logout {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  border-radius: 8px;
  color: var(--app-sell);
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
  transition: all 0.15s;
  cursor: pointer;
  background: none;
  border: none;
  width: 100%;
  text-align: left;
}

.sidebar-logout:hover {
  background: rgba(224, 160, 80, 0.08);
}

.sidebar-logout svg {
  flex-shrink: 0;
  opacity: 0.7;
}

/* ========== SLIM TOP BAR ========== */
.app-topbar {
  position: fixed;
  top: 0;
  left: 240px;
  right: 0;
  height: 52px;
  background: var(--app-surface-1);
  border-bottom: 1px solid rgba(var(--app-content-overlay-rgb),0.06);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 28px;
  z-index: var(--z-topbar, 900);
}

.topbar-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.topbar-breadcrumb {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
}

.topbar-breadcrumb a {
  color: #6a6a7a;
  text-decoration: none;
  transition: color 0.15s;
}

.topbar-breadcrumb a:hover {
  color: var(--app-text-muted-3);
}

.topbar-breadcrumb svg {
  color: #4a4a5a;
}

.topbar-breadcrumb span {
  color: var(--app-text-1);
  font-weight: 500;
}

.topbar-right {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* Hamburger toggle (mobile only) */
.sidebar-toggle {
  display: none;
  background: none;
  border: none;
  color: var(--app-text-muted-2);
  cursor: pointer;
  padding: 6px;
  border-radius: 6px;
  transition: all 0.15s;
}

.sidebar-toggle:hover {
  color: var(--app-text-1);
  background: rgba(var(--app-content-overlay-rgb),0.04);
}

/* Sidebar overlay (mobile) */
.sidebar-overlay {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0,0,0,0.6);
  z-index: var(--z-sidebar-overlay, 1100);
}

.sidebar-overlay.active {
  display: block;
}

/* Notification bell in topbar */
.app-icon-btn {
  position: relative;
  background: none;
  border: none;
  color: var(--app-text-muted-2);
  cursor: pointer;
  padding: 8px;
  border-radius: 8px;
  transition: all 0.2s;
}

.app-icon-btn:hover {
  color: var(--app-text-1);
  background: rgba(var(--app-content-overlay-rgb),0.04);
}

.notification-dot {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 7px;
  height: 7px;
  background: var(--app-primary);
  border-radius: 50%;
  border: 2px solid var(--app-surface-1);
}

/* ========== APP CONTENT WRAPPER ========== */
.app-content-wrapper {
  margin-left: 240px;
  flex: 1;
  min-height: 100vh;
  padding-top: 52px;
  transition: margin-left 0.2s ease;
}

/* ========== BUG #15: SIDEBAR COLLAPSED STATE ==========
   Icon-only sidebar (64px) with hover tooltips. body.sidebar-collapsed mirrors
   the .app-sidebar.collapsed class so content margin and topbar offset shift
   without relying on `:has()` selector support. */
.app-sidebar {
  transition: width 0.2s ease;
}
.app-sidebar.collapsed {
  width: 64px;
  min-width: 64px;
}

/* Sidebar header — flex row to host logo + collapse button */
.sidebar-header {
  display: flex;
  align-items: center;
  padding: 0 12px 0 0;
}
.sidebar-header .sidebar-logo {
  flex: 1;
}
.sidebar-collapse-btn {
  background: transparent;
  border: 1px solid rgba(var(--app-content-overlay-rgb), 0.08);
  border-radius: 6px;
  padding: 4px;
  color: var(--app-text-muted-2);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: color 0.15s ease;
}
.sidebar-collapse-btn:hover { color: var(--app-text-1); }
.sidebar-collapse-btn svg { transition: transform 0.2s ease; }
.app-sidebar.collapsed .sidebar-collapse-btn svg { transform: rotate(180deg); }

/* #529 (3): an explicit close control for the mobile drawer — the hamburger
   that opened it sits under the logo once the drawer is open, so there was no
   way to close it except tapping the overlay or Escape. Desktop-hidden;
   shown only inside the <=1024px block below. */
.sidebar-close-btn {
  display: none;
  background: transparent;
  border: 1px solid rgba(var(--app-content-overlay-rgb), 0.08);
  border-radius: 6px;
  padding: 4px;
  color: var(--app-text-muted-2);
  cursor: pointer;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: color 0.15s ease;
}
.sidebar-close-btn:hover { color: var(--app-text-1); }

/* Hide labels and group headers when collapsed.
   NOTE: `.sidebar-collapse-btn` is intentionally NOT in this list — keeping it
   visible (just centered + flipped) so the user can re-expand the sidebar.
   The hidden `.sidebar-logo` is replaced with the collapse button alone in
   the centered header. */
.app-sidebar.collapsed .logo-text,
.app-sidebar.collapsed .sidebar-section-label,
.app-sidebar.collapsed .sidebar-group-chevron,
.app-sidebar.collapsed .sidebar-group-header,
.app-sidebar.collapsed .sidebar-nav-label,
.app-sidebar.collapsed .sidebar-coin-name,
.app-sidebar.collapsed .sidebar-coin-ticker,
.app-sidebar.collapsed .sidebar-coin-expand,
.app-sidebar.collapsed .sidebar-coin-subitems,
.app-sidebar.collapsed .sidebar-user-info,
.app-sidebar.collapsed .sidebar-logout-label,
.app-sidebar.collapsed .sidebar-logo {
  display: none !important;
}

/* Center icons when collapsed */
.app-sidebar.collapsed .sidebar-nav-item,
.app-sidebar.collapsed .sidebar-coin-item,
.app-sidebar.collapsed .sidebar-logout {
  justify-content: center;
  padding: 12px 0;
}
.app-sidebar.collapsed .sidebar-header {
  justify-content: center;
  padding: 16px 0 12px;
}
.app-sidebar.collapsed .sidebar-collapse-btn {
  margin: 0;
}

/* Active nav highlight stays visible in collapsed mode without left border */
.app-sidebar.collapsed .sidebar-nav-item.active {
  border-left: none;
  background: rgba(92, 184, 230, 0.12);
}

/* Allow tooltips to escape the sidebar overflow boundary when collapsed.
   Sidebar default has `overflow: hidden`; we restore visible-x in collapsed
   mode so the absolutely-positioned tooltip is not clipped. */
.app-sidebar.collapsed {
  overflow: visible;
}
.app-sidebar.collapsed .sidebar-nav-scroll {
  overflow-x: visible;
}

/* Tooltip when collapsed (hover or keyboard focus shows full label) —
   covers both `.sidebar-nav-item` and the `.sidebar-logout` button. */
.app-sidebar.collapsed .sidebar-nav-item,
.app-sidebar.collapsed .sidebar-logout {
  position: relative;
}
.app-sidebar.collapsed .sidebar-nav-item::after,
.app-sidebar.collapsed .sidebar-logout::after {
  content: attr(data-nav-label);
  position: absolute;
  left: calc(100% + 8px);
  top: 50%;
  transform: translateY(-50%);
  background: #2a2a35;
  color: var(--app-text-1);
  padding: 6px 10px;
  border-radius: 6px;
  font-size: 12px;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s ease;
  z-index: 1200;
}
.app-sidebar.collapsed .sidebar-nav-item:hover::after,
.app-sidebar.collapsed .sidebar-nav-item:focus-visible::after,
.app-sidebar.collapsed .sidebar-logout:hover::after,
.app-sidebar.collapsed .sidebar-logout:focus-visible::after {
  opacity: 1;
}

/* Content margin shifts with collapsed sidebar */
body.sidebar-collapsed .app-content-wrapper {
  margin-left: 64px;
}
body.sidebar-collapsed .app-topbar {
  left: 64px;
}

/* ========== MAIN CONTENT ========== */
.app-main {
  padding: 28px 40px 80px;
}


/* ==================================================================
   DASHBOARD-SPECIFIC STYLES
   ================================================================== */

/* ========== WELCOME / HEADER ========== */
.dash-welcome {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 24px;
}

.dash-welcome h1 {
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 24px;
  font-weight: 500;
  color: var(--app-text-1);
  margin-bottom: 4px;
}

.dash-welcome h1 span {
  color: var(--app-primary);
}

.dash-date {
  font-size: 13px;
  color: #6a6a7a;
}

.dash-welcome-actions {
  display: flex;
  gap: 10px;
}

/* Simple / Pro mode toggle */
.mode-btn {
  background: none;
  border: 1px solid rgba(var(--app-content-overlay-rgb),0.08);
  color: #6a7280;
  font-size: 12px;
  font-weight: 600;
  padding: 6px 16px;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s;
  letter-spacing: 0.3px;
}

.mode-btn:hover {
  color: var(--app-text-1);
  border-color: rgba(var(--app-content-overlay-rgb),0.15);
}

.mode-btn.active {
  color: var(--app-primary);
  background: rgba(92, 184, 230, 0.1);
  border-color: rgba(92, 184, 230, 0.25);
}

.btn-sm {
  font-size: 13px;
  padding: 10px 24px;
}

/* ========== DASHBOARD GRID ROWS ========== */
.dash-row {
  display: grid;
  grid-template-columns: 3fr 2fr;
  gap: 16px;
  margin-bottom: 16px;
}

.dash-row-top {
  display: grid;
  grid-template-columns: 3fr 2fr;
  gap: 20px;
  margin-bottom: 16px;
}

/* ========== DASH CARD ========== */
.dash-card {
  background: #0d1117;
  border-radius: 12px;
  padding: 20px 24px;
  border: 1px solid rgba(var(--app-content-overlay-rgb),0.04);
}

.dash-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
}

.dash-card-header h2 {
  font-size: 15px;
  font-weight: 600;
  color: #e5e7eb;
  margin: 0;
}

.dash-card-header h3 {
  font-size: 13px;
  font-weight: 600;
  color: var(--app-text-muted-2);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin: 0;
}

.dash-card-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--app-text-1);
}

.dash-card-label {
  font-size: 12px;
  font-weight: 500;
  color: #6a6a7a;
  text-transform: uppercase;
  letter-spacing: 0.8px;
}

.dash-card-link {
  font-size: 12px;
  color: var(--app-primary);
  text-decoration: none;
  font-weight: 500;
}

.dash-card-link:hover {
  text-decoration: underline;
}

.dash-badge {
  font-size: 11px;
  font-weight: 600;
  color: var(--app-primary);
  background: rgba(92, 184, 230, 0.1);
  padding: 3px 10px;
  border-radius: 20px;
  letter-spacing: 0.5px;
}

/* ========== SIDEBAR STACK (right column stacking) ========== */
.dash-sidebar-stack {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* ========== QUICK ACTIONS (Command Center) ========== */
.quick-actions {
  display: flex;
  gap: 10px;
}

.quick-action-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  background: rgba(92, 184, 230, 0.08);
  border: 1px solid rgba(92, 184, 230, 0.15);
  border-radius: 8px;
  color: var(--app-primary);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  transition: all 0.2s;
  cursor: pointer;
  white-space: nowrap;
}

.quick-action-btn:hover {
  background: rgba(92, 184, 230, 0.14);
  border-color: rgba(92, 184, 230, 0.3);
}

.quick-action-btn svg {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
}

/* ========== NEXT ACTION BANNER ========== */
.next-action {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  background: linear-gradient(135deg, rgba(92, 184, 230, 0.06), rgba(224, 160, 80, 0.04));
  border: 1px solid rgba(92, 184, 230, 0.12);
  border-radius: 8px;
  margin-top: 4px;
}

.next-action-icon {
  font-size: 18px;
  flex-shrink: 0;
}

.next-action-text {
  flex: 1;
  font-size: 13px;
  color: #c0c0cc;
  line-height: 1.4;
}

.next-action-text strong {
  color: var(--app-text-1);
  font-weight: 600;
}

.next-action-link {
  font-size: 12px;
  color: var(--app-primary);
  text-decoration: none;
  font-weight: 500;
  white-space: nowrap;
}

.next-action-link:hover {
  text-decoration: underline;
}

/* ========== ONBOARDING CHECKLIST ========== */
.onboarding-checklist {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 8px;
}

.onboarding-step {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: #6a7280;
  white-space: nowrap;
}

.onboarding-step.done {
  color: #4ecb71;
}

.onboarding-step.active {
  color: var(--app-primary);
  font-weight: 600;
}

.onboarding-step-icon {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  flex-shrink: 0;
  border: 1.5px solid rgba(var(--app-content-overlay-rgb),0.1);
  color: #6a7280;
}

.onboarding-step.done .onboarding-step-icon {
  background: rgba(78, 203, 113, 0.15);
  border-color: rgba(78, 203, 113, 0.3);
  color: #4ecb71;
}

.onboarding-step.active .onboarding-step-icon {
  background: rgba(92, 184, 230, 0.15);
  border-color: rgba(92, 184, 230, 0.3);
  color: var(--app-primary);
}

.onboarding-progress {
  flex: 1;
  height: 3px;
  background: rgba(var(--app-content-overlay-rgb),0.06);
  border-radius: 2px;
  overflow: hidden;
}

.onboarding-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--app-primary), #4ecb71);
  border-radius: 2px;
  transition: width 0.3s ease;
}

/* ========== ACCOUNT SNAPSHOT ========== */
.snapshot-total {
  margin-bottom: 16px;
}

.snapshot-label {
  font-size: 11px;
  color: #6a7280;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  margin-bottom: 6px;
}

.snapshot-value {
  font-size: 32px;
  font-weight: 700;
  color: var(--app-text-1);
  letter-spacing: -0.5px;
  line-height: 1;
}

.snapshot-value .cents {
  font-size: 20px;
  color: var(--app-text-muted-2);
}

.snapshot-change {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  font-weight: 500;
  margin-top: 6px;
}

.snapshot-change.positive { color: #4ecb71; }
.snapshot-change.negative { color: #e65c5c; }

.snapshot-timeframe {
  color: #6a7280;
  font-weight: 400;
  margin-left: 6px;
}

/* Snapshot Breakdown Grid */
.snapshot-breakdown {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.snapshot-metric {
  padding: 10px 12px;
  background: rgba(var(--app-content-overlay-rgb),0.02);
  border-radius: 8px;
  border: 1px solid rgba(var(--app-content-overlay-rgb),0.03);
}

.metric-label {
  font-size: 11px;
  color: #6a7280;
  margin-bottom: 4px;
}

.metric-value {
  font-size: 16px;
  font-weight: 600;
  color: var(--app-text-1);
  font-variant-numeric: tabular-nums;
}

.metric-sub {
  font-size: 11px;
  color: #6a7280;
  margin-top: 2px;
}

/* Snapshot Chart — empty state while historical data is not yet implemented */
.snapshot-chart {
  margin-top: 16px;
}

.snapshot-chart-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 18px 12px;
  background: rgba(var(--app-content-overlay-rgb),0.02);
  border: 1px dashed rgba(var(--app-content-overlay-rgb),0.06);
  border-radius: 10px;
  text-align: center;
}

.snapshot-chart-empty-icon {
  opacity: 0.8;
  margin-bottom: 2px;
}

.snapshot-chart-empty-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--app-text-muted-2);
}

.snapshot-chart-empty-sub {
  font-size: 11px;
  color: var(--app-text-muted-2);
  max-width: 240px;
  line-height: 1.45;
}

/* ========== POSITIONS TABS ========== */
.positions-tabs {
  display: flex;
  gap: 4px;
}

.pos-tab {
  background: none;
  border: none;
  color: #6a6a7a;
  font-size: 12px;
  font-weight: 600;
  padding: 6px 14px;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.15s;
  letter-spacing: 0.3px;
}

.pos-tab:hover {
  color: var(--app-text-1);
  background: rgba(var(--app-content-overlay-rgb),0.04);
}

.pos-tab.active {
  color: var(--app-primary);
  background: rgba(92, 184, 230, 0.15);
}

.positions-panel {
  display: none;
}

.positions-panel.active {
  display: block;
}

.positions-scroll {
  overflow-x: auto;
}

.positions-scroll::-webkit-scrollbar {
  height: 4px;
}

.positions-scroll::-webkit-scrollbar-track {
  background: transparent;
}

.positions-scroll::-webkit-scrollbar-thumb {
  background: rgba(92, 184, 230, 0.3);
  border-radius: 2px;
}
.positions-scroll::-webkit-scrollbar-thumb:hover {
  background: rgba(92, 184, 230, 0.5);
}

.positions-header,
.position-row {
  display: flex;
  align-items: center;
  min-width: 820px;
}

.positions-header {
  border-bottom: 1px solid rgba(var(--app-content-overlay-rgb),0.06);
  padding-bottom: 10px;
  margin-bottom: 2px;
}

.positions-header .pcol {
  font-size: 11px;
  font-weight: 600;
  color: #4a4a5a;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.position-row {
  padding: 12px 0;
  border-bottom: 1px solid rgba(var(--app-content-overlay-rgb),0.03);
  transition: background 0.15s;
  cursor: pointer;
}

.position-row:last-child {
  border-bottom: none;
}

.position-row:hover {
  background: rgba(var(--app-content-overlay-rgb),0.015);
}

/* Position columns */
.pcol {
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}

.pcol-inst { width: 160px; }
.pcol-type { width: 75px; font-size: 11px; line-height: 1.3; }
.pcol-side { width: 70px; }
.pcol-size { width: 95px; font-size: 13px; color: var(--app-text-muted-3); }
.pcol-entry { width: 95px; font-size: 13px; color: #6a6a7a; }
.pcol-mark { width: 95px; font-size: 13px; color: var(--app-text-1); font-weight: 500; }
.pcol-liq { width: 95px; font-size: 13px; color: #6a6a7a; }
.pcol-lev { width: 60px; }
.pcol-pnl { flex: 1; text-align: right; min-width: 120px; }
.pcol-strike { width: 85px; font-size: 13px; color: var(--app-text-muted-3); }
.pcol-iv { width: 65px; font-size: 13px; color: var(--app-text-muted-3); }
.pcol-delta { width: 65px; font-size: 13px; color: var(--app-text-muted-3); }
.pcol-expiry { width: 60px; text-align: right; font-size: 12px; color: #6a6a7a; }

/* Instrument cell */
.inst-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--app-text-1);
  letter-spacing: 0.2px;
}

.inst-exchange {
  font-size: 11px;
  color: #4a4a5a;
  margin-top: 2px;
}

/* Side tags */
.side-tag {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 4px;
  letter-spacing: 0.3px;
  text-transform: uppercase;
}

.side-tag.long {
  color: #4ecb71;
  background: rgba(78, 203, 113, 0.1);
}

.side-tag.short {
  color: #e65c5c;
  background: rgba(230, 92, 92, 0.1);
}

/* Leverage tag */
.lev-tag {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  color: #e6a85c;
  background: rgba(230, 168, 92, 0.1);
  padding: 3px 8px;
  border-radius: 4px;
}

/* Type tags (Call/Put) */
.type-tag {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 4px;
  letter-spacing: 0.3px;
}

.type-tag.call {
  color: #4ecb71;
  background: rgba(78, 203, 113, 0.1);
}

.type-tag.put {
  color: #e65c5c;
  background: rgba(230, 92, 92, 0.1);
}

/* PnL values */
.pnl-val {
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.pnl-val.positive { color: #4ecb71; }
.pnl-val.negative { color: #e65c5c; }

.pnl-roe {
  font-size: 11px;
  font-weight: 500;
  margin-top: 2px;
}

.pnl-roe.positive { color: rgba(78, 203, 113, 0.7); }
.pnl-roe.negative { color: rgba(230, 92, 92, 0.7); }

/* Positions summary footer */
.positions-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 14px;
  margin-top: 8px;
  border-top: 1px solid rgba(var(--app-content-overlay-rgb),0.06);
}

.positions-count {
  font-size: 12px;
  color: #4a4a5a;
}

.positions-total {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 13px;
  color: #6a6a7a;
}

.positions-total .pnl-val {
  font-size: 14px;
}

/* Empty state for positions */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 32px 16px;
  text-align: center;
}

.empty-state-icon {
  font-size: 28px;
  margin-bottom: 12px;
  opacity: 0.6;
}

.empty-state-text {
  font-size: 13px;
  color: #6a7280;
  margin-bottom: 12px;
  line-height: 1.5;
}

.empty-state-actions {
  display: flex;
  gap: 8px;
}

.empty-cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  font-size: 12px;
  font-weight: 500;
  color: var(--app-primary);
  background: rgba(92, 184, 230, 0.08);
  border: 1px solid rgba(92, 184, 230, 0.15);
  border-radius: 6px;
  text-decoration: none;
  transition: all 0.2s;
  cursor: pointer;
}

.empty-cta:hover {
  background: rgba(92, 184, 230, 0.14);
  border-color: rgba(92, 184, 230, 0.3);
}

/* ========== MARKET TICKERS ========== */
.market-tickers {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  padding-bottom: 4px;
}

.market-tickers::-webkit-scrollbar {
  height: 3px;
}

.market-tickers::-webkit-scrollbar-thumb {
  background: rgba(var(--app-content-overlay-rgb),0.06);
  border-radius: 2px;
}

.market-ticker-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: rgba(var(--app-content-overlay-rgb),0.02);
  border-radius: 6px;
  border: 1px solid rgba(var(--app-content-overlay-rgb),0.03);
  white-space: nowrap;
  min-width: 0;
  flex-shrink: 0;
}

.market-ticker-name {
  font-size: 12px;
  font-weight: 600;
  color: var(--app-text-1);
}

/* Bug #20 fix: fixed-width price to prevent layout shift on price updates */
.market-ticker-price {
  font-size: 12px;
  color: var(--app-text-muted-3);
  font-variant-numeric: tabular-nums;
  min-width: 75px;
  text-align: right;
}

.market-ticker-change {
  font-size: 11px;
  font-weight: 600;
}

.market-ticker-change.positive { color: #4ecb71; }
.market-ticker-change.negative { color: #e65c5c; }

/* ========== AI SHORTCUTS ========== */
.ai-shortcuts {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.ai-shortcut-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: rgba(var(--app-content-overlay-rgb),0.02);
  border: 1px solid rgba(var(--app-content-overlay-rgb),0.04);
  border-radius: 8px;
  color: #c0c0cc;
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  transition: all 0.2s;
  cursor: pointer;
}

.ai-shortcut-btn:hover {
  background: rgba(92, 184, 230, 0.06);
  border-color: rgba(92, 184, 230, 0.12);
  color: var(--app-text-1);
}

.ai-shortcut-icon {
  font-size: 16px;
  flex-shrink: 0;
  width: 20px;
  text-align: center;
}

/* ========== FEATURE CARDS ========== */
.feature-cards {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.feature-card {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 14px 16px;
  background: rgba(var(--app-content-overlay-rgb),0.02);
  border: 1px solid rgba(var(--app-content-overlay-rgb),0.04);
  border-radius: 10px;
  text-decoration: none;
  transition: all 0.2s;
  cursor: pointer;
}

.feature-card:hover {
  background: rgba(var(--app-content-overlay-rgb),0.04);
  border-color: rgba(92, 184, 230, 0.15);
  box-shadow: 0 0 0 1px rgba(92, 184, 230, 0.08);
}

.feature-card-icon {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  flex-shrink: 0;
  background: rgba(92, 184, 230, 0.08);
}

.feature-card-body {
  flex: 1;
  min-width: 0;
}

.feature-card-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--app-text-1);
  margin-bottom: 2px;
}

.feature-card-desc {
  font-size: 12px;
  color: #6a7280;
  line-height: 1.4;
}

/* ========== HOLDINGS LIST ========== */
.holdings-list {
  display: flex;
  flex-direction: column;
}

.holding-row {
  display: flex;
  align-items: center;
  padding: 14px 0;
  border-bottom: 1px solid rgba(var(--app-content-overlay-rgb),0.04);
}

.holding-row:last-child {
  border-bottom: none;
}

.holding-asset {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 140px;
}

.holding-icon {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 700;
  color: var(--app-text-white);
  flex-shrink: 0;
}

.holding-icon.btc { background: linear-gradient(135deg, #f7931a, #e8830e); }
.holding-icon.eth { background: linear-gradient(135deg, #627eea, #4c6bdf); }
.holding-icon.sol { background: linear-gradient(135deg, #9945ff, #14f195); }
.holding-icon.usdc { background: linear-gradient(135deg, #2775ca, #1a5fb4); }

.holding-name {
  font-size: 14px;
  font-weight: 500;
  color: var(--app-text-1);
}

.holding-ticker {
  font-size: 12px;
  color: #6a6a7a;
  margin-top: 1px;
}

.holding-mid {
  flex: 1;
  padding: 0 16px;
}

.spark-chart {
  width: 80px;
  height: 30px;
  display: block;
}

.holding-values {
  text-align: right;
  min-width: 100px;
}

.holding-amount {
  font-size: 14px;
  font-weight: 600;
  color: var(--app-text-1);
  font-variant-numeric: tabular-nums;
}

.holding-change {
  font-size: 12px;
  font-weight: 500;
  margin-top: 2px;
}

.holding-change.positive { color: #4ecb71; }
.holding-change.negative { color: #e65c5c; }
.holding-change.neutral { color: #6a6a7a; }

/* ========== FUNDING ACTIONS ========== */
.funding-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.funding-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 12px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  transition: all 0.2s;
  cursor: pointer;
  border: 1px solid transparent;
}

.funding-btn.deposit {
  background: rgba(78, 203, 113, 0.08);
  border-color: rgba(78, 203, 113, 0.15);
  color: #4ecb71;
}

.funding-btn.deposit:hover {
  background: rgba(78, 203, 113, 0.14);
}

.funding-btn.withdraw {
  background: rgba(224, 160, 80, 0.08);
  border-color: rgba(224, 160, 80, 0.15);
  color: var(--app-sell);
}

.funding-btn.withdraw:hover {
  background: rgba(224, 160, 80, 0.14);
}

.funding-btn.buy {
  background: rgba(92, 184, 230, 0.08);
  border-color: rgba(92, 184, 230, 0.15);
  color: var(--app-primary);
}

.funding-btn.buy:hover {
  background: rgba(92, 184, 230, 0.14);
}

.funding-btn.convert {
  background: rgba(168, 130, 230, 0.08);
  border-color: rgba(168, 130, 230, 0.15);
  color: #a882e6;
}

.funding-btn.convert:hover {
  background: rgba(168, 130, 230, 0.14);
}

.funding-btn svg {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
}

/* ========== DEBIT CARD WIDGET ========== */
.dash-debit-card {
  padding: 16px 20px;
}

.debit-card-visual {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 14px;
  padding-bottom: 14px;
  border-bottom: 1px solid rgba(var(--app-content-overlay-rgb),0.04);
}

.debit-card-chip {
  width: 44px;
  height: 32px;
  border-radius: 6px;
  background: linear-gradient(135deg, #2a2a36, #3a3a46);
  border: 1px solid rgba(var(--app-content-overlay-rgb),0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.debit-card-info {
  flex: 1;
}

.debit-card-number {
  font-size: 13px;
  font-weight: 500;
  color: var(--app-text-muted-3);
  letter-spacing: 1px;
  font-variant-numeric: tabular-nums;
}

.debit-card-name {
  font-size: 11px;
  color: #6a7280;
  margin-top: 2px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.debit-card-balance {
  margin-bottom: 12px;
}

.debit-card-balance-label {
  font-size: 11px;
  color: #6a7280;
  margin-bottom: 2px;
}

.debit-card-balance-value {
  font-size: 20px;
  font-weight: 700;
  color: var(--app-text-1);
  font-variant-numeric: tabular-nums;
}

.debit-card-txns {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.debit-card-txn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
}

.debit-card-txn-name {
  color: var(--app-text-muted-3);
}

.debit-card-txn-amount {
  color: var(--app-text-1);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

/* ========== INSIGHTS GRID ========== */
.insights-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}

.insight-card {
  padding: 16px;
  background: rgba(var(--app-content-overlay-rgb),0.02);
  border: 1px solid rgba(var(--app-content-overlay-rgb),0.04);
  border-radius: 10px;
  transition: all 0.2s;
  cursor: pointer;
  text-decoration: none;
  display: block;
}

.insight-card:hover {
  background: rgba(var(--app-content-overlay-rgb),0.04);
  border-color: rgba(92, 184, 230, 0.12);
}

.insight-tag {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  padding: 2px 8px;
  border-radius: 4px;
  margin-bottom: 8px;
}

.insight-tag.market {
  color: var(--app-primary);
  background: rgba(92, 184, 230, 0.1);
}

.insight-tag.strategy {
  color: var(--app-sell);
  background: rgba(224, 160, 80, 0.1);
}

.insight-tag.education {
  color: #a882e6;
  background: rgba(168, 130, 230, 0.1);
}

.insight-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--app-text-1);
  margin-bottom: 4px;
  line-height: 1.4;
}

.insight-desc {
  font-size: 12px;
  color: #6a7280;
  line-height: 1.4;
  margin-bottom: 8px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.insight-meta {
  font-size: 11px;
  color: #4a4a5a;
}

/* ========== ACTIVITY LIST ========== */
.activity-list {
  display: flex;
  flex-direction: column;
}

.activity-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid rgba(var(--app-content-overlay-rgb),0.04);
}

.activity-row:last-child {
  border-bottom: none;
}

.activity-icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 14px;
}

.activity-icon.deposit {
  background: rgba(78, 203, 113, 0.1);
  color: #4ecb71;
}

.activity-icon.trade {
  background: rgba(92, 184, 230, 0.1);
  color: var(--app-primary);
}

.activity-icon.card-tx {
  background: rgba(168, 168, 184, 0.08);
  color: var(--app-text-muted-2);
}

.activity-icon.withdrawal {
  background: rgba(224, 160, 80, 0.1);
  color: var(--app-sell);
}

.activity-info {
  flex: 1;
  min-width: 0;
}

.activity-title {
  font-size: 13px;
  font-weight: 500;
  color: var(--app-text-1);
}

.activity-desc {
  font-size: 11px;
  color: #6a6a7a;
  margin-top: 1px;
}

.activity-values {
  text-align: right;
  flex-shrink: 0;
}

.activity-amount {
  font-size: 13px;
  font-weight: 600;
  color: var(--app-text-1);
  font-variant-numeric: tabular-nums;
}

.activity-amount.positive { color: #4ecb71; }
.activity-amount.negative { color: #e65c5c; }

.activity-time {
  font-size: 11px;
  color: #6a6a7a;
  margin-top: 2px;
}

/* ========== AFFILIATE SUMMARY ========== */
.affiliate-summary {
  display: flex;
  gap: 16px;
}

.affiliate-stat {
  flex: 1;
  padding: 12px 14px;
  background: rgba(var(--app-content-overlay-rgb),0.02);
  border-radius: 8px;
  border: 1px solid rgba(var(--app-content-overlay-rgb),0.03);
}

.affiliate-stat-label {
  font-size: 11px;
  color: #6a7280;
  margin-bottom: 4px;
}

.affiliate-stat-value {
  font-size: 18px;
  font-weight: 700;
  color: var(--app-text-1);
  font-variant-numeric: tabular-nums;
}

.affiliate-stat-sub {
  font-size: 11px;
  color: #6a7280;
  margin-top: 2px;
}

/* ========== TIER BADGE ========== */
.tier-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 1px;
  padding: 3px 10px;
  border-radius: 20px;
  vertical-align: middle;
  margin-left: 8px;
}
.tier-badge svg {
  flex-shrink: 0;
}
.tier-silver {
  color: #c0c0c0;
  background: rgba(192, 192, 192, 0.1);
  border: 1px solid rgba(192, 192, 192, 0.25);
}
.tier-silver svg {
  stroke: #c0c0c0;
  fill: rgba(192, 192, 192, 0.15);
}
.tier-gold {
  color: #ffd700;
  background: rgba(255, 215, 0, 0.1);
  border: 1px solid rgba(255, 215, 0, 0.25);
}
.tier-gold svg {
  stroke: #ffd700;
  fill: rgba(255, 215, 0, 0.15);
}
.tier-platinum {
  color: #e5e4e2;
  background: linear-gradient(135deg, rgba(180, 200, 220, 0.15), rgba(220, 220, 230, 0.1));
  border: 1px solid rgba(220, 220, 230, 0.3);
  text-shadow: 0 0 8px rgba(200, 210, 230, 0.3);
}
.tier-platinum svg {
  stroke: #e5e4e2;
  fill: rgba(200, 210, 230, 0.2);
}

/* ========== VERIFICATION BANNER ========== */
.dash-verify-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  background: linear-gradient(135deg, rgba(92, 184, 230, 0.06), rgba(92, 184, 230, 0.02));
  border-color: rgba(92, 184, 230, 0.12);
}

.verify-content {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.verify-content svg {
  flex-shrink: 0;
  margin-top: 2px;
}

.verify-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--app-text-1);
  margin-bottom: 4px;
}

.verify-desc {
  font-size: 13px;
  color: var(--app-text-muted-2);
  line-height: 1.5;
}

/* ========== UTILITY CLASSES ========== */
.val-positive { color: #4ecb71; }
.val-negative { color: #e65c5c; }

/* ========== LEGACY MARKET TICKER (top bar) ========== */
.market-ticker {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  padding: 0 32px;
  height: 40px;
  background: rgba(26, 26, 31, 0.8);
  border-bottom: 1px solid rgba(var(--app-content-overlay-rgb),0.04);
  overflow: hidden;
}

.ticker-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 20px;
  white-space: nowrap;
}

.ticker-symbol {
  font-size: 11px;
  font-weight: 700;
  color: var(--app-text-muted-2);
  letter-spacing: 0.5px;
}

.ticker-price {
  font-size: 12px;
  font-weight: 500;
  color: var(--app-text-1);
  /* Bug #38 fix: fixed width + tabular digits to prevent layout shift on price updates */
  min-width: 80px;
  display: inline-block;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.ticker-change {
  font-size: 11px;
  font-weight: 600;
}

.ticker-change.positive { color: #4ecb71; }
.ticker-change.negative { color: #e65c5c; }

.ticker-divider {
  width: 1px;
  height: 16px;
  background: rgba(var(--app-content-overlay-rgb),0.06);
  flex-shrink: 0;
}

/* ========== CHART AREA (compact) ========== */
.dash-chart-compact {
  margin-bottom: 20px;
  padding: 16px 24px;
}

.dash-chart-compact .perf-chart {
  min-height: 80px;
  max-height: 100px;
}

.chart-timeframes {
  display: flex;
  gap: 4px;
}

.tf-btn {
  background: none;
  border: none;
  color: #6a6a7a;
  font-size: 11px;
  font-weight: 600;
  padding: 5px 10px;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.15s;
  letter-spacing: 0.3px;
}

.tf-btn:hover {
  color: var(--app-text-1);
  background: rgba(var(--app-content-overlay-rgb),0.04);
}

.tf-btn.active {
  color: var(--app-primary);
  background: rgba(92, 184, 230, 0.1);
}

.chart-area {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.perf-chart {
  flex: 1;
  width: 100%;
  min-height: 80px;
}

.chart-labels {
  display: flex;
  justify-content: space-between;
  font-size: 10px;
  color: #4a4a5a;
  padding-top: 8px;
}


/* ==================================================================
   RESPONSIVE
   ================================================================== */

@media (max-width: 1024px) {
  /* Sidebar collapse */
  .app-sidebar {
    transform: translateX(-100%);
    transition: transform 0.3s ease;
    z-index: var(--z-sidebar, 1110);
  }
  .app-sidebar.open {
    transform: translateX(0);
  }
  .sidebar-toggle {
    display: flex;
  }
  /* BUG #15: collapsed-state has no effect on mobile (sidebar hides via translateX). */
  .app-sidebar.collapsed {
    width: 240px;
    min-width: 240px;
  }
  body.sidebar-collapsed .app-content-wrapper { margin-left: 0; }
  body.sidebar-collapsed .app-topbar { left: 0; }
  .sidebar-collapse-btn { display: none !important; }
  .sidebar-close-btn { display: inline-flex; }
  .app-topbar {
    left: 0;
  }
  .app-content-wrapper {
    margin-left: 0;
  }
  .app-main {
    padding: 24px 24px 60px;
  }

  /* Dashboard grid → single column */
  .dash-row,
  .dash-row-top {
    grid-template-columns: 1fr;
  }

  .dash-welcome {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }

  .dash-verify-banner {
    flex-direction: column;
    align-items: flex-start;
  }

  .market-ticker {
    padding: 0 16px;
    justify-content: flex-start;
  }

  .positions-scroll {
    margin: 0 -20px;
    padding: 0 20px;
  }

  .insights-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .quick-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
  }

  .onboarding-checklist {
    flex-wrap: wrap;
    gap: 10px;
  }

  .insights-grid {
    grid-template-columns: 1fr;
  }

  .snapshot-breakdown {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 480px) {
  .app-main {
    padding: 20px 16px 60px;
  }
  .app-topbar {
    padding: 0 16px;
  }
  .market-ticker {
    height: 36px;
  }
  .ticker-item {
    padding: 0 12px;
  }

  .snapshot-value {
    font-size: 26px;
  }

  .snapshot-breakdown {
    grid-template-columns: 1fr;
  }

  .quick-actions {
    grid-template-columns: 1fr;
  }

  .funding-actions {
    grid-template-columns: 1fr;
  }

  .affiliate-summary {
    flex-direction: column;
  }

  .onboarding-checklist {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* ========== MENU TILES (unified-format sidebar-item tiles) ========== */
/* ===== AI Trading announcement banner (dash-ai-banner:begin) =====
   One full-width band above the Wallet / Bank Card row, distinguished from the
   cards below it by a 1px AI-accent border and nothing else.

   EVERY COLOUR IN THIS BLOCK IS A TOKEN, AND THAT IS LOAD-BEARING. Vestex is a
   DARK theme and Ultimo a LIGHT one (see js/brand-boot.js THEMES), so a single
   hard-coded hex — a white overlay, a sampled dark background, white button ink
   — is by definition the Vestex-only version of this band. The two accent
   tokens resolve per brand (cyan on Vestex, gold on Ultimo) and
   `--app-primary-fg` is the ink that stays legible ON that accent in both.
   dashboard-ai-banner.test.js refuses any literal colour added here later.

   ===========================================================================
   WHERE THE ACCENT IS ALLOWED TO GO — the rule that makes the band readable
   ===========================================================================
   No image and no animation are permitted here, so the only instruments this
   band has are hierarchy, spacing, weight and ONE colour. A colour spent
   everywhere means nothing anywhere, so the accent is rationed:

     SOLID accent ...... the button, and nothing else on the dashboard. Even the
                         cards' own "primary" links below are a 10% tint with
                         accent text (.menu-card-cta-link.primary), so the one
                         filled accent object on the page is the band's action.
     TINTED accent ..... the band's own wash and 1px edge (how the band is told
                         apart from the cards at all), and the NEW pill.
     NO accent ......... everything else, the mark included. The mark is the
                         dashboard's own neutral chip surface
                         (rgba(var(--app-content-overlay-rgb), …), the same
                         surface .menu-card-status uses) precisely so it does
                         not become a third accent object competing with the
                         pill and the button.

   That also removes a light-brand defect: an accent-coloured GLYPH on an
   accent-tinted square is ~1.7:1 on Ultimo's white page — the same finding the
   pill rule below cites, one element further along. (No issue number here: this
   header's text sits INSIDE the marker the test slices on, so it is the one
   comment in this block the test's comment-stripper cannot strip, and a "#"
   followed by hex digits would read as a hard-coded colour.)

   Every ink in this block is therefore a
   neutral token (--app-text-*) or the accent's own ink (--app-primary-fg,
   used only ON the filled button). */
.dash-ai-banner {
  display: flex;
  align-items: center;
  /* 14px is the dashboard's own head gap (.menu-card-head), so the band's
     rhythm is the page's rather than a second one invented for it. */
  gap: 14px;
  /* 64-72px tall on desktop: 10+10 padding around the three line-heights below
     (21+16+13) is 70px, and min-height keeps the TWO-line form (no record to
     quote) from dropping under the band. Nothing in the text column carries a
     margin, so this arithmetic is the rendered height and not an estimate —
     dashboard-ai-banner.test.js checks the same sum.

     THAT SUM ASSUMES ONE LINE PER ROW, and the band is fluid, so it holds where
     the text column is wide enough to hold the sentence. Measured: the column is
     ~654px at a 1280px viewport and the shipped 84-character sub-line is ~520px,
     so it holds comfortably at desktop. It does NOT hold in two narrow windows —
     roughly 821-930px, and 1025-1150px, the latter because the sidebar reappears
     at 1025px and takes 240px of content width back. There the sub-line wraps to
     two lines and the band grows to ~86px. Every alternative is worse: stacking
     the band that early makes it ~120px, and clamping the line truncates the
     owner's sentence mid-word. So it grows, on purpose.

     What is NOT left to chance is the OPERATOR making it worse: the per-field
     length caps in functions/src/services/dashboard-banner-config.js are derived
     from this same 654px column, so no configured value can wrap at a width
     where the shipped wording would not (Codex R2). */
  min-height: 64px;
  padding: 10px 18px;
  /* The grid below gaps its cards by 18px; matching it makes the band read as
     the grid's first row instead of a strip parked on top of it. */
  margin-bottom: 18px;
  border: 1px solid var(--app-ai-accent);
  /* .menu-card's own radius. */
  border-radius: 16px;
  /* A wash of the accent rather than a surface colour: it reads as part of the
     card row on the dark brand and on the light one, with no second rule. */
  background: rgba(var(--app-ai-accent-rgb), 0.06);
}

/* A MARKER, not a second button. It carries the accent — it is the "new" signal
   — but as a tint behind neutral ink, and in the 6px rounded-rect shape the
   dashboard already uses for status chips (.menu-card-status), so it cannot be
   mistaken for the filled action at the other end of the band. Accent-coloured
   TEXT is the failure mode it avoids (~1.9:1 on Ultimo's light page, #889);
   --app-text-strong is ~13:1 on the tint under Vestex and ~16:1 under Ultimo. */
.dash-ai-banner-pill {
  flex-shrink: 0;
  font-size: 10px;
  font-weight: 700;
  /* Unitless on purpose: the band's height budget is the three TEXT lines, and
     a px value here would join that sum without being part of the stack. */
  line-height: 1;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  padding: 5px 8px;
  border-radius: 6px;
  background: rgba(var(--app-ai-accent-rgb), 0.16);
  color: var(--app-text-strong);
}

/* The feature's mark. Deliberately NOT an accent object (see the block header):
   a neutral chip, hairline edge, neutral glyph — legible on a white Ultimo page
   and a dark Vestex one, and quiet enough that the headline beside it is what
   the eye actually lands on. 30px, a step below the 46px card marks below, so
   the band reads as an announcement rather than a fifth card. */
.dash-ai-banner-icon {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: rgba(var(--app-content-overlay-rgb), 0.06);
  border: 1px solid var(--app-border);
  color: var(--app-text-strong);
}

.dash-ai-banner-icon svg {
  width: 18px;
  height: 18px;
}

.dash-ai-banner-text {
  flex: 1;
  /* Lets the column shrink below its content so a long configured sub-line
     wraps instead of pushing the button out of the band. */
  min-width: 0;
}

/* THE LINE THE EYE MUST LAND ON FIRST. The two card titles below it are 17px/600
   in --app-text-1; this is 18px/700 in --app-text-strong, so it wins on size,
   on weight and on ink — one step above them on each axis, which is enough to
   lead the page and short of shouting. It is the largest TEXT on the dashboard
   but not the largest thing: the cards' own figures (.menu-card-primary-value,
   28px) still dominate their tiles, as they should. */
.dash-ai-banner-headline {
  font-size: 18px;
  font-weight: 700;
  line-height: 21px;
  letter-spacing: -0.1px;
  color: var(--app-text-strong);
}

/* The claim. Body ink, body weight — it explains the headline and does not
   compete with it. */
.dash-ai-banner-sub {
  font-size: 12.5px;
  line-height: 16px;
  color: var(--app-text-1);
}

/* The featured bot's public record: PROOF offered after the claim, not a third
   headline. Two steps down from the sub-line — smaller AND in the muted ink —
   so it reads as a footnote to it. Only ever in the DOM when there is a real
   record to quote. */
.dash-ai-banner-record {
  font-size: 11px;
  line-height: 13px;
  color: var(--app-text-muted-2);
}

/* THE ACTION. The only filled accent object on the dashboard, so "this is the
   thing to click" needs no further decoration. --app-primary-fg is the ink that
   stays legible ON the accent in both brands. */
.dash-ai-banner-cta {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 18px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  /* The label is one line or the band grows: a wrapped button would break the
     64-72px geometry at exactly the narrow widths where it is already tight.
     The text column carries min-width:0, so nothing overflows instead. */
  white-space: nowrap;
  text-decoration: none;
  border: 1px solid var(--app-ai-accent);
  border-radius: 10px;
  background: var(--app-ai-accent);
  color: var(--app-primary-fg);
}

/* No transition, and that is the owner's "no animation" taken at its word
   (Codex R4). The rest of the dashboard fades its hovers — .menu-card and
   .menu-card-cta-link both carry 0.15-0.2s transitions — so this button is the
   one control on the page that changes instantly. That is the trade the
   constraint asks for, and the feedback is not lost: the state change itself is
   what the pointer needs, not the 150ms it takes to arrive. The rule below
   refuses any `transition` added to this block later. */
.dash-ai-banner-cta:hover {
  opacity: 0.88;
}

/* WCAG 2.4.7 — the band's ONLY interactive element, and it had no keyboard
   focus indicator. Same pattern as the #293 consent links: :focus-visible,
   2px ring, 2px offset. The ring is a NEUTRAL token, not the accent: an accent
   ring sitting on the accent wash is ~1.9:1 on Ultimo, i.e. no ring at all. */
.dash-ai-banner-cta:focus-visible {
  outline: 2px solid var(--app-text-strong);
  outline-offset: 2px;
}

@media (forced-colors: active) {
  .dash-ai-banner-cta:focus-visible {
    outline: 2px solid CanvasText;
  }
}

/* The `hidden` attribute must actually hide the record line: the rules above
   set no display on it, but this file has shipped that defect before
   (.menu-card[hidden] below), so the guard is explicit rather than assumed. */
.dash-ai-banner-record[hidden] { display: none !important; }

/* The band's SMALL-WIDTH rules are NOT here. They live in this file's one
   `@media (max-width: 820px)` block, beside the rule that collapses
   .menu-cards-grid to a single column — the band and the tiles it sits above
   must change shape at the same width, and a second block for the same
   breakpoint is how two rules for one layout drift apart. */
/* ===== dash-ai-banner:end ===== */

.menu-cards-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
  margin-bottom: 20px;
}

/* The `hidden` attribute must actually hide a menu card. `.menu-card` below
   sets display:flex (author origin), which overrides the UA
   `[hidden]{display:none}` rule — so the JS-gated AI Trading card would ship
   VISIBLE to every user. Exactly the defect `.sidebar-nav-item[hidden]` above
   exists to prevent; this class of bug has shipped here before. */
.menu-card[hidden] { display: none !important; }

/* Five cards in a two-column grid: Leverage Trading takes the whole middle
   row, so the rows read Wallet|Bank Card / Leverage / AI Trading|Account.
   In the <=820px single-column grid `1 / -1` resolves to the only column, so
   the span is a no-op there and mobile keeps stacking exactly as before. */
.menu-card.span-2 { grid-column: 1 / -1; }

.menu-card {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 24px;
  background: linear-gradient(180deg, #1c1c22 0%, #17171c 100%);
  border: 1px solid rgba(var(--app-content-overlay-rgb), 0.05);
  border-radius: 16px;
  text-decoration: none;
  color: var(--app-text-1);
  transition: border-color 0.2s ease, transform 0.15s ease, box-shadow 0.2s ease;
  min-height: 280px;
}

.menu-card:hover {
  border-color: rgba(92, 184, 230, 0.35);
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
}

.menu-card-head {
  display: flex;
  align-items: center;
  gap: 14px;
}

.menu-card-icon {
  width: 46px;
  height: 46px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(92, 184, 230, 0.1);
  border: 1px solid rgba(92, 184, 230, 0.2);
  border-radius: 11px;
  color: var(--app-primary);
}

.menu-card-icon svg {
  width: 22px;
  height: 22px;
}

.menu-card-title-wrap {
  flex: 1;
  min-width: 0;
}

.menu-card-title {
  font-size: 17px;
  font-weight: 600;
  color: var(--app-text-1);
  line-height: 1.2;
}

.menu-card-subtitle {
  font-size: 11px;
  color: var(--app-text-muted-2);
  margin-top: 3px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
}

.menu-card-status {
  font-size: 11px;
  font-weight: 500;
  color: var(--app-text-muted-2);
  padding: 5px 10px;
  background: rgba(var(--app-content-overlay-rgb), 0.04);
  border-radius: 6px;
  white-space: nowrap;
}

.menu-card-primary {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.menu-card-primary-label {
  font-size: 11px;
  color: var(--app-text-muted-2);
  text-transform: uppercase;
  letter-spacing: 0.6px;
}

.menu-card-primary-value {
  font-size: 28px;
  font-weight: 700;
  color: #f0f0f5;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

.menu-card-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.menu-card-body-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 10px;
  background: rgba(var(--app-content-overlay-rgb), 0.02);
  border-radius: 8px;
  gap: 10px;
  min-width: 0;
}

.menu-card-body-row .row-left {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  color: #c0c0cc;
  font-size: 13px;
}

.menu-card-body-row .row-right {
  font-size: 13px;
  font-weight: 500;
  color: var(--app-text-1);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.menu-card-body-row .row-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 5px;
  background: rgba(92, 184, 230, 0.12);
  color: var(--app-primary);
  font-size: 11px;
  font-weight: 600;
  flex-shrink: 0;
}

/* Multi-card: one row per card under the balance (brand · last4 · status). */
.menu-card-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 10px;
}
.menu-card-list[hidden] { display: none; }
.menu-card-list .row-badge {
  width: auto;
  padding: 0 7px;
  font-size: 10px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
}
.menu-card-list .row-right.is-active { color: #3fb950; }

.menu-card-meta {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  padding: 14px 0;
  border-top: 1px solid rgba(var(--app-content-overlay-rgb), 0.04);
  border-bottom: 1px solid rgba(var(--app-content-overlay-rgb), 0.04);
}

.menu-card-meta.meta-2 {
  grid-template-columns: 1fr 1fr;
}

.menu-card-meta-item {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.menu-card-meta-item .meta-label {
  font-size: 10px;
  color: var(--app-text-muted-2);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.menu-card-meta-item .meta-value {
  font-size: 14px;
  font-weight: 500;
  color: #c0c0cc;
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.menu-card-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: auto;
}

.menu-card-actions.multi {
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-start;
}

.menu-card-cta {
  font-size: 13px;
  font-weight: 600;
  color: var(--app-primary);
}

.menu-card-arrow {
  color: var(--app-primary);
  transition: transform 0.15s ease;
}

.menu-card:hover .menu-card-arrow {
  transform: translateX(3px);
}

/* Multi-link CTAs inside a single card */
.menu-card-cta-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  font-size: 12px;
  font-weight: 600;
  color: #c0c0cc;
  text-decoration: none;
  background: rgba(var(--app-content-overlay-rgb), 0.04);
  border: 1px solid rgba(var(--app-content-overlay-rgb), 0.05);
  border-radius: 8px;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.menu-card-cta-link:hover {
  background: rgba(92, 184, 230, 0.08);
  border-color: rgba(92, 184, 230, 0.3);
  color: var(--app-primary);
}

.menu-card-cta-link.primary {
  background: rgba(92, 184, 230, 0.1);
  border-color: rgba(92, 184, 230, 0.3);
  color: var(--app-primary);
}

.menu-card-cta-link.primary:hover {
  background: rgba(92, 184, 230, 0.18);
  border-color: rgba(92, 184, 230, 0.5);
}

.menu-card-cta-link.ghost {
  background: transparent;
  border-color: transparent;
  color: var(--app-text-muted-2);
}

.menu-card-cta-link.ghost:hover {
  color: var(--app-primary);
  background: rgba(92, 184, 230, 0.06);
}

/* Body rows that are themselves links (Account card) */
.menu-card-body-row.linkable {
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  transition: background 0.15s ease;
}

.menu-card-body-row.linkable:hover {
  background: rgba(92, 184, 230, 0.06);
}

/* ===== AI Trading card (copy-trade bots) =====
   One row per bot with an outstanding participation. The left cell can hold a
   long bot name + instrument label, so it truncates rather than pushing the
   stake/PnL column out of the card. */
.menu-ai-name-wrap {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.menu-ai-bot-link {
  color: var(--app-text-1);
  text-decoration: none;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.menu-ai-bot-link:hover {
  color: var(--app-primary);
  text-decoration: underline;
}

.menu-ai-instrument {
  font-size: 11px;
  color: var(--app-text-muted-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* State chip (§4 wording). Neutral by design: the review wordings are long and
   must read as information, not as an alarm colour. */
.menu-ai-chip {
  flex-shrink: 0;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 20px;
  background: rgba(var(--app-content-overlay-rgb), 0.08);
  color: var(--app-text-muted-2);
  white-space: nowrap;
}

.menu-ai-stake { color: var(--app-text-muted-2); font-weight: 500; }

/* PnL sign colour — the same pair the Leverage card uses, but as CLASSES, so a
   brand rule can override it (an inline style could not). `is-unknown` covers
   "—" / "Funds reserved": no number, so no direction to signal. */
.menu-ai-pnl.is-up { color: var(--app-primary); }
.menu-ai-pnl.is-down { color: var(--app-sell); }
.menu-ai-pnl.is-unknown { color: var(--app-text-muted-2); }

.menu-ai-onboard {
  font-size: 13px;
  line-height: 1.6;
  color: var(--app-text-muted-2);
}

/* §5 freshness line — shown only while a displayed number is behind. */
.menu-ai-note {
  font-size: 11px;
  color: var(--app-text-muted-2);
  margin-top: -8px;
}

/* Responsive */
@media (max-width: 820px) {
  .menu-cards-grid {
    grid-template-columns: 1fr;
    gap: 14px;
  }
  .menu-card {
    min-height: 240px;
    padding: 20px;
  }
  .menu-card-primary-value {
    font-size: 24px;
  }
  /* AI Trading banner: the band stacks and its button goes FULL WIDTH — a 12px
     button hugging the right edge of a 360px screen is not a tappable target.
     Wrapping rather than a plain column, so the NEW pill and the mark stay on
     one line together instead of becoming two near-empty rows. */
  .dash-ai-banner {
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 14px;
  }
  .dash-ai-banner-text,
  .dash-ai-banner-cta {
    flex-basis: 100%;
  }
  .dash-ai-banner-cta {
    width: 100%;
    /* A thumb target, not a desktop button stretched sideways: 44px is the
       minimum tappable height, and the desktop rule's 10px padding around a
       13px label lands at ~35px. */
    min-height: 44px;
    /* The desktop rule keeps the label on one line so the band cannot grow past
       its 64-72px; here the button owns a whole row, so a long configured label
       may wrap inside it rather than overflow a 360px screen. */
    white-space: normal;
  }
}

/* BUG #38: prevent layout shift on the market list as prices tick.
   Tabular-nums keeps every digit the same width, and min-width on the
   price / change columns stops the row from reflowing when the digit
   count changes (e.g. $9,998 → $10,002). */
.mover-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 8px; text-decoration: none; color: inherit; }
.mover-row:hover { background: rgba(92, 184, 230, 0.06); }
.mover-info { flex: 1; min-width: 0; }
.mover-price {
  font-variant-numeric: tabular-nums;
  min-width: 88px;
  text-align: right;
  font-weight: 600;
  color: #e5e7eb;
}
.mover-change {
  font-variant-numeric: tabular-nums;
  min-width: 64px;
  text-align: right;
  font-size: 12px;
  font-weight: 600;
}
.mover-change.positive { color: var(--app-primary); }
.mover-change.negative { color: var(--app-sell); }

/* ===== LB5 dark islands (whitelabel) =====
   Sidebar + topbar stay DARK on every brand by re-defining the content neutral
   tokens to Vestex dark values within their scope. Vestex: identical (zero-diff).
   Ultimo: content flips light; sidebar/topbar remain dark. Brand accent
   (--app-primary/buy/sell) is intentionally NOT overridden so it still themes. */
.app-sidebar,
.app-topbar {
  --app-bg: #222228;
  --app-shell-bg: #131316;
  --app-surface-1: #1a1a1f;
  --app-surface-2: #111827;
  --app-surface-card: #1a1a2e;
  --app-text-strong: #e2e8f0;
  --app-text-1: #e0e0e8;
  --app-text-muted: #8a94a6;
  --app-text-muted-2: #8a8a9a;
  --app-text-muted-3: #a8a8b8;
  --app-text-white: #ffffff;
  --app-content-overlay-rgb: 255, 255, 255;
}

/* ===== Ultimo light-theme overrides (whitelabel) =====
   Content cards that LB6 left as raw dark literals (gradient / #0d1117) — flip
   to a soft light surface on Ultimo. Vestex (data-brand=vestex) keeps its dark
   values untouched = zero-diff. The 4 top tiles + dash cards had dark bg with
   dark titles → invisible on the light page. */
html[data-brand="ultimo"] .menu-card {
  background: linear-gradient(180deg, #ffffff 0%, #f5f5f7 100%);
  border-color: var(--app-border);
}
html[data-brand="ultimo"] .dash-card {
  background: var(--app-surface-1);
  border: 1px solid var(--app-border);
}

/* ===== Ultimo dashboard menu-card INTERNALS (audit 2026-06-25) =====
   After .menu-card flips light, its inner elements were still styled for a dark
   card (near-white values, light-cyan icon bg + gold icon, washed cyan+gold CTAs,
   faint gray row text). Make values/row text dark, give icons a DARK bg so the
   gold pops, and turn the primary CTA into a SOLID gold accent (applies to all 4
   card CTAs at once). Scoped to ultimo → vestex zero-diff. */
html[data-brand="ultimo"] .menu-card-primary-value,
html[data-brand="ultimo"] .menu-card-meta-item .meta-value,
html[data-brand="ultimo"] .menu-card-body-row .row-left { color: var(--app-text-strong); }
html[data-brand="ultimo"] .menu-card-icon { background: #1a1a1f; border-color: rgba(0, 0, 0, 0.10); }
html[data-brand="ultimo"] .menu-card-body-row .row-badge { background: #1a1a1f; }
html[data-brand="ultimo"] .menu-card-cta-link { color: var(--app-text-strong); }
html[data-brand="ultimo"] .menu-card-cta-link.ghost { color: var(--app-text-muted); }
html[data-brand="ultimo"] .menu-card-cta-link.primary {
  background: var(--app-primary);
  border-color: var(--app-primary);
  color: var(--app-primary-fg);
}
html[data-brand="ultimo"] .menu-card-cta-link.primary:hover {
  background: var(--app-primary-hover);
  border-color: var(--app-primary-hover);
}
html[data-brand="ultimo"] .menu-card-cta-link.primary .menu-card-arrow,
html[data-brand="ultimo"] .menu-card-cta-link.primary svg { color: var(--app-primary-fg); }
html[data-brand="ultimo"] .menu-card-status {
  color: var(--app-text-strong);
  border: 1px solid var(--app-border);
}

/* ===== Ultimo — AI Trading card PnL, the #889 rule =====
   `--app-primary` (#f5b50a) and `--app-sell` (#e0a050) as TEXT on Ultimo's
   LIGHT card land at ~1.6-1.9:1, and under Ultimo the two hues are nearly the
   same gold, so colour carries almost no signal either. Per #889 the HUE moves
   into the BACKGROUND and the text goes to a neutral token. Nothing is lost:
   every one of these figures already carries an explicit +/- in the text
   (fmtSignedUsd), so the colour was redundant. The two tints are the same pair
   ai-trading.css uses for .ai-result-badge, so gain/loss stay distinguishable
   without relying on the brand accent. Ultimo-only ⇒ Vestex is byte-identical. */
html[data-brand="ultimo"] .menu-ai-pnl.is-up,
html[data-brand="ultimo"] .menu-ai-pnl.is-down {
  color: var(--app-text-strong);
  border-radius: 6px;
  padding: 0 6px;
}
html[data-brand="ultimo"] .menu-ai-pnl.is-up { background: rgba(61, 220, 132, 0.16); }
html[data-brand="ultimo"] .menu-ai-pnl.is-down { background: rgba(224, 160, 80, 0.20); }
