/* ═══════════════════════════════════════════════════════════════════════════
   OCTO X — LIQUID GLASS (28/10/2026)

   Hệ hình ảnh mới: nền aurora tối + panel kính mờ (glassmorphism), viền sáng
   như thuỷ tinh, highlight bóng (glossy) và chất "liquid glass" ở các pill /
   nút / thẻ. Toàn bộ HÀNH VI, ID, lớp chức năng giữ nguyên — chỉ thay tầng
   trình bày. Các rule bị test tĩnh "chốt" (tests/ui/*.spec.js) được giữ đúng
   nguyên văn, đừng sửa nếu không đọc lại spec:

     .workspace { display: grid; grid-template-columns: minmax(0, 1fr); …
     .channel-legend … repeat(6 …      .channel-chip … display: flex
     .calendar-panel … max-width: 500px
     .pair-tag.p-btc { border-color: #f5c451; background: #f5c451; color: #111; }
     .perf-clock / .perf-clock.idle / .perf-grid / .perf-tile / .stats-line
     .chip.active / .pager / .calendar-day.win / .calendar-day.loss
     .calendar-grid.by-month / .open-total(.positive) / .dock-mini-*
     .side-dock.has-orders … flex: 0 1 auto … max-height: 100%
     .dock-mini-group[data-dock-group="open"] { flex: 0 1 auto …
     [data-dock-group="closed"] .dock-mini-list … max-height: 168px
     .dock-cal … flex: 0 0 auto / .dock-cal .calendar-day span … .52rem
     .signal-lost / .signal-delay (--warning) / .signal-viz-frame.offline
     min-height: 44px · font-size: 16px · :focus-visible · prefers-reduced-motion
     overflow-x: hidden
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  color-scheme: dark;
  --bg: #04070e;
  --bg-soft: #070d18;
  --surface: rgba(17, 28, 48, .62);
  --surface-raised: rgba(255, 255, 255, .055);
  --surface-soft: rgba(255, 255, 255, .09);
  --border: rgba(154, 182, 226, .18);
  --border-strong: rgba(178, 208, 255, .32);
  --text: #eef4ff;
  --muted: #a8b8d4;
  --accent: #3fdac4;
  --accent-deep: #139d8c;
  --accent-2: #5b8cff;
  --accent-3: #a875ff;
  --buy: #2ce3a1;
  --sell: #ff6f8f;
  --warning: #ffc45c;
  --focus: #8fd8ff;
  --radius: 20px;
  --radius-sm: 13px;
  --glass-blur: 20px;
  --shadow-glass: 0 26px 60px -30px rgba(0, 0, 0, .9), 0 8px 24px -18px rgba(0, 0, 0, .7);
  --shadow-float: 0 18px 40px -18px rgba(0, 0, 0, .75), 0 2px 8px rgba(0, 0, 0, .35);
  --highlight-line: inset 0 1px 0 rgba(255, 255, 255, .16), inset 0 -1px 0 rgba(0, 0, 0, .32);
  --glass-fill: radial-gradient(130% 100% at 14% -32%, rgba(255, 255, 255, .13), transparent 58%),
                 linear-gradient(155deg, rgba(26, 41, 68, .66), rgba(8, 14, 26, .58) 52%, rgba(19, 31, 54, .64));
  --glass-fill-soft: radial-gradient(120% 100% at 16% -30%, rgba(255, 255, 255, .10), transparent 60%),
                      linear-gradient(160deg, rgba(255, 255, 255, .075), rgba(255, 255, 255, .022) 55%, rgba(255, 255, 255, .05));
  --font-body: "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --font-display: "Segoe UI Variable Display", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "Cascadia Mono", Consolas, "Courier New", monospace;
}

* { box-sizing: border-box; }

html { overflow-x: hidden; background: var(--bg); }

/* ── Nền aurora + hạt nhiễu ─────────────────────────────────────────────
   Nền nằm ở hai lớp ::before/::after của body để KHÔNG phải thêm phần tử
   vào HTML (spec cấm <svg>/thẻ lạ trong index.html). Lớp aurora chạy rất
   chậm (28s) và chỉ dùng transform ⇒ trình duyệt composite, không layout. */
body {
  position: relative;
  min-width: 0;
  min-height: 100vh;
  margin: 0;
  overflow-x: hidden;
  background: transparent;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.45;
  letter-spacing: .004em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
body::before {
  content: "";
  position: fixed;
  inset: -30vmax;
  z-index: -2;
  pointer-events: none;
  background:
    radial-gradient(42vmax 34vmax at 18% 12%, rgba(38, 200, 182, .37), transparent 62%),
    radial-gradient(38vmax 32vmax at 82% 8%, rgba(86, 122, 255, .32), transparent 64%),
    radial-gradient(46vmax 40vmax at 72% 88%, rgba(156, 96, 255, .27), transparent 66%),
    radial-gradient(30vmax 26vmax at 24% 82%, rgba(245, 196, 81, .13), transparent 68%),
    linear-gradient(180deg, #050912 0%, #04070e 55%, #060b16 100%);
  animation: aurora-drift 28s ease-in-out infinite alternate;
  will-change: transform;
}
/* Hạt nhiễu li ti phủ lên nền: làm bề mặt kính bớt "phẳng số" và có cảm giác
   vật liệu. Data-URI SVG nằm trong CSS (không phải thẻ <svg> trong HTML).
   encodeURI: %23 = dấu #, %25 = dấu %. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .045;
  mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
  background-size: 160px 160px;
}
@keyframes aurora-drift {
  0% { transform: translate3d(-2%, -1%, 0) scale(1) rotate(0deg); }
  50% { transform: translate3d(1.5%, 2%, 0) scale(1.06) rotate(2deg); }
  100% { transform: translate3d(3%, -2%, 0) scale(1.03) rotate(-2deg); }
}

::selection { background: rgba(63, 218, 196, .34); color: #fff; }

/* Thanh cuộn kính: mảnh, trong, không chiếm chỗ thị giác. */
* { scrollbar-width: thin; scrollbar-color: rgba(150, 180, 225, .35) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  border: 2px solid transparent;
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(150, 190, 240, .38), rgba(90, 120, 170, .28)) padding-box;
}
*::-webkit-scrollbar-thumb:hover { background: linear-gradient(180deg, rgba(63, 218, 196, .55), rgba(91, 140, 255, .4)) padding-box; }

button, input, select { min-height: 44px; font: inherit; }
button { cursor: pointer; }
button:focus-visible, input:focus-visible, select:focus-visible, a:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
/* Ô tick kính: bỏ ô vuông xám mặc định của trình duyệt, thay bằng viên thuỷ tinh
   19px có highlight trên + dấu tick vẽ bằng data-URI (KHÔNG thêm <svg> vào HTML —
   tests/ui/user-dashboard.spec.js cấm thẻ đó trong index.html). `appearance:none`
   biến input thành phần tử thường nên tự vẽ được; vẫn giữ `accent-color` cho trình
   duyệt quá cũ không hỗ trợ appearance trên checkbox. */
input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  accent-color: var(--accent);
  width: 19px;
  height: 19px;
  min-height: 0;
  margin: 0;
  padding: 0;              /* `input` chung có padding 10px 12px ⇒ width 19px bị đẩy lên 26px */
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  background: linear-gradient(160deg, rgba(255, 255, 255, .10), rgba(255, 255, 255, .02) 70%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22), inset 0 -3px 8px rgba(0, 0, 0, .38), 0 2px 6px -3px rgba(0, 0, 0, .7);
  cursor: pointer;
  transition: background .18s, border-color .18s, box-shadow .18s;
}
input[type="checkbox"]:hover { border-color: rgba(63, 218, 196, .55); }
input[type="checkbox"]:checked {
  border-color: rgba(63, 218, 196, .85);
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.2 8.6l3.1 3.1 6.5-6.6' fill='none' stroke='%2307161a' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 13px 13px no-repeat,
    linear-gradient(160deg, #74f3dd, #23bfa7 58%, #0f8d7a);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .55), inset 0 -2px 6px rgba(9, 60, 54, .45), 0 0 0 3px rgba(63, 218, 196, .14), 0 4px 14px -5px rgba(63, 218, 196, .65);
}
input[type="checkbox"]:disabled { opacity: .55; cursor: not-allowed; }
input[type="date"]::-webkit-calendar-picker-indicator { cursor: pointer; filter: invert(.82) sepia(.12) saturate(2.4) hue-rotate(140deg); opacity: .85; }
/* Mũi tên tăng/giảm của ô số (ô "Withdraw amount" ở tab Referrals): widget này do
   trình duyệt tự vẽ, KHÔNG nhận màu của mình — nhuộm bằng `filter` thì cả cái nền
   xám của nó cũng bị lật theo và thành một ô xám đặc giữa khung kính. Ẩn hẳn cho
   sạch; gõ số là đường chính, và ArrowUp/ArrowDown vẫn tăng/giảm được như thường. */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; appearance: none; margin: 0; }

