/* Portal khách hàng — dựng theo sh00t.host BẢN RENDER THẬT (đo từ screenshot
   crawl4ai 29/07): header trắng sticky nav inline (active = pill #e8edff chữ
   #3157d5), nút đen pill, nền ấm #f7f7f3, page-head breadcrumb mono xanh +
   tiêu đề khổng lồ, bảng bo 16 viền mảnh, giá serif Instrument.
   Phông: Manrope (display) / DM Sans (body) / JetBrains Mono (mã) /
   Instrument Serif (số lớn) — đúng 4 phông của sh00t. */
@import url("https://fonts.googleapis.com/css2?family=Manrope:wght@500;600;700;800&family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Instrument+Serif:ital@0;1&display=swap");

:root {
  --blue: #3157d5;            /* secondary cua sh00t */
  --blue-ink: #233e99;
  --blue-container: #e8edff;  /* nen pill active / tint */
  --dark: #171a22;            /* màu mực chính; dark mode đổi thành chữ sáng */
  /* Nền nhấn phải tách khỏi --dark: --dark là token CHỮ, nên ở dark mode nó thành
     màu sáng. Dùng lại nó làm nền sẽ tạo chữ trắng trên nền gần-trắng. */
  --contrast-surface: #171a22;
  --contrast-surface-hover: #242833;
  --code-surface: #171a22;
  --bg: #f7f7f3;
  --bg-alt: #f2f2ec;
  --surface: #fdfdf9;
  --surface-low: #f9f9f5;
  --line: #e2e2db;
  --line-strong: #d6d7d0;
  --text: #171a22;
  --muted: #555860;
  --faint: #84868c;
  --ok: #2d8653;
  --warn: #d98b15;
  --bad: #be3636;
  --danger: #be3636;
  --danger-soft: #d95252;
  --accent: #3157d5;          /* alias cho code cũ trỏ --accent */
  --accent-deep: #233e99;
  --shadow: 0 18px 48px -42px rgba(23, 26, 34, 0.5);
  --shadow-hover: 0 24px 54px -40px rgba(23, 26, 34, 0.55);
  --radius-lg: 18px;
  --radius-md: 14px;
  --radius-sm: 10px;
  --font-display: "Manrope", "DM Sans", sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "Cascadia Mono", monospace;
  /* Manrope đứng TRƯỚC Georgia làm dự phòng, vì "Instrument Serif" KHÔNG có bộ ký tự
     tiếng Việt.

     Đo qua Google Fonts CSS API 21/08: Instrument Serif chỉ có subset `latin` +
     `latin-ext`, KHÔNG có `vietnamese`. Nên các ký tự như "ở" (U+1EDF), "ầ" (U+1EA7),
     "ả" (U+1EA3), "ệ" (U+1EC7) không nằm trong font.

     Trình duyệt xử lý thiếu glyph theo TỪNG KÝ TỰ, không theo cả chuỗi: nó lấy chữ có
     sẵn từ Instrument Serif và lấy riêng mấy ký tự có dấu từ font kế tiếp. Trước đây font
     kế tiếp là Georgia — khác hẳn nét và tỉ lệ — nên một từ như "Trải nghiệm" hiện ra
     nửa serif nửa Georgia, lệch nét ngay giữa từ. Đó chính là "lỗi font" khách báo.

     Manrope CÓ subset `vietnamese` (đã đo cùng lúc) và là font toàn trang (--font-display),
     nên ký tự thiếu được lấp bằng thứ khách đang đọc ở mọi nơi khác — thống nhất hơn
     Georgia rất nhiều. Georgia giữ ở cuối cho trường hợp Google Fonts bị chặn. */
  --font-serif: "Instrument Serif", "Manrope", Georgia, serif;
}

* { box-sizing: border-box; font-family: inherit; }
[hidden] { display: none !important; }

html { font-size: 100%; }

/* Scale TOÀN TRANG 90% (user chốt 29/07). zoom co đều mọi thứ (cả px padding,
   ảnh, bảng) và giữ sticky/click đúng — mọi trình duyệt hiện đại đều hỗ trợ. */
body { zoom: 0.9; }

body {
  margin: 0;
  font-family: "DM Sans", system-ui, -apple-system, sans-serif;
  min-width: 320px;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
}

.muted { color: var(--faint); }

/* ================= HEADER trắng sticky, nav inline (sh00t) ================= */
.masthead {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 18px;
  min-height: 62px;
  padding: 10px clamp(16px, 3vw, 40px);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.masthead-brand { display: flex; align-items: center; text-decoration: none; color: inherit; }
/* Wordmark: width/height đã khai trên thẻ <img> để trình duyệt giữ chỗ trước khi
   ảnh tải xong (không thì header nhảy một nhịp lúc mở trang). Ở đây chỉ chốt
   height và để width tự tính, nên tỉ lệ không méo nếu sau này đổi ảnh khác. */
.brand-mark {
  height: 30px;
  width: auto;
  display: block;
}
/* Dark mode đổi sang wordmark chữ sáng (wordmark-dark.svg): bản thường chữ tối
   chìm nghỉm trên nền tối. Hai ảnh cùng class brand-mark để hưởng chung size. */
.brand-mark-dark { display: none; }
html.dark .brand-mark:not(.brand-mark-dark) { display: none; }
html.dark .brand-mark-dark { display: block; }
@media (max-width: 640px) {
  /* Màn hẹp: header xuống dòng (xem .masthead flex-wrap), thu wordmark để nó
     không đẩy nút Đăng nhập/Đăng ký xuống hàng riêng. */
  .brand-mark { height: 26px; }
}
/* .brand-block/.brand-accent là wordmark dạng CHỮ của bản trước, giữ lại vì trang
   chủ tĩnh (arkvn-token-web) vẫn dùng cùng bộ CSS này. Xoá ở đây là làm mất
   thương hiệu ở một mặt khác của sản phẩm. */
.brand-block {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.16rem;
  letter-spacing: -0.02em;
  color: var(--dark);
}
.brand-accent { color: var(--blue); }
.brand-tag { display: none; }

/* Nav inline giữa header — item icon+chữ, active = pill xanh nhạt */
.sidebar {
  display: flex;
  align-items: center;
  gap: 2px;
  flex: 1;
  min-width: 0;
  overflow-x: auto;
}
.nav-item {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 13px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--muted);
  font-family: inherit;
  font-size: 0.83rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.nav-item:hover { color: var(--text); background: var(--bg-alt); }
.nav-item.active { color: var(--blue); background: var(--blue-container); }
.nav-ico { width: 15px; height: 15px; display: inline-flex; flex-shrink: 0; }
.nav-ico svg { width: 100%; height: 100%; }

.masthead-user, .masthead-auth { display: flex; align-items: center; gap: 8px; margin-left: auto; }

/* Chip account + nút đen: pill tối kiểu "Sign in" của sh00t */
.user-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  border-radius: 999px;
  border: 0;
  background: var(--contrast-surface);
  color: #fdfdf9;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 140ms ease, transform 140ms ease;
}
.user-chip:hover { background: var(--contrast-surface-hover); transform: translateY(-1px); }
.user-chip-ico { width: 14px; height: 14px; display: inline-flex; flex-shrink: 0; }
.user-chip-ico svg { width: 100%; height: 100%; }
.user-email { color: inherit; font-weight: 600; max-width: 200px; overflow: hidden; text-overflow: ellipsis; }

/* ================= KHUNG TRANG — sidebar layout ================= */
.shell {
  /* body có zoom .9 nên 100vh bị co còn ~90% → dùng / 0.9 để shell phủ trọn. */
  min-height: calc(100vh / 0.9);
  display: flex;
  flex-direction: row; /* sidebar trái + app-main phải */
  align-items: stretch;
}
/* .layout giữ lại để code JS renderShell không cần sửa */
.layout { flex: 1; display: flex; flex-direction: column; }
.view {
  flex: 1;
  min-width: 0;
  width: 100%;
  padding: clamp(20px, 3vw, 40px) clamp(16px, 3vw, 48px) 60px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.page { display: flex; flex-direction: column; gap: 16px; }

.foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  padding: 16px clamp(16px, 3vw, 48px);
  border-top: 1px solid var(--line);
  background: var(--surface);
  text-align: left;
}
.foot-main { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.foot-contact { color: var(--muted); font-size: 0.76rem; }
.foot-contact a, .foot-links a { color: var(--blue-ink); text-decoration: none; }
.foot-contact a:hover, .foot-links a:hover { text-decoration: underline; }
.foot-links { display: flex; align-items: center; justify-content: flex-end; gap: 8px 14px; flex-wrap: wrap; }
.foot-links a { font-size: 0.72rem; white-space: nowrap; }

/* ================= SIDEBAR TRÁI ================= */
.leftnav {
  width: 272px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-right: 1px solid var(--line);
  /* sticky: cao bằng viewport để không cuộn theo nội dung */
  height: calc(100vh / 0.9);
  position: sticky;
  top: 0;
  overflow-y: auto;
  scrollbar-width: none;
  z-index: 60;
}
.leftnav::-webkit-scrollbar { display: none; }

.leftnav-head {
  padding: 14px 14px 10px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.leftnav-brand {
  display: flex;
  align-items: center;
  text-decoration: none;
  color: inherit;
}
.leftnav-brand .brand-mark { height: 24px; width: auto; }

.leftnav-close {
  display: none; /* chỉ hiện trên mobile */
  align-items: center;
  justify-content: center;
  width: 28px; height: 28px;
  padding: 0;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  flex-shrink: 0;
}
.leftnav-close:hover { background: var(--bg-alt); color: var(--text); }
.leftnav-close svg { width: 16px; height: 16px; }

/* ---- Nav sidebar dọc với group headers ---- */
/* Override horizontal .sidebar (bên dưới) thành dọc */
.sidebar {
  flex: 1;
  display: flex !important; /* override [hidden] sau khi JS inject */
  flex-direction: column;
  align-items: stretch;     /* bắt buộc nav-item giãn full width, không dúm giữa */
  padding: 10px 8px;
  gap: 0;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: none;
}
.sidebar::-webkit-scrollbar { display: none; }

.nav-group { display: flex; flex-direction: column; margin-bottom: 6px; }
.nav-group-label {
  padding: 8px 10px 4px;
  font-size: 0.63rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
  user-select: none;
}

.nav-group-label {
  padding: 8px 11px 4px;
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--faint);
  user-select: none;
}

.nav-item {
  display: flex;
  align-items: center;
  width: 100%;
  gap: 8px;
  padding: 8px 11px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--muted);
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
  text-align: left;
}
.nav-item:hover { color: var(--text); background: var(--bg-alt); }
.nav-item.active { color: var(--blue); background: var(--blue-container); }
.nav-ico { width: 14px; height: 14px; display: inline-flex; flex-shrink: 0; }
.nav-ico svg { width: 100%; height: 100%; }