.hidden { display: none !important; }
.muted { color: var(--muted); }
.message { min-height: 22px; margin: 8px 0 0; color: var(--muted); font-size: .9rem; }
.message.ok, .message.success { color: #8ff5d5; }
.message.err, .message.error { color: #ffb0c0; }
.full-width { width: 100%; }
.eyebrow {
  margin: 0 0 2px;
  color: #6ff0dc;
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  text-shadow: 0 0 18px rgba(63, 218, 196, .45);
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .eyebrow {
    background: linear-gradient(90deg, #6ff0dc, #9cc3ff 70%, #c7a6ff);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
  }
}

/* ── Màn hình dùng chung (đăng nhập, status, legal) ─────────────────── */
.screen { display: grid; min-height: 100vh; padding: clamp(16px, 4vw, 40px); place-items: center; }
.screen > .panel { width: min(760px, 100%); }

.auth-screen { display: grid; min-height: 100vh; padding: 20px; place-items: center; }
.auth-card {
  position: relative;
  width: min(100%, 470px);
  padding: clamp(22px, 4vw, 34px);
  border: 1px solid var(--border-strong);
  border-radius: 26px;
  background: var(--glass-fill);
  box-shadow: var(--shadow-glass), var(--highlight-line), 0 0 90px -30px rgba(63, 218, 196, .45);
  backdrop-filter: blur(26px) saturate(160%);
  -webkit-backdrop-filter: blur(26px) saturate(160%);
}
/* Vệt sáng chéo chạy ngang mặt kính — chất "glossy" của tấm thuỷ tinh. */
.auth-card::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(115deg, transparent 18%, rgba(255, 255, 255, .16) 34%, transparent 50%);
  opacity: .6;
}
.auth-card > * { position: relative; }
.auth-card h1 { margin: 24px 0 6px; font-size: clamp(1.5rem, 4vw, 1.95rem); letter-spacing: -.015em; }
.stack { display: grid; gap: 11px; margin-top: 18px; }
.stack label, .form-grid label, .filters label { display: grid; gap: 6px; color: var(--muted); font-size: .9rem; }

/* ── Thương hiệu ─────────────────────────────────────────────────────── */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  color: var(--text);
  font-family: var(--font-display);
  font-size: 1.06rem;
  font-weight: 850;
  letter-spacing: .1em;
  text-decoration: none;
  text-shadow: 0 0 22px rgba(63, 218, 196, .28);
}
/* Logo OCTO X — cắt từ ảnh chủ dự án gửi 28/10/2026 (`logo.png`, nền trong
   suốt, đã có sẵn quầng sáng xanh). Ảnh là <img> nên KHÔNG đặt nền gradient
   phía sau nữa: nền cũ sẽ lộ ra ở bốn góc trong suốt của ảnh. Bóng đổ đặt bằng
   `filter` để men theo đúng hình tròn của logo. */
.brand-mark {
  display: block;
  width: 38px;
  height: 38px;
  flex: 0 0 auto;
  object-fit: contain;
  filter: drop-shadow(0 0 12px rgba(126, 231, 26, .32));
}

/* ── Nút: pill kính, highlight trên, bóng dưới, vệt sáng khi hover ──── */
.btn {
  position: relative;
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  justify-content: center;
  gap: 6px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 999px;
  padding: 8px 16px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .14), rgba(255, 255, 255, .035) 48%, rgba(255, 255, 255, .07));
  color: var(--text);
  font-weight: 750;
  letter-spacing: .01em;
  text-shadow: 0 1px 0 rgba(0, 0, 0, .28);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .3),
    inset 0 -1px 0 rgba(0, 0, 0, .35),
    0 10px 22px -16px rgba(0, 0, 0, .95);
  transition: transform .15s ease, background .2s, border-color .2s, box-shadow .2s, color .2s, filter .2s;
}
/* Vệt sáng quét ngang khi hover — hiệu ứng "bóng loáng" kinh điển. */
.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(115deg, transparent 24%, rgba(255, 255, 255, .34) 44%, transparent 62%);
  transform: translateX(-130%);
  transition: transform .55s ease;
}
.btn:hover::after { transform: translateX(130%); }
.btn:hover { transform: translateY(-1px); border-color: rgba(255, 255, 255, .28); }
.btn:active { transform: translateY(1px) scale(.99); box-shadow: inset 0 2px 6px rgba(0, 0, 0, .4); }
.btn-primary {
  border-color: rgba(150, 255, 236, .6);
  background: linear-gradient(180deg, #8cf7e7 0%, #36d6bf 42%, #149a8b 100%);
  color: #04221d;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .4);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .85),
    inset 0 -2px 8px rgba(0, 88, 76, .5),
    0 12px 30px -10px rgba(38, 214, 192, .6),
    0 0 0 1px rgba(255, 255, 255, .06);
}
.btn-primary:hover { background: linear-gradient(180deg, #a3fbef 0%, #46e3cb 42%, #17ab99 100%); filter: brightness(1.04); }
.btn-secondary {
  border-color: rgba(120, 168, 255, .38);
  background: linear-gradient(180deg, rgba(86, 130, 255, .3), rgba(50, 82, 160, .22));
  color: #dce8ff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .28), inset 0 -1px 0 rgba(0, 0, 0, .35), 0 10px 26px -14px rgba(60, 110, 255, .55);
}
.btn-quiet {
  background: linear-gradient(180deg, rgba(255, 255, 255, .07), rgba(255, 255, 255, .02));
  border-color: var(--border);
  color: var(--muted);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12), inset 0 -1px 0 rgba(0, 0, 0, .3);
}
.btn-quiet:hover, .btn-secondary:hover { color: var(--text); border-color: rgba(63, 218, 196, .6); }
.btn-ghost {
  background: rgba(255, 255, 255, .045);
  border-color: var(--border);
  color: var(--muted);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
}
.btn-ghost:hover { color: var(--text); border-color: var(--accent); }
.btn-danger { border-color: rgba(255, 111, 143, .5); background: linear-gradient(180deg, #ff7d9b, #d94b6a); color: #2b0710; }
.btn-danger:hover { background: linear-gradient(180deg, #ff90aa, #e05a78); color: #2b0710; }
.btn-small { min-height: 32px; padding: 3px 12px; font-size: .84rem; }
.btn-inline { padding: 2px 10px; font-size: .8rem; }

/* ── Ô nhập: kính lõm, viền sáng khi focus ────────────────────────────── */
input, select {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  background:
    linear-gradient(180deg, rgba(4, 9, 18, .68), rgba(8, 15, 28, .44));
  color: var(--text);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, .5), inset 0 1px 0 rgba(255, 255, 255, .035);
  transition: border-color .18s, box-shadow .18s, background .18s;
}
input:hover, select:hover { border-color: var(--border-strong); }
input:focus, select:focus {
  border-color: rgba(63, 218, 196, .7);
  box-shadow:
    0 0 0 4px rgba(63, 218, 196, .14),
    0 0 26px rgba(63, 218, 196, .2),
    inset 0 1px 2px rgba(0, 0, 0, .45);
  outline: none;
}
input::placeholder { color: #6d7e9a; }
select {
  appearance: none;
  padding-right: 36px;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%239fb6d8' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"),
    linear-gradient(180deg, rgba(4, 9, 18, .68), rgba(8, 15, 28, .44));
  background-repeat: no-repeat, no-repeat;
  background-position: right 13px center, 0 0;
  background-size: 12px 8px, 100% 100%;
}
input[type="date"] { color-scheme: dark; }
input[type="number"] { font-variant-numeric: tabular-nums; }

/* ── Vỏ ứng dụng + topbar kính ───────────────────────────────────────── */
.app-shell { width: min(1480px, 100%); margin: 0 auto; padding: 0 16px 80px; }
.topbar {
  position: relative;
  display: flex;
  min-height: 60px;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 12px 0 2px;
  padding: 0 14px;
  border: 1px solid var(--border);
  border-radius: 20px;
  background:
    radial-gradient(120% 160% at 8% -40%, rgba(255, 255, 255, .14), transparent 55%),
    linear-gradient(160deg, rgba(22, 38, 64, .62), rgba(9, 16, 30, .55));
  box-shadow: var(--shadow-float), var(--highlight-line);
  backdrop-filter: blur(22px) saturate(160%);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
}
.account-summary { display: flex; min-width: 0; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
.account-email { max-width: 230px; overflow: hidden; color: var(--muted); text-overflow: ellipsis; white-space: nowrap; }
.tier-badge, .status-chip, .mode-chip {
  display: inline-flex;
  min-height: 26px;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 1px 10px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .08), rgba(255, 255, 255, .02));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .14);
  font-size: .74rem;
  font-weight: 750;
  white-space: nowrap;
}
.tier-badge {
  border-color: rgba(63, 218, 196, .55);
  background: linear-gradient(180deg, rgba(63, 218, 196, .24), rgba(63, 218, 196, .08));
  color: #a8fbee;
  text-transform: uppercase;
  letter-spacing: .06em;
  text-shadow: 0 0 14px rgba(63, 218, 196, .5);
}
.status-online, .mode-demo { color: var(--buy); border-color: color-mix(in srgb, var(--buy), transparent 45%); }
.status-offline, .mode-live { color: #ffbd6e; border-color: color-mix(in srgb, var(--warning), transparent 45%); }
.status-neutral, .mode-neutral { color: var(--muted); }
/* Chấm tín hiệu nhỏ trước chip trạng thái — "đèn" thuỷ tinh phát sáng. */
.status-online::before, .status-offline::before, .status-neutral::before {
  content: "";
  width: 7px;
  height: 7px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 10px currentColor;
}
.status-chip.support-link::before { display: none; }

/* ── Bố cục chính ────────────────────────────────────────────────────── */
.workspace { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; padding-top: 14px; }
.content { display: grid; min-width: 0; align-content: start; gap: 12px; }

/* Panel kính lớn: duy nhất tầng này được backdrop-filter (blur thật). Các
   thẻ con bên trong dùng gradient mờ + viền sáng để không stack blur. */
.panel {
  position: relative;
  min-width: 0;
  padding: clamp(14px, 1.6vw, 20px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--glass-fill);
  box-shadow: var(--shadow-glass), var(--highlight-line);
  backdrop-filter: blur(var(--glass-blur)) saturate(155%);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(155%);
}
/* Vệt sáng cong ở mép trên panel: cảm giác mặt kính dày, có cạnh vát. */
.panel::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  border-radius: inherit;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .45), transparent);
  pointer-events: none;
}
.panel h1, .panel h2, .panel h3 { margin: 0; line-height: 1.25; }
.panel h1, .panel h2 { font-family: var(--font-display); font-size: 1.14rem; letter-spacing: -.01em; color: #f6faff; }
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .panel > .panel-heading h2 {
    background: linear-gradient(180deg, #ffffff 12%, #dce8fa 58%, #a6bcda 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
  }
}
.auth-card h1, .modal-card h2 {
  background: none;
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .auth-card h1, .modal-card h2 {
    background: linear-gradient(180deg, #ffffff 12%, #dce8fa 58%, #a6bcda 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
  }
}
.panel h3 { font-size: .96rem; color: #dfeaff; }
.panel-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.panel-heading.compact { align-items: center; }
.status-list { display: grid; gap: 8px; margin: 10px 0; }
.status-list div { display: grid; gap: 2px; padding-bottom: 7px; border-bottom: 1px solid rgba(154, 182, 226, .14); }
.status-list dt { color: var(--muted); font-size: .8rem; }
.status-list dd { margin: 0; font-weight: 750; font-variant-numeric: tabular-nums; }

/* ── Panel tín hiệu ──────────────────────────────────────────────────── */
.signal-total {
  display: grid;
  min-width: 132px;
  grid-template-columns: 1fr 1fr;
  gap: 2px 10px;
  padding: 7px 12px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--glass-fill-soft);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12);
  color: var(--muted);
  font-size: .8rem;
  text-align: right;
}
.signal-total b { color: var(--text); font-size: .98rem; font-variant-numeric: tabular-nums; }
.signal-total .sig-buy, .signal-total .sig-buy b { color: var(--buy); text-shadow: 0 0 14px rgba(44, 227, 161, .5); }
.signal-total .sig-sell, .signal-total .sig-sell b { color: var(--sell); text-shadow: 0 0 14px rgba(255, 111, 143, .5); }
.signal-total small { grid-column: 1 / -1; }
/* Thanh "kéo co" Buy/Sell: tỉ lệ điểm đang hiện (cả hai = 0 ⇒ chia đôi, màu trung tính).
   app.js đọc CHÍNH hai con số vừa in ra nên thanh luôn khớp số, không tự tính lại từ
   payload (payload có lúc lệch vì nhánh "chưa đủ tín hiệu" đang nhấp nháy). */
.signal-total .sig-gauge {
  grid-column: 1 / -1;
  display: flex;
  gap: 2px;
  height: 4px;
  margin: 3px 0 1px;
  border-radius: 999px;
  overflow: hidden;
  background: rgba(4, 9, 18, .75);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, .7), inset 0 0 0 1px rgba(154, 182, 226, .16);
}
.signal-total .sig-gauge i { flex: 1 1 0; transition: flex-basis .55s cubic-bezier(.22, .8, .3, 1); }
.signal-total .sig-gauge .g-buy { background: linear-gradient(90deg, rgba(44, 227, 161, .22), var(--buy)); box-shadow: 0 0 12px rgba(44, 227, 161, .75); }
.signal-total .sig-gauge .g-sell { background: linear-gradient(270deg, rgba(255, 111, 143, .22), var(--sell)); box-shadow: 0 0 12px rgba(255, 111, 143, .7); }
.signal-action {
  margin-bottom: 10px;
  border: 1px solid rgba(63, 218, 196, .3);
  border-left: 3px solid var(--accent);
  border-radius: 10px;
  padding: 7px 12px;
  background: linear-gradient(90deg, rgba(63, 218, 196, .14), rgba(63, 218, 196, .04));
  color: #c9fbf2;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
  text-shadow: 0 0 16px rgba(63, 218, 196, .3);
}
.signal-action.buy { border-color: rgba(44, 227, 161, .35); border-left-color: var(--buy); background: linear-gradient(90deg, rgba(44, 227, 161, .14), rgba(44, 227, 161, .04)); }
.signal-action.sell { border-color: rgba(255, 111, 143, .35); border-left-color: var(--sell); background: linear-gradient(90deg, rgba(255, 111, 143, .13), rgba(255, 111, 143, .04)); }

/* Vành sáng CHẠY VÒNG quanh panel tín hiệu: một cung conic 1px quét dọc mép kính.
   Dùng `mask-composite: exclude` để chỉ còn lại đúng vành (nền bị cắt ruột), nên nó
   KHÔNG phủ lên nội dung. Góc xoay đi qua @property để conic-gradient nội suy được
   (xoay cả phần tử thì vành bo góc lệch khỏi panel — sai hoàn toàn).
   Trình duyệt không có @property/:has chỉ thấy một vành tĩnh — vẫn đúng, không vỡ. */
@property --rim-angle { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
.signal-panel { --rim-tint: rgba(63, 218, 196, .55); }
.signal-panel:has(.signal-action.sell) { --rim-tint: rgba(255, 111, 143, .5); }
/* ⚠ Toàn bộ hiệu ứng nằm TRONG @supports: thiếu mask-composite thì ::after sẽ là
   MỘT MẢNG CONIC ĐẶC phủ kín panel (không có mask thì `padding:1px` vô nghĩa) —
   thà không có hiệu ứng còn hơn phủ màu lên cả bảng tín hiệu. */
@supports ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
  .signal-panel::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    background: conic-gradient(from var(--rim-angle),
      transparent 0deg 44deg,
      var(--rim-tint) 74deg,
      transparent 118deg 246deg,
      rgba(168, 117, 255, .38) 282deg,
      transparent 322deg 360deg);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask-composite: exclude;
    opacity: .9;
    pointer-events: none;
    animation: rim-turn 9s linear infinite;
  }
  @keyframes rim-turn { to { --rim-angle: 360deg; } }
}
/* Mất tín hiệu / chợ nghỉ: mọi thứ trang trí phải ĐỨNG IM như đồ thị bên trong. */
.signal-panel:has(.signal-viz-frame.offline)::after { animation: none; opacity: .28; }

/* ── Thu nhỏ panel Market signals (31/10/2026) ───────────────────────────── */
/* Chủ dự án: *"user có thể đóng mở thu nhỏ Market signals cho đỡ lag giống như
   các tab khác, và khi thu nhỏ sắp xếp sao cho UI hiển thị hợp lý"*.
   Panel này KHÔNG phải `.tab-panel` nên không đi đường showPlaceholder/dock của
   Orders: thu nhỏ = GIỮ thanh tiêu đề (tên panel + điểm Buy/Sell + trạng thái
   kênh + nút ▸), ẩn phần đồ thị ⇒ các tab bên dưới trồi lên, bố cục liền mạch.
   Ẩn bằng CSS chỉ là phần NHÌN THẤY — vòng vẽ (ECharts 2 lần/giây + canvas 60 fps)
   được dừng thật trong signal-viz.js qua `OctoSignalViz.setPaused`. */
.signal-panel.is-min .signal-body { display: none; }
.signal-panel.is-min > .panel-heading { margin-bottom: 0; }
/* Vành conic quay quanh panel cũng là animation 9s vô hạn — thu gọn thì dừng. */
.signal-panel.is-min::after { animation: none; opacity: .3; }
.signal-head-group { min-width: 0; }

/* ── Tab / segmented / chip: pill kính ───────────────────────────────── */
.section-nav, .segmented { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: thin; }
.section-tab, .segmented button {
  min-height: 38px;
  flex: 0 0 auto;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px 14px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .08), rgba(255, 255, 255, .02));
  color: var(--muted);
  font-weight: 750;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12), 0 8px 18px -14px rgba(0, 0, 0, .9);
  transition: color .18s, border-color .18s, background .18s, box-shadow .18s, transform .15s;
}
.section-tab:hover, .segmented button:hover { color: var(--text); border-color: var(--border-strong); transform: translateY(-1px); }
.section-tab.active, .segmented button.active {
  border-color: rgba(63, 218, 196, .65);
  background: linear-gradient(180deg, rgba(63, 218, 196, .34), rgba(63, 218, 196, .12));
  color: #eafffb;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .4),
    inset 0 -1px 0 rgba(0, 0, 0, .25),
    0 0 22px rgba(63, 218, 196, .22);
}
.filters { display: flex; align-items: end; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.filters label { width: min(180px, 100%); }

/* ── Bảng ────────────────────────────────────────────────────────────── */
.table-wrap {
  width: 100%;
  overflow-x: auto;
  border: 1px solid rgba(154, 182, 226, .14);
  border-radius: 14px;
  background: rgba(4, 9, 18, .28);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .05);
}
.orders-table { width: 100%; min-width: 780px; border-collapse: collapse; }
.orders-table th, .orders-table td { padding: 8px 10px; border-bottom: 1px solid rgba(154, 182, 226, .12); text-align: left; white-space: nowrap; }
.orders-table tbody tr { transition: background .15s; }
.orders-table tbody tr:hover { background: rgba(63, 218, 196, .055); }
.orders-table tbody tr:last-child td { border-bottom: 0; }
.orders-table td { font-size: .92rem; font-variant-numeric: tabular-nums; }
.orders-table th {
  background: linear-gradient(180deg, rgba(255, 255, 255, .045), rgba(255, 255, 255, .015));
  color: #9db0cc;
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .07em;
  text-transform: uppercase;
}
.empty { color: var(--muted); text-align: center !important; font-style: italic; }
.buy, .positive { color: var(--buy); font-weight: 800; text-shadow: 0 0 16px rgba(44, 227, 161, .3); }
.sell, .negative { color: var(--sell); font-weight: 800; text-shadow: 0 0 16px rgba(255, 111, 143, .3); }
.st-open, .st-closed, .st-unconfirmed {
  display: inline-block;
  border: 1px solid transparent;
  border-radius: 999px;
  padding: 1px 10px;
  font-size: .78rem;
  font-weight: 750;
  line-height: 1.5;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18);
}
.st-open { color: #4bf0b4; border-color: rgba(44, 227, 161, .45); background: linear-gradient(180deg, rgba(44, 227, 161, .22), rgba(44, 227, 161, .08)); }
.st-closed { color: var(--muted); border-color: var(--border); background: linear-gradient(180deg, rgba(148, 163, 184, .18), rgba(148, 163, 184, .06)); }
/* Lệnh mà runner KHÔNG đọc nổi deal đóng: đã thôi là vị thế mở nhưng chưa có
   PnL. Màu cảnh báo để lộ ra ngay là "có gì đó chưa khớp", không im lặng như
   lệnh đã đóng bình thường. */
.st-unconfirmed {
  color: #f5c451;
  border-color: rgba(245, 196, 81, .45);
  background: linear-gradient(180deg, rgba(245, 196, 81, .22), rgba(245, 196, 81, .08));
  text-shadow: 0 0 14px rgba(245, 196, 81, .35);
}

/* ── Thẻ lệnh mobile + form + plan + callout ─────────────────────────── */
.order-cards { display: none; gap: 10px; }
.order-card {
  display: grid;
  gap: 6px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--glass-fill-soft);
  box-shadow: 0 18px 40px -28px rgba(0, 0, 0, .9), inset 0 1px 0 rgba(255, 255, 255, .12);
}
.order-card-head, .order-card-row { display: flex; justify-content: space-between; gap: 12px; }
.order-card-row { color: var(--muted); }
.order-card-row b { color: var(--text); text-align: right; font-variant-numeric: tabular-nums; }
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.upgrade-callout {
  margin: 12px 0;
  padding: 14px;
  border: 1px solid rgba(63, 218, 196, .3);
  border-radius: 16px;
  background:
    radial-gradient(120% 100% at 10% -30%, rgba(63, 218, 196, .18), transparent 60%),
    linear-gradient(160deg, rgba(63, 218, 196, .08), rgba(255, 255, 255, .02));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12), 0 18px 40px -32px rgba(0, 0, 0, .9);
}
.plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 12px; }
.plan {
  display: grid;
  gap: 8px;
  padding: 15px;
  border: 1px solid var(--border);
  border-radius: 18px;
  background: var(--glass-fill-soft);
  box-shadow: 0 18px 40px -28px rgba(0, 0, 0, .9), inset 0 1px 0 rgba(255, 255, 255, .12);
  transition: transform .2s, border-color .2s, box-shadow .2s;
}
.plan:hover {
  transform: translateY(-2px);
  border-color: rgba(63, 218, 196, .4);
  box-shadow: 0 26px 52px -28px rgba(0, 0, 0, .95), 0 0 32px -14px rgba(63, 218, 196, .4), inset 0 1px 0 rgba(255, 255, 255, .18);
}
.plan-price {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 850;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
  color: #f2fbff;
  text-shadow: 0 0 24px rgba(63, 218, 196, .3);
}
.plan ul { display: grid; gap: 7px; margin: 0; padding-left: 20px; color: var(--muted); }
.deposit-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 8px 0 2px; }
.deposit-row input { width: auto; min-width: 240px; flex: 1 1 260px; font-family: ui-monospace, Consolas, monospace; letter-spacing: .02em; }
.deposit-row .btn { flex: 0 0 auto; }
.deposit-qr {
  display: block;
  width: 172px;
  height: 172px;
  margin: 12px 0 2px;
  padding: 7px;
  border: 1px solid rgba(255, 255, 255, .35);
  border-radius: 16px;
  background: #fff;
  box-shadow: 0 14px 34px -16px rgba(0, 0, 0, .8), 0 0 0 6px rgba(255, 255, 255, .04);
}
.support-link { color: var(--accent); text-decoration: none; }
.support-link:hover { text-decoration: underline; }
.support-line { margin: 10px 0 0; color: var(--muted); font-size: .86rem; }