/* ---- Gold nav items: Chat AI + Gen Ảnh ---- */
.nav-item-gold { color: #92650a; background: #fff8e1; }
.nav-item-gold:hover { background: #fff3cd; color: #7a5408; }
.nav-item-gold.active { background: #f59e0b; color: #fff; }
.nav-item-gold-dot {
  margin-left: auto; font-size: 0.6rem; color: #f59e0b; flex-shrink: 0;
}
.nav-item-gold.active .nav-item-gold-dot { color: rgba(255,255,255,.8); }

/* ---- Live/Realtime nav item: teal nổi bật ---- */
.nav-item-live { color: #0e7a7a; background: #e6f7f7; font-weight: 700; }
.nav-item-live:hover { background: #cef0ef; color: #0a5f5f; }
.nav-item-live.active { background: #0e8a8a; color: #fff; }
.nav-item-live-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: #0e8a8a; flex-shrink: 0; margin-left: auto;
  animation: pulse-live 1.4s ease-in-out infinite;
}
.nav-item-live.active .nav-item-live-dot { background: rgba(255,255,255,.9); }
@keyframes pulse-live {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: .4; transform: scale(1.5); }
}

/* ---- Social support buttons (Zalo + Telegram) ---- */
.leftnav-social {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px 6px;
  border-top: 1px solid var(--line);
  flex-shrink: 0;
}
.social-btn {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 7px 10px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface-low); color: var(--muted);
  font-size: 0.75rem; font-weight: 600; cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease, color 140ms ease;
}
.social-btn:hover { border-color: var(--line-strong); color: var(--dark); background: var(--bg-alt); }
.social-btn svg { width: 16px; height: 16px; flex-shrink: 0; }
.social-btn-tg:hover { border-color: #229ed9; color: #229ed9; background: #e8f5fc; }
.social-btn-zalo:hover { border-color: #005aff; color: #005aff; background: #e6eeff; }

/* Social popup overlay */
.social-modal-overlay {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  background: rgba(23,26,34,.45);
}
.social-modal {
  background: var(--surface); border-radius: var(--radius-lg); padding: 24px;
  width: min(360px, 92vw); box-shadow: var(--shadow-hover);
  display: flex; flex-direction: column; align-items: center; gap: 14px;
}
.social-modal-title { font-family: var(--font-display); font-weight: 700; font-size: 1.1rem; color: var(--dark); }
.social-modal-qr { width: 180px; height: 180px; }
.social-modal-qr canvas { width: 100%; height: auto; }
.social-modal-link { font-family: var(--font-mono); font-size: 0.8rem; color: var(--blue); word-break: break-all; text-align: center; }
.social-modal-close { align-self: stretch; }

/* ---- CTA Direct Use buttons trên trang Tổng quan ---- */
/* 4 nút xếp MỘT hàng, cỡ ngang .btn của các trang khác — trước đây 2×2 full-width
   nên mỗi nút rộng gần nửa trang, to lệch hẳn so với tổng thể Portal. */
.cta-direct-row {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px;
  margin-bottom: 4px;
}
/* Cùng hình khối với .btn (padding/bo/cỡ chữ) để hàng lối đi nhanh không phình
   to hơn nút ở các trang khác. Trước đây bốn nút này tô gradient vàng đậm
   full-width nên hút hết mắt và đè lên phần ví ngay phía trên. */
.cta-direct-btn {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-width: 0;
  padding: 9px 14px; border-radius: 12px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--text);
  font-size: 0.86rem; font-weight: 600;
  cursor: pointer;
  transition: transform 160ms ease, border-color 160ms ease, background 160ms ease, color 160ms ease;
  text-align: center; line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cta-direct-btn:hover { transform: translateY(-1px); border-color: var(--faint); }
.cta-direct-btn:active { transform: translateY(0); }
.cta-direct-btn svg { width: 15px; height: 15px; flex-shrink: 0; opacity: .8; }
/* Hai lối đi chính chỉ nhấn bằng viền + chữ xanh, không nền đặc. */
.cta-direct-btn:not(.cta-secondary) {
  border-color: var(--blue);
  color: var(--blue-ink);
  background: var(--blue-container);
}
.cta-direct-btn:not(.cta-secondary):hover { border-color: var(--blue); filter: brightness(.98); }
@media (max-width: 1080px) {
  .cta-direct-row { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 480px) {
  .cta-direct-row { grid-template-columns: 1fr; }
  .cta-direct-btn { white-space: normal; }
}

/* ---- Analytics: date filter + history table ---- */
.ana-filter-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.ana-custom-row { margin-top: 8px; }
.ana-date-range { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.date-input {
  padding: 6px 10px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface); color: var(--text);
  font-family: var(--font-mono); font-size: 0.78rem; cursor: pointer;
}
.date-input:focus { outline: 2px solid var(--blue); outline-offset: 2px; }

/* Status dots trong bảng lịch sử request */
.status-dot {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  font-family: var(--font-mono); font-size: 0.72rem; font-weight: 600;
}
.status-ok  { background: #e3f4ea; color: #1a5c36; }
.status-bad { background: #fbe7e2; color: #771f1f; }
.font-mono  { font-family: var(--font-mono); font-size: 0.78rem; }

/* ---- Footer sidebar: info tài khoản ---- */
.leftnav-foot {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 11px 11px; border: 0; border-top: 1px solid var(--line);
  background: transparent; cursor: pointer; text-align: left;
  flex-shrink: 0; transition: background 140ms ease;
}
.leftnav-foot:hover { background: var(--bg-alt); }

.leftnav-user-avatar {
  width: 29px; height: 29px; border-radius: 50%;
  background: var(--blue-container); color: var(--blue);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.leftnav-user-avatar svg { width: 15px; height: 15px; }

.leftnav-user-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.leftnav-user-name {
  font-size: 0.82rem; font-weight: 800; color: var(--dark);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.leftnav-user-email {
  font-size: 0.7rem; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.leftnav-user-plan {
  font-size: 0.52rem; font-weight: 700; letter-spacing: 0.05em;
  padding: 2px 6px; border-radius: 999px;
  background: var(--blue-container); color: var(--blue);
  flex-shrink: 0;
  text-transform: uppercase;
}
.leftnav-user-plan.plan-pro { background: var(--contrast-surface); color: #fff; }

/* ================= APP MAIN (phần phải) ================= */
.app-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* TOPBAR (thay thế masthead trong layout mới) */
.topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 56px;
  padding: 8px 20px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.topbar-ham {
  display: none; /* ẩn desktop, hiện mobile */
  align-items: center;
  justify-content: center;
  width: 34px; height: 34px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  flex-shrink: 0;
}
.topbar-ham:hover { background: var(--bg-alt); color: var(--text); }
.topbar-ham svg { width: 18px; height: 18px; }
.topbar-title {
  flex: 1; min-width: 0;
  /* Không cho tràn tới banner giữa topbar.
   *
   * .topbar-brand nằm absolute ở giữa nên nó KHÔNG chiếm chỗ trong luồng flex; title với
   * flex:1 vì vậy giãn hết chiều rộng còn lại và hộp của nó phủ qua banner. Đo 21/08 ở
   * 1440px: title chiếm tới 938px trong khi banner bắt đầu ở 534px — chưa thấy đè vì tên
   * trang hiện tại ngắn ("Bảng điều khiển", 144px), nhưng một tên dài hơn sẽ chạy thẳng
   * qua chữ thương hiệu.
   *
   * Trừ 90px = nửa bề rộng banner (56px, đo được 112px) + khoảng thở. Tên dài quá sẽ bị
   * ellipsis TRƯỚC banner thay vì đè lên nó. */
  max-width: calc(50% - 90px);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.96rem;
  color: var(--dark);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.topbar-right {
  display: flex; align-items: center; gap: 8px; margin-left: auto;
}

/* Banner thương hiệu giữa topbar.

   # VÌ SAO position:absolute CHỨ KHÔNG PHẢI MỘT Ô FLEX

   Căn giữa MÀN HÌNH, không phải giữa hai phần tử cạnh nó. Nếu để trong luồng flex thì
   tên trang bên trái đẩy banner sang phải, và nó nhảy chỗ mỗi lần đổi trang ("Tổng quan"
   ngắn hơn "Hướng dẫn cài đặt") — một thứ nhận diện thương hiệu mà không đứng yên thì
   phản tác dụng.

   .topbar đã có position:sticky nên nó là mốc neo sẵn, không cần thêm gì.

   pointer-events:none vì đây là chữ TRANG TRÍ nằm trên cùng: không có nó thì dải giữa
   topbar thành vùng chết, hút mất cú bấm của bất cứ thứ gì nằm dưới. */
.topbar-brand {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  pointer-events: none;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1rem;
  letter-spacing: -0.01em;
  color: var(--dark);
  white-space: nowrap;
  user-select: none;
}
/* Dấu chấm tô màu nhấn: đủ để mắt nhận ra đây là một nhãn có chủ ý, không phải chữ lạc. */
.topbar-brand-dot { color: var(--accent); }

/* Hẹp thì ẨN, không co nhỏ.

   Dưới 900px, chỗ giữa topbar thuộc về tên trang — đó là thông tin khách ĐANG cần, còn tên
   miền thì họ vừa gõ để vào đây. Co chữ nhỏ lại sẽ có hai nhãn chen nhau và cả hai đều khó
   đọc; ẩn hẳn giữ được cái quan trọng hơn.

   Ngưỡng 900px trùng với breakpoint đã dùng trong file này, không đặt thêm số mới. */
@media (max-width: 900px) {
  .topbar-brand { display: none; }
  /* Banner đã ẩn thì trả lại toàn bộ chiều rộng cho tên trang.
   *
   * Giữ max-width ở đây sẽ cắt tên trang bằng ellipsis để nhường chỗ cho một thứ không
   * còn hiển thị — mất thông tin mà không đổi lấy gì. */
  .topbar-title { max-width: none; }
}

/* ================= MOBILE: sidebar overlay ================= */
.leftnav-overlay {
  display: none;
  position: fixed; inset: 0;
  background: rgba(23, 26, 34, 0.38);
  z-index: 59;
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms ease;
}

@media (max-width: 768px) {
  .leftnav {
    position: fixed;
    left: -276px;
    top: 0;
    height: 100%;
    z-index: 100;
    transition: left 200ms ease;
    box-shadow: none;
  }
  .leftnav.is-open {
    left: 0;
    box-shadow: 4px 0 24px rgba(23, 26, 34, 0.18);
  }
  .leftnav-close { display: flex; }
  .topbar-ham { display: flex; }
  .leftnav-overlay { display: block; }
  .leftnav-overlay.is-open { opacity: 1; pointer-events: all; }

  .view {
    padding: 16px 14px 48px;
  }
}

/* ================= PAGE HEAD kiểu sh00t ================= */
.page-head { margin-bottom: 8px; }
.page-crumb {
  margin: 0 0 14px;
  display: flex;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--blue);
}
.page-crumb-sep { color: var(--faint); }
.page-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2.4rem, 5vw, 3.6rem);
  line-height: 1.02;
  letter-spacing: -0.03em;
  color: var(--dark);
}
.page-sub {
  margin: 14px 0 0;
  max-width: 62ch;
  color: var(--muted);
  font-size: 0.98rem;
  line-height: 1.6;
}

/* Kicker nhỏ trong card (label-tiny giữ cho code cũ) */
.label-tiny {
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--faint);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* ================= NÚT ================= */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border-radius: 12px;
  padding: 9px 16px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--text);
  font-size: 0.86rem;
  font-weight: 600;
  cursor: pointer;
  transition: transform 160ms ease, box-shadow 160ms ease, border-color 160ms ease, background 160ms ease, color 160ms ease, filter 160ms ease;
}
.btn:hover { transform: translateY(-1px); border-color: var(--faint); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; box-shadow: none; }
.btn-primary {
  border: 0;
  color: #fff;
  background: var(--blue);
  border-radius: 999px;
  box-shadow: 0 10px 24px -12px rgba(49, 87, 213, 0.6);
}
.btn-primary:hover { filter: brightness(1.08); }
.btn-dark {
  border: 0;
  color: #fdfdf9;
  background: var(--contrast-surface);
  border-radius: 999px;
}
.btn-dark:hover { background: var(--contrast-surface-hover); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--muted); }
.btn-ghost:hover { color: var(--text); border-color: var(--line-strong); }
.btn-danger {
  border: 1px solid rgba(190, 54, 54, 0.4);
  color: var(--danger);
  background: rgba(190, 54, 54, 0.05);
}
.btn-danger:hover {
  border-color: transparent;
  color: #fff8f8;
  background: var(--danger);
}
.btn-pink {
  border: 0;
  color: #fff;
  background: var(--blue-ink);
  border-radius: 999px;
}
.btn-block { width: 100%; }

/* ================= FORM ================= */
.field { margin-bottom: 16px; }
.field label {
  display: block;
  margin-bottom: 7px;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
}
.field input {
  width: 100%;
  min-height: 42px;
  padding: 10px 13px;
  border-radius: 12px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--text);
  font-size: 0.92rem;
  outline: none;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}
.field input:focus { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(49, 87, 213, 0.15); }
.field input::placeholder { color: var(--faint); }
.auth-consent {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 4px 0 16px;
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.45;
}
.auth-consent input { flex: 0 0 auto; margin-top: 3px; accent-color: var(--blue); }
.auth-consent a { color: var(--blue-ink); }

.form-error {
  margin-bottom: 16px;
  padding: 11px 14px;
  border-radius: 12px;
  border: 1px solid rgba(190, 54, 54, 0.3);
  background: #fbe7e2;
  color: #771f1f;
  font-size: 0.88rem;
}
.form-ok {
  margin-bottom: 16px;
  padding: 11px 14px;
  border-radius: 12px;
  border: 1px solid rgba(45, 134, 83, 0.3);
  background: #e3f4ea;
  color: #1a5c36;
  font-size: 0.88rem;
}
.field-actions { margin-top: 4px; }

/* ================= PANEL / CARD ================= */
.panel, .auth-panel, .key-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 20px 0;
  flex-wrap: wrap;
}
.panel-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: -0.015em;
  color: var(--dark);
}
.panel-body { padding: 14px 20px 20px; }

/* Đích cuộn của nút "+ credit" trên header tài khoản. Khoảng chừa cho .masthead
   (sticky) do scrollToTopup() tính bằng JS, KHÔNG dùng scroll-margin-top: body
   có `zoom: .9` nên độ dài CSS và getBoundingClientRect lệch nhau đúng hệ số đó.
   Nháy viền một nhịp để mắt bắt được đích vừa cuộn tới. */
#topup-panel.is-flash {
  animation: topup-flash 1.6s ease-out;
}
@keyframes topup-flash {
  0%, 100% { border-color: var(--line); box-shadow: none; }
  15%      { border-color: var(--blue); box-shadow: 0 0 0 4px rgba(49, 87, 213, 0.16); }
  70%      { border-color: var(--blue); box-shadow: 0 0 0 4px rgba(49, 87, 213, 0.10); }
}
/* Khách bật "giảm chuyển động" thì bỏ hiệu ứng nháy, giữ nguyên việc cuộn. */
@media (prefers-reduced-motion: reduce) {
  #topup-panel.is-flash { animation: none; border-color: var(--blue); }
}

/* ================= AUTH ================= */
.auth-wrap { max-width: 420px; width: 100%; margin: auto; padding: 6vh 0; }
.auth-panel { padding: 30px 28px; }
.auth-title {
  margin: 0 0 20px;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.5rem;
  letter-spacing: -0.02em;
  color: var(--dark);
}
.auth-switch { margin: 16px 0 0; text-align: center; color: var(--muted); font-size: 0.86rem; }
.auth-switch a { color: var(--blue); font-weight: 700; text-decoration: none; }
.auth-switch a:hover { text-decoration: underline; }

/* ================= TRANG MODELS: bảng lớn kiểu sh00t ================= */
/* .ratio-note — dải thông báo hệ số nhóm model trên trang Models. Chỉ hiện khi
   hệ số khác ×1, nên nó không được chiếm chỗ như một panel: viền trái đậm + nền
   nhạt là đủ để mắt bắt được mà không tranh với bảng giá bên dưới. */
.ratio-note {
  margin: 14px 0 0;
  padding: 11px 14px;
  border-left: 3px solid var(--blue);
  border-radius: 8px;
  background: rgba(49, 87, 213, 0.07);
  color: var(--text);
  font-size: 0.88rem;
  font-weight: 600;
}
/* .guest-cta — dải mời đăng nhập, chỉ hiện với khách CHƯA có phiên trên trang
   bảng giá công khai. Đứng trên cùng $page (trước cả tiêu đề) vì nó trả lời câu
   hỏi khách đang có ngay lúc nhìn thấy giá: "đây có phải giá của tôi không?".
   Nền xanh nhạt + nút đặc để tách khỏi .ratio-note (dải của người ĐÃ đăng nhập)
   — hai dải không bao giờ xuất hiện cùng lúc, nhưng khác nhau về sắc độ giúp
   người đọc không nhầm hai trạng thái khi so hai ảnh chụp màn hình. */
.guest-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin: 0 0 18px;
  padding: 13px 16px;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  background: rgba(49, 87, 213, 0.05);
  color: var(--text);
  font-size: 0.9rem;
  font-weight: 600;
}
.msearch {
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: 460px;
  padding: 11px 15px;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  background: var(--surface);
  transition: border-color 160ms ease, box-shadow 160ms ease;
}
.msearch:focus-within { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(49, 87, 213, 0.14); }
.msearch-ico { width: 16px; height: 16px; color: var(--faint); flex-shrink: 0; }
.msearch-ico svg { width: 100%; height: 100%; }
.msearch input {
  flex: 1;
  border: 0;
  outline: none;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 0.92rem;
}
.msearch input::placeholder { color: var(--faint); }

.mtable-wrap {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  overflow-x: auto;
}
.mtable { width: 100%; border-collapse: collapse; min-width: 760px; }
.mtable th {
  padding: 9px 16px;
  text-align: left;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
  border-bottom: 1px solid var(--line);
}
.mtable td {
  padding: 7px 16px;
  border-bottom: 1px solid var(--bg-alt);
  color: var(--text);
  font-size: 0.86rem;
  vertical-align: middle;
}
.mtable tbody tr:last-child td { border-bottom: 0; }
.mtable tbody tr { transition: background 120ms ease; }
.mtable tbody tr:hover { background: var(--surface-low); }
.mname { display: flex; align-items: center; gap: 10px; min-width: 0; }
.mico {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 5px;
  border-radius: 50%;
}
.mico svg { width: 100%; height: 100%; }
.mname-copy { display: flex; flex-direction: column; gap: 0; min-width: 0; }
.mname-copy b {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 0.82rem;
  color: var(--dark);
}
.mname-copy code {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: var(--faint);
}
/* Model ID + nút copy nhanh: code xám + nút icon nhỏ hiện rõ khi hover hàng. */
.mid-row { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.mid-copy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 4px;
  flex-shrink: 0;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  color: var(--faint);
  cursor: pointer;
  opacity: 0;
  transition: opacity 140ms ease, color 140ms ease, border-color 140ms ease, background 140ms ease;
}
.mid-copy svg { width: 100%; height: 100%; }
.mtable tbody tr:hover .mid-copy { opacity: 1; }
.mid-copy:hover { color: var(--blue); border-color: var(--blue); background: var(--blue-container); }
.mid-copy:focus-visible { opacity: 1; outline: 2px solid var(--blue); outline-offset: 1px; }
@media (hover: none) { .mid-copy { opacity: 1; } }
.mprice { font-family: var(--font-mono); font-size: 0.82rem; color: var(--dark); white-space: nowrap; }
/* Giá 2 dòng: dòng Vào/Ra đậm, dòng cache mờ hơn — thay 4 số xếp ngang khó đọc. */
.mprice-2l { display: flex; flex-direction: column; gap: 2px; line-height: 1.35; }
.mprice-io small { color: var(--muted); font-size: 0.72rem; }
.mprice-io b { font-weight: 600; }
.mprice-sep { color: var(--faint); margin: 0 4px; }
.mprice-unit { color: var(--faint); font-size: 0.7rem; }
.mprice-cache small { color: var(--faint); font-size: 0.72rem; }

/* ---- Modal chi tiết tính tiền request (realtime) ---- */
.row-billable { cursor: pointer; }
.row-billable:hover td { background: var(--surface-low); }
.bill-detail-btn {
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: 8px;
  padding: 3px 10px;
  font-size: 0.74rem;
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
}
.bill-detail-btn:hover { border-color: var(--line-strong); color: var(--text); }
.bill-dialog { max-width: 430px; }
.bill-sec { margin-top: 14px; }
.bill-sec-title {
  margin: 0 0 8px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--faint);
}
.bill-row {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-top: none;
  font-size: 0.84rem;
}
.bill-sec .bill-row:first-of-type { border-top: 1px solid var(--line); border-radius: 8px 8px 0 0; }
.bill-sec .bill-row:last-of-type { border-radius: 0 0 8px 8px; }
.bill-sec .bill-row:first-of-type:last-of-type { border-radius: 8px; }
.bill-label { color: var(--muted); }
.bill-val { font-family: var(--font-mono); font-weight: 500; text-align: right; }
.bill-total { background: var(--bg-alt); }
.bill-total .bill-val { color: var(--ok); font-weight: 700; }
.bill-note { margin: 10px 0 0; font-size: 0.76rem; color: var(--faint); }
.mup-ok { color: var(--ok); font-weight: 700; }
.mup-warn { color: var(--warn); font-weight: 700; }
.mup-bad { color: var(--bad); font-weight: 700; }

/* Icon tròn màu brand (kiểu sh00t: claude cam tròn, openai đen tròn) */
.mico.tone-claude, .pick-ico.tone-claude, .zcard-ico.tone-claude { color: #fff; background: #d97757; }
.mico.tone-gpt, .pick-ico.tone-gpt, .zcard-ico.tone-gpt { color: #fff; background: #171a22; }
.mico.tone-grok, .pick-ico.tone-grok, .zcard-ico.tone-grok { color: #fff; background: #3d4046; }
.mico.tone-deepseek, .pick-ico.tone-deepseek, .zcard-ico.tone-deepseek { color: #fff; background: #4d6bfe; }
.mico.tone-glm, .pick-ico.tone-glm, .zcard-ico.tone-glm { color: #fff; background: #2d6eea; }
.mico.tone-kimi, .pick-ico.tone-kimi, .zcard-ico.tone-kimi { color: #fff; background: #101217; }
.mico.tone-gemini, .pick-ico.tone-gemini, .zcard-ico.tone-gemini, .chat-mico.tone-gemini { color: #fff; background: #1c69ff; }
/* Logo brand nhỏ trong Chat model list: tròn màu hãng như các icon .mico. */
.chat-mico {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px;
  border-radius: 50%;
  color: #fff;
}
.chat-mico svg { width: 100%; height: 100%; }
.chat-mico.tone-claude { background: #d97757; }
.chat-mico.tone-gpt { background: #171a22; }
.chat-mico.tone-grok { background: #3d4046; }
.chat-mico.tone-deepseek { background: #4d6bfe; }
.chat-mico.tone-glm { background: #2d6eea; }
.chat-mico.tone-kimi { background: #101217; }
.chat-mico.tone-qwen { background: #615ced; }

/* ================= BADGE ================= */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
}
.badge-active { color: var(--ok); background: rgba(45, 134, 83, 0.1); border: 1px solid rgba(45, 134, 83, 0.3); }
.badge-expired { color: var(--bad); background: #fbe7e2; border: 1px solid rgba(190, 54, 54, 0.3); }
.badge-off { color: var(--faint); background: var(--bg-alt); border: 1px solid var(--line); }
.badge-account { color: var(--blue); background: var(--blue-container); border: 1px solid rgba(49, 87, 213, 0.3); }
/* badge-pending: key còn số dư CHƯA nạp vào ví tài khoản — là việc cần làm, không
   phải trạng thái trung tính, nên dùng màu cảnh báo + nhịp thở nhẹ để mắt bắt được
   giữa hàng badge. Nhịp chỉ chạy trên opacity (compositor) và tắt theo
   prefers-reduced-motion. */
.badge-pending {
  color: var(--warn);
  background: color-mix(in oklab, var(--warn) 12%, transparent);
  border: 1px solid color-mix(in oklab, var(--warn) 38%, transparent);
  cursor: help;
  animation: badge-pending-breathe 2.4s ease-in-out infinite;
}
@keyframes badge-pending-breathe {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.62; }
}
@media (prefers-reduced-motion: reduce) {
  .badge-pending { animation: none; }
}

/* ================= KEYS ================= */
.keys-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.key-count { color: var(--muted); font-size: 0.9rem; }
.key-count b { color: var(--dark); font-weight: 800; font-size: 1.1rem; font-family: var(--font-display); }
.keys-head-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

.link-form { display: flex; gap: 10px; flex-wrap: wrap; }
.link-form input {
  flex: 1;
  min-width: 220px;
  min-height: 40px;
  padding: 9px 12px;
  border-radius: 12px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  outline: none;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}
.link-form input:focus { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(49, 87, 213, 0.14); }

.key-list { display: flex; flex-direction: column; gap: 12px; }
.key-card { border-radius: var(--radius-md); cursor: pointer; transition: border-color 160ms ease, box-shadow 160ms ease; }
.key-card:hover { border-color: var(--line-strong); box-shadow: var(--shadow); }
.key-card.open { border-color: rgba(49, 87, 213, 0.45); }
.key-card-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 15px 18px; }
.key-name { font-weight: 700; font-size: 0.95rem; color: var(--dark); }
.key-masked { flex: 1; min-width: 160px; color: var(--faint); font-family: var(--font-mono); font-size: 0.76rem; }
.key-expiry { color: var(--faint); font-size: 0.68rem; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; }
.key-detail { padding: 0 18px 16px; }
.key-full { margin-bottom: 14px; }
.key-full-value {
  margin-top: 6px;
  padding: 10px 13px;
  border-radius: 12px;
  border: 1px solid rgba(49, 87, 213, 0.3);
  background: var(--blue-container);
  color: var(--blue-ink);
  font-family: var(--font-mono);
  font-size: 0.76rem;
  word-break: break-all;
  user-select: all;
}
.key-detail-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.new-key-box {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 16px;
  padding: 14px 16px;
  border-radius: 12px;
  border: 1px solid rgba(49, 87, 213, 0.35);
  background: var(--blue-container);
}

/* ================= EMPTY / LOADING / TOAST ================= */
.empty-state { padding: 36px 24px; text-align: center; }
.empty-icon {
  width: 60px;
  height: 60px;
  margin: 0 auto 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px dashed var(--line-strong);
  background: var(--surface-low);
  color: var(--blue);
}
.empty-title { margin: 0 0 8px; font-family: var(--font-display); font-weight: 700; font-size: 1.05rem; color: var(--dark); }
.empty-desc { margin: 0 auto; max-width: 400px; color: var(--muted); font-size: 0.9rem; line-height: 1.55; }
.loading { padding: 44px; text-align: center; color: var(--faint); font-size: 0.9rem; }

.toasts { position: fixed; right: 18px; bottom: 18px; display: flex; flex-direction: column; gap: 10px; z-index: 120; }
.toast {
  padding: 12px 18px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow);
  color: var(--text);
  font-size: 0.9rem;
  animation: toast-in 220ms ease;
}
.toast.ok { border-color: rgba(45, 134, 83, 0.5); }
.toast.err { border-color: rgba(190, 54, 54, 0.5); }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

/* ================= STAT / VÍ ================= */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.stat-card, .plan-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface);
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.stat-value {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.55rem;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--dark);
}
.stat-value.stat-alt { color: var(--blue); }
.stat-value.stat-vip { color: var(--warn); }
.stat-sub { color: var(--faint); font-size: 0.8rem; }

/* Hàng ví trang Bảng điều khiển: ô cao bằng nhau, cỡ chữ/đệm giảm nhẹ cho khớp
   các trang khác. Khoanh vùng .wallet-grid để KHÔNG kéo theo .ana-grid và
   .kpi-grid vốn cùng dùng .stat-card/.stat-value. */
/* Cao đều cả hàng: chỉ giữ được sau khi khối "Cách dùng" trong ô VÍ REQUEST TẶNG
   rút còn một dòng. Trước đó ô ấy cao ~238px và stretch kéo cả 4 ô theo, để ô
   Credit/Bonus trống hơn 150px. */
.wallet-grid { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 10px; align-items: stretch; }
.wallet-grid .stat-card { padding: 13px 15px; gap: 5px; }
.wallet-grid .stat-value { font-size: 1.35rem; }
.wallet-grid .stat-sub { font-size: 0.76rem; }

.plan-bar { height: 8px; border-radius: 999px; background: var(--bg-alt); overflow: hidden; }
.plan-bar-fill { height: 100%; border-radius: 999px; transition: width 300ms ease; }
.plan-bar-fill.ok { background: var(--ok); }
.plan-bar-fill.warn { background: var(--warn); }
.plan-bar-fill.danger { background: var(--bad); }
.plan-meta { display: flex; flex-direction: column; gap: 2px; color: var(--faint); font-size: 0.82rem; }
.plan-remaining { color: var(--text); font-size: 0.88rem; font-weight: 600; }

/* ================= SPEND ORDER ================= */
.spend-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; }
.spend-box {
  padding: 16px 18px;
  border-radius: var(--radius-md);
  border: 1px solid var(--line);
  background: var(--surface);
  cursor: pointer;
  transition: border-color 160ms ease, background 160ms ease;
}
.spend-box:hover { border-color: var(--line-strong); }
.spend-box.active { border-color: var(--blue); background: var(--blue-container); }
.spend-label { font-family: var(--font-display); font-size: 0.95rem; font-weight: 700; color: var(--dark); }
.spend-box.active .spend-label { color: var(--blue); }
.spend-desc { margin-top: 5px; color: var(--muted); font-size: 0.82rem; line-height: 1.4; }

/* ================= REDEEM ================= */
.redeem-form { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.redeem-form input {
  flex: 1;
  min-width: 240px;
  min-height: 42px;
  padding: 9px 13px;
  border-radius: 12px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 0.82rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  outline: none;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}
.redeem-form input:focus { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(49, 87, 213, 0.14); }
.redeem-result {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  border-radius: 12px;
  border: 1px solid rgba(45, 134, 83, 0.4);
  background: rgba(45, 134, 83, 0.08);
  color: var(--ok);
  font-size: 0.92rem;
  font-weight: 600;
}

/* ================= USAGE / BẢNG ================= */
.usage-totals { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 18px; }
.usage-total {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  border-radius: var(--radius-md);
  border: 1px solid var(--line);
  background: var(--surface);
}
.usage-total b { font-family: var(--font-display); font-weight: 700; font-size: 1.15rem; line-height: 1; letter-spacing: -0.01em; font-variant-numeric: lining-nums tabular-nums; color: var(--dark); }
.usage-table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--surface); }
/* Nhãn trạng thái đơn hàng trong tab Lịch sử. */
.order-status { font-weight: 700; font-size: 0.82rem; }
.order-paid { color: var(--ok); }
.order-pending { color: var(--warn); }
.order-expired { color: var(--muted); }
.usage-table { width: 100%; border-collapse: collapse; font-size: 0.86rem; }
.usage-table th {
  padding: 11px 14px;
  text-align: left;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
  border-bottom: 1px solid var(--line);
}
.usage-table td { padding: 10px 14px; border-bottom: 1px solid var(--bg-alt); color: var(--text); }
.usage-table tbody tr:last-child td { border-bottom: 0; }
.usage-table .cell-model { font-family: var(--font-mono); font-size: 0.78rem; font-weight: 500; color: var(--dark); }
.usage-table .row-failed td { background: #fbe7e2; color: #771f1f; }
.tok-in { color: #be3636; font-weight: 600; }
.tok-out { color: #2d8653; font-weight: 600; }

/* ================= QUICKSTART / CHART ================= */
.quickstart-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.quickstart-value {
  flex: 1;
  min-width: 220px;
  padding: 10px 13px;
  border-radius: 12px;
  border: 1px solid var(--line-strong);
  background: var(--surface-low);
  color: var(--dark);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  word-break: break-all;
  user-select: all;
}
.chart-days { display: flex; align-items: flex-end; gap: 4px; height: 120px; padding: 6px 2px 0; }
.chart-day { flex: 1; min-width: 5px; display: flex; flex-direction: column; justify-content: flex-end; height: 100%; }
.chart-day-fill { border-radius: 4px 4px 0 0; background: var(--blue); opacity: 0.75; min-height: 2px; transition: height 300ms ease, opacity 160ms ease; }
.chart-day:hover .chart-day-fill { opacity: 1; }
.chart-legend { display: flex; justify-content: space-between; margin-top: 6px; color: var(--faint); font-size: 0.66rem; font-weight: 600; letter-spacing: 0.05em; }

/* ================= PICKER MODEL ================= */
.picker-wrap { margin-top: 6px; }
.pick-list { display: flex; flex-direction: column; gap: 6px; }
.pick-group-head {
  color: var(--faint);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin: 14px 0 4px;
}
.pick-group-head:first-child { margin-top: 0; }
.pick-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 10px; }
.pick-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 13px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--surface);
  cursor: pointer;
  transition: border-color 140ms ease, background 140ms ease;
}
.pick-card:hover { border-color: var(--line-strong); background: var(--surface-low); }
.pick-card.selected { border-color: var(--blue); background: var(--blue-container); }
.pick-card.locked { opacity: 0.55; cursor: not-allowed; }
.pick-card.locked:hover { border-color: var(--line); background: var(--surface); }
.pick-check {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  border: 1.5px solid var(--line-strong);
  background: var(--surface);
  color: #fff;
  transition: background 140ms ease, border-color 140ms ease;
}
.pick-card.selected .pick-check { background: var(--blue); border-color: var(--blue); }
.pick-check svg { width: 13px; height: 13px; }
.pick-ico {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px;
  border-radius: 50%;
}
.pick-ico svg { width: 100%; height: 100%; }
.pick-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pick-name { font-family: var(--font-mono); font-size: 0.8rem; font-weight: 500; word-break: break-all; line-height: 1.2; color: var(--dark); }
.pick-card.selected .pick-name { color: var(--blue-ink); }
.pick-price { color: var(--faint); font-size: 0.72rem; }
.pick-lock { flex-shrink: 0; color: var(--bad); font-size: 0.62rem; font-weight: 700; letter-spacing: 0.08em; }
.model-actions { display: flex; align-items: center; gap: 12px; margin-top: 14px; flex-wrap: wrap; }

/* ================= MODAL ================= */
.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(23, 26, 34, 0.4);
  backdrop-filter: blur(4px);
  animation: toast-in 180ms ease;
}
.modal-dialog {
  width: min(640px, 100%);
  max-height: 88vh;
  overflow-y: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: 0 40px 90px rgba(23, 26, 34, 0.3);
}
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 18px 20px 0; }
.modal-title { margin: 0; font-family: var(--font-display); font-size: 1.15rem; font-weight: 700; color: var(--dark); }
.modal-sub { margin: 4px 0 0; color: var(--muted); font-size: 0.86rem; }
.modal-close {
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--muted);
  width: 30px;
  height: 30px;
  border-radius: 9px;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  transition: color 140ms ease, border-color 140ms ease;
}
.modal-close:hover { color: var(--dark); border-color: var(--line-strong); }
.modal-body { padding: 16px 20px; }
.modal-section-head { display: flex; flex-direction: column; gap: 2px; margin: 14px 0 12px; padding-top: 14px; border-top: 1px solid var(--line); }
.modal-section-head:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.modal-section-head b { font-size: 0.95rem; color: var(--dark); }
.modal-section-head .muted { font-size: 0.82rem; }
.modal-foot { display: flex; justify-content: flex-end; gap: 10px; padding: 0 20px 18px; }
.modal-models { margin-top: 12px; }

/* ================= PILL ================= */
.pill-row { display: flex; gap: 8px; flex-wrap: wrap; }
.pill {
  min-height: 34px;
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--muted);
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 140ms ease, color 140ms ease, background 140ms ease;
}
.pill:hover { border-color: var(--faint); color: var(--text); }
.pill.active { color: var(--blue); border-color: rgba(49, 87, 213, 0.4); background: var(--blue-container); }

.quick-pill { display: inline-flex; align-items: center; gap: 7px; padding: 8px 16px; font-size: 0.84rem; }
.quick-pill::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--line-strong);
  transition: background 140ms ease;
}
.quick-pill.partial::before { background: var(--blue); opacity: 0.55; }
.quick-pill.active::before { background: var(--blue); }
.quick-pill.partial { color: var(--blue); border-color: rgba(49, 87, 213, 0.4); }

/* ================= LEGACY models classes (picker/zcard cũ) ================= */
.models-search {
  width: 100%;
  min-height: 42px;
  padding: 10px 14px;
  border-radius: 12px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--text);
  font-size: 0.92rem;
  outline: none;
}
.models-group-head { display: flex; align-items: baseline; gap: 10px; margin: 20px 0 10px; padding-bottom: 7px; border-bottom: 1px solid var(--line); }
.models-group-head:first-child { margin-top: 0; }
.models-group-head b { font-family: var(--font-display); font-size: 1rem; color: var(--dark); font-weight: 700; }
.models-group-head .muted { font-size: 0.76rem; }
.models-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(310px, 1fr)); gap: 12px; }
.zcard { display: flex; flex-direction: column; gap: 10px; padding: 14px 16px; border-radius: var(--radius-md); border: 1px solid var(--line); background: var(--surface); }
.zcard.locked { opacity: 0.6; }
.zcard-top { display: flex; align-items: center; gap: 11px; }
.zcard-ico { width: 34px; height: 34px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; padding: 7px; border-radius: 50%; }
.zcard-ico svg { width: 100%; height: 100%; }
.zcard-title { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.zcard-name { font-family: var(--font-mono); font-size: 0.86rem; font-weight: 600; word-break: break-all; color: var(--dark); }
.zcard-price { color: var(--dark); font-size: 0.84rem; font-weight: 600; }
.zcard-copy { flex-shrink: 0; width: 30px; height: 30px; border-radius: 9px; border: 1px solid var(--line); background: var(--surface); color: var(--muted); font-size: 0.9rem; cursor: pointer; }
.zcard-copy:hover { color: var(--dark); border-color: var(--line-strong); }
.zcard-desc { color: var(--muted); font-size: 0.85rem; line-height: 1.45; min-height: 1.45em; }
.zcard-foot { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; padding-top: 10px; border-top: 1px dashed var(--line); }
.zcard-tags { display: flex; gap: 6px; flex-wrap: wrap; }
.ztag { padding: 2px 9px; border-radius: 999px; border: 1px solid var(--line); background: var(--bg-alt); color: var(--muted); font-size: 0.72rem; font-weight: 600; }
.ztag-vip { color: #5b4126; background: #f7ebd9; border-color: #ecd5b7; }
.ztag-lock { color: var(--bad); border-color: rgba(190, 54, 54, 0.35); background: #fbe7e2; }
.zcard-stats { display: flex; gap: 16px; align-items: flex-end; flex-shrink: 0; }
.zstat { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.zstat-label { color: var(--faint); font-size: 0.64rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; }
.zstat b { font-size: 0.88rem; color: var(--dark); }
.zbars { display: flex; gap: 2px; align-items: flex-end; height: 16px; }
.zbar { width: 4px; height: 100%; border-radius: 1.5px; }
.zbar.ok { background: var(--ok); }
.zbar.fail { background: var(--bad); }

/* ================= REALTIME ================= */
.live-panel { border-top: 3px solid var(--blue); }
.live-head-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.live-dot { display: inline-flex; align-items: center; gap: 5px; color: var(--ok); font-size: 0.78rem; font-weight: 700; }
.live-dot.is-paused { color: var(--faint); }
.live-dot::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: currentColor; animation: live-pulse 2s ease-out infinite; }
.live-dot.is-paused::before { animation: none; }
@keyframes live-pulse {
  0% { box-shadow: 0 0 0 0 rgba(45, 134, 83, 0.5); }
  70% { box-shadow: 0 0 0 7px rgba(45, 134, 83, 0); }
  100% { box-shadow: 0 0 0 0 rgba(45, 134, 83, 0); }
}
@media (prefers-reduced-motion: reduce) { .live-dot::before { animation: none; } }
.live-toggle { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); font-size: 0.8rem; cursor: pointer; }
.live-updated {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-alt);
  color: var(--faint);
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
}
.usage-table tr.is-new td { animation: row-in 500ms ease; }
@keyframes row-in { from { background: var(--blue-container); } to { background: transparent; } }
@media (prefers-reduced-motion: reduce) { .usage-table tr.is-new td { animation: none; } }
.prov-badge {
  --pc: #64748b;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border-radius: 999px;
  padding: 3px 11px 3px 9px;
  font-size: 0.74rem;
  font-weight: 600;
  white-space: nowrap;
  color: color-mix(in srgb, var(--pc) 82%, #0b1a2e);
  background: color-mix(in srgb, var(--pc) 12%, #ffffff);
  border: 1px solid color-mix(in srgb, var(--pc) 38%, transparent);
}
.prov-badge::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--pc); }
.prov-claude { --pc: #d97757; }
.prov-gpt { --pc: #171a22; }
.prov-grok { --pc: #3d4046; }
.prov-deepseek { --pc: #4d6bfe; }
.prov-glm { --pc: #2d6eea; }
.prov-kimi { --pc: #101217; }

/* ================= PROFILE HUB ================= */
.profile-toc {
  position: sticky;
  top: 62px;
  z-index: 5;
  padding: 10px 0;
  background: linear-gradient(180deg, var(--bg) 78%, transparent);
}
.profile-section { display: flex; flex-direction: column; gap: 16px; scroll-margin-top: 130px; }
.profile-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; align-items: start; }
.ledger-delta-plus { color: var(--ok); }
.ledger-delta-minus { color: var(--bad); }

/* ================= DOCS ================= */
.docs-code {
  margin: 0;
  padding: 15px 17px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: #171a22;
  color: #e8eaf0;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  line-height: 1.65;
  overflow-x: auto;
  white-space: pre;
}
.docs-list { margin: 0; padding-left: 20px; color: var(--muted); font-size: 0.9rem; line-height: 1.7; }

/* ================= IMAGES ================= */
.images-form { display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; }
.images-prompt {
  width: 100%;
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: 0.92rem;
  resize: vertical;
  outline: none;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}
.images-prompt:focus { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(49, 87, 213, 0.14); }
.images-form-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.images-select {
  min-height: 40px;
  padding: 8px 12px;
  border-radius: 12px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 0.86rem;
}
.images-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; }
.images-item { border: 1px solid var(--line); border-radius: var(--radius-md); overflow: hidden; background: var(--surface); }
.images-item img { display: block; width: 100%; height: auto; }
.images-item-meta { padding: 8px 12px; display: flex; gap: 8px; align-items: center; }
.images-item-size { font-size: .78rem; flex: 1; min-width: 0; }

/* Nút tải ảnh: 44×44 là mức TỐI THIỂU bấm được bằng ngón tay (Apple HIG,
   WCAG 2.5.8 Target Size). Bản cũ là thẻ <a> chữ .78rem cao ~14px nên trên
   điện thoại gần như không trúng — đó là lỗi "không bấm được tải xuống".
   touch-action:manipulation bỏ độ trễ 300ms chờ double-tap của Safari. */
.img-dl-btn {
  min-height: 44px; min-width: 44px;
  padding: 0 14px;
  display: inline-flex; align-items: center; justify-content: center;
  gap: 6px; flex: 0 0 auto;
  font-size: .82rem; font-weight: 600;
  color: var(--text); background: var(--surface-2, transparent);
  border: 1px solid var(--line); border-radius: var(--radius-sm, 8px);
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: rgba(0, 0, 0, .08);
}
.img-dl-btn:hover { background: var(--surface-3, var(--surface-2, transparent)); border-color: var(--text-muted, var(--line)); }
.img-dl-btn:active { transform: translateY(1px); }
.img-dl-btn:focus-visible { outline: 2px solid var(--blue, #60a5fa); outline-offset: 2px; }

/* Màn hẹp: nút chiếm cả dòng để vùng bấm rộng hết chiều ngang thẻ. */
@media (max-width: 520px) {
  .images-item-meta { flex-wrap: wrap; }
  .images-item-size { flex: 1 0 100%; }
  .img-dl-btn { flex: 1 0 100%; }
}

/* ---- Trang tạo ảnh: nút chọn tỉ lệ / độ phân giải ---- */
.img-field-head { display: flex; justify-content: space-between; align-items: baseline; }
.img-field-label { display: block; font-size: .82rem; font-weight: 600; color: var(--text-muted, #9aa4b2); margin-bottom: 6px; }
.img-btn-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); gap: 8px; }
.img-btn {
  min-height: 40px;
  padding: 8px 10px;
  border-radius: 10px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: .86rem;
  cursor: pointer;
  transition: border-color 140ms ease, background 140ms ease, box-shadow 140ms ease;
}
.img-btn:hover { border-color: var(--blue); }
.img-btn.is-active {
  border-color: var(--green, #34d399);
  background: rgba(52, 211, 153, 0.12);
  box-shadow: 0 0 0 1px var(--green, #34d399) inset;
  font-weight: 600;
}
.img-tier-btn { display: flex; flex-direction: column; align-items: center; gap: 2px; line-height: 1.2; }
.img-tier-name { font-weight: 700; }
.img-tier-price { font-size: .74rem; color: var(--text-muted, #9aa4b2); }
.img-btn.is-active .img-tier-price { color: var(--green, #34d399); }
.img-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 14px; }
.img-row-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; margin-top: 14px; }
.img-slider { width: 100%; margin-top: 8px; accent-color: var(--green, #34d399); }
.img-summary {
  margin-top: 14px;
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px solid var(--line-strong);
  background: rgba(52, 211, 153, 0.06);
}
.img-summary-main { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px; }
.img-summary-total { color: var(--green, #34d399); font-size: 1.02rem; }
/* Tab switcher Tạo ảnh / Sửa-Tham chiếu */
.img-tabbar { display: flex; gap: 6px; margin-bottom: 14px; background: var(--surface); padding: 4px; border-radius: 12px; border: 1px solid var(--line-strong); }
.img-tab {
  flex: 1;
  min-height: 40px;
  padding: 8px 12px;
  border-radius: 9px;
  border: none;
  background: transparent;
  color: var(--text-muted, #9aa4b2);
  font: inherit;
  font-size: .9rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.img-tab:hover { color: var(--text); }
.img-tab.is-active { background: var(--green, #34d399); color: #06281c; }

/* ================= RESPONSIVE ================= */
@media (max-width: 860px) {
  .masthead { flex-wrap: wrap; }
  .sidebar { order: 3; width: 100%; flex-basis: 100%; }
  .nav-item { padding: 7px 11px; font-size: 0.8rem; }
  .nav-ico { display: none; }
  .view { padding: 24px 16px 48px; }
  .profile-toc { top: 0; }
}
@media (max-width: 560px) {
  .user-email { max-width: 110px; }
  .key-card-head { gap: 10px; }
  .img-row-2, .img-row-3 { grid-template-columns: 1fr; }
}

/* ================= ĐIỆN THOẠI: khung CỐ ĐỊNH, không nhảy khi bật bàn phím =========
   Toàn bộ khối này chỉ chạy ở <= 720px. Giao diện MÁY TÍNH không đổi một pixel.

   Bốn việc, theo đúng thứ tự khách phàn nàn:

   1. TOP BAR QUÁ LỚN + KHÔNG TỰ ẨN. Trên màn hẹp header đang xuống 2 hàng (nav
      wrap xuống dòng riêng) nên ăn ~120px trong khoảng 640px chiều cao khả dụng.
      Ở đây: thu gọn về MỘT hàng, và khi cuộn xuống trong tab Chat thì header
      TỰ ẨN (xem .is-chat-mobile bên dưới) để trả chiều cao cho khung soạn.

   2. KHÔNG BỊ PHÓNG TO KHI BẬT BÀN PHÍM. Gốc rễ KHÔNG phải thẻ viewport mà là
      CỠ CHỮ Ô NHẬP: iOS Safari tự phóng trang khi focus vào input có font-size
      < 16px, và .chat-input đang để 0.95rem. Nhưng body có `zoom: .9`, nên
      0.95rem thực tế chỉ còn ~13.7px trên màn hình -> chắc chắn bị zoom.
      Vá bằng cách nâng cỡ chữ ô nhập lên mức mà SAU khi nhân zoom vẫn >= 16px:
      16 / 0.9 = 17.8px -> dùng 18px cho chắc. Đây là cách vá đúng; khoá zoom
      bằng user-scalable=no cũng hết nhảy nhưng chặn luôn người thị lực kém.

   3. CHIỀU CAO CỐ ĐỊNH. 100vh trên di động = chiều cao khi thanh địa chỉ ĐÃ ẨN,
      nên trang luôn cao hơn khung nhìn và composer bị đẩy khuất dưới mép. Dùng
      100dvh (dynamic viewport height) để khung co theo đúng phần thấy được, kể
      cả lúc bàn phím mở. Chuỗi min-height:0 từ shell -> layout -> view -> chat
      phải liền mạch thì phần cuộn mới nằm ở .chat-thread chứ không phải ở body
      (body cuộn = cả header lẫn composer trôi đi, đúng cảm giác "trang nhảy").

   4. BỎ CHÂN TRANG. Trên di động nó chỉ chiếm chỗ. Ẩn hẳn ở tab Chat. */
@media (max-width: 720px) {
  /* Header MỘT hàng: nav cuộn ngang cùng hàng thay vì rơi xuống dòng riêng. */
  .masthead {
    flex-wrap: nowrap;
    gap: 10px;
    min-height: 52px;
    padding: 6px 12px;
    padding-left: max(12px, env(safe-area-inset-left));
    padding-right: max(12px, env(safe-area-inset-right));
  }
  .sidebar { order: 0; width: auto; flex-basis: auto; flex: 1; min-width: 0; }
  .brand-mark { height: 22px; }

  /* Khối tài khoản bên phải KHÔNG được nuốt hết chiều ngang.
     Đo thật ở 375px: chip email + nút Đăng xuất ăn 236/375px, ép nav còn ĐÚNG
     0px — Models/Tài liệu biến mất, khách không bấm được gì.
     Vá: bỏ CHỮ (email + "Đăng xuất") khỏi masthead trên di động, giữ lại icon.
     Không mất chức năng nào: tên tài khoản và nút Đăng xuất đều đã có sẵn,
     to và rõ, ngay trong trang Hồ sơ (.acct-head). */
  .masthead-user { flex-shrink: 0; gap: 6px; }
  .user-email { display: none; }
  .user-chip { padding: 8px; }
  #btn-logout { display: none; }
  .bell-btn { width: 32px; height: 32px; padding: 7px; }

  .foot { align-items: flex-start; flex-direction: column; gap: 10px; }
  .foot-links { justify-content: flex-start; }
}

/* ---- Chỉ khi ĐANG Ở TAB CHAT trên di động (app.js gắn .is-chat-mobile vào
   <body>). Tách riêng vì khoá chiều cao là hành vi ĐÚNG cho khung chat nhưng
   SAI cho mọi trang khác — trang Thống kê/Lịch sử phải cuộn được bình thường. */
@media (max-width: 720px) {
  /* Khoá khung đúng bằng phần THẤY ĐƯỢC; body không cuộn, chỉ .chat-thread cuộn. */
  body.is-chat-mobile { overflow: hidden; }
  body.is-chat-mobile .shell {
    /* Chia cho 0.9 vì body có `zoom: .9`: độ dài CSS khai ở đây bị nhân 0.9 khi
       render, nên 100dvh trần sẽ chỉ phủ 90% khung nhìn và chừa một dải trống
       đúng bằng 10% dưới đáy. Cùng cách bù đã dùng cho .shell bản máy tính. */
    height: calc(100dvh / 0.9);
    min-height: 0;
    overflow: hidden;
  }
  body.is-chat-mobile .layout { min-height: 0; overflow: hidden; }
  body.is-chat-mobile .view {
    min-height: 0;
    overflow: hidden;
    padding: 8px 10px 0;
    padding-left: max(10px, env(safe-area-inset-left));
    padding-right: max(10px, env(safe-area-inset-right));
    padding-bottom: env(safe-area-inset-bottom);
    gap: 8px;
  }

  /* Header tự ẩn khi cuộn xuống trong khung chat (app.js bật .hide-top). */
  body.is-chat-mobile .masthead {
    transition: transform 180ms ease, opacity 180ms ease;
  }
  body.is-chat-mobile.hide-top .masthead {
    transform: translateY(-100%);
    opacity: 0;
    pointer-events: none;
    position: fixed;
    left: 0;
    right: 0;
  }

  /* Nhường tối đa chiều cao cho vùng trò chuyện: bỏ header hồ sơ + dải tab +
     danh sách phiên. Vào Chat trên điện thoại là để CHAT. Vẫn đổi tab được
     bằng nút quay lại của app.js (.chat-mobile-back). */
  body.is-chat-mobile .acct-head,
  body.is-chat-mobile .acct-tabs,
  body.is-chat-mobile .chat-sidebar { display: none; }

  body.is-chat-mobile .acct-body { gap: 0; min-height: 0; }
  body.is-chat-mobile .chat-wrap { gap: 0; min-height: 0; }
  body.is-chat-mobile .chat-main { gap: 8px; min-height: 0; }
  /* min-height 240px của bản máy tính sẽ làm tràn khung đã khoá -> phải gỡ. */
  body.is-chat-mobile .chat-thread {
    min-height: 0;
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }
  body.is-chat-mobile .chat-composer {
    flex-shrink: 0;
    padding: 8px 10px 8px;
    box-shadow: none;
  }
  /* >= 16px SAU khi nhân zoom .9 — chặn auto-zoom của iOS. Xem mục 2 ở trên. */
  body.is-chat-mobile .chat-input { font-size: 18px; max-height: 120px; }
}

/* Dải điều hướng nhỏ của chat di động: lối RA (vì dải tab đã bị giấu) + nút tạo
   phiên mới (vì sidebar phiên cũng bị giấu). app.js chỉ dựng nó khi màn <= 720px,
   nên trên máy tính không có gì để hiện — vẫn khai display:none ở bản rộng để
   nếu sau này có ai dựng nó ngoài nhánh đó thì cũng không lọt ra desktop. */
.chat-mobile-bar { display: none; }
@media (max-width: 720px) {
  body.is-chat-mobile .chat-mobile-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-shrink: 0;
    padding: 2px 0 6px;
  }
  .chat-mobile-back,
  .chat-mobile-hist,
  .chat-mobile-new {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    /* 44px là cỡ chạm tối thiểu — nút nhỏ hơn thì ngón tay bấm trượt. */
    min-height: 44px;
    padding: 8px 14px;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    background: var(--surface);
    color: var(--text);
    font-family: inherit;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
  }
  .chat-mobile-back-ico { width: 16px; height: 16px; flex-shrink: 0; }
  .chat-mobile-back-ico svg { width: 100%; height: 100%; }
  .chat-mobile-new { color: var(--blue); border-color: rgba(49, 87, 213, 0.35); background: var(--blue-container); }
}

/* ---- Ngăn kéo LỊCH SỬ cho chat di động ----
 *
 * Vì sao cần: bản di động giấu `.chat-sidebar` để nhường chiều cao cho vùng trò
 * chuyện, nhưng sidebar là NƠI DUY NHẤT mở lại phiên cũ — nên trên điện thoại khách
 * không có đường nào tìm lại cuộc trò chuyện hôm qua. Lịch sử vẫn nằm ở server, chỉ
 * là không có cửa vào.
 *
 * Ngăn kéo dùng CHÍNH phần tử `.chat-sidebar` (app.js chuyển nó vào đây trên di
 * động), không dựng bản sao — nên `renderSessions` vẫn ghi vào đúng một danh sách,
 * không có chuyện hai bản lệch nhau.
 *
 * ⚠️ Độ ưu tiên: `body.is-chat-mobile .chat-sidebar` là (0,2,1). Muốn hiện lại
 * sidebar trong ngăn kéo phải viết `body.is-chat-mobile .chat-drawer .chat-sidebar`
 * = (0,3,1) mới thắng. Viết `.chat-drawer .chat-sidebar` (0,2,0) là THUA và ngăn kéo
 * mở ra rỗng trơn — kiểu lỗi im lặng, mở mới thấy. */
.chat-drawer { display: none; }
.chat-drawer.open { display: block; position: fixed; inset: 0; z-index: 70; }
.chat-drawer-back {
  position: absolute;
  inset: 0;
  background: rgba(15, 17, 21, 0.45);
  animation: chatDrawerFade 160ms ease;
}
.chat-drawer-panel {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: min(86vw, 320px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 12px;
  background: var(--bg);
  border-right: 1px solid var(--line);
  box-shadow: 18px 0 42px rgba(15, 17, 21, 0.18);
  animation: chatDrawerIn 180ms cubic-bezier(0.16, 1, 0.3, 1);
}
.chat-drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-shrink: 0;
}
.chat-drawer-title { font-size: 0.82rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--faint); }
.chat-drawer-x {
  min-width: 44px;
  min-height: 44px;
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
}
body.is-chat-mobile .chat-drawer .chat-sidebar {
  display: flex;
  flex: 1;
  min-height: 0;
  border-right: 0;
  padding-right: 0;
}
@keyframes chatDrawerFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes chatDrawerIn { from { transform: translateX(-100%); } to { transform: translateX(0); } }
@media (prefers-reduced-motion: reduce) {
  .chat-drawer-back, .chat-drawer-panel { animation: none; }
}

/* ---- Realtime kiểu usage cũ: KPI vạch màu trái + cell model 2 dòng ---- */
.kpi-grid { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.stat-card.kpi { position: relative; overflow: hidden; }
.stat-card.kpi::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 4px;
  background: var(--kpi, #3157d5);
}
.kpi-grid .kpi:nth-child(1) { --kpi: #3157d5; }
.kpi-grid .kpi:nth-child(2) { --kpi: #2d8653; }
.kpi-grid .kpi:nth-child(3) { --kpi: #be3636; }
.kpi-grid .kpi:nth-child(4) { --kpi: #22a06b; }
.kpi-grid .kpi:nth-child(5) { --kpi: #0e9ec2; }
.kpi-grid .kpi:nth-child(6) { --kpi: #7c3aed; }
.kpi-grid .kpi:nth-child(7) { --kpi: #d98b15; }
.usage-table td.num, .usage-table th.num { text-align: right; white-space: nowrap; }
.usage-table .cell-model b { display: block; font-weight: 600; }
.usage-table .cell-model small { display: block; margin-top: 2px; color: var(--faint); font-size: 0.68rem; }
.bucket-chip {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: var(--bg-alt);
  color: var(--muted);
  font-size: 0.74rem;
  font-weight: 600;
  white-space: nowrap;
}

/* ---- Dashboard account kiểu sh00t /profile: header + tab riêng biệt ---- */

/* Trang Hồ sơ ĐẨY SÁT LÊN: khối tên + số dư + Đăng xuất là thứ khách vào xem
   đầu tiên, không đáng bị đẩy xuống bởi khoảng đệm dành cho page-head khổ lớn
   (trang Models/Tài liệu vẫn giữ nguyên đệm đó vì chúng CÓ tiêu đề lớn).
   Dùng :has để chỉ trang nào thật sự có .acct-head mới co lại — cùng kỹ thuật
   đã dùng cho .acct-body:has(.chat-wrap) bên dưới. */
.view:has(.acct-head) { padding-top: clamp(10px, 1.2vw, 16px); }

.acct-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.acct-id { display: flex; align-items: center; gap: 14px; min-width: 0; }
.acct-avatar {
  width: 46px;
  height: 46px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 11px;
  border-radius: 14px;
  background: var(--blue);
  color: #fff;
}
.acct-avatar svg { width: 100%; height: 100%; }
.acct-copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.acct-copy b { font-family: var(--font-display); font-weight: 800; font-size: 1.3rem; letter-spacing: -0.02em; color: var(--dark); }
.acct-copy .muted { font-size: 0.8rem; }
.acct-actions { display: flex; align-items: center; gap: 10px; }
.acct-balance {
  color: var(--blue);
  border-color: rgba(49, 87, 213, 0.35);
  background: var(--blue-container);
  font-family: var(--font-mono);
  font-size: 0.82rem;
  text-decoration: none;
}
.acct-balance:hover { border-color: var(--blue); }

.acct-tabs {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface);
  overflow-x: auto;
}

/* Mỗi tab là MỘT KHỐI MÀU nhận diện riêng.
   Màu đi theo data-tab (xem TABS trong app.js), không theo thứ tự :nth-child —
   thêm/bớt/đổi chỗ tab thì màu vẫn dính đúng tab đó.
   Hai biến mỗi tab: --tab-ink (chữ + màu nền khi active) và --tab-soft (nền
   nhạt lúc nghỉ). Tab đang chọn ĐẢO NGƯỢC thành nền đặc chữ trắng để phân biệt
   được cả khi không nhìn màu (tương phản chứ không chỉ sắc độ). */
.acct-tab {
  padding: 13px 22px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: var(--tab-soft, var(--bg-alt));
  color: var(--tab-ink, var(--muted));
  font-family: inherit;
  font-size: 0.98rem;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease, transform 120ms ease;
}
.acct-tab[data-tab="overview"] { --tab-ink: #3157d5; --tab-soft: #e8edff; }
.acct-tab[data-tab="keys"]     { --tab-ink: #2d8653; --tab-soft: #e2f3e9; }
.acct-tab[data-tab="chat"]     { --tab-ink: #7b3fc4; --tab-soft: #f0e8fb; }
.acct-tab[data-tab="images"]   { --tab-ink: #c2557a; --tab-soft: #fbe8ef; }
.acct-tab[data-tab="stats"]    { --tab-ink: #b3720c; --tab-soft: #fdf0dc; }
.acct-tab[data-tab="realtime"] { --tab-ink: #0f7f8c; --tab-soft: #ddf2f4; }
.acct-tab[data-tab="history"]  { --tab-ink: #555860; --tab-soft: #eeeee8; }

.acct-tab:hover { border-color: var(--tab-ink, var(--line-strong)); }
.acct-tab.active {
  background: var(--tab-ink, var(--blue));
  border-color: var(--tab-ink, var(--blue));
  color: #fff;
}
.acct-tab:focus-visible { outline: 2px solid var(--tab-ink, var(--blue)); outline-offset: 2px; }
.acct-body { display: flex; flex-direction: column; gap: 16px; }

/* Mua nhanh credit (BUY A PLAN kiểu sh00t: hàng gói + giá + nút) */
.buy-list { display: flex; flex-direction: column; gap: 10px; }
.buy-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-low);
  transition: border-color 140ms ease;
}
.buy-row:hover { border-color: var(--line-strong); }
.buy-copy { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.buy-copy b { font-family: var(--font-display); font-weight: 700; font-size: 0.98rem; color: var(--dark); }
.buy-desc { font-family: var(--font-mono); font-size: 0.7rem; }
.buy-price { font-family: var(--font-serif); font-size: 1.3rem; color: var(--dark); white-space: nowrap; }
/* Nhãn CHỮ ở cột giá (vd "Trải nghiệm") vẽ bằng font-display, KHÔNG bằng font-serif.

   Instrument Serif không có glyph tiếng Việt, nên một nhãn có dấu bị vẽ bằng HAI font
   cùng lúc: chữ không dấu từ serif, chữ có dấu từ font dự phòng. Đo 21/08 trên chính
   trình duyệt: "Trải nghiệm" = 9 ký tự serif + 2 ký tự ("ả", "ệ") từ font khác. Mắt thấy
   ngay vì hai font khác cả nét lẫn chiều cao chữ x.

   Số tiền ("50.000đ") vẫn để font-serif: chữ số và "đ" (U+0111) đều CÓ trong Instrument
   Serif — đã đo — nên chúng vẽ trọn bằng một font, đúng dáng thiết kế muốn. */
.buy-price-name { font-family: var(--font-display); font-weight: 700; font-size: 1.05rem; }

/* Ô hiện key tạo sẵn lúc đăng ký (showFirstKeyModal).

   font-mono + user-select:all: khách bấm một lần là chọn trọn chuỗi, kể cả khi nút Copy
   không dùng được (clipboard API cần ngữ cảnh bảo mật, và portal có thể chạy sau HTTP thô
   trong LAN). Đây là lần duy nhất chuỗi key hiện ra nên phải còn đường copy tay.

   word-break: break-all để chuỗi dài không tràn ra ngoài hộp thoại trên màn hình hẹp. */
.firstkey-value {
  font-family: var(--font-mono);
  font-size: 0.92rem;
  padding: 12px 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-alt);
  color: var(--text);
  word-break: break-all;
  user-select: all;
}
.buy-btn { min-width: 76px; }

/* Analytics tab: 4 ô + 2 cột Top models | Daily usage */
.ana-grid { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.ana-cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); gap: 16px; align-items: start; }
@media (max-width: 900px) { .ana-cols { grid-template-columns: 1fr; } }
.top-models { display: flex; flex-direction: column; gap: 12px; }
.top-model { display: flex; flex-direction: column; gap: 5px; }
.top-model-line { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.top-model-rank { font-family: var(--font-mono); font-size: 0.68rem; color: var(--faint); }
.top-model-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 0.8rem;
  color: var(--dark);
}
.top-model-meta { font-family: var(--font-mono); font-size: 0.72rem; color: var(--faint); white-space: nowrap; }
.top-model-bar { height: 5px; border-radius: 999px; background: var(--bg-alt); overflow: hidden; }
.top-model-fill { height: 100%; border-radius: inherit; background: var(--blue); opacity: 0.8; }

/* ---- Tab Realtime: gom vào giữa 1240px như trang usage cũ + bảng kiểu cũ ---- */
.rt-wrap {
  width: min(100%, 1240px);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
/* Bảng đối soát trong live-panel: header dính nền xám xanh, min-width như
   credit-table-live cũ để cột không giãn quá xa nhau. */
.live-panel .usage-table { min-width: 860px; }
.live-panel .usage-table th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--bg-alt);
  color: var(--muted);
  border-bottom: 0;
  box-shadow: inset 0 -1px 0 var(--line);
}
/* Tiêu đề khối trong live-panel dùng cùng hệ .sec-title/.sec-title-sm với
   realtime bên trên; không ép nhỏ riêng để tránh lệch phông/scale toàn trang. */
.live-panel .sec-title { font-size: 1.2rem; }
.live-panel .usage-table-wrap { max-height: 620px; overflow-y: auto; }

/* ================= TAB REALTIME: y hệt trang usage cũ =================
   Kicker cam #ff952b, tiêu đề navy #17365d ngoài card, pill kỳ gradient xanh,
   KPI card trắng viền trái màu + số navy lớn. Chỉ phông giữ theo portal. */
.rt-section { display: flex; flex-direction: column; gap: 14px; }
.sec-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
}
.sec-copy { display: flex; flex-direction: column; gap: 4px; }
.sec-kicker {
  margin: 0;
  color: var(--blue);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.sec-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.5rem;
  line-height: 1.18;
  letter-spacing: -0.015em;
  color: var(--dark);
}
.sec-title-sm { font-size: 1.2rem; }
.sec-note {
  margin: 2px 0 0;
  max-width: 46ch;
  color: var(--muted);
  font-size: 0.88rem;
  line-height: 1.6;
}

/* Pill kỳ: cùng hệ phông/màu với dải gói tháng — trắng, viền mảnh, active xanh. */
.rt-section .pill-row { gap: 8px; }
.rt-section .pill {
  padding: 6px 16px;
  border-color: var(--line-strong);
  background: var(--surface);
  color: var(--muted);
  font-weight: 600;
}
.rt-section .pill:hover { border-color: var(--faint); background: var(--bg-alt); color: var(--text); }
.rt-section .pill.active {
  border-color: transparent;
  color: #fff;
  background: var(--blue);
  box-shadow: 0 4px 12px rgba(49, 87, 213, 0.3);
}

/* KPI card usage cũ: trắng, viền trái 4px màu luân phiên, phông giống gói tháng. */
.rt-wrap .stat-grid { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 14px; }
.rt-wrap .stat-card {
  position: relative;
  overflow: hidden;
  padding: 14px 16px 15px 18px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow);
  gap: 4px;
}
.rt-wrap .stat-card::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 4px;
  background: var(--blue);
}
.rt-wrap .stat-grid > .stat-card:nth-child(6n+2)::before { background: var(--ok); }
.rt-wrap .stat-grid > .stat-card:nth-child(6n+3)::before { background: var(--bad); }
.rt-wrap .stat-grid > .stat-card:nth-child(6n+4)::before { background: #34c48b; }
.rt-wrap .stat-grid > .stat-card:nth-child(6n+5)::before { background: #5fc8ef; }
.rt-wrap .stat-grid > .stat-card:nth-child(6n+6)::before { background: #8b5cf6; }
.rt-wrap .stat-grid > .stat-card:nth-child(6n+7)::before { background: var(--warn); }
.rt-wrap .stat-card .label-tiny { color: var(--faint); }
/* Số KPI dùng Instrument Serif cao–dẹt như giá gói tháng (user chốt 30/07):
   to hơn Manrope một chút cho cân với dáng serif. */
.rt-wrap .stat-value {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 2rem;
  line-height: 1.05;
  letter-spacing: 0;
  color: var(--dark);
}
.rt-wrap .stat-sub { color: var(--muted); }

/* Panel live: viền trên xanh dày như usage cũ, dùng token portal */
.live-panel {
  border-top: 3px solid var(--blue);
  border-radius: 12px;
  border-left: 1px solid var(--line);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow);
}
.live-head { align-items: flex-start; }
.live-panel .panel-body { padding: 0 18px 16px; }

/* Bảng đối soát: badge provider xanh nhạt chấm tròn, chip Ví xám, In/Out màu,
   badge Thành công viền xanh lá — cùng hệ token portal. */
.rt-wrap .usage-table td { color: var(--text); }
.rt-wrap .usage-table .cell-model b { color: var(--dark); }
.rt-wrap .prov-badge {
  color: var(--blue-ink);
  background: var(--blue-container);
  border: 1px solid rgba(49, 87, 213, 0.35);
}
.rt-wrap .prov-badge::before { background: var(--blue); box-shadow: none; }
.rt-wrap .prov-claude { color: var(--blue-ink); }
.rt-wrap .bucket-chip { background: var(--bg-alt); border-color: var(--line-strong); color: var(--muted); }
.rt-wrap .tok-in { color: var(--bad); }
.rt-wrap .tok-out { color: var(--ok); }
.rt-wrap .badge-active { color: var(--ok); background: #eafaf2; border-color: rgba(45, 134, 83, 0.4); }

/* ---- Thanh trượt tự chọn mức nạp (TOKEN TOP-UP kiểu sh00t) ---- */
.topup-box {
  margin-top: 14px;
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-low);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.topup-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.topup-right { text-align: right; }
.topup-amount {
  margin-top: 3px;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.8rem;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--dark);
}
.topup-total {
  margin-top: 3px;
  font-family: var(--font-serif);
  font-size: 1.8rem;
  line-height: 1;
  color: var(--blue-ink);
}
/* Ô THANH TOÁN cho gõ tay — giữ dáng .topup-total nhưng là input sửa được:
   căn phải, gạch chân mảnh để lộ rõ "gõ được", focus tô viền accent. */
.topup-total-input {
  margin-top: 3px;
  width: 100%;
  max-width: 220px;
  border: none;
  border-bottom: 1.5px dashed var(--line-strong, #c9cede);
  background: transparent;
  text-align: right;
  font-family: var(--font-serif);
  font-size: 1.8rem;
  line-height: 1.15;
  color: var(--blue-ink);
  font-variant-numeric: tabular-nums;
  padding: 0 0 2px;
  outline: none;
}
.topup-total-input:focus {
  border-bottom-color: var(--accent);
}
/* "Fable 5 khả dụng" tô xanh lá để nhấn: mức nạp tự chọn (ví credit) DÙNG được
   Fable 5, khác gói tháng (không gồm Fable 5). */
.topup-fable-ok { color: var(--ok); font-weight: 700; }

/* Dòng khuyến mãi dưới thanh trượt nạp: phần ĐANG ĐƯỢC hưởng tô xanh đậm để
   khách thấy ngay, phần gợi ý "nạp thêm để lên mốc" giữ màu mờ. */
.topup-promo {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px;
  min-height: 20px;
  padding-top: 2px;
  font-size: 0.82rem;
}
.topup-promo-hit { color: var(--ok); font-weight: 600; }

.topup-range {
  width: 100%;
  height: 5px;
  appearance: none;
  -webkit-appearance: none;
  border-radius: 999px;
  background: var(--line);
  outline: none;
  cursor: pointer;
}
.topup-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--blue);
  border: 3px solid #fff;
  box-shadow: 0 2px 8px rgba(49, 87, 213, 0.45);
  cursor: grab;
}
.topup-range::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--blue);
  border: 3px solid #fff;
  box-shadow: 0 2px 8px rgba(49, 87, 213, 0.45);
  cursor: grab;
}
.topup-scale {
  display: flex;
  justify-content: space-between;
  color: var(--faint);
  font-family: var(--font-mono);
  font-size: 0.7rem;
}
.topup-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding-top: 10px;
  border-top: 1px dashed var(--line);
}

/* ---- Gói tháng: grid card kiểu pricing sh00t (3 cột, giá serif lớn, hàng
   thông số mono căn 2 đầu, card "phổ biến" nền sáng hơn + viền xanh) ---- */
.plans-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
  gap: 14px;
}
.plan-cardx {
  display: flex;
  flex-direction: column;
  padding: 20px 20px 18px;
  border-radius: var(--radius-md);
  border: 1px solid var(--line);
  background: var(--surface);
  transition: border-color 160ms ease, transform 160ms ease, box-shadow 160ms ease;
}
.plan-cardx:hover { transform: translateY(-2px); border-color: var(--line-strong); box-shadow: var(--shadow); }
.plan-cardx.is-hot { border-color: var(--blue); background: var(--surface-low); }
.plan-cardx-head { display: flex; align-items: center; gap: 10px; }
.plan-cardx-name {
  font-family: var(--font-display);
  font-size: 1.12rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--dark);
}
.plan-hot {
  padding: 3px 9px;
  border-radius: 6px;
  background: var(--blue-container);
  color: var(--blue);
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.08em;
}
.plan-cardx-desc { margin: 6px 0 0; font-size: 0.86rem; }
.plan-cardx-price { margin-top: 16px; }
.plan-price-num {
  font-family: var(--font-serif);
  font-size: 2.1rem;
  line-height: 1;
  color: var(--dark);
}
.plan-cardx-term { margin: 7px 0 0; font-size: 0.78rem; }
.plan-specs {
  margin: 16px 0 18px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.plan-spec { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.plan-spec span { color: var(--muted); font-size: 0.83rem; }
.plan-spec b { font-family: var(--font-mono); font-size: 0.83rem; font-weight: 500; color: var(--text); }
.plan-buy { margin-top: auto; width: 100%; text-decoration: none; }

/* Gói 1,3,5 (is-tint): nền đậm hơn cho dải card đan xen đậm–nhạt. */
.plan-cardx.is-tint { background: var(--bg-alt); }
.plan-cardx.is-tint.is-hot { background: var(--blue-container); }

/* ---- Card VIP-Unlimited: nhấn màu tím + 3 nút giá + badge SẮP CÓ ---- */
.plan-cardx.is-vip { border-color: #7c5cff; box-shadow: 0 0 0 1px rgba(124, 92, 255, 0.12) inset; }
.plan-cardx.is-vip:hover { border-color: #6a45ff; }

/* Card VIP của OpenAI: teal thay cho tím Anthropic. Hai hãng nằm cạnh nhau trên
   cùng một hàng, cùng màu thì khách đọc thành ba biến thể của một sản phẩm. */
.plan-cardx.is-vip.is-openai {
  border-color: #10a37f;
  box-shadow: 0 0 0 1px rgba(16, 163, 127, 0.12) inset;
}
.plan-cardx.is-vip.is-openai:hover { border-color: #0d8a6a; }
.plan-cardx.is-vip.is-openai .vip-soon {
  background: rgba(16, 163, 127, 0.12);
  color: #0d8a6a;
}
.plan-cardx.is-vip.is-openai .vip-buy-btn { background: #10a37f; border-color: #10a37f; }
.plan-cardx.is-vip.is-openai .vip-buy-btn:hover { background: #0d8a6a; border-color: #0d8a6a; }
.plan-cardx.is-vip.is-openai .vip-buy-btn.is-disabled {
  background: var(--line);
  border-color: var(--line);
  color: var(--muted);
}
.plan-cardx.is-vip.is-openai .vip-price-num { color: #0d8a6a; }
.vip-soon {
  padding: 3px 9px;
  border-radius: 6px;
  background: rgba(124, 92, 255, 0.12);
  color: #6a45ff;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.08em;
}
/* HẾT SUẤT — đỏ, khác hẳn tím "SẮP CÓ": hai trạng thái này dẫn tới hành động khác
   nhau (chờ có người hết hạn vs chờ mở bán), nên không được trông giống nhau. */
.vip-soldout {
  padding: 3px 9px;
  border-radius: 6px;
  background: rgba(190, 54, 54, 0.12);
  color: var(--bad);
  border: 1px solid rgba(190, 54, 54, 0.3);
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.08em;
}
/* Số suất còn lại: thông tin thật + lý do mua sớm. Màu cảnh báo khi sắp hết. */
.vip-seats-left {
  margin: 8px 0 0;
  font-size: 0.8rem;
  color: var(--warn);
  font-weight: 600;
}
.vip-seats-out {
  margin: 8px 0 0;
  font-size: 0.8rem;
  color: var(--bad);
  font-weight: 600;
}
/* Đếm ngược tới lúc có suất: cùng màu đỏ "hết suất" (vẫn là trạng thái không mua
   được), nhưng số giờ để font mono cho khỏi nhảy bề rộng mỗi giây. */
.vip-countdown {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px;
  line-height: 1.5;
}
.vip-countdown-clock {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.vip-countdown-at {
  color: var(--muted);
  font-weight: 500;
}
.vip-active-note {
  margin: 8px 0 0;
  font-size: 0.8rem;
  color: #2d8653;
  font-weight: 600;
}
.vip-price-row { margin-top: 16px; display: flex; flex-direction: column; gap: 10px; }
/* Mỗi mốc giá = một ô xếp DỌC: hàng nhãn thời hạn + giá ở trên, nút Mua full-width
   ở dưới. Nhất quán mọi bề rộng, nút Mua luôn rõ ràng ở cuối, không bao giờ đè giá. */
.vip-price-item {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 14px;
  border-radius: 12px;
  background: rgba(106, 69, 255, 0.08);
  border: 1px solid rgba(106, 69, 255, 0.18);
}
.vip-price-item.is-disabled { background: var(--bg-alt); border-color: var(--line); }
.vip-price-copy {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.vip-buy-btn {
  width: 100%;
  background: #6a45ff;
  border-color: #6a45ff;
}
.vip-buy-btn:hover { background: #5a37e0; border-color: #5a37e0; }
.vip-buy-btn.is-disabled { background: var(--line); border-color: var(--line); color: var(--muted); cursor: not-allowed; }
.vip-price-dur { font-weight: 700; color: var(--dark); }
.vip-price-num { font-family: var(--font-mono); font-size: 0.95rem; color: var(--blue-ink); font-weight: 600; }

/* ---- Wizard mua VIP ---- */
.vip-buy-summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  padding: 14px 0 16px;
  border-bottom: 1px solid var(--line);
}
.vip-buy-price { font-family: var(--font-serif); font-size: 1.6rem; line-height: 1; color: #6a45ff; white-space: nowrap; }
.vip-nokey { padding: 18px 0 4px; display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }
.vip-nokey p { margin: 0; color: var(--muted); }
.vip-key-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.vip-key-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color 140ms ease, background 140ms ease;
}
.vip-key-row:hover { border-color: var(--line-strong); background: var(--bg-alt); }
.vip-key-name { flex: 1; font-weight: 600; color: var(--text); }
.vip-key-has { font-size: 0.78rem; color: #2d8653; font-weight: 600; }

/* ---- Khối "Sinh lệnh cài đặt" (tab API Keys) ---- */
.setup-apps {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 14px;
}
.setup-app {
  padding: 9px 16px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--muted);
  font-family: inherit;
  font-size: 0.84rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 140ms ease, color 140ms ease, background 140ms ease;
}
.setup-app:hover { border-color: var(--faint); color: var(--text); }
.setup-app.active {
  border-color: transparent;
  color: #fff;
  background: var(--blue);
  box-shadow: 0 4px 12px rgba(49, 87, 213, 0.3);
}
.setup-pane { display: flex; flex-direction: column; gap: 12px; }
.setup-controls { display: flex; gap: 14px; flex-wrap: wrap; }
.setup-field { display: flex; flex-direction: column; gap: 5px; min-width: 220px; flex: 1; }
.setup-select {
  min-height: 40px;
  padding: 8px 12px;
  border-radius: 12px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 0.86rem;
}
/* Clip hướng dẫn Claude Desktop: khung 16:9, nền tối cho lúc chưa tải poster */
.setup-video-wrap { max-width: 720px; }
.setup-video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 12px;
  background: #0b1020;
  border: 1px solid var(--line-strong);
}

/* Mốc auto-compact: thanh trượt + ô nhập số, dùng lại thumb của .topup-range */
.setup-compact {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--surface-soft, rgba(127, 143, 178, 0.06));
}
.setup-compact-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.setup-compact-hint {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--blue);
}
.setup-compact-row {
  display: flex;
  align-items: center;
  gap: 14px;
}
.setup-compact-row .setup-range { flex: 1; min-width: 0; }
.setup-compact-num {
  width: 128px;
  flex: none;
  font-family: var(--font-mono);
  text-align: right;
}
.setup-compact .setup-note { font-size: 0.8rem; }
@media (max-width: 560px) {
  .setup-compact-row { flex-wrap: wrap; }
  .setup-compact-num { width: 100%; text-align: left; }
}

.setup-outwrap { position: relative; }
.setup-out { margin: 0; padding-right: 100px; white-space: pre-wrap; word-break: break-all; }
.setup-copy {
  position: absolute;
  top: 10px;
  right: 10px;
  min-height: 30px;
  padding: 4px 12px;
  font-size: 0.76rem;
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.25);
  color: #d7e0ee;
}
.setup-copy:hover { background: rgba(255, 255, 255, 0.16); border-color: rgba(255, 255, 255, 0.4); color: #fff; }
.setup-note { margin: 0; font-size: 0.84rem; line-height: 1.55; }
.setup-steps {
  margin: 0;
  padding-left: 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  color: var(--text);
  font-size: 0.9rem;
  line-height: 1.6;
}
.setup-inline-code {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  padding: 1px 7px;
  border-radius: 6px;
  background: var(--blue-container);
  color: var(--blue-ink);
}
/* Ô cảnh báo trong danh sách bước cài: dùng cho cái bẫy ExecutionPolicy của
   Windows — khách gặp "running scripts is disabled" rất dễ tưởng key sai. */
.setup-note-warn {
  margin-top: 2px;
  padding: 9px 12px;
  border-left: 3px solid var(--warn);
  border-radius: 0 8px 8px 0;
  background: color-mix(in oklab, var(--warn) 9%, transparent);
  font-size: 0.84rem;
  line-height: 1.55;
  list-style: none;
}
.setup-note-warn b { color: var(--text); }

.setup-shot { margin: 10px 0 0; }
.setup-shot img {
  display: block;
  max-width: min(100%, 560px);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.setup-shot figcaption { margin-top: 5px; color: var(--faint); font-size: 0.76rem; }

/* ---- Video hướng dẫn cài Codex (đầu nội dung TAB CODEX, dưới hàng 4 nút) ----
 *
 * ⛔ CHỈ TAB CODEX: clip quay đúng thao tác cài Codex, tab khác dùng là chỉ sai
 * việc (tab Claude Desktop vốn đã có clip riêng của nó).
 *
 * ⛔ TÊN CLASS KHÔNG ĐƯỢC LÀ `.setup-video`: tên đó ĐÃ DÙNG ở trên cho chính THẺ
 * <video> của clip Claude Desktop. Bản đầu của khối này đặt `.setup-video` lên
 * thẻ <figure> BỌC NGOÀI, nên figure thừa hưởng `width:100%` + `aspect-ratio:16/9`
 * + `background:#0b1020` của rule kia ⇒ figure rộng cả panel (~1900px) hoá cao
 * ~1070px: một khối navy chiếm gần hết trang, video 720px lọt ở góc trên. Đó là
 * hình khách đã thấy. Giữ tiền tố `setup-guide-` riêng để không tái diễn.
 *
 * File 12,5 MB nằm ở /assets/setup-demo/ do CADDY phục vụ, KHÔNG đi qua
 * go:embed — nên đổi video không cần build exe. `preload="metadata"` trong HTML
 * làm trình duyệt chỉ tải vài KB đầu để biết thời lượng; đo thật: moov atom ở
 * byte 60 nên metadata đọc được ngay, và Caddy trả 206 Partial Content nên tua
 * được mà không tải cả file.
 *
 * max-width 720px và viền/nền lấy ĐÚNG theo clip Claude Desktop
 * (.setup-video-wrap ở trên) để hai video trong cùng trang không lệch cỡ nhau.
 * aspect-ratio giữ chỗ TRƯỚC khi metadata về — thiếu nó thì <video> cao 0px rồi
 * trang giật một nhịp khi biết kích thước thật (CLS), khách thấy là "trang nhảy".
 */
.setup-guide-video {
  margin: 0 0 14px;
  max-width: 720px;
}
.setup-guide-video video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 12px;
  background: #0b1020;
  border: 1px solid var(--line-strong);
}
.setup-guide-video figcaption {
  margin-top: 6px;
  /* --muted (#555860, 6,7:1) chứ không --faint (#84868c, 3,39:1 — dưới AA 4,5).
   * Chú thích của .setup-shot là nhãn phụ cho ảnh nên --faint hợp, còn dòng này
   * là CHỈ DẪN HÀNH ĐỘNG ("chọn app bạn dùng ở hàng nút phía dưới") — khách phải
   * đọc được nó mới biết bước tiếp theo. Đã đo tương phản trên nền #f7f7f3. */
  color: var(--muted);
  font-size: 0.78rem;
}
.setup-guide-video-title {
  display: block;
  margin-bottom: 8px;
  color: var(--text);
  font-size: 0.9rem;
  font-weight: 600;
}

/* ---- Khung terminal sinh lệnh: bar 3 chấm + thân gradient navy + glow ---- */
.setup-term {
  border-radius: 14px;
  overflow: hidden;
  border: 1px solid rgba(49, 87, 213, 0.25);
  box-shadow: 0 16px 40px -18px rgba(23, 40, 90, 0.45);
  transition: box-shadow 200ms ease, border-color 200ms ease;
}
.setup-term:hover {
  border-color: rgba(49, 87, 213, 0.45);
  box-shadow: 0 20px 48px -18px rgba(49, 87, 213, 0.5);
}
.setup-term-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  background: linear-gradient(180deg, #1d2740, #16203a);
  border-bottom: 1px solid rgba(120, 150, 230, 0.18);
}
.setup-dots { display: inline-flex; gap: 6px; }
.setup-dots i { width: 11px; height: 11px; border-radius: 50%; display: inline-block; }
.setup-dots .d-red { background: #ff5f57; }
.setup-dots .d-yellow { background: #febc2e; }
.setup-dots .d-green { background: #28c840; }
.setup-term-title {
  flex: 1;
  color: #8fa3cc;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.setup-term .setup-copy {
  position: static;
  min-height: 26px;
  padding: 3px 12px;
  font-size: 0.74rem;
  border-radius: 8px;
}
.setup-term-body {
  margin: 0;
  padding: 16px 18px;
  background:
    radial-gradient(circle at 90% -30%, rgba(95, 200, 239, 0.14), transparent 42%),
    linear-gradient(150deg, #131c33 0%, #0f1830 55%, #101f3f 100%);
  color: #dbe6ff;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  line-height: 1.7;
  white-space: pre-wrap;
  word-break: break-all;
  position: relative;
}
/* Dấu nhắc $ xanh trước lệnh */
.setup-term-body code::before {
  content: "$ ";
  color: #5fc8ef;
  font-weight: 600;
}

/* Ảnh demo sau hướng dẫn Claude Code / Codex: rộng hơn ảnh bước */
.setup-shot-demo { margin-top: 14px; }
.setup-shot-demo img { max-width: min(100%, 760px); }

/* ================= Ô VÍ REQUEST TẶNG (ô thứ 4 hàng ví) =================
   Ví chỉ-đọc: viền trái tím để phân biệt với 3 ví tiêu tiền, kèm khối
   "Cách dùng" hướng dẫn chọn model trong Claude Desktop / Claude Code. */
.gift-card { border-left: 3px solid #8b5cf6; }
.stat-value.stat-gift { color: #7c3aed; }
/* Gợi ý cách dùng: MỘT dòng phẳng, không khung viền. Bản cũ là khối bọc viền
   tím 3 dòng cao ~108px, kéo ô này cao gấp 3 các ô ví còn lại. */
.gift-how {
  margin-top: 2px;
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  font-size: 0.73rem;
  line-height: 1.4;
  color: var(--muted);
}
.gift-how code {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  padding: 1px 5px;
  border-radius: 5px;
  background: #fff;
  border: 1px solid rgba(139, 92, 246, 0.28);
  color: #6d28d9;
}

/* ================= CHAT AI (tab trong Hồ sơ, kiểu Notion AI) =================
   Cột hội thoại cuộn + composer dính đáy. Phông/màu theo token portal, giữ
   dáng bong bóng + thanh công cụ như Notion nhưng ở tông sáng. */
/* ---- KHUNG CHAT CUỘN RIÊNG: khoá chiều cao TRỌN CHUỖI cha ----
 *
 * # LỖI ĐÃ ĐO ĐƯỢC
 *
 * Đo 21/08 ở 1440x900 với 30 tin nhắn: .chat-thread cao 3116px (giãn theo nội dung),
 * trang cuộn được (scrollHeight 3368 > clientHeight 900), và .chat-thread KHÔNG cuộn riêng
 * dù có overflow-y:auto. Khách phải lăn cả trang web để đọc lại đoạn trên, và khung soạn
 * trôi mất khỏi màn hình.
 *
 * # VÌ SAO overflow-y:auto MỘT MÌNH KHÔNG ĐỦ
 *
 * overflow chỉ sinh thanh cuộn khi phần tử BỊ GIỚI HẠN chiều cao. Ở đây không mắt nào
 * trong chuỗi cha đặt trần, nên .chat-thread cứ giãn và không bao giờ "tràn".
 *
 * Chuỗi cha: body → .shell → .app-main → .view → .page → .chat-wrap → .chat-main →
 * .chat-thread. Bản vá trước chỉ làm .page và .acct-body — nửa chuỗi. Ba mắt còn hỏng, đo
 * bằng getComputedStyle:
 *
 *	.view      min-height: auto   → flex item giãn theo nội dung, KHÔNG co lại được
 *	.app-main  min-height: auto   → cùng lỗi
 *	.shell     min-height: 1000px, flex: 0 1 auto → chỉ đặt SÀN, không đặt TRẦN
 *
 * min-height:auto là mặc định của flex item và là mắt đứt phổ biến nhất: mọi mắt trung
 * gian phải min-height:0 mới cho con co lại được.
 *
 * # VÌ SAO DÙNG :has(.chat-wrap)
 *
 * Khoá chiều cao body/shell là thay đổi TOÀN TRANG. Chỉ trang Chat cần nó; các trang khác
 * (bảng giá, lịch sử, hồ sơ) phải cuộn bình thường theo nội dung. :has() giới hạn phạm vi
 * đúng bằng "trang đang có khung chat" — cùng cách bản vá trước đã dùng, chỉ làm nốt.
 *
 * # 100dvh, KHÔNG PHẢI 100vh
 *
 * dvh trừ luôn thanh địa chỉ động của trình duyệt di động; 100vh trên iOS Safari tính cả
 * phần bị thanh đó che, nên khung soạn nằm dưới vạch nhìn thấy. Chia 0.9 vì body có
 * zoom:.9 (xem chú thích ở .shell) — không chia thì khung thiếu đúng 10% chiều cao. */
body:has(.chat-wrap) {
  /* height, KHÔNG phải min-height: min-height cho phép giãn thêm, mà giãn thêm chính là
   * thứ làm cả trang cuộn. */
  height: calc(100dvh / 0.9);
  overflow: hidden;
}
.shell:has(.chat-wrap) { height: 100%; min-height: 0; }
.app-main:has(.chat-wrap) { min-height: 0; }
.view:has(.chat-wrap) { min-height: 0; overflow: hidden; }
.page:has(.chat-wrap) { flex: 1; min-height: 0; }
.acct-body:has(.chat-wrap) { flex: 1; min-height: 0; }
/* Trang Chat: giảm padding đáy để khung soạn nằm sát footer hơn. */
.view:has(.chat-wrap) { padding-bottom: 18px; }
/* .chat-thread bỏ min-height:240px khi ở trong chuỗi đã khoá.
 *
 * 240px là sàn hợp lý khi khung tự do giãn, nhưng ở đây nó thành SÀN CỨNG: trên màn hình
 * thấp (hoặc khi bàn phím di động chiếm nửa dưới) nó ép khung cao hơn chỗ còn lại và đẩy
 * khung soạn ra ngoài vùng thấy được. */
.chat-wrap .chat-thread { min-height: 0; }
/* Bố cục Chat: sidebar phiên (trái) + vùng chính (phải). Giãn đầy chiều cao. */
.chat-wrap {
  display: grid;
  grid-template-columns: 248px minmax(0, 1fr);
  gap: 18px;
  flex: 1;
  min-height: 0;
}
/* Khung chat LẤP TRỌN cột của nó.
 *
 * Bản trước: width: min(100%, 1080px) + margin: 0 auto — nhưng .chat-main nằm TRONG
 * cột 1fr của .chat-wrap, nên trên màn rộng nó tự bó lại 1080px rồi CĂN GIỮA phần
 * còn lại. Đo 1990px: sidebar hết ở 295, khung chat mới bắt đầu ở 600 — một khoảng
 * TRỐNG 305px nằm ngay cạnh sidebar, và 320px nữa ở mép phải. Trống hai bên vì
 * cùng một dòng lệnh.
 *
 * Giờ khung (thread + ô nhập) lấp trọn cột, dính sidebar. Bề rộng ĐỌC được giữ ở
 * tầng bong bóng chứ không ở tầng khung — xem .chat-msg-assistant .chat-bubble. */
.chat-main {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-height: 0;
  width: 100%;
  margin: 0;
}

/* Sidebar phiên chat (kiểu Notion): nút tạo mới trên, danh sách cuộn dưới. */
.chat-sidebar {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
  padding-right: 4px;
  border-right: 1px solid var(--line);
}
.chat-ses-new {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 140ms ease, background 140ms ease;
}
.chat-ses-new:hover { border-color: var(--blue); background: var(--blue-container); color: var(--blue-ink); }
.chat-ses-new-ico { width: 15px; height: 15px; flex-shrink: 0; }
.chat-ses-new-ico svg { width: 100%; height: 100%; }
.chat-ses-list { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.chat-ses-group {
  padding: 8px 8px 4px;
  color: var(--faint);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.chat-ses-empty { padding: 12px 8px; color: var(--faint); font-size: 0.82rem; }
.chat-ses-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 9px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--muted);
  transition: background 130ms ease, color 130ms ease;
}
.chat-ses-item:hover { background: var(--bg-alt); color: var(--text); }
.chat-ses-item.active { background: var(--blue-container); color: var(--blue-ink); }
.chat-ses-ico { width: 15px; height: 15px; flex-shrink: 0; opacity: 0.8; }
.chat-ses-ico svg { width: 100%; height: 100%; }
.chat-ses-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.83rem;
}
.chat-ses-del {
  border: 0;
  background: transparent;
  color: var(--faint);
  font-size: 1.05rem;
  line-height: 1;
  padding: 0 3px;
  cursor: pointer;
  opacity: 0;
  flex-shrink: 0;
}
.chat-ses-item:hover .chat-ses-del { opacity: 1; }
.chat-ses-del:hover { color: var(--bad); }

.chat-hint {
  padding: 9px 13px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--bg-alt);
  color: var(--muted);
  font-size: 0.82rem;
}
.chat-thread {
  flex: 1;
  min-height: 240px;
  overflow-y: auto;
  padding: 6px 4px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.chat-empty {
  margin: auto;
  /* 460px, không phải 420px: khối này giờ mang thêm hai đoạn lưu ý về tệp (.chat-empty-note).
     Giữ 420 sẽ bó chúng thành cột hẹp và mỗi đoạn tràn ra 5-6 dòng. */
  max-width: 460px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  color: var(--muted);
}
.chat-empty-ico {
  width: 46px;
  height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 11px;
  border-radius: 14px;
  background: var(--blue-container);
  color: var(--blue);
}
.chat-empty-ico svg { width: 100%; height: 100%; }
.chat-empty-title { margin: 0; font-family: var(--font-display); font-weight: 700; font-size: 1.15rem; color: var(--dark); }
.chat-empty-desc { margin: 0; font-size: 0.9rem; line-height: 1.6; }
/* Hộp ghi chú về tệp, dưới phần lời mời.
 *
 * # VÌ SAO PHẢI LÀ MỘT HỘP CÓ NỀN
 *
 * Phần trên (.chat-empty-title + .chat-empty-desc) căn GIỮA. Hai đoạn ghi chú thì phải căn
 * TRÁI — chúng dài, và chữ căn giữa nhiều dòng buộc mắt tìm lại đầu dòng mỗi lần xuống hàng.
 *
 * Nhưng để hai kiểu căn cạnh nhau TRẦN trong cùng một khối thì mép trái so le, và nó đọc
 * thành "xiên vẹo" — đúng như chủ hệ thống chỉ ra khi xem bản đầu. Nền + viền biến chỗ đổi
 * kiểu căn thành ranh giới CÓ CHỦ Ý: mắt nhận ra đây là khối khác nên không so mép trái của
 * nó với dòng phía trên nữa. */
.chat-empty-tips {
  width: 100%;
  margin-top: 4px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-low);
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.chat-empty-note {
  margin: 0;
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--faint);
}
.chat-empty-note b { color: var(--muted); font-weight: 600; }

/* Bề rộng ĐỌC được đặt ở hàng tin, không ở khung: khung lấp trọn cột (ô nhập trải
 * hết bề ngang), còn CHỮ giữ một cữ đọc dễ. Bỏ cữ này thì trên màn 1990px một dòng
 * văn xuôi dài ~200 ký tự — mắt mất dấu đầu dòng khi xuống dòng.
 *
 * Cắt ở HÀNG (không cắt riêng bong bóng) để tin của khách căn phải theo CÙNG cữ với
 * chữ trợ lý. Cắt riêng bong bóng thì tin khách bay ra tận mép phải màn hình, cách
 * chữ trợ lý cả nửa gang tay. */
.chat-msg { display: flex; gap: 10px; max-width: min(100%, 1180px); }
.chat-msg-user { justify-content: flex-end; }
.chat-avatar {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px;
  border-radius: 50%;
}
.chat-avatar-ai { background: var(--blue); color: #fff; }
.chat-avatar svg { width: 100%; height: 100%; }
.chat-bubble {
  max-width: 78%;
  padding: 11px 15px;
  border-radius: 16px;
  font-size: 0.92rem;
  line-height: 1.62;
  white-space: pre-wrap;
  word-break: break-word;
}
.chat-msg-user .chat-bubble {
  background: var(--contrast-surface);
  color: #fff;
  border-bottom-right-radius: 5px;
}
/* Trong .chat-stack, 78% tính theo cột (đã hẹp hơn hàng) nên bong bóng bị bó thêm
   một lần nữa. Cột đã giữ lề phải, nên ở đây trả về 100%. */
.chat-stack .chat-bubble { max-width: 100%; }
.chat-msg-assistant .chat-bubble {
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--text);
  border-bottom-left-radius: 5px;
}

/* Cột nội dung của tin nhắn trợ lý: khối suy nghĩ, dòng hoạt động, bong bóng và
   thẻ tải xếp dọc. min-width:0 để chữ dài vẫn ngắt dòng được trong flex row. */
.chat-stack {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
  flex: 1 1 auto;
}

/* Markdown trong bong bóng trả lời.
   Bong bóng thường dùng white-space: pre-wrap để giữ ngắt dòng của văn bản thuần; bản
   Markdown đã có thẻ khối riêng nên phải TẮT nó, không thì mỗi dòng nguồn thành một
   dòng trống thừa. */
.chat-bubble.chat-md { white-space: normal; }
.chat-md > *:first-child { margin-top: 0; }
.chat-md > *:last-child { margin-bottom: 0; }
.chat-md .md-p { margin: 0 0 9px; }
.chat-md .md-h {
  margin: 14px 0 7px;
  font-weight: 700;
  line-height: 1.35;
}
/* Tiêu đề của model nằm TRONG một bong bóng chat, nên nhỏ hơn tiêu đề trang: h3 của
   model to bằng tiêu đề trang sẽ át cả bố cục. */
.chat-md h3.md-h { font-size: 1rem; }
.chat-md h4.md-h { font-size: 0.94rem; }
.chat-md h5.md-h, .chat-md h6.md-h { font-size: 0.88rem; color: var(--muted); }
.chat-md .md-list { margin: 0 0 9px; padding-left: 20px; }
.chat-md .md-list li { margin: 3px 0; }
.chat-md .md-hr { margin: 12px 0; border: 0; border-top: 1px solid var(--line); }
.chat-md .md-quote {
  margin: 0 0 9px;
  padding: 6px 11px;
  border-left: 3px solid var(--line-strong);
  background: var(--bg-alt);
  color: var(--muted);
}
.chat-md code {
  padding: 1px 5px;
  border-radius: 5px;
  background: var(--bg-alt);
  border: 1px solid var(--line);
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.86em;
}
.chat-md .md-pre {
  margin: 0 0 9px;
  padding: 10px 12px;
  border-radius: 9px;
  background: var(--code-surface);
  overflow-x: auto;
}
.chat-md .md-pre code {
  padding: 0;
  border: 0;
  background: none;
  color: #e8e8e3;
  font-size: 0.82rem;
  line-height: 1.55;
}
.chat-md .md-table {
  margin: 0 0 10px;
  border-collapse: collapse;
  width: 100%;
  font-size: 0.86rem;
  /* Bảng giá thường có số dài; cho cuộn ngang thay vì ép cột hẹp đến mức xuống dòng
     giữa con số. */
  display: block;
  overflow-x: auto;
  white-space: nowrap;
}
.chat-md .md-table th, .chat-md .md-table td {
  padding: 6px 10px;
  border: 1px solid var(--line);
  text-align: left;
}
.chat-md .md-table th { background: var(--bg-alt); font-weight: 700; }
.chat-md .md-table tbody tr:nth-child(even) { background: var(--surface-low); }
/* Số liệu dễ so sánh theo cột khi cùng bề rộng chữ số. */
.chat-md .md-table td { font-variant-numeric: tabular-nums; }
.chat-md a { color: var(--blue); text-decoration: underline; text-underline-offset: 2px; }
.chat-md a:hover { color: var(--accent-deep); }
.chat-md strong { font-weight: 700; color: var(--text); }

/* Ba đốm "đang gõ" trong bong bóng trả lời còn rỗng.

   Đây là thứ DUY NHẤT lấp quãng chờ token đầu. Đường /v1 không gửi dấu vết tool nào
   (khối suy nghĩ và dòng "đang đọc trang…" đã bỏ cùng nguồn Notion), và quãng chờ đó
   có thể tới 95 giây khi key đang xếp hàng RPM — không có gì ở đây thì khách nhìn một
   ô trắng và kết luận là web hỏng. */
.chat-bubble.chat-typing {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 0;
  padding: 12px 14px;
}
.chat-typing-dot {
  width: 7px;
  height: 7px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--faint);
  /* Chỉ animate opacity/transform để giữ trên compositor: khối này sống suốt quãng
     chờ nên không được gây reflow. */
  animation: chat-typing-bounce 1.25s ease-in-out infinite;
}
.chat-typing-dot:nth-child(2) { animation-delay: 0.18s; }
.chat-typing-dot:nth-child(3) { animation-delay: 0.36s; }
@keyframes chat-typing-bounce {
  0%, 100% { opacity: 0.3; transform: translateY(0); }
  40% { opacity: 1; transform: translateY(-3px); }
}
/* Người bật giảm-chuyển-động thì bỏ nhịp nhảy, giữ ba đốm tĩnh — vẫn đủ nói "đang chờ". */
@media (prefers-reduced-motion: reduce) {
  .chat-typing-dot { animation: none; opacity: 0.55; }
}

/* Composer: khung bo lớn, textarea trên, thanh công cụ dưới (trái: +/web,
   phải: model + gửi) — bố cục đúng Notion. */
.chat-composer {
  position: relative;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: var(--shadow);
  padding: 12px 14px 10px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.chat-composer:focus-within { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(49, 87, 213, 0.12); }

/* Chip tệp đang đính kèm, nằm TRÊN ô nhập trong khung soạn. */
.chat-attach-row { display: flex; flex-wrap: wrap; gap: 7px; }
.chat-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px 4px 9px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-alt);
  font-size: 0.76rem;
  color: var(--muted);
  max-width: 260px;
}
/* Đang đọc tệp: làm mờ để phân biệt với tệp đã sẵn sàng.
 *
 * Cần dấu hiệu THẤY ĐƯỢC vì send() chặn khi còn tệp chưa đọc xong — không có nó thì khách
 * bấm gửi, bị chặn, và không hiểu vì sao. */
.chat-chip.is-loading { opacity: 0.6; }
.chat-chip-ico { width: 13px; height: 13px; flex-shrink: 0; }
.chat-chip-ico svg { width: 100%; height: 100%; }
.chat-chip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-chip-size { flex-shrink: 0; color: var(--faint); font-size: 0.7rem; }
.chat-chip-x {
  border: 0; background: transparent; cursor: pointer;
  color: var(--faint); font-size: 1rem; line-height: 1; padding: 0 2px;
}
.chat-chip-x:hover { color: var(--bad); }

/* Tên tệp hiện lại TRONG bong bóng tin nhắn của khách, sau khi đã gửi. */
.chat-msg-files { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.chat-msg-file {
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.16);
  font-size: 0.72rem;
  opacity: 0.9;
}
.chat-input {
  width: 100%;
  border: 0;
  outline: none;
  resize: none;
  background: transparent;
  color: var(--text);
  font-family: inherit;
  font-size: 0.95rem;
  line-height: 1.6;
  max-height: 200px;
}
.chat-composer-bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.chat-tools-left, .chat-tools-right { display: flex; align-items: center; gap: 8px; }
.chat-tool-wrap { position: relative; }
.chat-tool-btn {
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
  transition: border-color 140ms ease, color 140ms ease, background 140ms ease;
}
.chat-tool-btn svg { width: 100%; height: 100%; }
.chat-tool-btn:hover { color: var(--text); border-color: var(--line-strong); background: var(--bg-alt); }

/* Công tắc TÌM WEB đang BẬT phải thấy rõ: mỗi lượt tìm là tiền thật trả cho nhà cung
   cấp, nên một nút hai trạng thái trông giống nhau là nút khiến người ta tra web mà
   không biết mình đang tra. */
.chat-tool-btn.is-on {
  color: var(--blue);
  border-color: rgba(49, 87, 213, 0.45);
  background: var(--blue-container);
}

/* Dòng "đang làm gì" trong bong bóng đang gõ ("Đang tìm trên web…"). Cùng hàng với ba
   đốm nên cần khoảng thở bên phải. */
.chat-typing-what {
  margin-right: 8px;
  color: var(--muted);
  font-size: 0.86rem;
}

/* Nút chọn model + dropdown chia nhóm */
.chat-model-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
}
.chat-model-btn:hover { border-color: var(--line-strong); background: var(--bg-alt); }
.chat-model-btn .chat-mico { width: 18px; height: 18px; padding: 3px; }
.chat-model-caret { width: 13px; height: 13px; color: var(--faint); }
.chat-model-caret svg { width: 100%; height: 100%; }
/* Bảng chọn mô hình: HAI CỘT — nhóm bên trái, danh sách + ô tìm bên phải.
   Hai nhóm có danh mục model khác nhau hoàn toàn nên chúng là hai ngữ cảnh song song,
   không phải hai bộ lọc của cùng một danh sách; cột trái thể hiện đúng quan hệ đó và
   giữ nhóm luôn nhìn thấy khi cuộn danh sách dài. */
.chat-mm-left {
  flex: 0 0 138px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 6px;
  border-right: 1px solid var(--line);
  background: var(--surface-low);
}
.chat-mm-title {
  padding: 3px 8px 7px;
  color: var(--faint);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.chat-mm-tick { display: inline-flex; width: 13px; height: 13px; flex: 0 0 auto; color: var(--blue); }
.chat-mm-tick svg { width: 100%; height: 100%; }

/* Chọn API key. Mỗi key được cấp một tập model riêng, nên đây là thông tin quyết định
   "model này gọi được không". */
.chat-mm-key {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 9px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: none;
  font: inherit;
  font-size: 0.76rem;
  color: var(--muted);
  text-align: left;
  cursor: pointer;
}
.chat-mm-key:hover { background: var(--bg-alt); color: var(--text); }
.chat-mm-key.is-on { background: var(--surface); border-color: var(--line-strong); color: var(--text); }
.chat-mm-key-name { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-mm-key-tag {
  flex: 0 0 auto;
  padding: 0 4px;
  border-radius: 999px;
  background: rgba(49, 87, 213, 0.1);
  color: var(--blue);
  font-size: 0.62rem;
  font-weight: 700;
}
/* Danh sách model được cấp: chữ nhỏ, xuống dòng được — đây là nội dung để ĐỌC, không
   phải nhãn, nên không cắt bằng ellipsis. */
.chat-mm-key-models {
  padding: 2px 9px 7px;
  color: var(--faint);
  font-size: 0.68rem;
  line-height: 1.45;
  word-break: break-word;
}
.chat-mm-right { flex: 1 1 auto; display: flex; flex-direction: column; min-width: 0; }
.chat-mm-searchwrap {
  position: relative;
  padding: 8px 8px 6px;
  border-bottom: 1px solid var(--line);
}
.chat-mm-searchico {
  position: absolute;
  left: 17px;
  top: 50%;
  transform: translateY(-45%);
  width: 14px;
  height: 14px;
  color: var(--faint);
  pointer-events: none;
}
.chat-mm-searchico svg { width: 100%; height: 100%; }
.chat-mm-search {
  width: 100%;
  padding: 7px 10px 7px 30px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg-alt);
  font: inherit;
  font-size: 0.8rem;
  color: var(--text);
}
.chat-mm-search:focus {
  outline: none;
  border-color: var(--blue);
  background: var(--surface);
}
.chat-mm-search::placeholder { color: var(--faint); }
.chat-mm-list { flex: 1 1 auto; overflow-y: auto; padding: 4px; }
/* Giá từng model, đẩy sát phải trước dấu tích. */
.chat-model-price {
  margin-left: auto;
  padding-left: 8px;
  color: var(--faint);
  font-size: 0.68rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.chat-model-empty {
  padding: 18px 10px;
  color: var(--faint);
  font-size: 0.82rem;
  text-align: center;
}
/* Nhãn nhóm + hệ số trên nút chọn model, nhỏ hơn tên model để không tranh thứ tự đọc. */
/* Chưa chọn mô hình (vừa đổi nhóm): viền gạch để thấy đây là việc còn phải làm, chứ
   không phải một lựa chọn đã xong. */
.chat-model-btn.is-unset {
  border-style: dashed;
  border-color: var(--warn);
}
.chat-model-btn.is-unset .chat-model-name { color: var(--warn); }
.chat-model-src {
  padding: 2px 6px;
  border-radius: 999px;
  background: var(--surface-low);
  border: 1px solid var(--line);
  color: var(--faint);
  font-size: 0.68rem;
  font-weight: 600;
  white-space: nowrap;
}

.chat-model-menu {
  position: absolute;
  bottom: calc(100% + 8px);
  right: 0;
  /* Hai cột nên cần rộng hơn bản một cột (288px): 138px cột nhóm + chỗ cho tên model
     kèm giá. Kẹp theo viewport để không tràn màn hình hẹp. */
  width: min(520px, calc(100vw - 32px));
  max-height: 400px;
  /* Cuộn nằm ở cột phải (.chat-mm-list), không ở đây — nếu để ở đây thì cột nhóm sẽ
     cuộn đi mất khi lướt danh sách model dài. */
  overflow: hidden;
  display: flex;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: var(--shadow-hover);
  z-index: 20;
}
.chat-model-group {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 10px 5px;
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.chat-model-group .chat-mico { width: 17px; height: 17px; padding: 3px; }
.chat-model-item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font-family: inherit;
  font-size: 0.85rem;
  text-align: left;
  cursor: pointer;
}
.chat-model-item:hover { background: var(--bg-alt); }
.chat-model-item.active { color: var(--blue); font-weight: 600; }
.chat-model-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-model-check { width: 15px; height: 15px; color: var(--blue); flex-shrink: 0; }
.chat-model-check svg { width: 100%; height: 100%; }

.chat-send {
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px;
  border: 0;
  border-radius: 10px;
  background: var(--blue);
  color: #fff;
  cursor: pointer;
  transition: filter 140ms ease;
}
.chat-send svg { width: 100%; height: 100%; }
.chat-send:hover { filter: brightness(1.08); }

@media (max-width: 720px) {
  .chat-wrap { grid-template-columns: 1fr; }
  .chat-sidebar {
    border-right: 0;
    border-bottom: 1px solid var(--line);
    padding: 0 0 10px;
    max-height: 168px;
  }
}
@media (max-width: 560px) {
  .chat-model-name { max-width: 92px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .chat-thread { min-height: 200px; }
}

/* ================= THÔNG BÁO ADMIN: chuông + badge + popup + panel ================= */
.bell-btn {
  position: relative;
  width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 9px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
  transition: color 140ms ease, border-color 140ms ease, background 140ms ease;
}
.bell-btn:hover { color: var(--text); border-color: var(--line-strong); background: var(--bg-alt); }
.bell-ico { width: 100%; height: 100%; }
.bell-ico svg { width: 100%; height: 100%; }
.bell-badge {
  position: absolute;
  top: -5px;
  right: -5px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--bad);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 700;
  line-height: 1;
  box-shadow: 0 0 0 2px var(--surface);
}

/* Popup BẮT BUỘC: overlay tối chặn giữa màn, card giữa, chỉ ẩn khi bấm Đã đọc. */
.ann-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(23, 26, 34, 0.55);
  backdrop-filter: blur(2px);
  animation: ann-fade 160ms ease;
}
@keyframes ann-fade { from { opacity: 0; } to { opacity: 1; } }
.ann-popup {
  width: min(100%, 480px);
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  border-top: 4px solid var(--blue);
  background: var(--surface);
  box-shadow: var(--shadow-hover);
  padding: 22px 24px 20px;
  animation: ann-pop 180ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
@keyframes ann-pop { from { transform: translateY(10px) scale(0.98); opacity: 0; } to { transform: none; opacity: 1; } }
.ann-popup.ann-lv-warn { border-top-color: var(--warn); }
.ann-popup.ann-lv-critical { border-top-color: var(--bad); }
.ann-popup-kicker {
  color: var(--blue);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.ann-lv-warn .ann-popup-kicker { color: var(--warn); }
.ann-lv-critical .ann-popup-kicker { color: var(--bad); }
.ann-popup-title {
  margin: 6px 0 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.25rem;
  color: var(--dark);
}
.ann-popup-body {
  margin: 12px 0 0;
  color: var(--text);
  font-size: 0.94rem;
  line-height: 1.65;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 46vh;
  overflow-y: auto;
}
.ann-popup-meta { margin: 14px 0 0; color: var(--faint); font-size: 0.78rem; }
.ann-popup-actions { margin-top: 18px; display: flex; justify-content: flex-end; }

/* Panel lịch sử thông báo (mở từ chuông): thả từ góc phải trên. */
.ann-panel {
  position: fixed;
  top: 66px;
  right: clamp(12px, 3vw, 40px);
  z-index: 190;
  width: min(94vw, 380px);
  max-height: min(70vh, 560px);
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: var(--shadow-hover);
  animation: ann-pop 160ms ease;
}
.ann-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 13px 15px;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-display);
  font-size: 0.98rem;
  color: var(--dark);
}
.ann-panel-x { border: 0; background: transparent; color: var(--faint); font-size: 1.3rem; line-height: 1; cursor: pointer; padding: 0 4px; }
.ann-panel-x:hover { color: var(--text); }
.ann-panel-list { flex: 1; min-height: 0; overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 8px; }
.ann-panel-empty { padding: 24px 12px; text-align: center; color: var(--faint); font-size: 0.86rem; }
.ann-item {
  padding: 11px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-low);
}
.ann-item.is-unread { background: var(--blue-container); border-color: rgba(49, 87, 213, 0.3); }
.ann-item-top { display: flex; align-items: center; gap: 8px; }
.ann-item-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--blue); flex-shrink: 0; }
.ann-lv-warn .ann-item-dot { background: var(--warn); }
.ann-lv-critical .ann-item-dot { background: var(--bad); }
.ann-item-title { flex: 1; min-width: 0; font-weight: 700; font-size: 0.9rem; color: var(--dark); }
.ann-item-badge {
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--blue);
  color: #fff;
  font-size: 0.62rem;
  font-weight: 700;
}
.ann-item-body { margin: 6px 0 0; color: var(--muted); font-size: 0.84rem; line-height: 1.55; white-space: pre-wrap; word-break: break-word; }
.ann-item-foot { margin-top: 9px; display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.ann-item-time { color: var(--faint); font-size: 0.72rem; font-family: var(--font-mono); }
.ann-item-read { color: var(--ok); font-size: 0.74rem; font-weight: 600; }
.ann-item-mark {
  border: 1px solid var(--blue);
  background: var(--surface);
  color: var(--blue);
  font-family: inherit;
  font-size: 0.74rem;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  cursor: pointer;
}
.ann-item-mark:hover { background: var(--blue); color: #fff; }

/* ================= MODAL NẠP CREDIT (SePay) =================
   Overlay + card 2 cột: QR bên trái, thông tin chuyển khoản bên phải. Dùng lại
   token/animation của popup thông báo để cùng một ngôn ngữ thị giác. */
.pay-overlay {
  position: fixed;
  inset: 0;
  z-index: 210;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(23, 26, 34, 0.55);
  backdrop-filter: blur(2px);
  animation: ann-fade 160ms ease;
}
.pay-card {
  width: min(100%, 720px);
  max-height: 90vh;
  overflow-y: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  border-top: 4px solid var(--blue);
  background: var(--surface);
  box-shadow: var(--shadow-hover);
  animation: ann-pop 180ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
.pay-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 22px 14px;
  border-bottom: 1px solid var(--line);
}
.pay-title {
  margin: 4px 0 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.2rem;
  color: var(--dark);
}
.pay-x {
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--muted);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
}
.pay-x:hover { border-color: var(--line-strong); background: var(--bg-alt); color: var(--text); }

.pay-body {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 20px;
  padding: 18px 22px 20px;
}
.pay-qr {
  display: flex;
  align-items: flex-start;
  justify-content: center;
}
.pay-qr img {
  width: 100%;
  max-width: 220px;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: #fff;
  padding: 6px;
}
/* QR vẽ ngay trong trình duyệt từ chuỗi VietQR (không qua service ảnh của cổng
   thanh toán). Cùng khuôn với .tglink-qr-canvas: image-rendering pixelated để
   module QR không bị làm mờ khi canvas bị scale lên, background trắng vì app bank
   cần tương phản thật. KHÔNG đặt aspect-ratio — canvas đã vuông sẵn, height:auto
   giữ đúng tỉ lệ gốc. */
.pay-qr-canvas {
  width: 100%;
  max-width: 220px;
  height: auto;
  image-rendering: pixelated;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: #fff;
  padding: 6px;
}
.pay-qr-fallback {
  padding: 16px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-md);
  color: var(--muted);
  font-size: 0.82rem;
  text-align: center;
}
.pay-info { min-width: 0; }
.pay-hint { margin: 0 0 12px; color: var(--muted); font-size: 0.85rem; line-height: 1.55; }
.pay-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px dashed var(--line);
}
.pay-row-label {
  flex-shrink: 0;
  width: 116px;
  color: var(--faint);
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.pay-row-value {
  flex: 1;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: 0.9rem;
  color: var(--text);
  word-break: break-all;
}
.pay-memo { font-weight: 700; color: var(--blue); font-size: 1rem; }
.pay-row-memo { background: var(--blue-container); border-radius: var(--radius-sm); padding: 8px 10px; border-bottom: 0; margin-top: 4px; }
.pay-copy {
  flex-shrink: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--muted);
  font-family: inherit;
  font-size: 0.74rem;
  font-weight: 600;
  padding: 4px 9px;
  cursor: pointer;
}
.pay-copy:hover { border-color: var(--blue); color: var(--blue); }
.pay-warn {
  margin: 12px 0 0;
  color: var(--warn);
  font-size: 0.8rem;
  line-height: 1.5;
}
.pay-expire { margin-top: 12px; color: var(--muted); font-size: 0.84rem; }
.pay-countdown { font-family: var(--font-mono); font-weight: 700; color: var(--text); }
.pay-countdown.is-expired { color: var(--warn); font-weight: 600; }
.pay-status {
  margin-top: 12px;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--bg-alt);
  color: var(--muted);
  font-size: 0.83rem;
  line-height: 1.45;
}
.pay-spinner {
  flex-shrink: 0;
  width: 13px;
  height: 13px;
  border: 2px solid var(--line-strong);
  border-top-color: var(--blue);
  border-radius: 50%;
  animation: pay-spin 700ms linear infinite;
}
@keyframes pay-spin { to { transform: rotate(360deg); } }

@media (max-width: 620px) {
  .pay-body { grid-template-columns: 1fr; }
  .pay-qr img { max-width: 200px; }
  .pay-qr-canvas { max-width: 200px; }
  .pay-row { flex-wrap: wrap; }
  .pay-row-label { width: 100%; }
}

/* ================= LIÊN KẾT TELEGRAM =================
   Khối mời nhận credit dùng thử (tab Tổng quan, khi CHƯA liên kết), ô trạng
   thái khi ĐÃ liên kết, và modal QR + nút mở bot. Dùng chung token/màu với modal
   nạp SePay để hai luồng "quét QR rồi chờ xác nhận" nhìn nhất quán.

   .tglink-locked bên dưới là card khoá tính năng của luồng CŨ (khi liên kết còn
   bắt buộc). Cổng chặn đã gỡ nên nó không còn được dựng trong luồng thường —
   giữ lại vì tgLockedCard vẫn tồn tại cho trường hợp bật chặn lại. */

/* --- Khối mời nhận quà (vàng, nổi bật, đầu tab Tổng quan) --- */
.tggift {
  /* Vàng đặc chứ không nhạt: đây là khối phải đập vào mắt trước cả hàng ví.
     Viền trái dày thay cho viền trên vì khối nằm ngang và rất rộng. */
  border-left: 4px solid var(--warn);
  background: linear-gradient(100deg, #fff6e2 0%, #fffdf7 62%);
  overflow: hidden;
  position: relative;
}
.tggift-body {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 20px 24px;
}
.tggift-ico {
  flex-shrink: 0;
  width: 54px;
  height: 54px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 12px;
  border-radius: 16px;
  background: var(--warn);
  color: #fff;
  box-shadow: 0 6px 16px color-mix(in oklab, var(--warn) 34%, transparent);
}
.tggift-ico svg { width: 100%; height: 100%; }
.tggift-copy { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.tggift-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.12rem;
  line-height: 1.35;
  color: #7a4d05;
}
.tggift-desc {
  margin: 0;
  font-size: 0.87rem;
  line-height: 1.55;
  color: color-mix(in oklab, #7a4d05 72%, transparent);
}
.tggift-cta {
  flex-shrink: 0;
  background: var(--warn);
  border-color: var(--warn);
  color: #fff;
  font-weight: 700;
  padding: 11px 22px;
  box-shadow: 0 4px 12px color-mix(in oklab, var(--warn) 32%, transparent);
}
.tggift-cta:hover:not(:disabled) {
  background: #c07c11;
  border-color: #c07c11;
  color: #fff;
}
@media (max-width: 620px) {
  .tggift-body { flex-direction: column; align-items: flex-start; gap: 14px; padding: 18px; }
  .tggift-cta { width: 100%; }
}

/* --- Card khoá thay nội dung tab (luồng cũ, xem ghi chú đầu mục) --- */
.tglink-locked { border-top: 3px solid var(--warn); }
.tglink-locked-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
  padding: 40px 24px;
}
.tglink-lock-ico {
  width: 46px;
  height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 11px;
  border-radius: 14px;
  background: #fdf3e3;
  color: var(--warn);
}
.tglink-lock-ico svg { width: 100%; height: 100%; }
.tglink-lock-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--dark);
}
.tglink-lock-desc {
  margin: 0;
  max-width: 52ch;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.6;
}

/* --- Ô trạng thái liên kết ở tab Tổng quan --- */
.tglink-row-body {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 12px;
  flex-wrap: wrap;
  padding: 11px 15px;
}
/* Icon PHẢI có kích thước: <svg> không width/height trong CSS rơi về cỡ mặc
   định của trình duyệt (~300×150) và đội cao cả ô, đẩy chữ ra giữa panel. */
.tglink-row-ico {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  color: var(--blue);
  background: var(--blue-container);
}
.tglink-row-ico svg { width: 15px; height: 15px; }
.tglink-row-copy {
  flex: 1 1 240px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.tglink-row-copy b { font-size: 0.9rem; }
.tglink-row-copy p { margin: 0; font-size: 0.8rem; line-height: 1.45; }
.tglink-row-value { font-size: 0.9rem; color: var(--text); }
.tglink-row-actions { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.tglink-badge {
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid var(--line);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.tglink-badge.is-linked { color: var(--ok); background: #eafaf2; border-color: rgba(45, 134, 83, 0.35); }
.tglink-badge.is-unlinked { color: var(--warn); background: #fdf3e3; border-color: rgba(217, 139, 21, 0.35); }

/* --- Modal QR liên kết --- */
.tglink-overlay {
  position: fixed;
  inset: 0;
  z-index: 210;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(23, 26, 34, 0.55);
  backdrop-filter: blur(2px);
  animation: ann-fade 160ms ease;
}
.tglink-card {
  width: min(100%, 680px);
  max-height: 90vh;
  overflow-y: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  border-top: 4px solid var(--blue);
  background: var(--surface);
  box-shadow: var(--shadow-hover);
  animation: ann-pop 180ms cubic-bezier(0.16, 1, 0.3, 1);
}
.tglink-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 22px 14px;
  border-bottom: 1px solid var(--line);
}
.tglink-title {
  margin: 4px 0 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.2rem;
  color: var(--dark);
}
.tglink-x {
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--muted);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
}
.tglink-x:hover { border-color: var(--line-strong); background: var(--bg-alt); color: var(--text); }
.tglink-body {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 20px;
  padding: 18px 22px 20px;
}
.tglink-qr { display: flex; align-items: flex-start; justify-content: center; }
/* Nền trắng cố định + không bị dark-mode filter: camera phải quét được. */
.tglink-qr-canvas {
  width: 100%;
  max-width: 220px;
  height: auto;
  image-rendering: pixelated;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: #fff;
  padding: 6px;
}
.tglink-qr-fallback {
  padding: 16px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-md);
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.5;
}
.tglink-info { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.tglink-hint { margin: 0; color: var(--muted); font-size: 0.88rem; line-height: 1.6; }
.tglink-open { text-decoration: none; text-align: center; }
.tglink-copy { text-align: center; }
.tglink-expire {
  padding-top: 8px;
  border-top: 1px dashed var(--line);
  color: var(--muted);
  font-size: 0.84rem;
}
.tglink-countdown { font-family: var(--font-mono); font-weight: 700; color: var(--text); }
.tglink-countdown.is-expired { color: var(--warn); font-weight: 600; }
.tglink-status {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--bg-alt);
  color: var(--muted);
  font-size: 0.83rem;
  line-height: 1.45;
}
.tglink-spinner {
  flex-shrink: 0;
  width: 13px;
  height: 13px;
  border: 2px solid var(--line-strong);
  border-top-color: var(--blue);
  border-radius: 50%;
  animation: pay-spin 700ms linear infinite;
}

@media (max-width: 620px) {
  .tglink-body { grid-template-columns: 1fr; }
  .tglink-qr-canvas { max-width: 200px; }
  .tglink-row-body { flex-direction: column; align-items: flex-start; }
}

/* --- Thẻ tệp tải xuống trong luồng chat ---
   Trợ lý trả nội dung tệp trong khối mã có gắn tên; trình duyệt dựng tệp bằng
   Blob rồi tải về. Thẻ đứng riêng dưới bong bóng trả lời để nút Tải xuống không
   lẫn vào phần chữ. */
.chat-file-card {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 8px 0 0 44px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-alt);
  max-width: 340px;
}
.chat-file-ico { width: 18px; height: 18px; flex-shrink: 0; color: var(--muted); }
.chat-file-name {
  font-size: 0.85rem;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.chat-file-dl {
  margin-left: auto;
  flex-shrink: 0;
  padding: 5px 11px;
  border-radius: 7px;
  border: 1px solid var(--line);
  background: var(--bg);
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--accent);
  cursor: pointer;
}
.chat-file-dl:hover { border-color: var(--accent); }

/* ---- Chuyển key cũ vào ví tài khoản (A3) ---- */
/* Bảng kê xem-trước: mỗi dòng một nguồn tiền, nhãn trái giá trị phải — khách
   phải đọc được "đổi cái gì lấy cái gì" TRƯỚC khi bấm nút không đảo ngược. */
.import-preview {
  margin: 12px 0;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  overflow: hidden;
}
.import-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 14px;
  font-size: 0.85rem;
}
.import-row + .import-row { border-top: 1px solid var(--line); }
.import-row-label { color: var(--muted); }
.import-row-value {
  font-family: var(--font-mono);
  font-weight: 600;
  white-space: nowrap;
}


/* ====================================================================
   DARK MODE — html.dark override palette
   ==================================================================== */
html.dark {
  --blue: #58a6ff;
  --blue-ink: #a5c8ff;
  --blue-container: #1f3358;
  --dark: #e6edf3;
  /* Nền xanh đậm giữ bong bóng/control có cấp bậc riêng trên nền tối; chữ trắng đạt
     11,07:1. Code dùng nền gần-đen riêng để không mang sắc xanh của hành động. */
  --contrast-surface: #243b67;
  --contrast-surface-hover: #2c4a7f;
  --code-surface: #0d1117;
  --bg: #0d1117;
  --bg-alt: #161b22;
  --surface: #161b22;
  --surface-low: #0d1117;
  --line: #30363d;
  --line-strong: #444c56;
  --text: #e6edf3;
  --muted: #8b949e;
  --faint: #6e7681;
  --ok: #3fb950;
  --warn: #e3b341;
  --bad: #f85149;
  --danger: #f85149;
  --danger-soft: #ff7b72;
  --accent: #58a6ff;
  --accent-deep: #a5c8ff;
  --shadow: 0 18px 48px -42px rgba(0,0,0,.9);
  --shadow-hover: 0 24px 54px -40px rgba(0,0,0,.9);
}

/* Dark: form inputs (nhiều input dùng màu hệ thống, cần reset) */
html.dark input,
html.dark select,
html.dark textarea {
  background: var(--surface);
  color: var(--text);
  border-color: var(--line-strong);
  color-scheme: dark;
}
html.dark input::placeholder { color: var(--faint); }
html.dark input[type="date"]::-webkit-calendar-picker-indicator { filter: invert(0.8); }

/* Dark: status dots (hardcoded light colors) */
html.dark .status-ok  { background: #0d3320; color: #56d364; }
html.dark .status-bad { background: #3d0d0d; color: #f85149; }

/* Dark: gold nav items */
html.dark .nav-item-gold { color: #e8b030; background: #221900; }
html.dark .nav-item-gold:hover { background: #2e2200; color: #f0c840; }
html.dark .nav-item-gold.active { background: #9a6000; color: #fff; }
html.dark .nav-item-gold-dot { color: #d09020; }
html.dark .nav-item-gold.active .nav-item-gold-dot { color: rgba(255,255,255,.8); }

/* Dark: live/realtime nav items */
html.dark .nav-item-live { color: #30c8c8; background: #061a1a; }
html.dark .nav-item-live:hover { background: #0a2828; color: #20e0e0; }
html.dark .nav-item-live.active { background: #0a7878; color: #fff; }
html.dark .nav-item-live-dot { background: #30c8c8; }

/* Dark: social hover tints */
html.dark .social-btn-tg:hover { background: #041e2a; }
html.dark .social-btn-zalo:hover { background: #03082e; }

/* Dark: code blocks */
html.dark pre,
html.dark .docs-code { background: #0d1117; border-color: var(--line); }

/* Dark: auth panel */
html.dark .auth-panel { background: var(--surface); border-color: var(--line); }

/* Dark: hàng lối đi nhanh — nền phẳng theo surface, hai nút chính giữ tint xanh */
html.dark .cta-direct-btn { background: var(--surface); color: var(--text); }
html.dark .cta-direct-btn:not(.cta-secondary) {
  background: #1e2d50;
  color: var(--blue-ink);
}
html.dark .cta-direct-btn:not(.cta-secondary):hover { background: #26395e; filter: none; }

/* ====================================================================
   TOGGLE BUTTONS — Theme + Language (trong topbar-right)
   ==================================================================== */
.btn-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0;
  border: 1px solid var(--line); border-radius: 9px;
  background: transparent; color: var(--muted);
  cursor: pointer; flex-shrink: 0;
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
}
.btn-icon:hover { background: var(--bg-alt); color: var(--text); border-color: var(--line-strong); }
.btn-icon svg { width: 16px; height: 16px; }

.btn-lang {
  display: inline-flex; align-items: center; justify-content: center;
  height: 34px; padding: 0 11px;
  border: 1px solid var(--line); border-radius: 9px;
  background: transparent; color: var(--muted);
  font-family: var(--font-display);
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.06em;
  cursor: pointer; flex-shrink: 0; white-space: nowrap;
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
}
.btn-lang:hover { background: var(--bg-alt); color: var(--text); border-color: var(--line-strong); }

/* ====================================================================
   CHIP SỐ DƯ TOPBAR (#topbar-wallet) — cập nhật 10 giây/lần

   Hình thái: hai viên pill sát nhau, cao ĐÚNG 34px như .btn-icon/.btn-lang
   ngay bên cạnh. Lệch 1px ở đây là cả hàng topbar trông như xếp sai.

   Con số đi phông MONO, không phải phông thân. Số dư đổi giá trị mỗi nhịp
   poll; phông tỉ lệ thay đổi bề rộng theo từng chữ số nên chip sẽ co giãn
   và đẩy các nút cạnh nó nhảy chỗ mỗi 10 giây. Mono giữ bề rộng ổn định.

   Hai chip KHÁC MÀU vì chúng là hai loại tiền khác nhau: quota gói tháng
   (dùng hết là hết trong ngày, mai có lại) mang màu nhấn xanh; ví credit
   (tiền thật đã nạp) mang màu mực trung tính. Cùng màu là mời khách cộng
   hai số vào nhau.
   ==================================================================== */
.tw-chips { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.tw-chip {
  display: inline-flex; align-items: center; gap: 6px;
  height: 34px; padding: 0 10px;
  border: 1px solid var(--line); border-radius: 9px;
  background: var(--surface-low); color: var(--text);
  cursor: pointer; white-space: nowrap;
  font: inherit;
  transition: background 140ms ease, border-color 140ms ease, color 140ms ease;
}
.tw-chip:hover { background: var(--bg-alt); border-color: var(--line-strong); }
.tw-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.tw-chip svg { width: 15px; height: 15px; flex-shrink: 0; color: var(--faint); }
.tw-chip:hover svg { color: var(--muted); }
.tw-num {
  font-family: var(--font-mono);
  font-size: 0.78rem; font-weight: 600;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
/* Đơn vị nhỏ và mờ: nó là NHÃN, đọc một lần rồi thôi — không được cạnh tranh
   chú ý với con số, thứ khách quay lại nhìn liên tục. */
.tw-unit {
  font-size: 0.62rem; font-weight: 700; letter-spacing: 0.06em;
  color: var(--faint); text-transform: uppercase;
}

/* Chip gói tháng: viền + chữ màu nhấn, kèm đốm nhịp cho biết quota đang chạy
   theo ngày (khác ví credit — số tĩnh cho tới khi nạp/tiêu). */
.tw-chip-plan {
  border-color: color-mix(in srgb, var(--accent) 38%, var(--line));
  background: var(--blue-container);
  color: var(--accent-deep);
}
.tw-chip-plan:hover {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, var(--surface));
}
.tw-chip-plan svg { color: var(--accent); }
.tw-chip-plan:hover svg { color: var(--accent-deep); }
.tw-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent); flex-shrink: 0;
  animation: pulse-live 1.4s ease-in-out infinite;
}

/* Chip ví credit: nhấn mạnh con số bằng cỡ chữ, không bằng màu — đây là ô
   khách đọc thường xuyên nhất trên topbar. */
.tw-chip-credit .tw-num { font-size: 0.82rem; font-weight: 700; }

/* tw-bump: nháy MỘT lần khi con số vừa đổi (app.js gắn class, không gắn khi
   giá trị y cũ). Dùng transform + background — cả hai đều là thuộc tính
   compositor, không gây reflow cho topbar sticky.

   prefers-reduced-motion: nhịp nháy ở đây là thông tin PHỤ (con số mới vẫn
   nằm đó để đọc), nên tắt hẳn là mất mát bằng không. */
.tw-bump { animation: tw-bump 620ms ease-out 1; }
@keyframes tw-bump {
  0%   { transform: scale(1); }
  22%  { transform: scale(1.07); background: color-mix(in srgb, var(--accent) 20%, var(--surface)); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .tw-bump { animation: none; }
  .tw-dot { animation: none; }
}

/* Màn hẹp: giữ chip nhưng bỏ phần trang trí.

   Số dư là thứ đáng giữ nhất ở topbar mobile — khách dùng điện thoại vẫn cần
   biết còn tiền hay không. Cắt icon + nhãn "cr" thu chip lại còn ~52px, đủ chỗ
   cho hamburger + tên trang + theme/lang + đăng xuất trên màn 360px. */
@media (max-width: 640px) {
  .tw-chip { padding: 0 8px; gap: 4px; }
  .tw-chip svg, .tw-unit { display: none; }
  /* Chip gói tháng nhường chỗ trước: nó là thông tin thứ hai, và khách có gói
     tháng thì con số ví credit vẫn cho biết tình trạng chung. */
  .tw-chip-plan { display: none; }
}

/* Dark mode: chip credit theo nền surface-low của dark; chip gói tháng phải
   tự khai màu vì --blue-container ở dark là nền ĐẬM còn --accent-deep là chữ
   ĐẬM — dùng nguyên cặp đó sẽ ra chữ tối trên nền tối. */
html.dark .tw-chip-plan { color: var(--accent); }
html.dark .tw-chip-plan:hover { color: var(--text); }

/* ---- Bảng API keys kiểu sub2api (15/08) ---- */
.key-table-wrap { margin-top: 4px; }
.key-table td { vertical-align: middle; }
.key-table .key-name { font-weight: 600; }
.key-mask-cell { display: flex; align-items: center; gap: 8px; }
.key-mask-cell .key-masked { font-size: .8rem; }
.key-group-select { max-width: 220px; }
.key-row-actions { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }

/* Modal "Sử dụng khóa API": khối lệnh tối + hàng nhãn/nút sao chép */
.use-key-dialog { max-width: 720px; }
.use-key-dialog .pill-row { margin-bottom: 10px; }
.use-key-block { margin-top: 12px; }
.use-key-block-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 6px;
}
.use-key-block .setup-term-body { margin: 0; max-height: 260px; overflow: auto; }

/* ---- Group picker nhóm Claude (15/08; dựng lại 28/08 theo cam Anthropic) ----

   Cụm này là bộ CHỌN SẢN PHẨM Claude, nên nó mang cam Anthropic #d97757 — cùng màu
   .tone-claude/.prov-claude đã dùng ở nơi khác trong file này, không đặt màu mới.

   BA lỗi bản cũ, đều đã đo trên trình duyệt 28/08:
     1. `.gp-panel { background: var(--panel) }` — biến `--panel` KHÔNG được khai ở
        đâu trong file (dùng 1 lần, khai 0 lần). var() không phân giải được làm cả
        khai báo background thành invalid at computed-value time → về `transparent`,
        nên bảng chọn trong suốt và chữ các dòng key phía sau chồng lên nhau.
     2. `.gp-row { background: transparent }` — từng dòng không có nền, nên kể cả khi
        panel đã đục thì các nhóm vẫn dính thành một khối không tách được.
     3. Panel absolute nằm trong .mtable-wrap có `overflow-x: auto`. Một trục auto
        biến phần tử thành scroll container ở CẢ hai trục, nên panel của dòng cuối bị
        cắt. Nay JS treo panel vào <body> bằng position:fixed (xem groupPicker). */
.key-table td:nth-child(3) { min-width: 250px; }
:root {
  --claude: #d97757;
  --claude-ink: #a8452a;
  --claude-soft: #fdf1ec;
}
html.dark {
  --claude: #e08a6d;
  --claude-ink: #f0b9a5;
  --claude-soft: #2a1a14;
}
.gp-wrap { position: relative; display: inline-block; min-width: 230px; }
.gp-btn {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px 10px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface); color: var(--text); cursor: pointer;
  font: inherit; font-size: .85rem; text-align: left;
  transition: border-color 120ms ease, background 120ms ease, box-shadow 120ms ease;
}
.gp-btn:hover {
  border-color: var(--claude);
  background: var(--claude-soft);
}
.gp-btn:focus-visible {
  outline: 2px solid var(--claude);
  outline-offset: 1px;
}
.gp-dot {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
  background: var(--claude);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--claude) 20%, transparent);
}
.gp-name {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-weight: 600;
}
.gp-placeholder { flex: 1; color: var(--muted); }
.gp-ratio {
  flex-shrink: 0;
  font-size: .7rem; font-weight: 700; padding: 2px 7px; border-radius: 6px;
  font-variant-numeric: tabular-nums;
  background: color-mix(in srgb, var(--claude) 16%, transparent);
  color: var(--claude-ink);
}
.gp-caret { color: var(--muted); font-size: .7rem; flex-shrink: 0; }

/* Panel: fixed (JS tự tính toạ độ) + nền ĐỤC. z-index trên .modal-backdrop của
   portal để panel trong modal tạo key không bị nền mờ phủ lên. */
.gp-panel {
  position: fixed; z-index: 1200; top: 0; left: 0; width: 360px;
  background: var(--surface);
  border: 1px solid var(--line-strong); border-radius: 14px;
  box-shadow: 0 20px 44px -20px rgba(23, 26, 34, .34), 0 2px 8px -2px rgba(23, 26, 34, .18);
  padding: 8px; max-height: 340px; overflow-y: auto;
}
html.dark .gp-panel {
  box-shadow: 0 20px 44px -18px rgba(0, 0, 0, .78), 0 0 0 1px rgba(255, 255, 255, .04);
}
.gp-panel::before {
  content: "Nhóm định tuyến Claude";
  display: block; padding: 2px 8px 7px;
  font-size: .64rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--claude-ink);
}
.gp-search {
  width: 100%; margin-bottom: 8px;
  border-radius: 9px;
}
.gp-search:focus {
  border-color: var(--claude);
  outline: none;
}
.gp-list { display: flex; flex-direction: column; gap: 6px; }

/* Mỗi nhóm là một THẺ có nền riêng — đây là phần chữa "không đọc được nhóm nào ra
   nhóm nào": nền + viền + khoảng cách, không còn dòng trong suốt dính nhau. */
.gp-row {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 9px 11px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg-alt);
  color: var(--text); cursor: pointer; font: inherit; font-size: .85rem; text-align: left;
  transition: background 120ms ease, border-color 120ms ease, transform 120ms ease;
}
.gp-row:hover {
  background: var(--claude-soft);
  border-color: var(--claude);
}
.gp-row:focus-visible {
  outline: 2px solid var(--claude);
  outline-offset: 1px;
}
.gp-row.active {
  background: var(--claude-soft);
  border-color: var(--claude);
  box-shadow: inset 3px 0 0 var(--claude);
}
.gp-row-name { flex: 1; display: flex; align-items: center; gap: 9px; min-width: 0; }
.gp-row-text {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-weight: 600;
}
.gp-row.active .gp-row-text { color: var(--claude-ink); }
.gp-check {
  flex-shrink: 0; width: 12px;
  color: var(--claude); font-weight: 700; font-size: .8rem;
}
.gp-mount { margin-top: 4px; }

/* ---- Panel "Nguồn Claude cho key" ở Bảng điều khiển (28/08) ----
   Ba việc trên một hàng: chọn key → chọn nguồn → dùng/sao chép. Xuống cột ở màn
   hẹp thay vì bóp nhỏ, vì cả ba đều là điều khiển cần bấm chính xác.

   Nền gold nhạt để khối nổi khỏi dãy panel trắng của Bảng điều khiển. Dùng LẠI
   bộ màu gold đã có ở .nav-item-gold thay vì đặt tông mới, để portal không sinh
   thêm một sắc vàng thứ hai. Gradient tắt dần về --surface nên chỉ đầu khối có
   màu — "nhấn nhẹ", không thành thẻ cảnh báo. */
.crp-panel {
  border-color: #efd49a;
  background: linear-gradient(180deg, #fff8e1, var(--surface) 76%);
}
.crp-panel .panel-title { color: #7a5408; }
html.dark .crp-panel {
  border-color: #574000;
  background: linear-gradient(180deg, #241a02, var(--surface) 76%);
}
html.dark .crp-panel .panel-title { color: #e8b030; }

.crp-row {
  display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap;
}
.crp-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
/* KHÔNG cho ô key giãn hết hàng: nội dung của nó là "tên · sk-…" ngắn, kéo dài
   360px chỉ tạo một dải trống rồi đẩy nút Sử dụng ra sát lề phải. flex-basis cố
   định giữ ba khối đứng liền nhau, đọc thành một câu từ trái sang phải. */
.crp-field:first-child { flex: 0 1 320px; }
.crp-field:nth-child(2) { flex: 0 0 auto; }
.crp-select {
  width: 100%; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface); color: var(--text);
  font: inherit; font-size: .85rem;
}
.crp-select:focus { border-color: #d99a0b; outline: none; }
.crp-picker { display: flex; align-items: center; min-height: 36px; }
.crp-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
@media (max-width: 720px) {
  .crp-row { flex-direction: column; align-items: stretch; }
  .crp-field:first-child { flex: 1 1 auto; }
  .crp-actions { justify-content: flex-start; }
}

/* ---- crp-duo: khối chọn nguồn + khối ĐIỂM DANH đứng cạnh nhau ---------------

   Grid hai cột thay vì flex: cột điểm danh phải giữ bề rộng ĐỦ ĐỌC một câu điều
   kiện ("nạp từ 100.000đ trong 7 ngày gần nhất") mà không ngắt dòng lắt nhắt,
   còn cột nguồn thì co giãn được. minmax(0, …) là bắt buộc — thiếu nó thì nội
   dung dài (tên key + mask) đẩy cột tràn khỏi khung thay vì co lại.

   align-items:start để hai panel KHÔNG bị kéo cao bằng nhau: khối điểm danh cao
   thấp thay đổi theo trạng thái (chưa/đã điểm danh), stretch sẽ để lại một dải
   trống dưới khối nguồn. */
.crp-duo {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: 14px;
  align-items: start;
}
.crp-duo > .panel { margin: 0; }
@media (max-width: 980px) {
  .crp-duo { grid-template-columns: minmax(0, 1fr); }
}

/* ---- Khối ĐIỂM DANH NGÀY ---------------------------------------------------

   Tông XANH thành công (--ok) để tách khỏi tông gold của khối nguồn ngay bên
   cạnh: hai khối cùng hàng mà cùng màu thì đọc thành một khối, và cú bấm "nhận
   quà" mất hẳn tính mời gọi.

   ⚠️ CHỈ dùng biến ĐÃ KHAI ở :root (--surface, --line, --text, --muted, --ok).
   Bài học 28/08: một khối panel dùng var(--panel) chưa từng được khai, background
   thành invalid ⇒ trong suốt, và CSS KHÔNG báo lỗi gì cả. */
.ck-panel {
  border-color: #bfe3cd;
  background: linear-gradient(180deg, #edfaf1, var(--surface) 76%);
}
.ck-panel .panel-title { color: #1c6b41; }
html.dark .ck-panel {
  border-color: #1f4a33;
  background: linear-gradient(180deg, #0f2318, var(--surface) 76%);
}
html.dark .ck-panel .panel-title { color: #4cc47c; }

.ck-body { display: flex; flex-direction: column; gap: 12px; }

/* Phần THƯỞNG: con số to là thứ khách đọc trước, nên nó mang cỡ chữ lớn nhất
   trong khối và đơn vị đi kèm ở cỡ thường — tương phản cỡ chữ làm phân cấp,
   không cần thêm màu hay viền. */
.ck-reward { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.ck-reward-num {
  font-family: var(--font-display);
  font-size: 1.9rem; font-weight: 800; line-height: 1;
  color: #1c6b41; letter-spacing: -.02em;
}
html.dark .ck-reward-num { color: #4cc47c; }
.ck-reward-unit { font-size: .86rem; color: var(--muted); }

/* Phần ĐIỀU KIỆN: hai dòng nhãn–giá trị thẳng cột, rồi thanh tiến độ. Nhãn có
   bề rộng cố định để "Yêu cầu" và "Đã đạt" gióng cột — khách so hai con số
   theo chiều dọc, lệch cột là phải đọc lại. */
.ck-req {
  display: flex; flex-direction: column; gap: 6px;
  padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface);
}
.ck-req-line { display: flex; gap: 8px; align-items: baseline; font-size: .82rem; }
.ck-req-label {
  flex: 0 0 58px;
  color: var(--faint); text-transform: uppercase;
  font-size: .68rem; letter-spacing: .06em; font-weight: 700;
}
.ck-req-val { color: var(--text); min-width: 0; }
.ck-req-val.ck-ok { color: var(--ok); font-weight: 600; }
.ck-req-val.ck-warn { color: var(--warn); font-weight: 600; }

.ck-bar {
  height: 6px; margin-top: 2px;
  border-radius: 999px; background: var(--line); overflow: hidden;
}
.ck-bar-fill {
  height: 100%; border-radius: 999px;
  background: var(--warn);
  transition: width .3s ease;
}
.ck-bar-fill.ck-bar-ok { background: var(--ok); }

/* Phần LƯỢT HÔM NAY: chỉ hiện sau khi đã điểm danh. */
.ck-today {
  padding: 10px 12px;
  border: 1px dashed #bfe3cd; border-radius: var(--radius-sm);
}
html.dark .ck-today { border-color: #1f4a33; }
.ck-today-num { font-size: 1.05rem; }
.ck-today-num strong { font-family: var(--font-display); font-weight: 800; color: var(--ok); }
.ck-today-sub { font-size: .78rem; margin-top: 2px; }

.ck-btn { width: 100%; justify-content: center; }
.ck-btn:disabled { opacity: .55; cursor: default; }
.ck-note { margin: 0; font-size: .76rem; line-height: 1.55; }

/* ---- Trang Trạng thái kênh (16/08 v2: logo thật, Nhanh/Ổn/Đang chậm, nút refresh,
   thẻ viền gradient + nền sâu, chữ nhỏ gọn) ---- */
.ch-topbar { display: flex; align-items: center; gap: 10px; margin: 4px 0 14px; flex-wrap: wrap; }
.ch-overall { font-weight: 800; font-size: .68rem; letter-spacing: .09em; padding: 6px 14px; border-radius: 999px; background: var(--surface); border: 1px solid var(--line); }
.ch-refresh {
  margin-left: auto; display: inline-flex; align-items: center; gap: 6px; font: inherit;
  font-size: .7rem; font-weight: 700; color: var(--muted); background: var(--surface);
  border: 1px solid var(--line); border-radius: 999px; padding: 6px 13px; cursor: pointer;
  transition: color .15s ease, border-color .15s ease, transform .1s ease;
}
.ch-refresh:hover { color: var(--text); border-color: var(--line-strong); }
.ch-refresh:active { transform: scale(.96); }
.ch-refresh svg { width: 12px; height: 12px; }
.ch-refresh.spin svg { animation: ch-spin .7s linear infinite; }
@keyframes ch-spin { to { transform: rotate(360deg); } }
.ch-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; }
/* Thẻ = 1px viền gradient (padding-box trick): sang mà không nặng nề; hover nâng
   nhẹ + đổ bóng sâu. Lớp .ch-inner lót nền để hở đúng 1px viền màu. */
.ch-card {
  position: relative; border-radius: 16px; padding: 1px;
  background: linear-gradient(165deg, var(--line-strong), var(--line) 45%, color-mix(in srgb, var(--line) 30%, transparent));
  transition: transform .18s ease, box-shadow .18s ease;
}
.ch-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-hover); }
.ch-card.ch-fast { background: linear-gradient(165deg, color-mix(in srgb, var(--ok) 55%, var(--line)), var(--line) 55%); }
.ch-card.ch-slow { background: linear-gradient(165deg, color-mix(in srgb, var(--bad) 60%, var(--line)), var(--line) 55%); }
.ch-inner {
  border-radius: 15px; background: var(--surface); height: 100%;
  padding: 14px 15px 11px; display: flex; flex-direction: column; gap: 10px;
}
html.dark .ch-inner { background: linear-gradient(180deg, #1e222c, #171a22 70%); }
.ch-head { display: flex; align-items: center; gap: 9px; }
/* Logo hãng: chip vuông bo góc, nền tông hãng giống bảng giá (tone-*), icon trắng. */
.ch-logo {
  flex: 0 0 38px; width: 38px; height: 38px; border-radius: 11px; display: flex;
  align-items: center; justify-content: center; color: #fff; background: var(--faint);
  box-shadow: inset 0 -6px 12px rgba(0,0,0,.18);
}
.ch-logo svg { width: 21px; height: 21px; }
.ch-logo.tone-claude { background: #d97757; }
.ch-logo.tone-gpt { background: #171a22; }
html.dark .ch-logo.tone-gpt { background: #10a37f; }
.ch-logo.tone-grok { background: #3d4046; }
.ch-logo.tone-deepseek { background: #4d6bfe; }
.ch-title { flex: 1; min-width: 0; }
/* Tên kênh KHÔNG cắt bằng ellipsis: cho xuống tối đa 2 dòng để khách đọc đủ tên
   mà không phải rê chuột chờ tooltip. */
.ch-name {
  font-weight: 800; font-size: .95rem; letter-spacing: -.01em;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.ch-model { color: var(--faint); font-size: .68rem; letter-spacing: .03em; margin-top: 1px; font-family: var(--font-mono); }
.ch-state {
  display: inline-flex; align-items: center; gap: 5px; font-size: .7rem; font-weight: 800;
  letter-spacing: .04em; padding: 4px 10px; border-radius: 999px; white-space: nowrap;
  border: 1px solid var(--line); background: var(--bg-alt); color: var(--faint);
}
.ch-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.ch-card.ch-fast .ch-state { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 35%, transparent); background: color-mix(in srgb, var(--ok) 9%, transparent); }
.ch-card.ch-fast .ch-dot { animation: ch-pulse 2s ease-out infinite; }
.ch-card.ch-ok .ch-state { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 35%, transparent); background: color-mix(in srgb, var(--warn) 9%, transparent); }
.ch-card.ch-slow .ch-state { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 35%, transparent); background: color-mix(in srgb, var(--bad) 9%, transparent); }
@keyframes ch-pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 45%, transparent); } 100% { box-shadow: 0 0 0 6px transparent; } }
.ch-metrics { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }
.ch-card.ch-3col .ch-metrics { grid-template-columns: 1fr 1fr 1fr; }
.ch-metric {
  border: 1px solid var(--line); border-radius: 10px; padding: 6px 9px 7px;
  background: color-mix(in srgb, var(--bg-alt) 55%, transparent);
}
.ch-metric .label-tiny { font-size: .62rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ch-value { margin-top: 2px; font-size: 1.02rem; font-weight: 800; font-family: var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.lat-green { color: #2f9e6e; }
.lat-yellow { color: #d9a03c; }
.lat-red { color: #d05454; }
/* Sparkline + chân thẻ DÍNH ĐÁY thẻ (margin-top:auto): thẻ ít nội dung không để
   foot lơ lửng giữa thẻ — mọi thẻ cùng hàng trông đều tăm tắp. */
.ch-spark { display: flex; align-items: flex-end; gap: 2px; height: 26px; overflow: hidden; margin-top: auto; }
.ch-bar { flex: 1 1 2px; min-width: 2px; max-width: 6px; height: 100%; border-radius: 2px; opacity: .85; }
.ch-bar.lat-green { background: #2f9e6e; }
.ch-bar.lat-yellow { background: #e6b450; }
.ch-bar.lat-red { background: #d05454; }
.ch-foot { display: flex; justify-content: space-between; color: var(--faint); font-size: .64rem; letter-spacing: .05em; }
/* Tiêu đề ngăn BẢNG GIÁ MODEL nhúng dưới lưới kênh + khoảng cách thoáng. */
.ch-section {
  margin: 26px 0 10px; font-family: var(--font-mono); font-size: .68rem; font-weight: 700;
  letter-spacing: .12em; color: var(--muted);
  display: flex; align-items: center; gap: 10px;
}
.ch-section::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.models-embed { margin-top: 4px; }

/* ---- Trang TIẾP THỊ LIÊN KẾT (aff) ----------------------------------------
   Sắc XANH DƯƠNG thương hiệu, cố ý KHÁC màu xanh lá của khối Điểm danh: hai
   chương trình khuyến mãi khác nhau, và dùng cùng một sắc thái sẽ làm khách đọc
   nhanh tưởng là cùng một thứ.

   ⚠️ CHỈ dùng biến ĐÃ KHAI ở :root (--surface, --line, --text, --muted, --blue,
   --blue-ink, --font-display). Bài học 28/08: một panel dùng var(--panel) chưa
   từng khai làm background thành invalid ⇒ trong suốt, và CSS không báo lỗi. */
.aff-panel {
  border-color: #c3d0f5;
  background: linear-gradient(180deg, #eef2ff, var(--surface) 76%);
}
.aff-panel .panel-title { color: var(--blue-ink); }
html.dark .aff-panel {
  border-color: #24365e;
  background: linear-gradient(180deg, #121a2e, var(--surface) 76%);
}

/* Con số thưởng: cỡ chữ lớn nhất trong khối làm phân cấp, cùng khuôn .ck-reward. */
.aff-reward { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.aff-reward-num {
  font-family: var(--font-display);
  font-size: 1.9rem; font-weight: 800; line-height: 1;
  color: var(--blue-ink); letter-spacing: -.02em;
}
.aff-reward-unit { font-size: .86rem; color: var(--muted); }
.aff-rule { margin: 8px 0 14px; font-size: .82rem; line-height: 1.6; }

/* Hàng LINK: ô nhập giãn hết chỗ còn lại, nút giữ nguyên bề rộng. wrap để trên
   màn hẹp nút xuống dòng thay vì bóp ô link thành vài ký tự. */
.aff-link-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.aff-link-input {
  flex: 1 1 260px; min-width: 0;
  font-family: var(--font-mono); font-size: .8rem;
  padding: 10px 12px; color: var(--text);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.aff-link-input:focus { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(49, 87, 213, 0.14); }

.aff-code-row {
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
  margin-top: 10px; font-size: .82rem;
}
.aff-code {
  font-family: var(--font-mono); font-weight: 700; letter-spacing: .08em;
  padding: 3px 8px; border-radius: 6px;
  background: var(--surface-low); border: 1px solid var(--line);
}

.aff-stats { margin: 14px 0; }

/* Ô nhập mã của người được mời — cùng khuôn .redeem-form để hai chỗ nhập mã
   trong portal trông như một. */
.aff-attach-form { display: flex; gap: 10px; flex-wrap: wrap; }
.aff-attach-form input {
  flex: 1 1 220px; min-width: 0;
  font-family: var(--font-mono); font-size: .85rem; letter-spacing: .06em;
  padding: 10px 12px; color: var(--text);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.aff-attach-form input:focus { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(49, 87, 213, 0.14); }

/* Dòng thông báo "đang đăng ký qua mã X" trên form đăng ký. */
.auth-ref-note {
  margin: 0 0 4px; padding: 9px 11px;
  font-size: .8rem; line-height: 1.5; color: var(--blue-ink);
  background: var(--blue-container); border-radius: var(--radius-sm);
}
html.dark .auth-ref-note { color: var(--blue-ink); }

/* ---- GÓI TOKEN "CLAUDE KÊNH GIÁ RẺ" ---- */

/* Mô tả đặc tính chung, đặt trên bảng thông số. */
.pack-blurb { margin: 0 0 14px; font-size: .88rem; line-height: 1.6; }

/* Bảng "gói này là gì": các dòng nhãn–giá trị, khung vàng gold để tách khỏi phần
   còn lại của trang.

   ⚠️ KHÔNG dùng `justify-content: space-between` ở .pack-fact. Nó dán nhãn vào lề
   TRÁI và giá trị vào lề PHẢI, nên trên màn hình rộng giữa hai cột là một khoảng
   trắng cả nghìn pixel — mắt phải nhảy hết bề ngang để ghép một cặp, và mỗi dòng
   có điểm bắt đầu của giá trị khác nhau (vì căn phải theo độ dài từng câu).

   Thay bằng cột nhãn CỐ ĐỊNH BỀ NGANG + giá trị căn TRÁI ngay sau đó: mọi giá trị
   thẳng một mép, cặp nhãn–giá trị nằm trong tầm mắt. max-width giữ độ dài dòng ở
   mức đọc được và margin auto đưa cả khối vào giữa. */
.pack-facts {
  margin: 0 auto 16px;
  max-width: 760px;
  padding: 16px 20px;
  background: color-mix(in oklab, var(--warn) 7%, var(--surface));
  border: 1px solid color-mix(in oklab, var(--warn) 45%, transparent);
  border-radius: var(--radius-sm);
  display: flex; flex-direction: column; gap: 9px;
}
.pack-fact { display: flex; align-items: baseline; gap: 14px; }
.pack-fact span {
  flex: 0 0 148px;
  color: var(--muted); font-size: .82rem;
}
.pack-fact b { flex: 1 1 auto; font-size: .82rem; font-weight: 500; color: var(--text); line-height: 1.5; }

/* Ô gói đang chạy + thanh tiến độ token. */
.pack-current {
  margin: 0 0 14px; padding: 14px 16px;
  background: var(--surface-low);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
}
/* Gói đã cạn token vẫn hiện (nó giữ chỗ tới hết 24h) nhưng đổi màu viền để khách
   thấy ngay trạng thái khác, không phải đọc mới biết. */
.pack-current.is-out { border-color: var(--warn); background: var(--bg-alt); }
.pack-current-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 10px;
}
.pack-current-head b { font-size: .92rem; }
.pack-current-head span { font-size: .8rem; }
.pack-current-note { margin: 9px 0 0; font-size: .82rem; line-height: 1.55; }

.pack-bar {
  height: 8px; border-radius: 999px; overflow: hidden;
  background: var(--line);
}
.pack-bar-fill {
  height: 100%; border-radius: 999px;
  background: var(--blue);
  transition: width 300ms ease;
}
.pack-current.is-out .pack-bar-fill { background: var(--warn); }

/* Hàng đợi gói đã mua trước. */
.pack-queue {
  margin: 0 0 14px; padding: 12px 16px;
  background: var(--bg-alt);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-sm);
}
.pack-queue-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 8px;
}
.pack-queue-head b { font-size: .88rem; }
.pack-queue-head span { font-size: .78rem; }
.pack-queue-list { display: flex; flex-direction: column; gap: 6px; }
.pack-queue-row {
  display: flex; align-items: baseline; gap: 12px;
  font-size: .82rem;
}
.pack-queue-row b { min-width: 74px; }
.pack-queue-row span { color: var(--muted); }

/* Câu nhắc "gói mua bây giờ sẽ vào lượt lúc …" — đặt ngay trên dải card giá. */
.pack-queue-note {
  margin: 0 0 14px; padding: 10px 12px;
  font-size: .82rem; line-height: 1.55; color: var(--blue-ink);
  background: var(--blue-container); border-radius: var(--radius-sm);
}
html.dark .pack-queue-note { color: var(--blue-ink); }

@media (max-width: 560px) {
  /* Hai cột thành hai dòng: ở bề ngang hẹp, cột nhãn 148px chiếm gần nửa màn hình
     nên giá trị bị bóp thành 4-5 chữ mỗi dòng và mất hẳn khả năng đọc. flex phải
     trả về auto, nếu không thì nhãn vẫn giữ 148px chiều CAO khi đã đổi trục. */
  .pack-fact { flex-direction: column; gap: 2px; }
  .pack-fact span { flex: 0 0 auto; }
  .pack-queue-row { flex-wrap: wrap; gap: 4px 12px; }
}

/* Hai ĐỒNG HỒ/BỘ ĐẾM của gói đang chạy, đứng cạnh nhau: thời gian còn lại và token
   đã dùng/tổng.

   Vì sao PHẢI cạnh nhau, không phải một dòng chữ: gói hết theo HAI TRỤC ĐỘC LẬP —
   hết giờ khi còn token, hoặc hết token khi còn giờ. Khách không suy ra trục kia từ
   trục này, nên gộp thành một câu là buộc họ tự đoán. */
.pack-meters {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin: 12px 0 12px;
}
.pack-meter {
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.pack-meter-label { color: var(--muted); font-size: .74rem; text-transform: uppercase; letter-spacing: .04em; }
/* Số to, font mono: đồng hồ đổi từng giây nên chữ có độ rộng thay đổi sẽ làm cả ô
   nhảy qua nhảy lại mỗi nhịp. */
.pack-clock-num, .pack-meter-num {
  font-family: var(--font-mono);
  font-size: 1.12rem; font-weight: 600; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.pack-meter-sub { font-size: .74rem; }
.pack-current.is-out .pack-clock-num { color: var(--warn); }

/* Đồng hồ "vào lượt sau" của gói đang xếp hàng. */
.pack-queue-clock {
  font-family: var(--font-mono); font-size: .82rem; font-weight: 600;
  font-variant-numeric: tabular-nums; color: var(--text);
}

@media (max-width: 560px) {
  /* Hai bộ đếm xuống hai dòng: ở bề ngang hẹp, "180.000.000 / 1.000.000.000 token"
     bị bóp mất số. */
  .pack-meters { grid-template-columns: 1fr; }
}

/* ── Khung vàng cho CẢ khu gói token ──────────────────────────────────────────
   Dùng LẠI bộ gold của .crp-panel (#efd49a sáng / #574000 tối) thay vì đặt sắc
   vàng thứ hai. Khác .crp-panel một điểm có chủ ý: KHÔNG gradient nền. Khối này
   cao (3 tab + 5 thẻ giá), gradient tắt ở 76% sẽ đổ bóng vàng lên giữa dãy card
   và làm chữ trong thẻ mờ đi; ở đây chỉ cần viền đóng khung. */
/* Viền 2px + halo vàng: chủ hệ thống yêu cầu khoanh nổi bật CẢ khu vực gói (01/09).
   Bản trước dùng 1px #efd49a và halo mờ 28% — trên nền trắng gần như không thấy
   khung. Nâng độ đậm chứ KHÔNG đổi sang nền vàng: nền màu sẽ đè lên 5 thẻ gói bên
   trong (mỗi thẻ đã có nền riêng) và làm bảng giá khó đọc.

   SẮC ĐỘ (đổi 01/09 lần 3 — chủ hệ thống chốt CYAN): rời hẳn họ vàng sang teal-cyan
   sâu #0e7c86. Chọn teal sẫm chứ không cyan neon (#00e5ff): neon trên nền trắng chỉ
   đạt ~1.6:1 nên viền biến thành vệt sáng nhoè, còn teal sẫm giữ được chất kim loại
   như bản gold mà không đụng dải vàng của .crp-panel — hai khung vàng cạnh nhau
   trước đó đọc ra "cùng một sản phẩm". Halo vẫn là MỰC (rgba đen), không phải cyan:
   cyan bọc cyan cho ra vẻ nhãn khuyến mãi.

   BỐN biến ở :root vì tab và "???" bên dưới phải lấy CÙNG sắc — ba nơi khai ba mã
   là ba mã lệch nhau sau lần sửa thứ tư. Biến thứ tư (--pack-accent-lit) là sắc
   SÁNG chỉ dùng cho chữ trên nền mực: #0e7c86 trên #0b2429 chỉ 3,3:1, dưới ngưỡng
   4,5:1 của chữ thường — xem .pack-tabs .acct-tab.active. */
:root {
  --pack-accent: #0e7c86;
  --pack-accent-ink: #0a5b63;
  --pack-accent-soft: #e6f5f7;
  --pack-accent-lit: #7fe0e8;
}
html.dark {
  --pack-accent: #3aa8b0;
  --pack-accent-ink: #86d8de;
  --pack-accent-soft: #082024;
  --pack-accent-lit: #9ae7ee;
}
.pack-panel {
  border: 2px solid var(--pack-accent);
  box-shadow: 0 0 0 4px rgba(14, 124, 134, .12), 0 6px 22px rgba(6, 26, 28, .1);
}
.pack-panel .panel-title { color: var(--pack-accent-ink); letter-spacing: .01em; }
html.dark .pack-panel {
  box-shadow: 0 0 0 4px rgba(58, 168, 176, .16), 0 6px 22px rgba(0, 0, 0, .34);
}

/* ── Tab kênh ────────────────────────────────────────────────────────────────
   Dựng trên .acct-tab sẵn có (đã có .active, :focus-visible, transition) nên ở đây
   chỉ thêm HAI thứ .acct-tab không có: bảng màu gold cho 3 tab kênh, và cho phép
   xuống dòng ở bề ngang hẹp.

   Ba tab dùng CHUNG một cặp --tab-ink/--tab-soft, khác hẳn dãy tab Tài khoản nơi
   mỗi tab một màu. Cố ý: màu ở đây phân biệt "đang chọn / chưa chọn", không phân
   biệt tab nào với tab nào — ba kênh là ba mức giá của CÙNG một sản phẩm, tô ba
   màu khác nhau sẽ đọc thành ba sản phẩm rời. */
.pack-tabs {
  --tab-ink: var(--pack-accent-ink);
  --tab-soft: var(--pack-accent-soft);
  flex-wrap: wrap;
  margin: 0 0 4px;
  border-color: rgba(14, 124, 134, .4);
  background: transparent;
}
html.dark .pack-tabs { border-color: rgba(58, 168, 176, .45); }

/* Tab ĐANG CHỌN: nền MỰC TEAL SẪM, chữ cyan sáng — không phải nền cyan chữ trắng
   như .acct-tab mặc định. Hai lý do, cái sau mới là cái chính:
     · cyan đặc #0e7c86 dưới chữ trắng chỉ đạt ~3,6:1, dưới ngưỡng 4,5:1;
     · một khối cyan đặc giữa dãy tab cyan nhạt đọc ra nhãn giảm giá. Đảo sang
       mực sẫm giữ nguyên độ tương phản "đang chọn" mà chuyển chất từ nhựa sang
       kim loại — cùng cách thẻ cao cấp dùng nền tối viền sáng.
   Chữ phải là --pack-accent-lit (sắc SÁNG), KHÔNG phải --pack-accent: #0e7c86 trên
   nền #0b2429 chỉ 3,3:1. Đây là chỗ duy nhất cần sắc thứ tư đó.
   Giữ nền đặc (không chỉ đổi màu chữ) để phân biệt được cả khi không nhìn màu. */
.pack-tabs .acct-tab.active {
  background: #0b2429;
  border-color: #0b2429;
  color: var(--pack-accent-lit);
  box-shadow: inset 0 0 0 1px rgba(127, 224, 232, .45);
}
html.dark .pack-tabs .acct-tab.active {
  background: #061a1d;
  border-color: rgba(58, 168, 176, .7);
  color: var(--pack-accent-lit);
}

/* Câu mô tả kênh, ngay dưới thanh tab. */
.pack-tab-note { margin: 8px 0 14px; font-size: .82rem; line-height: 1.55; }

/* ── Kênh chưa chốt giá ──────────────────────────────────────────────────────
   "???" phải to bằng cỡ giá thật để khách hiểu đây là CHỖ của giá, không phải một
   lỗi hiển thị. Dashed viền để phân biệt với thẻ gói bán được. */
.pack-soon {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 30px 18px;
  text-align: center;
  background: var(--bg-alt);
  border: 1px dashed rgba(14, 124, 134, .55);
  border-radius: var(--radius-md);
}
.pack-soon-price {
  font-family: var(--font-mono);
  font-size: 2.1rem; font-weight: 700; letter-spacing: .06em;
  color: var(--pack-accent-ink);
}
.pack-soon p { margin: 0; max-width: 46ch; font-size: .86rem; line-height: 1.6; }
html.dark .pack-soon { border-color: rgba(58, 168, 176, .5); }

@media (max-width: 560px) {
  /* Ba tab xuống ba dòng đầy chiều ngang: ở bề ngang hẹp, nhãn "Claude Kênh Giá Rẻ
     — Tốc độ chậm" bị bóp thành 4 dòng chữ trong một nút hẹp. overflow-x của
     .acct-tabs cũng phải tắt, nếu không flex-wrap không có tác dụng. */
  .pack-tabs { flex-direction: column; align-items: stretch; overflow-x: visible; }
  .pack-tabs .acct-tab { white-space: normal; text-align: left; }
}