/* ── Ba đồ thị tín hiệu ──────────────────────────────────────────────── */
.signal-viz-shell { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.signal-viz-card {
  position: relative;
  min-width: 0;
  padding: 11px;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--glass-fill-soft);
  box-shadow: 0 20px 44px -30px rgba(0, 0, 0, .9), inset 0 1px 0 rgba(255, 255, 255, .13);
  overflow: hidden;
}
.signal-viz-card::after {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(63, 218, 196, .5), transparent);
  opacity: .8;
  pointer-events: none;
}
/* Vệt loá quét chéo qua mặt kính mỗi ~9s, ba thẻ LỆCH PHA nên chỉ một thẻ loá tại một
   thời điểm (ba thẻ cùng loá là đèn sân khấu, không phải kính). Trượt bằng transform
   để không đụng layout; `overflow: hidden` của thẻ đã cắt phần thừa. */
.signal-viz-card::before {
  content: "";
  position: absolute;
  top: -35%;
  bottom: -35%;
  left: -62%;
  width: 46%;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .07) 42%, rgba(214, 240, 255, .16) 50%, rgba(255, 255, 255, .07) 58%, transparent);
  transform: translateX(0) skewX(-16deg);
  opacity: 0;
  animation: card-sheen 9s cubic-bezier(.42, 0, .28, 1) infinite;
}
.signal-viz-card:nth-child(2)::before { animation-delay: 3s; }
.signal-viz-card:nth-child(3)::before { animation-delay: 6s; }
@keyframes card-sheen {
  0%, 60% { transform: translateX(0) skewX(-16deg); opacity: 0; }
  65% { opacity: 1; }
  92%, 100% { transform: translateX(345%) skewX(-16deg); opacity: 0; }
}
.signal-viz-card:has(.signal-viz-frame.offline)::before { animation: none; opacity: 0; }
.signal-viz-card h3 {
  margin: 0 0 7px;
  color: #9fb3d1;
  font-size: .72rem;
  letter-spacing: .13em;
  text-transform: uppercase;
}
.signal-viz-frame { position: relative; }
/* Radar: quầng sáng tròn của khung + CÁNH QUÉT quay tròn THẬT (28/10/2026).
   Bản cũ là một mảng conic phía SAU canvas và phủ gần kín khung (inset 6% 8%),
   lại bị hai lớp splitArea của ECharts (alpha .3–.35) trùm lên ⇒ chỉ còn một
   vệt xanh rất mờ, to hơn hẳn vòng radar nên nhìn như đứng yên. Bản mới:
   - đúng kích thước vòng radar của ECharts: bán kính 67% của cạnh ngắn
     (chiều cao chart 208px) ⇒ đường kính ~139px; hẹp hơn 208px thì 67% bề ngang;
   - nằm TRÊN canvas (z-index 2) để đọc ra chùm sáng đang quay, không phải màu nền;
   - tia dẫn sáng ở mép trước (::after của <i>) như kim máy quét;
   - animation gắn với :not(.offline) ⇒ mất tín hiệu/chợ nghỉ là đứng im tuyệt đối,
     không phải cuộc đua specificity với luật .offline nữa. */
.signal-viz-card:has(#signal-radar) .signal-viz-frame {
  border-radius: 14px;
  background: radial-gradient(circle at 50% 52%, rgba(63, 218, 196, .09), rgba(168, 117, 255, .05) 46%, transparent 66%);
}
.viz-sweep {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 2;
  width: min(67%, 139.4px);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  pointer-events: none;
  opacity: .95;
}
.viz-sweep i {
  position: absolute;
  inset: 0;
  display: block;
  border-radius: inherit;
  background: conic-gradient(from 0deg,
    rgba(63, 218, 196, 0) 0deg 268deg,
    rgba(63, 218, 196, .05) 296deg,
    rgba(63, 218, 196, .17) 332deg,
    rgba(111, 240, 220, .5) 352deg,
    rgba(214, 255, 249, .95) 359deg,
    rgba(63, 218, 196, 0) 360deg);
  /* Mờ dần vào tâm: chùm sáng không được tô đặc cả hình tròn. */
  -webkit-mask-image: radial-gradient(circle, rgba(0, 0, 0, 0) 7%, rgba(0, 0, 0, .5) 40%, #000 96%);
  mask-image: radial-gradient(circle, rgba(0, 0, 0, 0) 7%, rgba(0, 0, 0, .5) 40%, #000 96%);
  mix-blend-mode: screen;
}
/* Tia dẫn: từ tâm ra mép, trùng mép trước của cánh quạt (conic 359deg = hướng 12h). */
.viz-sweep i::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 0;
  width: 2px;
  height: 50%;
  margin-left: -1px;
  background: linear-gradient(180deg, rgba(230, 255, 251, 1), rgba(111, 240, 220, .5) 58%, rgba(63, 218, 196, 0));
  box-shadow: 0 0 12px rgba(120, 255, 230, .95), 0 0 26px rgba(63, 218, 196, .45);
}
.signal-viz-frame:not(.offline) .viz-sweep i { animation: sweep-turn 4.2s linear infinite; }
@keyframes sweep-turn { to { transform: rotate(1turn); } }
.signal-viz-frame.offline .viz-sweep { opacity: .22; }
.signal-chart { position: relative; z-index: 1; height: 208px; }
.viz-scanline {
  position: absolute;
  right: 0;
  left: 0;
  top: 50%;
  z-index: 2;
  height: 46px;
  margin-top: -23px;
  pointer-events: none;
  /* Dải sáng mềm, lõi sáng ở GIỮA: vệt quét đọc ra như chùm sáng, không phải kẻ chỉ.
     Màu XANH DƯƠNG (28/10/2026 — chủ dự án yêu cầu): tách hẳn khỏi sắc teal của
     radar/mesh để ba thẻ không cùng một màu. */
  background: linear-gradient(180deg,
    rgba(87, 201, 255, 0),
    rgba(87, 201, 255, .05) 40%,
    rgba(87, 201, 255, .18) 48.5%,
    rgba(87, 201, 255, .92) 50%,
    rgba(87, 201, 255, .18) 51.5%,
    rgba(87, 201, 255, .05) 60%,
    rgba(87, 201, 255, 0));
  filter: drop-shadow(0 0 15px rgba(87, 201, 255, .5));
  animation: viz-scan 7.2s ease-in-out infinite;
}
/* Biên độ ±76px (không phải ±104px = nửa khung): dải sáng cao 46px, đi hết
   104px là nửa dải bị cắt ở mép khung và trông như một thanh đặc dán đáy.
   7,2s/vòng (3,6s mỗi chiều) và gần như KHÔNG tắt: bản 3,4s tắt hẳn ở hai đầu
   nên người xem thấy "chạy một nhịp rồi biến mất" — chủ dự án muốn quét
   lên xuống chậm VÀ liên tục. */
@keyframes viz-scan {
  0%, 100% { transform: translateY(-76px); opacity: .5; }
  50% { transform: translateY(76px); opacity: 1; }
}
.channel-legend { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 6px; margin-top: 8px; }
.channel-chip {
  display: flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
  padding: 5px 8px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--glass-fill-soft);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
}
.channel-chip i { width: 9px; height: 9px; flex: 0 0 auto; border-radius: 50%; background: var(--accent); box-shadow: 0 0 10px rgba(63, 218, 196, .8); }
.channel-chip.telemetry i { background: #b07bff; box-shadow: 0 0 10px rgba(176, 123, 255, .8); }
.channel-chip span { min-width: 0; overflow: hidden; color: var(--muted); font-size: .78rem; text-overflow: ellipsis; white-space: nowrap; }
.channel-chip b { margin-left: auto; font-size: .82rem; font-weight: 800; font-variant-numeric: tabular-nums; }
/* "Mức nạp" của từng chân: một vạch sáng dưới chân chip dài đúng % của chân đó.
   `--fill`/`--fill-color` do signal-viz.js.paintLegend đặt (cùng hàm `valueColor` với
   con số ⇒ vạch và số không bao giờ lệch màu). */
.channel-chip { position: relative; overflow: hidden; transition: border-color .18s, background .18s, box-shadow .18s, transform .18s; }
.channel-chip:hover {
  transform: translateY(-1px);
  border-color: rgba(63, 218, 196, .45);
  background: var(--glass-fill);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18), 0 10px 22px -14px rgba(0, 0, 0, .9), 0 0 20px -8px rgba(63, 218, 196, .8);
}
.channel-chip::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: var(--fill, 0%);
  height: 2px;
  pointer-events: none;
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, var(--fill-color, var(--accent)));
  box-shadow: 0 0 10px var(--fill-color, var(--accent));
  transition: width .5s cubic-bezier(.22, .8, .3, 1);
}
.mobile-nav { display: none; }

/* ── Nút thu nhỏ panel ───────────────────────────────────────────────── */
/* Nút ▸ của từng panel. Từ 23/10/2026 KHÔNG còn panel sidebar nào thu gọn
   (ACCOUNT/SAFETY đã bỏ) nên chỉ còn .dock-toggle — đừng dựng lại .panel-toggle. */
.dock-toggle {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .09), rgba(255, 255, 255, .02));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .16), 0 8px 18px -14px rgba(0, 0, 0, .9);
  color: var(--muted);
  line-height: 1;
}
.dock-toggle span { display: block; font-size: .95rem; transition: transform .18s ease, color .18s; }
.dock-toggle:hover { border-color: rgba(63, 218, 196, .6); color: var(--text); }
.dock-toggle:hover span { transform: translateX(2px); color: var(--accent); }

/* ── Hiệu năng ───────────────────────────────────────────────────────── */
.perf-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 9px; }
.perf-tile {
  display: grid;
  gap: 2px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--glass-fill-soft);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12), 0 12px 26px -22px rgba(0, 0, 0, .9);
}
.perf-label { color: #93a7c4; font-size: .7rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; }
.perf-tile b { overflow: hidden; font-size: 1.12rem; font-weight: 850; font-variant-numeric: tabular-nums; text-overflow: ellipsis; white-space: nowrap; }
.perf-tile small { color: var(--muted); font-size: .78rem; }
.filter-row { display: flex; align-items: end; justify-content: space-between; gap: 8px 12px; flex-wrap: wrap; margin-bottom: 4px; }
.filter-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.chip {
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px 13px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .075), rgba(255, 255, 255, .02));
  color: var(--muted);
  font-weight: 750;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12), 0 8px 16px -14px rgba(0, 0, 0, .9);
  transition: color .18s, border-color .18s, background .18s, box-shadow .18s;
}
.chip:hover { border-color: var(--border-strong); color: var(--text); }
.chip.active {
  border-color: rgba(63, 218, 196, .65);
  background: linear-gradient(180deg, rgba(63, 218, 196, .32), rgba(63, 218, 196, .1));
  color: #eafffb;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .38), 0 0 20px rgba(63, 218, 196, .22);
}
.filter-row .filters { margin-bottom: 0; }
.stats-line {
  min-height: 24px;
  margin: 8px 0 10px;
  border: 1px solid rgba(63, 218, 196, .16);
  border-left: 3px solid var(--accent);
  border-radius: 9px;
  padding: 6px 11px;
  background: linear-gradient(90deg, rgba(63, 218, 196, .1), rgba(63, 218, 196, .02));
  font-size: .86rem;
  font-variant-numeric: tabular-nums;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07);
}
.pager { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.pager .btn { min-height: 32px; padding: 4px 10px; }
.pager label { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); font-size: .9rem; }
.pager select { width: auto; min-width: 88px; }
.hint { margin: 0 0 10px; font-size: .82rem; }
.perf-head { gap: 10px; }
.perf-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.perf-actions .btn { min-height: 32px; padding: 3px 11px; }
.perf-clock {
  min-width: 86px;
  padding: 5px 10px;
  border: 1px solid rgba(63, 218, 196, .28);
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(63, 218, 196, .16), rgba(63, 218, 196, .05));
  color: #bafff3;
  font-family: ui-monospace, Consolas, monospace;
  font-size: .86rem;
  font-variant-numeric: tabular-nums;
  text-align: center;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .16), 0 0 20px -8px rgba(63, 218, 196, .5);
  text-shadow: 0 0 14px rgba(63, 218, 196, .5);
}
.perf-clock.idle { color: var(--muted); border-color: var(--border); background: rgba(255, 255, 255, .03); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08); text-shadow: none; }
.head-group { display: inline-flex; flex: 0 0 auto; align-items: center; gap: 8px; }
.head-group > .btn { white-space: nowrap; }
.open-total {
  display: inline-flex;
  align-items: center;
  min-height: 30px;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 11px;
  background: var(--glass-fill-soft);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12);
  font-size: .8rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.open-total.positive { color: #4bf0b4; border-color: color-mix(in srgb, var(--buy), transparent 45%); text-shadow: 0 0 14px rgba(44, 227, 161, .4); }
.open-total.negative { color: #ff8a94; border-color: color-mix(in srgb, var(--sell), transparent 45%); text-shadow: 0 0 14px rgba(255, 111, 143, .4); }

/* ── Dock phải (Orders thu nhỏ) ──────────────────────────────────────── */
.workspace.with-dock { grid-template-columns: minmax(0, 1fr) 300px; }
.side-dock { display: flex; min-width: 0; flex-direction: column; gap: 8px; align-self: start; position: sticky; top: 14px; }
.dock-mini {
  width: 100%;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--glass-fill);
  box-shadow: var(--shadow-float), var(--highlight-line);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
}
.dock-mini-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 10px;
  border-bottom: 1px solid rgba(154, 182, 226, .14);
  background: linear-gradient(180deg, rgba(255, 255, 255, .06), rgba(255, 255, 255, .015));
}
.dock-mini-head b { font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; }
.dock-mini-head .btn { min-height: 28px; padding: 2px 10px; border-radius: 999px; font-size: .76rem; }
.dock-mini-head .dock-mini-total {
  display: inline-flex;
  align-items: center;
  min-height: 20px;
  padding: 0 9px;
  margin-left: auto;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: rgba(4, 9, 18, .4);
  font-size: .7rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.dock-mini-total[hidden] { display: none; }
.dock-mini-head .dock-mini-total.positive { color: #4bf0b4; border-color: color-mix(in srgb, var(--buy), transparent 45%); }
.dock-mini-head .dock-mini-total.negative { color: #ff8a94; border-color: color-mix(in srgb, var(--sell), transparent 45%); }
.dock-mini-list { display: grid; max-height: 24vh; overflow-y: auto; margin: 0; padding: 0; list-style: none; }
.dock-mini-list .dock-empty { padding: 8px 10px; color: var(--muted); font-size: .78rem; }
.dock-mini-group { min-width: 0; }
.dock-mini-group + .dock-mini-group { border-top: 1px solid rgba(154, 182, 226, .14); }
.dock-mini-title { display: block; padding: 7px 10px 1px; font-size: .62rem; font-weight: 800; letter-spacing: .11em; text-transform: uppercase; color: #93a7c4; }
/* `flex` chứ KHÔNG `grid`: thẻ bot chỉ có khi lệnh do bot đánh (lệnh cũ để trống) — lưới cố định số cột sẽ dồn cột tiền sang trái ở đúng những dòng thiếu thẻ. */
.dock-row { display: flex; align-items: center; gap: 4px 6px; padding: 6px 10px; border-bottom: 1px solid rgba(154, 182, 226, .1); font-size: .78rem; }
.dock-row:last-child { border-bottom: 0; }
.dock-row .dir { font-weight: 850; }
.dock-row .meta { flex: 1 1 auto; min-width: 0; overflow: hidden; color: var(--muted); text-overflow: ellipsis; white-space: nowrap; }
.dock-row .val { margin-left: auto; text-align: right; font-variant-numeric: tabular-nums; }
/* Ô "Open orders" (lệnh đang mở, PnL nổi) nổi bật hơn "Closed orders": nền tint
   accent + viền khung + nội dung sáng — phân biệt rõ lệnh mở với lệnh đã đóng. */
.dock-mini-group[data-dock-group="open"] {
  background: linear-gradient(180deg, rgba(63, 218, 196, .18), rgba(63, 218, 196, .05));
  box-shadow: inset 0 0 0 1px rgba(63, 218, 196, .36), inset 0 1px 0 rgba(255, 255, 255, .16);
}
.dock-mini-group[data-dock-group="open"] + .dock-mini-group { border-top-color: rgba(63, 218, 196, .4); }
.dock-mini-group[data-dock-group="open"] .dock-mini-title { color: #bafff3; }
.dock-mini-group[data-dock-group="open"] .dock-row { border-left: 2px solid rgba(63, 218, 196, .55); }
.dock-mini-group[data-dock-group="open"] .dock-row .meta { color: #cbd6e8; }
.dock-mini-group[data-dock-group="open"] .dock-row .val:not(.positive):not(.negative) { color: #7de3c6; font-weight: 800; }
/* Khối LỊCH ở đáy dock (chỉ có khi Orders thu nhỏ): ĐÚNG bảng lịch của tab Orders
   thu nhỏ lại — hai kiểu xem By day / By month, ô dùng chung .calendar-day nên màu
   thắng/thua và cách vẽ khớp lịch ở tab Orders. */
.dock-cal { flex: 0 0 auto; border-top: 1px solid rgba(154, 182, 226, .14); }
.dock-cal-head { display: flex; align-items: center; justify-content: space-between; gap: 6px; padding: 5px 10px 2px; }
.dock-cal-head .dock-mini-title { padding: 0; }
.dock-cal-head .segmented button { min-height: 22px; padding: 1px 8px; font-size: .66rem; border-radius: 999px; }
.dock-cal-nav { display: flex; align-items: center; gap: 4px; padding: 2px 10px 4px; }
.dock-cal-nav .btn { min-height: 24px; padding: 0 7px; border-radius: 999px; font-size: .78rem; line-height: 1; }
.dock-cal-nav b { flex: 1 1 auto; min-width: 0; color: var(--text); font-size: .74rem; font-variant-numeric: tabular-nums; text-align: center; }
/* Chế độ THÁNG: 3 cột cho vừa cột phải 300px (lịch ở tab Orders rộng hơn nên để 4). */
.dock-cal .calendar-grid.by-month { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* Khe 2px + lề 8px (lịch tab Orders để 3px/10px) để ô ngày rộng thêm ~2px — đủ cho số
   tiền không bị cắt trong cột phải 300px. Hàng thứ PHẢI dùng cùng khe/lề, lệch là cột
   không thẳng. */
.dock-cal .calendar-dow, .dock-cal .calendar-grid { gap: 2px; padding: 0 8px; }
.dock-cal .calendar-dow { margin-bottom: 3px; }
.dock-cal .calendar-dow span { font-size: .52rem; }
.dock-cal .calendar-grid { padding-bottom: 8px; }
/* Ô NGÀY chỉ rộng ~39px (7 cột trong cột phải 300px) ⇒ số tiền ở dock bỏ dấu $ (xem
   `dockMoney` trong app.js) và hạ cỡ chữ: đo được "−277.50" (7 ký tự) ≈ 33px ở .52rem,
   vừa trong 35px — để .58rem là số ÂM (dài hơn "+22.00" một ký tự) bị cắt mất phần lẻ. */
.dock-cal .calendar-day { min-height: 30px; padding: 1px 1px 3px; }
.dock-cal .calendar-day b { font-size: .62rem; }
.dock-cal .calendar-day span { font-size: .52rem; }
/* Nấc hạ cỡ chữ cho số dài — phải khai Ở ĐÂY nữa: `.dock-cal .calendar-day span` (0,3,1)
   mạnh hơn `.calendar-day span.long` (0,2,1), thiếu dòng này là dock không hạ gì cả. */
.dock-cal .calendar-day span.long { font-size: .46rem; }
.dock-cal .calendar-day small { font-size: .5rem; }
.dock-cal .calendar-dow[hidden] { display: none; }
/* The dock is hidden via the hidden attribute when nothing is minimized;
   author display:flex would override the UA [hidden] rule, so guard it. */
.side-dock[hidden] { display: none; }
/* Orders thu nhỏ → card bó CAO THEO NỘI DUNG, không giãn hết cột khi ít lệnh:
   nhóm Open cao đúng số lệnh đang mở (nhiều lệnh tới mức chạm trần → tự cuộn
   nội bộ, KHÔNG đẩy mất nhóm Closed); Closed bó gọn 6 lệnh đóng gần nhất (JS đã
   slice(0, 6) — scroll chỉ để phòng màn hình quá thấp); khối lịch nằm DƯỚI CÙNG
   và không co (flex 0 0 auto) nên hai danh sách lệnh nhường chỗ cho nó, không
   ngược lại. */
@media (min-width: 1101px) {
  .side-dock.has-orders { height: calc(100vh - 28px); }
  .side-dock.has-orders .dock-mini[data-dock-name="orders"] { display: flex; flex: 0 1 auto; min-height: 0; max-height: 100%; flex-direction: column; }
  .side-dock.has-orders .dock-mini[data-dock-name="orders"] .dock-mini-group { display: flex; min-height: 0; flex-direction: column; }
  .side-dock.has-orders .dock-mini[data-dock-name="orders"] .dock-mini-group[data-dock-group="open"] { flex: 0 1 auto; }
  .side-dock.has-orders .dock-mini[data-dock-name="orders"] .dock-mini-group[data-dock-group="closed"] { flex: 0 0 auto; }
  .side-dock.has-orders .dock-mini[data-dock-name="orders"] .dock-mini-list { flex: 1 1 auto; min-height: 0; max-height: none; }
  .side-dock.has-orders .dock-mini[data-dock-name="orders"] [data-dock-group="closed"] .dock-mini-list { flex: 0 0 auto; max-height: 168px; }
}

/* ── Đăng ký / xác nhận email / lưu đăng nhập ───────────────────────── */
/* `label.check-row` (không phải `.check-row`) là CỐ Ý: `.stack label` ở trên
   có độ ưu tiên 0-1-1 nên `.check-row` trần (0-1-0) thua và ô tick bị đẩy
   xuống một hàng riêng. Giữ tiền tố `label` để luật này thắng. */
label.check-row { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: .9rem; }
.check-row input { width: 19px; height: 19px; min-height: 0; flex: 0 0 auto; }
/* Câu hỏi captcha + đáp án phải nằm CÙNG một dòng, ô nhập xuống dòng dưới.
   Không có luật này thì `.stack label` (grid) tách mỗi nút con thành một hàng:
   "Confirm you are not a robot:" / "12 + 7" / ô nhập — đọc rời rạc. */
label.captcha-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 8px;
  color: var(--muted);
  font-size: .9rem;
}
label.captcha-row input { flex: 1 1 100%; }
.captcha-row b { color: var(--text); font-size: 1rem; letter-spacing: .06em; font-variant-numeric: tabular-nums; }
.verify-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 12px;
  padding: 11px 15px;
  border: 1px solid color-mix(in srgb, var(--warning), transparent 40%);
  border-left: 4px solid var(--warning);
  border-radius: 14px;
  background:
    linear-gradient(90deg, rgba(255, 196, 92, .16), rgba(255, 196, 92, .05));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .14), 0 16px 38px -30px rgba(0, 0, 0, .9);
  color: #ffe1b0;
  font-size: .9rem;
}
.verify-banner b { color: #fff; }
.verify-banner a { color: var(--focus); }
/* Mất tín hiệu: băng đỏ + đồ thị xám & đứng im (không còn tia quét chạy). */
.signal-lost {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 4px 0 0;
  padding: 7px 13px;
  border: 1px solid color-mix(in srgb, var(--sell), transparent 40%);
  border-left: 4px solid var(--sell);
  border-radius: 12px;
  background: linear-gradient(90deg, rgba(255, 111, 143, .18), rgba(255, 111, 143, .05));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .14), 0 0 28px -10px rgba(255, 111, 143, .6);
  color: #ffd7db;
  font-size: .86rem;
}
.signal-lost b { color: #fff; letter-spacing: .1em; }
/* Băng "xem trễ" — KHÁC hẳn băng mất tín hiệu (đỏ). Trễ là trạng thái bình
   thường của tài khoản chưa có gói, không phải sự cố; để chung màu đỏ sẽ khiến
   user tưởng hệ thống hỏng. */
.signal-delay {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 4px 0 0;
  padding: 7px 13px;
  border: 1px solid color-mix(in srgb, var(--warning), transparent 40%);
  border-left: 4px solid var(--warning);
  border-radius: 12px;
  background: linear-gradient(90deg, rgba(240, 180, 41, .16), rgba(240, 180, 41, .05));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12);
  color: #ffe9bf;
  font-size: .86rem;
}
.signal-delay b { color: #fff; letter-spacing: .1em; }
.signal-viz-frame.offline { filter: grayscale(.55) brightness(.85); }
.signal-viz-frame.offline .viz-scanline { animation: none; }

/* ── Lịch thắng/thua (tab Orders) ─────────────────────────────────────
   Nền xanh = ngày LÃI, nền đỏ = ngày LỖ (số tiền + số lệnh W/L ngay trong ô).
   Ô không có lệnh đóng để trống mờ — nhìn một cái là biết ngày nào bot chạy.
   Lịch là bảng PHỤ trong tab Orders: giữ nó gọn (~1/4 diện tích) để không
   chiếm chỗ của bảng lệnh — đây là bảng tra cứu nhanh. */
.calendar-panel {
  max-width: 500px;
  margin: 8px 0 10px;
  padding: 9px 11px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--glass-fill-soft);
  box-shadow: 0 18px 40px -30px rgba(0, 0, 0, .9), inset 0 1px 0 rgba(255, 255, 255, .12);
}
.calendar-head { display: flex; align-items: center; justify-content: space-between; gap: 6px 10px; flex-wrap: wrap; margin-bottom: 6px; }
.calendar-head .segmented button { min-height: 26px; padding: 2px 10px; font-size: .76rem; }
.calendar-nav { display: flex; align-items: center; gap: 4px; }
.calendar-nav .btn { min-height: 26px; padding: 2px 9px; font-size: .8rem; }
.calendar-nav b { min-width: 92px; color: var(--text); font-size: .84rem; text-align: center; font-variant-numeric: tabular-nums; }
.calendar-dow { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; margin-bottom: 3px; }
.calendar-dow span { color: #8ea2bf; font-size: .6rem; font-weight: 800; letter-spacing: .06em; text-align: center; text-transform: uppercase; }
.calendar-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.calendar-grid.by-month { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* Ô ngày rất hẹp (~60px) nên số $ phải tự cắt đuôi: để tràn ra là vỡ cả lưới. */
.calendar-day {
  display: flex;
  min-height: 34px;
  min-width: 0;
  flex-direction: column;
  gap: 0;
  justify-content: flex-start;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 9px;
  padding: 2px 4px;
  background: rgba(255, 255, 255, .035);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06);
  text-align: left;
  font-variant-numeric: tabular-nums;
  transition: border-color .15s, transform .15s, box-shadow .15s;
}
.calendar-day b { color: var(--muted); font-size: .62rem; font-weight: 800; line-height: 1.15; }
.calendar-day span { overflow: hidden; color: var(--text); font-size: .7rem; font-weight: 850; line-height: 1.15; text-overflow: ellipsis; white-space: nowrap; }
/* Số tiền từ 8 ký tự (lỗ 4 chữ số) hạ thêm một nấc cho khỏi cắt mất dấu trừ — xem
   `calendarMoneyText` trong app.js (số ≥ 1000 chỉ in 1 số lẻ TRƯỚC, đây là nấc thứ hai). */
.calendar-day span.long { font-size: .62rem; }
.calendar-day small { overflow: hidden; color: var(--muted); font-size: .56rem; line-height: 1.1; text-overflow: ellipsis; white-space: nowrap; }
.calendar-day.win {
  border-color: color-mix(in srgb, var(--buy), transparent 40%);
  background: linear-gradient(180deg, rgba(44, 227, 161, .24), rgba(44, 227, 161, .08));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .16), 0 0 18px -8px rgba(44, 227, 161, .55);
}
.calendar-day.win b, .calendar-day.win span { color: #9df0cf; }
.calendar-day.loss {
  border-color: color-mix(in srgb, var(--sell), transparent 40%);
  background: linear-gradient(180deg, rgba(255, 111, 143, .22), rgba(255, 111, 143, .07));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .14), 0 0 18px -8px rgba(255, 111, 143, .5);
}
.calendar-day.loss b, .calendar-day.loss span { color: #ffb3ba; }
.calendar-day.breakeven { border-color: color-mix(in srgb, var(--muted), transparent 55%); background: color-mix(in srgb, var(--muted), transparent 90%); }
.calendar-day.empty, .calendar-day.blank { border-color: transparent; background: transparent; box-shadow: none; }
.calendar-day.empty b { color: color-mix(in srgb, var(--muted), transparent 45%); }
.calendar-day.blank { min-height: 0; padding: 0; }
button.calendar-day { cursor: pointer; font: inherit; }
button.calendar-day:hover { border-color: var(--accent); transform: translateY(-1px); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18), 0 0 20px -8px rgba(63, 218, 196, .6); }
.calendar-grid.by-month .calendar-day { min-height: 32px; }
.calendar-foot { display: flex; align-items: center; justify-content: space-between; gap: 4px 10px; flex-wrap: wrap; margin-top: 6px; }
.calendar-summary { color: var(--text); font-size: .76rem; font-weight: 750; font-variant-numeric: tabular-nums; }
.calendar-hint { margin: 0; font-size: .68rem; }

/* ── Tab Upgrade: nhập mã thưởng + lịch sử nạp/thưởng ─────────────── */
/* Ô nhập mã phải co giãn theo bề ngang còn lại (mã dài 8-24 ký tự), nút đứng
   yên bên cạnh — để `width: 100%` mặc định của `input` là nút bị đẩy xuống dòng. */
.reward-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 8px 0 2px; }
.reward-row input { width: auto; min-width: 200px; flex: 1 1 220px; letter-spacing: .12em; text-transform: uppercase; font-weight: 750; }
.reward-row .btn { flex: 0 0 auto; }
#billing-history .orders-table { min-width: 620px; }
#billing-history .stats-line { margin-bottom: 0; }

/* ── Ví điểm + tab Referrals (hoa hồng) ────────────────────────────── */
.points-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 9px; margin: 10px 0 2px; }
.points-tile {
  display: grid;
  gap: 2px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--glass-fill-soft);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12);
}
.points-tile b { font-size: 1.08rem; font-weight: 850; font-variant-numeric: tabular-nums; text-shadow: 0 0 20px rgba(63, 218, 196, .25); }
.points-tile span { font-size: .7rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: #93a7c4; }
.affiliate-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 11px; margin-top: 10px; }
.affiliate-card {
  display: grid;
  align-content: start;
  gap: 8px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: 18px;
  background: var(--glass-fill-soft);
  box-shadow: 0 20px 44px -30px rgba(0, 0, 0, .9), inset 0 1px 0 rgba(255, 255, 255, .12);
}
.affiliate-card .status-list { margin: 0; }
/* Mã mời đọc qua chat/điện thoại nên phải to, giãn chữ và không xuống dòng. */
.aff-code-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin: 0; }
.aff-code-row b {
  color: #bafff3;
  font-family: ui-monospace, Consolas, monospace;
  font-size: 1.55rem;
  letter-spacing: .2em;
  text-shadow: 0 0 22px rgba(63, 218, 196, .45);
}
.aff-link-label { display: grid; gap: 6px; color: var(--muted); font-size: .9rem; }
.aff-link-label input { font-family: ui-monospace, Consolas, monospace; font-size: .82rem; }
.rank-line { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 1.05rem; }
.rank-icon { font-size: 1.55rem; line-height: 1; filter: drop-shadow(0 0 12px rgba(255, 196, 92, .4)); }
.rank-pct { margin-left: auto; border: 1px solid rgba(63, 218, 196, .35); border-radius: 999px; padding: 1px 10px; background: rgba(63, 218, 196, .1); color: #bafff3; font-size: .78rem; font-weight: 800; }
.rank-bar {
  height: 10px;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: rgba(4, 9, 18, .55);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, .5);
}
.rank-fill {
  display: block;
  width: 0;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #2fd0b9, #7cf3e2 55%, #a8fff2);
  box-shadow: 0 0 16px rgba(63, 218, 196, .7);
  transition: width .3s ease;
}
.rank-list { display: grid; gap: 4px; }
.rank-row { display: flex; align-items: center; gap: 8px; padding: 5px 9px; border: 1px solid transparent; border-radius: 10px; color: var(--muted); font-size: .82rem; }
.rank-row.current { border-color: var(--border); background: var(--glass-fill-soft); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); color: var(--text); font-weight: 750; }
.rank-row b { margin-left: auto; font-variant-numeric: tabular-nums; }
#aff-commission-body .empty, #aff-withdrawals-body .empty { text-align: center; }

/* ── Thông báo + phiên đăng nhập (trước đây chưa có style) ──────────── */
.panel-heading .btn { min-height: 34px; }
.notification-item {
  display: grid;
  gap: 4px;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--glass-fill-soft);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
  font-size: .9rem;
}
.notification-item strong { color: #e8f1ff; }
.notification-item p { margin: 2px 0 4px; color: var(--muted); font-size: .88rem; }
.notification-item small { color: #8ea2bf; font-size: .76rem; }
.notification-item.warning { border-color: rgba(255, 196, 92, .4); }
.notification-item.critical, .notification-item.error { border-color: rgba(255, 111, 143, .45); }
.notification-item .btn { justify-self: start; min-height: 30px; padding: 3px 12px; font-size: .78rem; }

/* ── Bots của user (23/10/2026) ───────────────────────────────────────
   Thẻ bot ở tab Bots + thẻ bot trong bảng Orders (cả bảng đầy đủ, thẻ mobile
   và dock thu nhỏ) + hộp điều khoản một lần. */
/* `auto-fit` (không phải `auto-fill`): 3 bot thì ba thẻ GIÃN đầy bề ngang, không
   để lại một cột trống bên phải — cột trống làm nút Delete rớt xuống hàng hai. */
.bot-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 11px; margin-top: 10px; }
.bot-card {
  display: grid;
  gap: 8px;
  align-content: start;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: 18px;
  background: var(--glass-fill-soft);
  box-shadow: 0 20px 44px -30px rgba(0, 0, 0, .9), inset 0 1px 0 rgba(255, 255, 255, .13);
  transition: border-color .2s, transform .2s, box-shadow .2s;
}
.bot-card:hover { transform: translateY(-2px); border-color: var(--border-strong); box-shadow: 0 28px 54px -30px rgba(0, 0, 0, .95), 0 0 30px -14px rgba(63, 218, 196, .35), inset 0 1px 0 rgba(255, 255, 255, .18); }
.bot-card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.bot-card-left { display: flex; align-items: center; gap: 8px; min-width: 0; }
.bot-tag {
  display: inline-block;
  padding: 2px 8px;
  border: 1px solid rgba(63, 218, 196, .45);
  border-radius: 8px;
  background: rgba(63, 218, 196, .13);
  color: #bafff3;
  font-family: ui-monospace, Consolas, monospace;
  font-size: .74rem;
  font-weight: 800;
  letter-spacing: .1em;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18), 0 0 14px -6px rgba(63, 218, 196, .6);
}
/* 6 MÀU CỦA BOT (24/10/2026) — tối đa 6 bot đã lưu nên mỗi bot một màu, user
   chọn ở tab Configuration. Màu chỉ đổi CÁCH HIỂN THỊ ô 3 ký tự (bảng Orders
   đầy đủ, thẻ mobile, dock, thẻ bot); giá trị thật nằm ở `bots.color` và hợp
   đồng `octo_server/contracts/bot_colors.py` — đừng thêm màu thứ 7 ở đây mà
   không thêm ở đó (server sẽ trả 422 khi lưu). */
.bot-tag.c-teal { border-color: rgba(63, 218, 196, .55); background: rgba(63, 218, 196, .16); color: #9df5e6; }
.bot-tag.c-blue { border-color: rgba(96, 165, 250, .55); background: rgba(96, 165, 250, .16); color: #a9d3ff; }
.bot-tag.c-violet { border-color: rgba(176, 123, 255, .55); background: rgba(176, 123, 255, .16); color: #d3c5ff; }
.bot-tag.c-amber { border-color: rgba(245, 196, 81, .55); background: rgba(245, 196, 81, .16); color: #ffd98a; }
.bot-tag.c-rose { border-color: rgba(251, 113, 133, .55); background: rgba(251, 113, 133, .16); color: #ffb3bd; }
.bot-tag.c-lime { border-color: rgba(163, 230, 53, .55); background: rgba(163, 230, 53, .16); color: #d3f58a; }
.bot-status { padding: 2px 8px; border-radius: 999px; font-size: .7rem; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; white-space: nowrap; box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25); }
.bot-status.st-running { color: #062a1f; background: linear-gradient(180deg, #8bf7c8, #46d99a); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .55), 0 0 16px -4px rgba(70, 217, 154, .7); }
.bot-status.st-stopped { color: var(--muted); background: rgba(148, 163, 184, .18); }
.bot-status.st-blocked { color: #3b0f0f; background: linear-gradient(180deg, #ffd97e, #f5c451); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), 0 0 16px -6px rgba(245, 196, 81, .8); }
.bot-status.st-offline { color: #3b0f0f; background: linear-gradient(180deg, #ffb0b6, #f28b82); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .45); }
.bot-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 0; color: var(--muted); font-size: .78rem; }
.bot-meta b { color: var(--text); font-variant-numeric: tabular-nums; }
.bot-blocked {
  margin: 0;
  padding: 7px 9px;
  border: 1px solid rgba(245, 196, 81, .4);
  border-radius: 10px;
  background: linear-gradient(90deg, rgba(245, 196, 81, .14), rgba(245, 196, 81, .04));
  color: #f5c451;
  font-size: .78rem;
}
.bot-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.bot-editor {
  display: grid;
  gap: 8px;
  margin-bottom: 12px;
  padding: 13px;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--glass-fill-soft);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12);
}
.bot-editor .row { display: flex; flex-wrap: wrap; align-items: end; gap: 8px; }
.bot-editor label { display: grid; gap: 4px; color: var(--muted); font-size: .78rem; }
.bot-editor input, .bot-editor select { min-width: 130px; }
#config-name { text-transform: uppercase; letter-spacing: .2em; font-family: ui-monospace, Consolas, monospace; font-weight: 800; }
/* Ô chọn màu của bot (24/10/2026): swatch là <button> THẬT để bàn phím chọn
   được; màu nền khai trùng `.bot-tag.c-*` để ô chọn và nhãn trong Orders nhìn
   ra cùng một màu. Viền `selected` dùng màu trắng (không dùng màu của swatch)
   — swatch vàng trên nền tối mà viền vàng thì mất hút. */
.color-field { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.color-field > span { color: var(--muted); font-size: .78rem; }
.color-swatches { display: flex; flex-wrap: wrap; gap: 6px; }
/* `min-height` phải khai lại: luật chung `button { min-height: 44px }` (và
   34px ở màn rộng) mạnh hơn `height` nên không có dòng này swatch thành hình
   bầu dục cao 44px. */
.color-swatch { width: 26px; height: 26px; min-height: 26px; padding: 0; border: 2px solid transparent; border-radius: 50%; cursor: pointer; box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), inset 0 -4px 8px rgba(0, 0, 0, .35); }
.color-swatch.selected { border-color: #fff; box-shadow: 0 0 0 2px rgba(255, 255, 255, .22), 0 0 16px rgba(255, 255, 255, .35), inset 0 1px 0 rgba(255, 255, 255, .6); }
.color-swatch.c-teal { background: #35b8a5; }
.color-swatch.c-blue { background: #60a5fa; }
.color-swatch.c-violet { background: #a78bfa; }
.color-swatch.c-amber { background: #f5c451; }
.color-swatch.c-rose { background: #fb7185; }
.color-swatch.c-lime { background: #a3e635; }
td.bot-col { width: 74px; white-space: nowrap; }
.order-card-left { display: flex; align-items: center; gap: 7px; min-width: 0; }
.dock-row .bot-tag { padding: 1px 4px; font-size: .64rem; letter-spacing: .04em; }
/* CẶP của lệnh / của bot (24/10/2026): nhãn 3 ký tự, vàng cho XAU, BTC nền
   VÀNG GOLD CHỮ ĐEN (chủ dự án chốt 24/10/2026 — "để nhìn phân biệt giữa xau
   và btc rõ hơn"): XAU là nhãn VIỀN vàng, BTC là nhãn ĐẶC nền vàng, hai kiểu
   khác hẳn nhau nên liếc nhanh vẫn tách được, kể cả ở dock thu nhỏ. Tên hiện
   ở đây là tên CHUẨN server trả (`bot_symbol`), không phải tên broker
   (XAUUSDm/BTCUSDm) — hai tài khoản hai sàn phải đọc ra cùng một thứ. */
.pair-tag { display: inline-block; padding: 2px 7px; border: 1px solid rgba(245, 196, 81, .45); border-radius: 8px; background: rgba(245, 196, 81, .12); color: #f5c451; font-family: ui-monospace, Consolas, monospace; font-size: .7rem; font-weight: 800; letter-spacing: .1em; white-space: nowrap; box-shadow: inset 0 1px 0 rgba(255, 255, 255, .14); }
.pair-tag.p-btc { border-color: #f5c451; background: #f5c451; color: #111; }
td.pair-col { width: 58px; white-space: nowrap; }
.dock-row .pair-tag { padding: 1px 4px; font-size: .58rem; letter-spacing: .02em; }
#signal-pairs { margin-top: 6px; }
.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(3, 7, 14, .66);
  backdrop-filter: blur(10px) saturate(120%);
  -webkit-backdrop-filter: blur(10px) saturate(120%);
}
.modal-card {
  width: min(560px, 100%);
  max-height: 86vh;
  overflow-y: auto;
  padding: 20px;
  border: 1px solid var(--border-strong);
  border-radius: 22px;
  background: var(--glass-fill);
  box-shadow: 0 40px 100px -30px rgba(0, 0, 0, .95), var(--highlight-line), 0 0 80px -40px rgba(63, 218, 196, .5);
  backdrop-filter: blur(26px) saturate(160%);
  -webkit-backdrop-filter: blur(26px) saturate(160%);
}
.modal-card h2 { margin: 0 0 8px; }
.modal-card p { color: var(--muted); }
.terms-list { display: grid; gap: 8px; margin: 10px 0; padding-left: 20px; color: var(--muted); font-size: .88rem; }
.modal-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 12px; }
.modal-actions .grow { flex: 1 1 220px; }

/* ── Responsive ──────────────────────────────────────────────────────── */
@media (max-width: 1100px) {
  .signal-viz-shell { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .channel-legend { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .workspace.with-dock { grid-template-columns: 1fr; }
  .side-dock {
    position: fixed;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 40;
    max-height: 46vh;
    flex-direction: row;
    flex-wrap: wrap;
    align-content: start;
    overflow-y: auto;
    padding: 8px;
    border-top: 1px solid var(--border);
    background: linear-gradient(180deg, rgba(12, 20, 36, .92), rgba(8, 14, 26, .96));
    box-shadow: 0 -14px 40px rgba(0, 0, 0, .45), inset 0 1px 0 rgba(255, 255, 255, .12);
    backdrop-filter: blur(20px) saturate(150%);
    -webkit-backdrop-filter: blur(20px) saturate(150%);
  }
  .dock-mini { flex: 1 1 min(320px, 100%); }
}
@media (max-width: 700px) {
  .app-shell { padding: 0 12px 84px; }
  .topbar { min-height: 56px; border-radius: 18px; padding: 0 12px; }
  .account-summary { display: none; }
  .workspace { padding-top: 14px; }
  .panel-heading { flex-direction: column; }
  .panel-heading.compact { align-items: flex-start; }
  .signal-total { width: 100%; text-align: left; }
  /* Màn hẹp: ô điểm + nút thu nhỏ nằm chung một hàng, ô điểm co lại vừa phải. */
  .signal-head-group { display: flex; width: 100%; }
  .signal-head-group .signal-total { flex: 1 1 auto; width: auto; }
  .signal-viz-shell { grid-template-columns: 1fr; }
  .channel-legend { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 8px; }
  .signal-chart { height: 250px; }
  .section-nav { display: none; }
  .form-grid { grid-template-columns: 1fr; }
  .orders-table { display: none; }
  .table-wrap { overflow: visible; }
  .order-cards { display: grid; }
  .mobile-nav {
    position: fixed;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 45;
    display: flex;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    border-top: 1px solid var(--border);
    border-radius: 18px 18px 0 0;
    background: linear-gradient(180deg, rgba(18, 30, 52, .78), rgba(8, 14, 26, .94));
    box-shadow: 0 -18px 44px rgba(0, 0, 0, .55), inset 0 1px 0 rgba(255, 255, 255, .14);
    backdrop-filter: blur(22px) saturate(160%);
    -webkit-backdrop-filter: blur(22px) saturate(160%);
    padding-bottom: env(safe-area-inset-bottom, 0);
  }
  .mobile-nav::-webkit-scrollbar { display: none; }
  /* 7 tab phải THẤY ĐỦ ở 390px: `flex-basis` cố định 68px trước đây cho ra 476px
     ⇒ tab Upgrade nằm ngoài màn hình, phải vuốt mới biết là có. Để `auto` + cho
     co tới min-content: 390/360px vừa khít, màn hẹp hơn (320px) vẫn cuộn ngang
     được vì `overflow-x: auto` ở trên. */
  .mobile-nav button {
    flex: 1 1 auto;
    min-height: 56px;
    padding: 0 7px;
    border: 0;
    border-top: 3px solid transparent;
    background: transparent;
    color: var(--muted);
    font-size: .67rem;
    font-weight: 750;
    letter-spacing: .01em;
    white-space: nowrap;
    transition: color .18s, background .18s;
  }
  .mobile-nav button.active {
    border-top-color: var(--accent);
    color: #c3f2ea;
    text-shadow: 0 0 16px rgba(63, 218, 196, .6);
    background: radial-gradient(120% 100% at 50% 0%, rgba(63, 218, 196, .18), transparent 72%);
  }
  .filters label { width: 100%; }
  .perf-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .filter-row { align-items: stretch; flex-direction: column; }
  .filter-chips { order: 2; }
  .pager { justify-content: center; }
  .pager .btn { flex: 1 1 auto; }
  .perf-actions { width: 100%; justify-content: space-between; }
  .perf-clock { flex: 1 1 auto; }
  input, select { font-size: 16px; }
  .segmented button { min-height: 44px; }
  .dock-toggle { width: 44px; height: 44px; }
  .side-dock { bottom: 60px; }
  .calendar-panel { max-width: none; }   /* màn hẹp thì giới hạn bề ngang là vô nghĩa */
  .calendar-day { min-height: 38px; padding: 2px 3px; }
  .calendar-grid, .calendar-dow { gap: 3px; }
  .calendar-grid.by-month { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .points-grid { grid-template-columns: 1fr; }
  .bot-list { grid-template-columns: 1fr; }
  .modal-card { padding: 16px; border-radius: 18px; }
}
@media (min-width: 701px) {
  button, input, select, .section-tab, .segmented button { min-height: 34px; }
  .dock-toggle { width: 34px; height: 34px; border-radius: 11px; }
  .filter-row { flex-wrap: nowrap; }
  .filters { flex-wrap: nowrap; }
  .filters label { width: 124px; }
  .filters input { min-height: 30px; padding: 3px 8px; }
  .filters .btn { padding: 2px 11px; border-radius: 999px; font-size: .86rem; }
}

/* ── Dự phòng khi trình duyệt không có backdrop-filter ───────────────── */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .panel, .auth-card, .modal-card, .topbar, .dock-mini, .mobile-nav, .side-dock {
    background: linear-gradient(160deg, #0e1a2e, #0a1220 60%, #101c32);
  }
  body::before { opacity: .8; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; transition-duration: .01ms !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; }
  body::before { animation: none; }
  /* ⚠ Hai hiệu ứng dưới đây là thứ CHỦ DỰ ÁN yêu cầu chạy LIÊN TỤC (28/10/2026).
     Trước đây khối này giấu hẳn chúng (`display: none`) nên máy nào bật "giảm
     chuyển động" của hệ điều hành (Windows: Settings > Accessibility > Visual
     effects > Animation effects = OFF) sẽ KHÔNG THẤY GÌ CẢ — đúng ca chủ dự án
     báo "cả 2 đều không thấy gì trên UI web". Luật `*` ở trên còn ép
     animation-duration .01ms nên kể cả không giấu thì radar cũng đứng im.
     Vì vậy: KHÔNG giấu, và ép lại đúng animation bằng !important (selector ở đây
     đặc hiệu hơn `*` nên thắng giữa hai khai báo !important). Vẫn giữ luật ĐÓNG
     BĂNG khi mất tín hiệu / chợ nghỉ bằng :not(.offline) — đó là luật của dự án. */
  .signal-viz-frame:not(.offline) .viz-sweep i { animation: sweep-turn 4.2s linear infinite !important; }
  .signal-viz-frame:not(.offline) .viz-scanline { animation: viz-scan 7.2s ease-in-out infinite !important; }
}
