/* =========================================================================
   VisioMind AI Hub — Hệ thống thiết kế & giao diện Chat
   Thẩm mỹ "Ink & Signal": nền mực sẫm, một điểm nhấn tím điện (accent) dùng
   tiết chế cho các trạng thái sống động. Không phụ thuộc framework CSS.
   ========================================================================= */

/* ---------- Biến chủ đề (Dark mặc định) ---------- */
:root {
  --bg:            #0e1016;
  --bg-elev:       #15181f;
  --surface:       #1c2029;
  --surface-hover: #232833;
  --border:        rgba(255, 255, 255, 0.08);
  --border-strong: rgba(255, 255, 255, 0.14);
  --text:          #e8eaed;
  --text-muted:    #9aa0aa;
  --text-faint:    #6b7280;

  --accent:        #7b6cf6;
  --accent-hover:  #8f82f8;
  --accent-soft:   rgba(123, 108, 246, 0.14);
  --danger:        #ef4444;
  --success:       #22c55e;
  --warning:       #f59e0b;

  --user-bubble:   rgba(123, 108, 246, 0.13);

  --radius:        14px;
  --radius-sm:     9px;
  --sidebar-w:     272px;

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
          Arial, "Noto Sans", sans-serif;
  --mono: "SF Mono", "JetBrains Mono", "Fira Code", ui-monospace, Menlo, Consolas, monospace;

  --shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  /* Lớp phủ nhẹ — xem ghi chú ở khối [data-theme="light"]. */
  --overlay:        rgba(255, 255, 255, 0.055);
  --overlay-strong: rgba(255, 255, 255, 0.085);
}

/* ---------- Light mode ---------- */
[data-theme="light"] {
  --bg:            #f6f6f8;
  --bg-elev:       #ffffff;
  --surface:       #ffffff;
  --surface-hover: #f0f0f3;
  --border:        rgba(0, 0, 0, 0.09);
  --border-strong: rgba(0, 0, 0, 0.16);
  --text:          #16181d;
  --text-muted:    #5c626d;
  --text-faint:    #8b909a;
  --accent:        #6d5eff;
  --accent-hover:  #5a49f5;
  --accent-soft:   rgba(109, 94, 255, 0.10);
  --user-bubble:   rgba(109, 94, 255, 0.09);
  --shadow: 0 12px 32px rgba(0, 0, 0, 0.12);
  /* Lớp phủ nhẹ trên nền. Theme tối phủ TRẮNG mờ, theme sáng phải phủ ĐEN mờ — dùng cùng
     một giá trị cho cả hai khiến ô nhập và bong bóng vô hình trên nền sáng. */
  --overlay:        rgba(0, 0, 0, 0.045);
  --overlay-strong: rgba(0, 0, 0, 0.075);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html, body { height: 100%; }

body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}

button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }
input, textarea { font-family: inherit; }
a { color: var(--accent); }

/* Scrollbar tinh gọn */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 8px; border: 3px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background: var(--text-faint); background-clip: padding-box; }

/* =========================================================================
   Bố cục chính
   ========================================================================= */
.layout {
  display: flex;
  height: 100vh;            /* dự phòng cho trình duyệt cũ */
  height: 100vh; height: 100dvh;           /* CHIỀU CAO ĐỘNG: tự trừ đi bàn phím trên di động */
  height: calc(100vh - var(--kb, 0px)); height: calc(100dvh - var(--kb, 0px));  /* dự phòng thêm: JS đo bàn phím (Safari cũ) */
}

/* ---------- Sidebar ---------- */
.sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: var(--bg-elev);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  transition: width 0.28s var(--ease), transform 0.28s var(--ease);
  overflow: hidden;
}
.sidebar.collapsed { width: 0; border-right: none; }

.sidebar-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 16px 12px;
}

/* Dấu hiệu thương hiệu: chấm "node" nhấp nháy báo AI cục bộ đang sống */
.brand { display: flex; align-items: center; gap: 9px; font-weight: 650; letter-spacing: -0.3px; font-size: 16px; }
.brand-node {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 var(--accent);
  animation: pulse 2.6s var(--ease) infinite;
}
@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 rgba(123, 108, 246, 0.5); }
  70%  { box-shadow: 0 0 0 7px rgba(123, 108, 246, 0); }
  100% { box-shadow: 0 0 0 0 rgba(123, 108, 246, 0); }
}

.new-chat-btn {
  flex-shrink: 0;
  margin: 4px 12px 12px;
  padding: 11px 14px;
  display: flex; align-items: center; gap: 9px;
  background: var(--accent);
  color: #fff;
  border-radius: var(--radius-sm);
  font-weight: 550;
  font-size: 14px;
  transition: background 0.15s, transform 0.1s;
}
.new-chat-btn:hover { background: var(--accent-hover); }
.new-chat-btn:active { transform: scale(0.98); }
.new-chat-btn svg { width: 17px; height: 17px; }

.conv-list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 0 8px; }
.conv-list-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.6px; color: var(--text-faint); padding: 8px 10px 6px; }

.conv-item {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font-size: 14px;
  cursor: pointer;
  transition: background 0.13s, color 0.13s;
  position: relative;
}
.conv-item:hover { background: var(--surface-hover); color: var(--text); }
.conv-item.active { background: var(--accent-soft); color: var(--text); }
.conv-item .title { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.conv-item .actions { display: none; gap: 2px; }
.conv-item:hover .actions, .conv-item.active .actions { display: flex; }
.icon-btn {
  width: 26px; height: 26px; display: grid; place-items: center;
  border-radius: 6px; color: var(--text-faint);
  transition: background 0.12s, color 0.12s;
}
.icon-btn:hover { background: var(--border-strong); color: var(--text); }
.icon-btn.danger:hover { color: var(--danger); }
.icon-btn svg { width: 15px; height: 15px; }

.sidebar-foot { flex-shrink: 0; border-top: 1px solid var(--border); padding: 10px 12px; }
.user-chip {
  display: flex; align-items: center; gap: 10px;
  padding: 8px; border-radius: var(--radius-sm);
  transition: background 0.13s;
}
.user-chip:hover { background: var(--surface-hover); }
.avatar {
  width: 30px; height: 30px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), #b5a6ff);
  display: grid; place-items: center; color: #fff; font-weight: 600; font-size: 13px;
  flex-shrink: 0; overflow: hidden;
}
.avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.user-chip .meta { flex: 1; overflow: hidden; }
.user-chip .name { font-size: 13.5px; font-weight: 550; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.user-chip .role { font-size: 11.5px; color: var(--text-faint); }

/* =========================================================================
   Khu vực chat chính
   ========================================================================= */
.main { flex: 1; display: flex; flex-direction: column; min-width: 0; }

.topbar {
  height: 56px; flex-shrink: 0;
  display: flex; align-items: center; gap: 12px;
  padding: 0 16px;
  border-bottom: 1px solid var(--border);
  /* Mặc định của flex là min-width:auto, nên một nhãn dài đẩy vỡ cả hàng thay vì bị cắt.
     Thanh này cao cố định 56px: phải cắt bớt, không được xuống dòng. */
  min-width: 0;
}
.topbar > * { min-width: 0; }
.topbar .toggle-sidebar { display: grid; }

/* Bộ chọn model */
.model-select {
  position: relative;
}
.model-select-btn {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 14px; font-weight: 550;
  transition: background 0.13s, border-color 0.13s;
}
.model-select-btn { max-width: 240px; }
/* Tên model do người dùng tự đặt, dài bao nhiêu cũng có. Cắt ở đây, giữ đủ tên trong title. */
.model-select-btn #current-model {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.model-select-btn .dot, .model-select-btn svg { flex-shrink: 0; }
.model-select-btn:hover { background: var(--surface-hover); border-color: var(--border-strong); }
.model-select-btn .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--success); }
.model-select-btn .dot.off { background: var(--text-faint); }
.model-select-btn svg { width: 15px; height: 15px; color: var(--text-muted); }

.model-menu {
  position: absolute; top: calc(100% + 6px); left: 0;
  min-width: 280px; max-width: 380px; max-height: 380px;
  display: flex; flex-direction: column; overflow: hidden;   /* ô tìm kiếm đứng yên, danh sách cuộn */
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 6px;
  z-index: 40;
  opacity: 0; transform: translateY(-6px); pointer-events: none;
  transition: opacity 0.16s, transform 0.16s;
}
.model-menu.open { opacity: 1; transform: translateY(0); pointer-events: auto; }
.model-option {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 10px; border-radius: var(--radius-sm);
  font-size: 14px; cursor: pointer;
}
.model-option:hover { background: var(--surface-hover); }
.model-option.selected { color: var(--accent); font-weight: 600; }
.model-option .check { margin-left: auto; opacity: 0; }
.model-option.selected .check { opacity: 1; }
.model-menu .empty-note { padding: 12px 10px; font-size: 13px; color: var(--text-faint); }

/* Bộ chọn model CÓ TÌM KIẾM khi nhúng ở trang khác (Studio / Projects / Image) */
.model-select--enhanced .model-menu { max-width: min(380px, calc(100vw - 24px)); }
.model-menu.align-right { left: auto; right: 0; }

.topbar-spacer { flex: 1; }

/* ---------- Chọn QVI / Line trên thanh trên cùng ---------- */
.qvi-context {
  display: flex; align-items: center; gap: 8px;
  min-width: 0;                 /* cho phép ô chọn co lại thay vì đẩy vỡ hàng */
}
.qvi-context[hidden] { display: none; }
.qvi-label {
  font-size: 13px; color: var(--text-muted); white-space: nowrap; flex-shrink: 0;
}
.qvi-select {
  max-width: 220px; min-width: 120px;
  padding: 7px 10px;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  font-size: 14px; font-weight: 550;
  text-overflow: ellipsis;
}
.qvi-select:hover { border-color: var(--border-strong); }
.qvi-select:disabled { opacity: 0.6; cursor: progress; }
.qvi-approve {
  display: inline-flex; align-items: center; gap: 7px; flex-shrink: 0;
  padding: 7px 12px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  color: var(--text-muted); font-size: 14px; white-space: nowrap;
  transition: background 0.13s, color 0.13s, border-color 0.13s;
}
.qvi-approve:hover {
  background: var(--surface-hover); color: var(--text); border-color: var(--border-strong);
}
.qvi-approve svg { width: 16px; height: 16px; flex-shrink: 0; }
.topbar-actions { display: flex; align-items: center; gap: 4px; }

/* Vùng cuộn tin nhắn */
.messages { flex: 1; overflow-y: auto; scroll-behavior: smooth; }
.messages-inner { max-width: 760px; margin: 0 auto; padding: 28px 20px 12px; }

/* Trạng thái rỗng */
.empty-state {
  height: 100%; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  padding: 40px 20px; gap: 14px;
}
.empty-logo {
  width: 54px; height: 54px; border-radius: 16px;
  background: var(--accent-soft);
  display: grid; place-items: center;
}
.empty-logo .brand-node { width: 16px; height: 16px; }
.empty-state h1 { font-size: 24px; font-weight: 650; letter-spacing: -0.5px; }
.empty-state p { color: var(--text-muted); max-width: 420px; }
.suggestions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 12px; width: 100%; max-width: 460px; }
.suggestion {
  text-align: left; padding: 13px 15px;
  border: 1px solid var(--border); border-radius: var(--radius);
  font-size: 13.5px; color: var(--text-muted);
  transition: border-color 0.14s, background 0.14s, color 0.14s;
}
.suggestion:hover { border-color: var(--accent); background: var(--accent-soft); color: var(--text); }

/* Tin nhắn */
.msg { display: flex; gap: 14px; padding: 14px 0; }
.msg .msg-avatar {
  width: 30px; height: 30px; border-radius: 8px; flex-shrink: 0;
  display: grid; place-items: center; font-size: 13px; font-weight: 600; overflow: hidden;
}
.msg .msg-avatar img { width: 100%; height: 100%; display: block; object-fit: cover; }
.msg-avatar-fallback, .msg-avatar-ai { display: grid; width: 100%; height: 100%; place-items: center; }
.msg.user .msg-avatar { background: var(--user-bubble); color: var(--accent); }
.msg.assistant .msg-avatar { background: var(--accent); color: #fff; }
.msg .msg-body { flex: 1; min-width: 0; padding-top: 3px; }
.msg-images { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.msg-img { max-width: 220px; max-height: 220px; border-radius: 12px; border: 1px solid var(--border); object-fit: cover; cursor: pointer; }
.msg .msg-role { font-size: 13px; font-weight: 650; margin-bottom: 3px; }

/* Nội dung markdown đã render */
.md { font-size: 15px; line-height: 1.7; word-wrap: break-word; overflow-wrap: break-word; }
.md > *:first-child { margin-top: 0; }
.md > *:last-child { margin-bottom: 0; }
.md p { margin: 0 0 12px; }
.md h1, .md h2, .md h3, .md h4 { margin: 20px 0 10px; font-weight: 650; line-height: 1.3; }
.md h1 { font-size: 1.5em; } .md h2 { font-size: 1.3em; } .md h3 { font-size: 1.13em; }
.md ul, .md ol { margin: 0 0 12px; padding-left: 24px; }
.md li { margin: 4px 0; }
.md a { text-decoration: underline; text-underline-offset: 2px; }
.md blockquote { border-left: 3px solid var(--accent); padding: 2px 0 2px 14px; margin: 0 0 12px; color: var(--text-muted); }
.md hr { border: none; border-top: 1px solid var(--border); margin: 18px 0; }
.md :not(pre) > code {
  font-family: var(--mono); font-size: 0.88em;
  background: var(--surface); border: 1px solid var(--border);
  padding: 1px 6px; border-radius: 6px;
}
.md table { border-collapse: collapse; width: 100%; margin: 0 0 14px; font-size: 14px; display: block; overflow-x: auto; }
.md th, .md td { border: 1px solid var(--border); padding: 8px 12px; text-align: left; }
.md th { background: var(--surface); font-weight: 600; }

/* Code block + nút Copy */
.code-block {
  margin: 4px 0 16px; border-radius: 12px; overflow: hidden;
  border: 1px solid var(--border); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);
}
.code-block-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 14px; background: var(--bg-elev);
  border-bottom: 1px solid var(--border);
  font-size: 11.5px; color: var(--text-faint); font-family: var(--mono);
  letter-spacing: 0.05em; text-transform: uppercase;
}
/* Tên file (khi khối mã khai báo ```lang path) — nổi bật hơn nhãn ngôn ngữ */
.code-block-head .code-file {
  color: var(--accent, #7b6cf6); text-transform: none; letter-spacing: 0;
  font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 70%;
}
.copy-btn {
  display: flex; align-items: center; gap: 5px;
  font-size: 11.5px; color: var(--text-muted);
  font-family: var(--font, system-ui, sans-serif);
  text-transform: none; letter-spacing: 0;
  padding: 4px 9px; border-radius: 7px; border: 1px solid transparent;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.copy-btn:hover { background: var(--surface-hover); color: var(--text); border-color: var(--border); }
.copy-btn svg { width: 13px; height: 13px; }
.copy-btn.copied { color: var(--success); }
.code-block pre { margin: 0; padding: 15px 16px; overflow-x: auto; background: var(--bg); }
.code-block code {
  font-family: var(--mono); font-size: 13px; line-height: 1.7;
  white-space: pre; tab-size: 2; -moz-tab-size: 2; color: var(--code-fg, #abb2bf);
}
/* Thanh cuộn ngang gọn cho code */
.code-block pre::-webkit-scrollbar { height: 9px; }
.code-block pre::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 8px; }
.code-block pre::-webkit-scrollbar-thumb:hover { background: var(--text-faint); }
.code-block pre::-webkit-scrollbar-track { background: transparent; }

/* Tô màu cú pháp — bảng màu tối (mặc định) */
.tok-cmt { color: #7d8799; font-style: italic; }
.tok-str { color: #98c379; }
.tok-num { color: #d19a66; }
.tok-kw  { color: #c678dd; }
.tok-lit { color: #56b6c2; }
.tok-fn  { color: #61afef; }

/* Bảng màu sáng */
[data-theme="light"] .code-block code { color: #383a42; }
[data-theme="light"] .tok-cmt { color: #9098a3; }
[data-theme="light"] .tok-str { color: #50a14f; }
[data-theme="light"] .tok-num { color: #b76b01; }
[data-theme="light"] .tok-kw  { color: #a626a4; }
[data-theme="light"] .tok-lit { color: #0184bc; }
[data-theme="light"] .tok-fn  { color: #4078f2; }

/* Con trỏ gõ khi đang stream */
.typing-cursor { display: inline-block; width: 8px; height: 16px; background: var(--accent); border-radius: 2px; vertical-align: text-bottom; animation: blink 1s steps(2) infinite; }
@keyframes blink { 50% { opacity: 0; } }

/* Chấm "đang gõ" trước khi có token đầu tiên */
.typing-dots { display: inline-flex; gap: 4px; padding: 4px 0; }
.typing-dots span { width: 7px; height: 7px; border-radius: 50%; background: var(--text-faint); animation: bounce 1.3s var(--ease) infinite; }
.typing-dots span:nth-child(2) { animation-delay: 0.18s; }
.typing-dots span:nth-child(3) { animation-delay: 0.36s; }
@keyframes bounce { 0%, 60%, 100% { transform: translateY(0); opacity: 0.5; } 30% { transform: translateY(-5px); opacity: 1; } }

/* =========================================================================
   Vùng nhập
   ========================================================================= */
.composer-wrap {
  flex-shrink: 0;
  padding: 8px 20px 18px;
  /* Chừa chỗ cho thanh home / vùng khuyết của điện thoại */
  padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  background: var(--bg);     /* nền đặc: nội dung không "lòi" ra sau ô nhập */
}
.composer {
  max-width: 760px; margin: 0 auto;
  border: 1px solid var(--border-strong);
  border-radius: 24px;
  background: var(--bg-elev);
  padding: 10px 10px 8px 14px;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.composer:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

/* Chip tài liệu đính kèm */
.doc-chip {
  display: none; align-items: center; gap: 8px;
  margin-bottom: 8px; padding: 7px 10px;
  background: var(--accent-soft); border-radius: var(--radius-sm);
  font-size: 13px; color: var(--text);
}
.doc-chip.show { display: inline-flex; }
.doc-chip svg { width: 15px; height: 15px; color: var(--accent); }
.doc-chip .remove { margin-left: 4px; cursor: pointer; color: var(--text-muted); }
.doc-chip .remove:hover { color: var(--danger); }

/* Xem trước ảnh đính kèm trong ô nhập */
.image-previews { display: none; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.image-previews.show { display: flex; }
.img-thumb { position: relative; width: 62px; height: 62px; border-radius: 10px; overflow: hidden; border: 1px solid var(--border-strong); }
.img-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.img-thumb .remove {
  position: absolute; top: 2px; right: 2px; width: 18px; height: 18px;
  display: grid; place-items: center; border-radius: 50%;
  background: rgba(0,0,0,0.6); color: #fff; font-size: 12px; line-height: 1; cursor: pointer;
}
.img-thumb .remove:hover { background: var(--danger); }

/* Ô chữ chiếm TRỌN một dòng; công cụ nằm ở hàng dưới (kiểu ChatGPT/Claude).
   Bản cũ xếp tất cả trên một hàng ngang, nên mỗi nút thêm vào lại bóp ô chữ hẹp lại —
   bật chế độ Flow là còn một mẩu vừa đủ vài chữ. */
.composer textarea {
  display: block; width: 100%; resize: none; border: none; outline: none;
  background: none; color: var(--text); font-family: inherit;
  font-size: 15px; line-height: 1.55;
  min-height: 26px; max-height: 200px; padding: 4px 4px 2px;
}
.composer-tools {
  display: flex; align-items: center; gap: 8px; margin-top: 4px;
}
.tool-group {
  display: flex; align-items: center; gap: 2px;
  flex: 1; min-width: 0;
  /* Bật Flow là có thêm 🔧 + bộ chọn máy + 📎; trên điện thoại hàng này sẽ chật.
     Cho cuộn ngang thay vì để các nút bị ép méo hoặc đẩy nút Gửi ra khỏi màn hình. */
  overflow-x: auto; scrollbar-width: none;
}
.tool-group::-webkit-scrollbar { display: none; }
/* Trong hàng cuộn ngang, KHÔNG cho phần tử co lại: co lại thì trên điện thoại bộ chọn máy
   bị bóp còn một mẩu không đọc được tên, thay vì để người dùng vuốt ngang. */
.tool-group > * { flex-shrink: 0; }
.composer textarea::placeholder { color: var(--text-faint); }
.attach-btn { width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; color: var(--text-muted); transition: background 0.13s, color 0.13s; flex-shrink: 0; }
.attach-btn:hover { background: var(--surface-hover); color: var(--text); }
.attach-btn svg { width: 19px; height: 19px; }
.send-btn {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  background: var(--accent); color: #fff; display: grid; place-items: center;
  transition: background 0.13s, transform 0.1s, opacity 0.13s;
}
.send-btn:hover { background: var(--accent-hover); }
.send-btn:active { transform: scale(0.94); }
.send-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.send-btn svg { width: 18px; height: 18px; }
.composer-hint { max-width: 760px; margin: 8px auto 0; text-align: center; font-size: 11.5px; color: var(--text-faint); }

/* =========================================================================
   Tiện ích chung: nút, toast, menu người dùng
   ========================================================================= */
.ghost-btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 12px; border-radius: var(--radius-sm);
  color: var(--text-muted); font-size: 14px;
  transition: background 0.13s, color 0.13s;
}
.ghost-btn:hover { background: var(--surface-hover); color: var(--text); }
.ghost-btn svg { width: 17px; height: 17px; }

/* Menu người dùng */
.user-menu {
  position: absolute; bottom: 62px; left: 12px; right: 12px;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius); box-shadow: var(--shadow); padding: 6px;
  opacity: 0; transform: translateY(6px); pointer-events: none;
  transition: opacity 0.16s, transform 0.16s; z-index: 50;
}
.user-menu.open { opacity: 1; transform: translateY(0); pointer-events: auto; }
.user-menu a, .user-menu button {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 9px 10px; border-radius: var(--radius-sm);
  font-size: 14px; color: var(--text); text-decoration: none; text-align: left;
}
.user-menu a:hover, .user-menu button:hover { background: var(--surface-hover); }
.user-menu svg { width: 16px; height: 16px; color: var(--text-muted); }

/* Toast thông báo */
.toast-stack { position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; gap: 8px; z-index: 200; }
.toast {
  padding: 11px 16px; border-radius: var(--radius); font-size: 14px;
  background: var(--surface); border: 1px solid var(--border-strong);
  box-shadow: var(--shadow); animation: toast-in 0.25s var(--ease);
  max-width: 340px;
}
.toast.error { border-left: 3px solid var(--danger); }
.toast.success { border-left: 3px solid var(--success); }
@keyframes toast-in { from { opacity: 0; transform: translateY(10px); } }

/* Lớp phủ mobile */
.overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.5);
  opacity: 0; pointer-events: none; transition: opacity 0.25s; z-index: 30;
}
.overlay.show { opacity: 1; pointer-events: auto; }

/* =========================================================================
   Responsive
   ========================================================================= */
@media (max-width: 820px) {
  .sidebar {
    position: fixed; top: 0; left: 0; z-index: 40;
    width: var(--sidebar-w);
    height: 100vh;            /* dự phòng trình duyệt cũ */
    height: 100vh; height: 100dvh;           /* Chrome Android: bám vùng hiển thị thực (trừ thanh địa chỉ) */
    transform: translateX(-100%); box-shadow: var(--shadow);
  }
  .sidebar.open { transform: translateX(0); }
  .sidebar.collapsed { width: var(--sidebar-w); transform: translateX(-100%); }
  .messages-inner, .composer, .composer-hint { max-width: 100%; }
  .suggestions { grid-template-columns: 1fr; }
  .topbar .toggle-sidebar { display: grid; }
}

/* Tôn trọng người dùng tắt hiệu ứng chuyển động */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* Nhãn node trong menu chọn model */
.model-node { font-size: 10.5px; padding: 1px 6px; border-radius: 999px; background: var(--accent-soft); color: var(--accent); margin-left: 6px; vertical-align: middle; }
/* Model do admin đặt mặc định — đứng đầu danh sách, ai cũng dùng được. Nhãn xám nhạt để
   nó giải thích chứ không tranh chú ý với tên model. */
.model-default { font-size: 10.5px; padding: 1px 6px; border-radius: 999px;
  background: var(--overlay-strong); color: var(--text-muted); margin-left: 6px;
  vertical-align: middle; font-weight: 600; }

/* Focus rõ ràng cho bàn phím */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* =========================================================================
   Nâng cấp trải nghiệm (tính năng pro)
   ========================================================================= */

/* Tìm kiếm hội thoại */
.conv-search { flex-shrink: 0; display: flex; align-items: center; gap: 8px; margin: 0 12px 10px; padding: 8px 11px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.conv-search svg { width: 15px; height: 15px; color: var(--text-faint); flex-shrink: 0; }
.conv-search input { flex: 1; border: none; outline: none; background: none; color: var(--text); font-size: 13.5px; }
.conv-search input::placeholder { color: var(--text-faint); }

/* Hành động trên tin nhắn (copy / regenerate) */
.msg-actions { display: flex; gap: 4px; margin-top: 8px; opacity: 0; transition: opacity 0.14s; }
.msg:hover .msg-actions, .msg-actions.pinned { opacity: 1; }
.msg-action {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px; border-radius: 7px; font-size: 12px; color: var(--text-muted);
  transition: background 0.12s, color 0.12s;
}
.msg-action:hover { background: var(--surface-hover); color: var(--text); }
.msg-action svg { width: 13px; height: 13px; }
.msg-action.done { color: var(--success); }

/* Thống kê dưới câu trả lời */
.msg-stats { margin-top: 6px; font-size: 11.5px; color: var(--text-faint); display: flex; gap: 12px; }

/* ============ Khối suy nghĩ của model (reasoning / thinking models) ============
   Triết lý: KHÔNG phải nội dung chính, nên phải LÙI VỀ SAU — chữ mờ, không viền,
   không nền. Đang nghĩ thì mở sẵn và nhấp nháy nhẹ; nghĩ xong thì tự thu gọn. */
.reasoning { margin: 0 0 14px; }

.reasoning > summary {
  display: inline-flex; align-items: center; gap: 7px;
  cursor: pointer; user-select: none; list-style: none;
  padding: 4px 8px; margin-left: -8px; border-radius: 8px;
  font-size: 13px; color: var(--text-faint);
  transition: color 0.15s, background 0.15s;
}
.reasoning > summary::-webkit-details-marker { display: none; }
.reasoning > summary:hover { color: var(--text-muted); background: var(--surface); }

.reasoning .th-icon { width: 14px; height: 14px; flex-shrink: 0; opacity: 0.8; }
.reasoning .th-chev {
  width: 13px; height: 13px; flex-shrink: 0; opacity: 0.6;
  transition: transform 0.2s ease;
}
.reasoning[open] > summary .th-chev { transform: rotate(90deg); }

/* Icon để TĨNH khi đang nghĩ — không nhấp nháy, chữ cuộn đã đủ báo hiệu */
.reasoning.thinking .th-icon { opacity: 0.75; }
/* Nhãn "Đang suy nghĩ…" để TĨNH (trước đây có hiệu ứng quét sáng gây cảm giác nháy) */
.th-shimmer { color: var(--text-muted); }

/* Nội dung suy nghĩ: khung nhỏ cố định, chữ cuộn dần lên */
.reasoning .reason-body {
  margin: 6px 0 0 6px;
  padding: 8px 12px;
  background: rgba(128, 128, 128, 0.07);
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 12.5px; line-height: 1.65; color: var(--text-faint);
  max-height: 140px;                 /* khung nhỏ cố định */
  overflow-y: auto;                  /* chữ chạy/cuộn bên trong */
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong, #8884) transparent;
}
.reasoning .reason-body::-webkit-scrollbar { width: 6px; }
.reasoning .reason-body::-webkit-scrollbar-track { background: transparent; }
.reasoning .reason-body::-webkit-scrollbar-thumb { background: var(--border-strong, var(--border)); border-radius: 3px; }
.reasoning .reason-body p { margin: 7px 0; }
.reasoning .reason-body p:first-child { margin-top: 0; }
.reasoning .reason-body p:last-child { margin-bottom: 0; }
.reasoning .reason-body code { font-size: 12px; opacity: 0.9; }
.reasoning .reason-body .code-block { margin: 8px 0; opacity: 0.85; }
.reasoning .reason-body h1, .reasoning .reason-body h2, .reasoning .reason-body h3 {
  font-size: 13px; font-weight: 600; color: var(--text-muted); margin: 8px 0 4px;
}

/* Nút cuộn xuống cuối */
.scroll-bottom {
  position: absolute; left: 50%; transform: translateX(-50%) translateY(8px);
  bottom: 104px; width: 38px; height: 38px; border-radius: 50%;
  background: var(--surface); border: 1px solid var(--border-strong); box-shadow: var(--shadow);
  display: grid; place-items: center; color: var(--text); z-index: 10;
  opacity: 0; pointer-events: none; transition: opacity 0.18s, transform 0.18s;
}
.scroll-bottom.show { opacity: 1; pointer-events: auto; transform: translateX(-50%) translateY(0); }
.scroll-bottom svg { width: 18px; height: 18px; }
.scroll-bottom:hover { background: var(--surface-hover); }

/* Nút gửi khi đang stream -> chế độ Dừng */
.send-btn.stop { background: var(--danger); }
.send-btn.stop:hover { background: #dc2626; }

/* Kéo-thả ảnh vào ô nhập */
.composer.dragover { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.composer.dragover::after { content: "Thả ảnh vào đây"; position: absolute; }

/* Lightbox xem ảnh */
.lightbox {
  position: fixed; inset: 0; z-index: 300; background: rgba(0,0,0,0.85);
  display: none; align-items: center; justify-content: center; padding: 32px; cursor: zoom-out;
}
.lightbox.show { display: flex; }
.lightbox img { max-width: 92vw; max-height: 92vh; border-radius: 10px; box-shadow: 0 20px 60px rgba(0,0,0,0.5); }

/* Con trỏ zoom cho ảnh trong tin nhắn */
.msg-img { cursor: zoom-in; }

@media (max-width: 820px) {
  .scroll-bottom { bottom: 96px; }
}

/* Thanh trên cùng trên máy hẹp: giữ MỘT hàng, rút gọn phần chữ dài trước.
   Nhãn và chữ trên nút biến mất, nhưng aria-label/title vẫn còn nên trình đọc màn hình
   và tooltip không mất thông tin. */
@media (max-width: 820px) {
  .topbar { gap: 8px; padding: 0 10px; }
  .model-select-btn { max-width: 150px; }
  .qvi-label { display: none; }
  .qvi-select { min-width: 96px; max-width: 150px; font-size: 13px; }
  .qvi-approve-text { display: none; }
  .qvi-approve { padding: 7px 9px; }
}
@media (max-width: 560px) {
  /* Dưới 560px không đủ chỗ cho cả hai. Ưu tiên ô chọn QVI vừa đủ đọc được tên line,
     phần còn lại dành cho tên model — tên đầy đủ vẫn có trong tooltip. */
  .model-select-btn { max-width: 132px; padding: 7px 9px; }
  .qvi-select { min-width: 80px; max-width: 112px; padding: 7px 8px; }
  .topbar { gap: 6px; padding: 0 8px; }
}

/* ---------- Nguồn trích dẫn từ Cơ sở tri thức (RAG) ---------- */
.msg-sources {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin-top: 12px; padding: 9px 11px;
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--accent); border-radius: 8px;
}
.msg-sources .src-label {
  width: 100%; font-size: 11.5px; font-weight: 600; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 2px;
}
.msg-sources .src-item {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; color: var(--text-muted);
  background: var(--bg-elev); border: 1px solid var(--border);
  padding: 3px 9px; border-radius: 999px; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.msg-sources .src-item b { color: var(--accent); font-weight: 600; }

/* Nguồn là ẢNH (visual RAG): thumbnail bấm để phóng to */
.msg-sources .src-item.is-img { padding-left: 4px; }
.msg-sources .src-thumb {
  width: 26px; height: 26px; object-fit: cover; border-radius: 5px;
  border: 1px solid var(--border); cursor: zoom-in; opacity: 0;
  transition: opacity 0.2s, transform 0.12s;
}
.msg-sources .src-thumb.loaded { opacity: 1; }
.msg-sources .src-thumb:hover { transform: scale(1.08); border-color: var(--accent); }

/* ===================== Modal (Bộ nhớ / Tri thức của tôi) ===================== */
.modal {
  position: fixed; inset: 0; z-index: 200; display: none;
  background: rgba(0, 0, 0, 0.55); backdrop-filter: blur(3px);
  align-items: center; justify-content: center; padding: 20px;
}
.modal.open { display: flex; }
.modal-box {
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: 16px; width: min(760px, 100%); max-height: 86vh;
  overflow-y: auto; padding: 20px 22px; box-shadow: 0 24px 60px rgba(0,0,0,0.45);
}
.modal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.modal-head h3 { font-size: 17px; font-weight: 650; }
.modal-close {
  width: 30px; height: 30px; border-radius: 8px; color: var(--text-muted);
  font-size: 15px; transition: background 0.12s, color 0.12s;
}
.modal-close:hover { background: var(--surface-hover); color: var(--text); }

.modal-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; padding: 10px 12px; margin-bottom: 12px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
}
.modal-bar-right { display: flex; gap: 6px; flex-wrap: wrap; }
.switch { display: flex; align-items: center; gap: 8px; font-size: 13.5px; cursor: pointer; }
.switch input { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
.chip-btn.danger { color: var(--danger); }

.mem-hint { font-size: 12.5px; color: var(--text-faint); margin-bottom: 12px; line-height: 1.5; }

.mem-add { display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.mem-add select, .mem-add input {
  padding: 9px 11px; border-radius: 9px; border: 1px solid var(--border);
  background: var(--surface); color: var(--text); font-size: 13px; outline: none;
}
.mem-add select { flex: 0 0 140px; }
.mem-add input { flex: 1; min-width: 120px; }
.mem-add select:focus, .mem-add input:focus { border-color: var(--accent); }

.mem-list { display: flex; flex-direction: column; gap: 6px; }
.mem-list .empty { color: var(--text-faint); font-size: 13.5px; padding: 18px 4px; line-height: 1.6; }
.mem-row {
  display: grid; grid-template-columns: 96px 1fr auto auto; gap: 10px; align-items: center;
  padding: 9px 11px; background: var(--surface);
  border: 1px solid var(--border); border-radius: 10px;
}
.mem-row.pinned { border-color: var(--accent); background: var(--accent-soft); }
.mem-cat {
  font-size: 11px; font-weight: 600; color: var(--accent);
  background: var(--accent-soft); padding: 3px 8px; border-radius: 999px; text-align: center;
}
.mem-body { min-width: 0; }
.mem-key { font-size: 11.5px; color: var(--text-faint); margin-bottom: 2px; }
.mem-sub { font-size: 11.5px; color: var(--text-faint); }
.mem-val {
  width: 100%; background: transparent; border: 1px solid transparent; color: var(--text);
  font-size: 13.5px; padding: 3px 5px; border-radius: 6px; outline: none;
}
.mem-val:hover { border-color: var(--border); }
.mem-val:focus { border-color: var(--accent); background: var(--bg); }
.mem-imp { font-size: 11px; color: var(--warning, #f0a500); letter-spacing: -1px; white-space: nowrap; }
.mem-acts { display: flex; gap: 5px; }

@media (max-width: 640px) {
  .mem-row { grid-template-columns: 1fr auto; }
  .mem-cat, .mem-imp { grid-column: 1; justify-self: start; }
}

/* ===================== Nút & form dùng trong modal =====================
   Các class này vốn chỉ có trong admin.css. Trang chat chỉ nạp style.css,
   nên phải định nghĩa lại ở đây, nếu không modal sẽ mất hoàn toàn bố cục
   (input/textarea về mặc định inline-block => nằm cạnh nhau). */
.chip-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; font-size: 12.5px; font-weight: 500;
  color: var(--text-muted); background: var(--surface);
  border: 1px solid var(--border); border-radius: 9px;
  cursor: pointer; transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.chip-btn:hover { background: var(--surface-hover); color: var(--text); border-color: var(--border-strong); }
.chip-btn.danger:hover { border-color: var(--danger); background: rgba(239, 68, 68, 0.1); color: var(--danger); }

.primary-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; font-size: 13px; font-weight: 600;
  color: #fff; background: var(--accent); border: 1px solid var(--accent);
  border-radius: 9px; cursor: pointer; transition: filter 0.12s, transform 0.06s;
}
.primary-btn:hover { filter: brightness(1.08); }
.primary-btn:active { transform: translateY(1px); }
.primary-btn svg { width: 15px; height: 15px; }

.mini {
  padding: 4px 9px; font-size: 11.5px; font-weight: 500;
  color: var(--text-muted); background: var(--bg-elev);
  border: 1px solid var(--border); border-radius: 7px;
  cursor: pointer; transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.mini:hover { background: var(--surface-hover); color: var(--text); }
.mini.danger:hover { border-color: var(--danger); color: var(--danger); background: rgba(239, 68, 68, 0.1); }

.badge { font-size: 11px; padding: 2px 9px; border-radius: 999px; font-weight: 600; white-space: nowrap; }
.badge.on  { background: rgba(34, 197, 94, 0.15); color: var(--success); }
.badge.idx { background: var(--accent-soft); color: var(--accent); }
.badge.err { background: rgba(239, 68, 68, 0.15); color: var(--danger); }

/* Khối thêm tài liệu trong modal "Tri thức của tôi" */
.modal .kb-add { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.modal .kb-add input[type="text"] {
  width: 100%; padding: 10px 13px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
  font-size: 13.5px; font-family: inherit; outline: none;
}
.modal .kb-add textarea {
  width: 100%; min-height: 96px; resize: vertical; padding: 11px 13px;
  border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--surface); color: var(--text);
  font-size: 13.5px; font-family: inherit; line-height: 1.55; outline: none;
}
.modal .kb-add input:focus, .modal .kb-add textarea:focus {
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.modal .kb-add-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.modal .kb-status { font-size: 12.5px; color: var(--text-muted); }

/* =========================================================================
   Ô NHẬP TRÊN ĐIỆN THOẠI — to hơn, dễ bấm, không bị bàn phím che
   ========================================================================= */
@media (max-width: 820px) {
  .composer-wrap {
    padding: 8px 12px;
    padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
    /* Dính đáy màn hình khả kiến, luôn nổi trên nội dung */
    position: sticky; bottom: 0; z-index: 20;
    border-top: 1px solid var(--border);
  }

  .composer {
    border-radius: 24px;
    padding: 6px 6px 6px 12px;
  }

  .composer textarea {
    /* 16px là NGƯỠNG BẮT BUỘC: dưới 16px, Safari/iOS tự phóng to trang khi gõ */
    font-size: 16px;
    line-height: 1.45;
    padding: 10px 0;
    min-height: 24px;
    max-height: 40vh;          /* gõ dài vẫn thấy, không nuốt hết màn hình */
  }

  /* Vùng chạm ≥ 44px theo khuyến nghị của Apple/Google */
  .attach-btn { width: 42px; height: 42px; }
  .attach-btn svg { width: 21px; height: 21px; }
  .send-btn { width: 42px; height: 42px; }
  .send-btn svg { width: 20px; height: 20px; }

  .composer-tools { gap: 6px; }

  /* Dòng gợi ý chiếm chỗ quý giá trên màn hình nhỏ -> ẩn khi bàn phím bật */
  .composer-hint { font-size: 11px; margin-top: 6px; }
  body.kb-open .composer-hint { display: none; }

  /* Bàn phím bật: thu gọn khoảng đệm cho ô nhập nổi hẳn lên */
  body.kb-open .composer-wrap { padding-bottom: 6px; }
  body.kb-open .topbar { display: none; }   /* nhường chỗ cho nội dung + ô nhập */
}

@media (max-width: 820px) {
  /* Cuộn mượt, không "kéo" luôn cả trang phía sau khi đã cuộn hết tin nhắn */
  .messages {
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
  /* Vùng tin nhắn chừa chỗ để dòng cuối không nấp sau ô nhập */
  .messages-inner { padding-bottom: 8px; }
}

/* Nhãn trạng thái câu trả lời (dừng giữa chừng / bị gián đoạn) */
.msg-status {
  display: inline-block; margin-top: 8px;
  font-size: 11.5px; font-weight: 500;
  padding: 3px 9px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--border); color: var(--text-faint);
}
.msg-status.cancelled { color: var(--warning); border-color: rgba(245, 158, 11, 0.3); }
.msg-status.failed { color: var(--danger); border-color: rgba(239, 68, 68, 0.3); }

/* "Đang tạo câu trả lời…" khi mở lại hội thoại đang sinh dở */
.gen-pending {
  display: flex; align-items: center; gap: 8px;
  margin-top: 6px; font-size: 13.5px; color: var(--text-muted);
}
.gp-dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent);
  animation: gp-pulse 1.2s ease-in-out infinite;
}
@keyframes gp-pulse {
  0%, 100% { opacity: 0.35; transform: scale(0.85); }
  50%      { opacity: 1;    transform: scale(1.15); }
}

/* ===== Modal Tài khoản & mật khẩu ===== */
#account-modal .modal-box { max-width: 440px; }
.account-section { padding: 4px 2px 2px; }
.account-section h4 {
  margin: 0 0 12px; font-size: 13px; font-weight: 600;
  color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em;
}
.acc-field { display: block; margin-bottom: 12px; }
.acc-field > span {
  display: block; margin-bottom: 5px; font-size: 12.5px; color: var(--text-faint);
}
.acc-field > input {
  width: 100%; box-sizing: border-box;
  padding: 9px 12px; border-radius: 9px;
  border: 1px solid var(--border); background: var(--bg);
  color: var(--text); font-size: 14px; font-family: inherit;
  transition: border-color 0.12s, box-shadow 0.12s;
}
.acc-field > input:focus {
  outline: none; border-color: var(--accent, #7b6cf6);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent, #7b6cf6) 22%, transparent);
}
#account-modal .primary-btn { width: 100%; margin-top: 2px; }
.account-divider {
  height: 1px; background: var(--border); margin: 18px 0;
}

/* ===== Internet Search: nút toggle + menu ===== */
.search-toggle { position: relative; display: inline-flex; }
#search-btn { position: relative; }
#search-btn.active { color: var(--accent); }
.search-dot {
  position: absolute; right: 3px; bottom: 3px; width: 7px; height: 7px; border-radius: 50%;
  background: var(--text-faint); box-shadow: 0 0 0 2px var(--bg-composer, var(--bg));
}
.search-dot.auto { background: var(--accent); }
.search-dot.always { background: #22c55e; }
.search-dot.never { background: transparent; box-shadow: none; }
.search-menu {
  position: absolute; bottom: calc(100% + 8px); left: 0; z-index: 60; min-width: 232px;
  background: var(--bg-elev); border: 1px solid var(--border-strong, var(--border));
  border-radius: 12px; padding: 8px; box-shadow: 0 10px 30px rgba(0,0,0,.35);
  display: none;
}
.search-menu.open { display: block; }
.search-menu-title { font-size: 12px; color: var(--text-faint); padding: 4px 8px 8px; font-weight: 600; }
.search-menu label {
  display: flex; align-items: center; gap: 8px; padding: 8px; border-radius: 8px;
  cursor: pointer; font-size: 13.5px; color: var(--text);
}
.search-menu label:hover { background: var(--surface-hover); }
.search-menu label em { color: var(--text-faint); font-style: normal; font-size: 12px; }
.search-menu input[type="radio"] { accent-color: var(--accent); }

/* ===== Trạng thái đang tìm ===== */
.msg-search-status {
  display: inline-flex; align-items: center; gap: 7px; margin-bottom: 8px;
  font-size: 13px; color: var(--text-muted); background: var(--bg-elev);
  border: 1px solid var(--border); border-radius: 20px; padding: 5px 12px;
}
.ss-spin {
  width: 12px; height: 12px; border: 2px solid var(--border-strong, var(--border));
  border-top-color: var(--accent); border-radius: 50%; display: inline-block;
  animation: ss-rotate .7s linear infinite;
}
@keyframes ss-rotate { to { transform: rotate(360deg); } }

/* ===== Nguồn Internet ===== */
.msg-web-sources { margin-top: 12px; }
.msg-web-sources .src-label { font-size: 12.5px; color: var(--text-faint); font-weight: 600; margin-bottom: 6px; }
.web-src-item {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px; margin-bottom: 6px;
  border: 1px solid var(--border); border-radius: 10px; text-decoration: none;
  color: var(--text); transition: border-color .15s, background .15s;
}
.web-src-item:hover { border-color: var(--accent); background: var(--surface-hover); }
.ws-num {
  flex-shrink: 0; width: 22px; height: 22px; border-radius: 50%; background: var(--accent);
  color: #fff; font-size: 12px; font-weight: 700; display: grid; place-items: center;
}
.ws-body { display: flex; flex-direction: column; min-width: 0; }
.ws-title { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ws-host { font-size: 11.5px; color: var(--text-faint); }

/* ===== Ảnh AI vẽ trong chat ===== */
.msg-images { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 10px; }
.msg-img-link { display: block; border-radius: 12px; overflow: hidden; border: 1px solid var(--border); max-width: 360px; }
.msg-img-link img { display: block; width: 100%; height: auto; cursor: zoom-in; transition: transform .2s; }
.msg-img-link:hover img { transform: scale(1.02); }

/* ===== Badge model cloud trong bộ chọn ===== */
.model-cloud {
  font-size: 10.5px; padding: 1px 7px; border-radius: 10px; margin-left: 6px;
  background: rgba(123, 108, 246, 0.16); color: var(--accent); font-weight: 600; vertical-align: middle;
}

/* ===== Tìm kiếm trong bộ chọn model ===== */
.model-search {
  display: flex; align-items: center; gap: 8px; padding: 2px 2px 8px;
  border-bottom: 1px solid var(--border); margin-bottom: 6px; flex-shrink: 0;
}
.model-search input {
  flex: 1; min-width: 0; padding: 8px 11px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--bg); color: var(--text);
  font-size: 13.5px; font-family: inherit;
}
.model-search input:focus { outline: none; border-color: var(--accent); }
.ms-count { font-size: 11.5px; color: var(--text-faint); white-space: nowrap; flex-shrink: 0; }
.model-list { overflow-y: auto; flex: 1; min-height: 0; scrollbar-width: thin; }
.model-list::-webkit-scrollbar { width: 6px; }
.model-list::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
.model-option.active { background: var(--surface-hover); box-shadow: inset 2px 0 0 var(--accent); }
.mo-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── v2.9.38: tích hợp Decision Logic vào chat ─────────────────────────── */
.doc-decision {
  display: none; margin-left: 8px; padding: 3px 10px; border-radius: 999px;
  border: 1px solid var(--accent); background: transparent; color: var(--accent);
  font-size: 12px; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.doc-decision.show { display: inline-flex; }
.doc-decision:hover { background: var(--accent); color: #fff; }

.msg-decision {
  margin-top: 10px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--bg-elev, var(--bg)); padding: 12px 14px; max-width: 640px;
}
.dc-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 4px; }
.dc-title { font-weight: 700; font-size: 14px; color: var(--text); }
.dc-badge { font-size: 11px; font-weight: 700; padding: 2px 9px; border-radius: 999px; }
.dc-badge.safe { background: rgba(34,197,94,.16); color: var(--success); }
.dc-badge.mid  { background: rgba(245,158,11,.16); color: var(--warning); }
.dc-badge.low  { background: rgba(239,68,68,.16); color: var(--danger); }
.dc-sub { font-size: 12px; color: var(--text-muted); margin-bottom: 10px; }
.dc-key { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 8px; }
.dc-k { text-align: center; background: var(--bg); border: 1px solid var(--border); border-radius: 9px; padding: 8px 6px; }
.dc-k b { display: block; font-size: 18px; }
.dc-k span { font-size: 10.5px; color: var(--text-muted); }
.dc-k.danger b { color: var(--danger); }
.dc-k.warn b { color: var(--warning); }
.dc-k.ok b { color: var(--success); }
.dc-thin { font-size: 12px; color: var(--danger); margin-bottom: 8px; }
.dc-rules, .dc-alts { margin-top: 6px; }
.dc-rules summary, .dc-alts summary { cursor: pointer; font-size: 12.5px; color: var(--accent); font-weight: 600; }
.dc-rules pre {
  margin-top: 6px; padding: 10px; background: var(--bg); border: 1px solid var(--border);
  border-radius: 8px; overflow-x: auto; font-size: 12px; line-height: 1.5; white-space: pre;
}
.dc-tbl { width: 100%; border-collapse: collapse; margin-top: 6px; font-size: 11.5px; }
.dc-tbl th, .dc-tbl td { border-bottom: 1px solid var(--border); padding: 5px 6px; text-align: left; }
.dc-tbl .dc-feat { color: var(--text-muted); }
.dc-tbl .dc-fok { color: var(--danger); font-weight: 600; }
.dc-lv { padding: 1px 7px; border-radius: 999px; font-size: 10.5px; font-weight: 600; }
.dc-lv.safe { background: rgba(34,197,94,.16); color: var(--success); }
.dc-lv.mid  { background: rgba(245,158,11,.16); color: var(--warning); }
.dc-lv.low  { background: rgba(239,68,68,.16); color: var(--danger); }
.dc-open {
  display: inline-block; margin-top: 10px; padding: 7px 14px; border-radius: 8px;
  background: linear-gradient(135deg, var(--accent), var(--accent-hover, var(--accent)));
  color: #fff; font-size: 12.5px; font-weight: 650; text-decoration: none;
}
.dc-open:hover { filter: brightness(1.06); }
@media (max-width: 640px) { .dc-key { grid-template-columns: 1fr; } .msg-decision { max-width: 100%; } }

/* ── v2.9.47: chỉ báo Skill đã kích hoạt ─────────────────────────────── */
.skill-chip {
  display: inline-flex; align-items: center; gap: 6px; margin-bottom: 8px;
  padding: 3px 10px; border-radius: 999px; font-size: 12px; font-weight: 600;
  color: var(--accent); background: rgba(123,108,246,.12); border: 1px solid rgba(123,108,246,.35);
}
.skill-chip .skill-ic { font-size: 11px; }

/* ---- AI Vision Agent (tích hợp trong chat) ---- */
.va-toggle.active { background: var(--accent, #7b6cf6); color: #fff; border-radius: 8px; }
/* Bộ chọn NƠI THỰC THI: máy chủ (Hub) hay NX Desktop của người dùng. Chỉ hiện khi bật chế
   độ Flow, và thu về một biểu tượng khi tài khoản chưa có máy nào đăng ký. */
.va-target { max-width: 190px; height: 32px; padding: 0 6px; font: inherit; font-size: 12.5px;
  color: var(--text); background: var(--overlay); border: 1px solid var(--border);
  border-radius: 8px; cursor: pointer; }
.va-target:hover { background: var(--surface-hover); }
.va-target:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.va-target.va-target-1 { max-width: 44px; }
/* Quãng Hub thụ động chờ máy người dùng chạy — không hiện gì thì người dùng tưởng treo. */
.va-tool-wait { margin-top: 6px; padding: 8px 10px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--overlay); font-size: 13px; }
.va-tool-wait ul { margin: 4px 0 0; padding-left: 18px; }
.va-tool-wait code { font-family: var(--mono); font-size: 11.5px; color: var(--text-muted); }
/* Ảnh / log / kết quả máy người dùng gửi lên. Không có khối này thì hỏi "cho xem ảnh" xong
   vẫn phải mở NX Desktop lên nhìn — mất hẳn ý nghĩa của việc hỏi từ Web. */
.va-xem-box { margin-top: 8px; display: flex; flex-direction: column; gap: 8px; }
.va-xem { padding: 8px 10px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--overlay); }
.va-xem-head { font-size: 12.5px; color: var(--text-muted); margin-bottom: 6px; }
.va-xem-head code { font-family: var(--mono); font-size: 11.5px; }
.va-xem-anh { display: block; max-width: 100%; max-height: 420px; border-radius: 8px;
  background: var(--bg); }
.va-xem-log { margin: 0; padding: 8px; max-height: 260px; overflow: auto;
  background: var(--bg-elev); border-radius: 8px; font-family: var(--mono);
  font-size: 11.5px; line-height: 1.5; white-space: pre-wrap; word-break: break-word; }
.va-result { margin-top: 8px; padding: 10px 12px; border: 1px solid var(--border);
  border-radius: 10px; background: rgba(123,108,246,0.06); font-size: 14px; line-height: 1.6; }
.va-actions { margin-top: 8px; }
.va-result .btn-sm { padding: 6px 12px; border-radius: 8px; border: 1px solid var(--accent, #7b6cf6);
  background: var(--accent, #7b6cf6); color: #fff; cursor: pointer; font-size: 13px; }
.va-result .btn-sm:hover { opacity: .9; }
/* Trạng thái thất bại: viền + nền đỏ nhạt để phân biệt ngay với khối kết quả thành công.
   Dùng màu cảnh báo của theme, không chói, vẫn đọc được trên nền tối. */
.va-result.va-failed { border-color: rgba(240, 92, 92, 0.55); background: rgba(240, 92, 92, 0.07); }
.va-result.va-failed i { color: var(--text-muted); font-style: normal; }


/* ---- Hội thoại làm rõ yêu cầu trước khi Vision Agent thay đổi flow ---- */
.va-clarify { margin-top: 6px; padding: 14px; border-radius: 12px;
  border: 1px solid rgba(123,108,246,.42); background: rgba(123,108,246,.07);
  font-size: 14px; line-height: 1.55; }
.va-clarify.ready { border-color: rgba(78,201,138,.48); background: rgba(78,201,138,.07); }
.va-clarify-head { font-weight: 700; font-size: 15px; margin-bottom: 3px; }
.va-clarify-note { color: var(--text-muted); font-size: 12px; margin-bottom: 12px; }
.va-question { padding: 10px 0; border-top: 1px solid var(--border); }
.va-question:first-of-type { border-top: 0; padding-top: 2px; }
.va-options { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 8px; }
.va-option { border: 1px solid rgba(123,108,246,.5); background: var(--overlay);
  color: var(--text); border-radius: 999px; padding: 6px 11px; cursor: pointer;
  font: inherit; font-size: 12px; transition: border-color .15s, background .15s; }
.va-option:hover { border-color: var(--accent, #7b6cf6); background: rgba(123,108,246,.14); }
.va-option.selected { border-color: var(--accent, #7b6cf6); background: var(--accent, #7b6cf6); color: #fff; }
.va-answer-input { display: block; width: 100%; box-sizing: border-box; margin-top: 8px;
  padding: 8px 10px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--overlay); color: var(--text); font: inherit; font-size: 13px; outline: none; }
.va-answer-input:focus { border-color: var(--accent, #7b6cf6); box-shadow: 0 0 0 2px rgba(123,108,246,.12); }
.va-clarify-actions .va-submit-answers { border-color: var(--accent, #7b6cf6);
  background: var(--accent, #7b6cf6); color: #fff; }
.va-clarify-actions .va-submit-answers:disabled { cursor: not-allowed; opacity: .42; }
.va-clarify-summary { margin-top: 8px; padding: 10px 12px; border-radius: 8px;
  border-left: 3px solid #4ec98a; background: rgba(0,0,0,.1); white-space: normal; }
.va-clarify-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.va-clarify-actions .btn-sm { padding: 7px 12px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--border); background: var(--overlay); color: var(--text); }
.va-clarify-actions .va-confirm { border-color: #4ec98a; background: #319c68; color: #fff; }
.va-clarify-actions .va-cancel:hover { border-color: #f05c5c; color: #f05c5c; }
@media (max-width: 640px) {
  .va-clarify { padding: 12px; }
  .va-options, .va-clarify-actions { align-items: stretch; }
  .va-clarify-actions .btn-sm { flex: 1 1 auto; }
}

/* ---- Dòng thời gian chi tiết của Vision Agent ---- */
.va-steps { margin: 6px 0 2px; border-left: 2px solid var(--border); padding-left: 10px; }
.va-steps > summary { cursor: pointer; font-size: 13px; color: var(--text-muted);
  list-style: none; padding: 2px 0; user-select: none; }
.va-steps > summary::-webkit-details-marker { display: none; }
.va-steps > summary::before { content: "▸ "; }
.va-steps[open] > summary::before { content: "▾ "; }
.va-steps > summary:hover { color: var(--text); }
.va-phase { font-size: 12px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--accent, #7b6cf6); margin: 8px 0 2px; }
.va-step-list { margin: 0; padding-left: 18px; font-size: 13px; line-height: 1.5; }
.va-step-list > li { margin: 1px 0; }
.va-step-icon { color: #4ec98a; font-weight: 700; }
.va-step-bad .va-step-icon { color: #f05c5c; }
.va-step-bad { color: #f05c5c; }
.va-step-ms { color: var(--text-muted); font-size: 12px; }
.va-step-detail { color: var(--text-muted); font-size: 12px; margin: 1px 0 3px 14px; }
.va-step-bad .va-step-detail { color: #f0a0a0; }
/* Mã chẩn đoán nx-flow (edge.type, flow.no-root…) — tra được trực tiếp trong tài liệu */
.va-step-cmd { font-family: ui-monospace, "Cascadia Code", Consolas, monospace; font-size: 11px;
  color: var(--text-muted); background: rgba(255,255,255,.04); border-radius: 4px;
  padding: 1px 5px; display: inline-block; margin: 0 0 3px 14px; }
.va-steps code { font-size: 12px; background: rgba(255,255,255,.05); border-radius: 4px; padding: 0 4px; }
.va-bad { color: #f05c5c; }

/* ---- Gợi ý chuyển sang Vision Agent (hiện trong chat thường) ---- */
.vision-suggest { margin-top: 8px; padding: 10px 12px; border-radius: 10px;
  border: 1px dashed var(--accent, #7b6cf6); background: rgba(123,108,246,.06);
  font-size: 14px; line-height: 1.55; }
.vision-suggest .btn-sm { margin-top: 8px; padding: 6px 12px; border-radius: 8px;
  border: 1px solid var(--accent, #7b6cf6); background: var(--accent, #7b6cf6);
  color: #fff; cursor: pointer; font-size: 13px; }
.vision-suggest .btn-sm:hover { opacity: .9; }
.vision-suggest p { margin: 0; }
.vision-badge { margin-top: 6px; font-size: 12px; color: var(--text-muted); }

/* ---- Chỉ báo "đang chạy" ---- */
.va-running { display: flex; align-items: center; gap: 8px; margin-top: 4px;
  font-size: 13px; color: var(--text-muted); }
.va-elapsed { font-variant-numeric: tabular-nums; }
.va-dots { display: inline-flex; gap: 4px; }
.va-dots i { width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent, #7b6cf6); display: inline-block;
  animation: va-pulse 1.2s ease-in-out infinite; }
.va-dots i:nth-child(2) { animation-delay: .2s; }
.va-dots i:nth-child(3) { animation-delay: .4s; }
@keyframes va-pulse { 0%, 80%, 100% { opacity: .25; } 40% { opacity: 1; } }
/* Tôn trọng thiết lập giảm chuyển động của hệ điều hành */
@media (prefers-reduced-motion: reduce) {
  .va-dots i { animation: none; opacity: .7; }
}
.va-hint { font-size: 12px; color: var(--text-muted); margin: 2px 0 0 14px;
  font-style: italic; }
.va-mat-ket-noi { color: #e8b84b; display: block; line-height: 1.5;
  border-left: 2px solid #e8b84b; padding-left: 8px; }
/* Nhãn cho câu trả lời lấy thẳng từ catalog nx-flow (không qua LLM) — giúp người dùng
   biết thông tin này là dữ kiện chính xác, không phải model suy diễn. */
.va-src { margin-top: 10px; font-size: 12px; color: var(--text-muted);
  border-top: 1px solid var(--border); padding-top: 6px; }

/* ---- Kiến thức hệ thống (Knowledge Center) ---- */
.kc-note { color: var(--text-muted); font-size: 13px; line-height: 1.6; margin: 0 0 14px; }
.sk-cost { padding: 10px 12px; border-radius: 10px; margin-bottom: 14px; font-size: 14px;
  border-left: 3px solid var(--accent); background: rgba(123,108,246,.07); }
.sk-cost.warn { border-left-color: #e8b84b; background: rgba(232,184,75,.08); }
.sk-cost.over { border-left-color: #f05c5c; background: rgba(240,92,92,.08); }
.sk-cost-note { font-size: 12px; color: var(--text-muted); margin-top: 4px; }
.sk-form { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.sk-form input, .sk-form textarea, .sk-form select {
  background: var(--overlay); border: 1px solid var(--border);
  border-radius: 8px; color: var(--text); padding: 8px 10px; font: inherit; font-size: 14px; }
.sk-form textarea { resize: vertical; }
.sk-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.sk-row #sk-priority { width: 90px; }
.sk-preview { background: var(--overlay); border: 1px solid var(--border);
  border-radius: 8px; padding: 12px; font-size: 13px; line-height: 1.55; white-space: pre-wrap;
  max-height: 320px; overflow-y: auto; margin-bottom: 14px; }
.sk-item { border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px;
  margin-bottom: 8px; }
.sk-item.off { opacity: .5; }
.sk-item-head { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; font-size: 14px; }
.sk-badge { font-size: 11px; padding: 2px 7px; border-radius: 999px;
  background: var(--overlay-strong); color: var(--text-muted); }
.sk-act { margin-left: auto; display: flex; gap: 6px; }
.sk-item-body { font-size: 13px; color: var(--text-muted); margin-top: 6px;
  line-height: 1.5; white-space: pre-wrap; }
.kc-mini { padding: 3px 9px; border-radius: 6px; border: 1px solid var(--border);
  background: transparent; color: var(--text); cursor: pointer; font-size: 12px; }
.kc-mini.danger { color: #f05c5c; border-color: rgba(240,92,92,.4); }

/* ---- Tính năng bị cắt quyền ---- */
/* Chế độ "mờ đi": dùng khi ẩn hẳn làm vỡ bố cục hàng nút. */
.feature-off { opacity: .35; cursor: not-allowed; pointer-events: none; }

/* ---- Nhắn tin giữa người dùng (Unified Chat) ---- */
/* MỘT hàng "Tin nhắn", không phải một khối ba ô.
 *
 * Bản trước là một thẻ có viền bao, ba ô icon-trên-nhãn-dưới, cao ~62px kể cả lề. Ba vấn đề:
 *   · nó đọc như một KHỐI LẠ chèn vào giữa danh sách hội thoại và thẻ người dùng — khác
 *     nhịp, khác chiều (dọc, trong khi cả sidebar là các hàng ngang), khác cỡ chữ (11px);
 *   · viền bao thứ hai nằm ngay trên viền của `.sidebar-foot` -> hai đường kẻ song song
 *     cách nhau vài pixel, thứ luôn trông như lỗi dựng giao diện;
 *   · "Hồ sơ" bị xếp ngang hàng với hai hành động nhắn tin, trong khi nó là mục CÁ NHÂN —
 *     đúng chỗ của nó là menu người dùng ngay bên dưới, cạnh "Tài khoản & mật khẩu".
 *
 * Sau khi trả "Hồ sơ" về đúng chỗ, còn lại đúng một hành động chính (mở danh sách người để
 * nhắn) và một hành động phụ (tạo nhóm) — vừa vặn MỘT hàng, dùng đúng khuôn của `.conv-item`
 * nên nó hoà vào sidebar thay vì ngồi đè lên. Cao 34px thay vì 62px.
 */
.dm-tools { display: flex; align-items: center; gap: 2px; margin: 6px 8px 2px; }
.dm-tool { flex: 1; min-width: 0; position: relative; display: flex; align-items: center;
  gap: 9px; padding: 8px 8px 8px 10px; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--text-muted); font: inherit; font-size: 13.5px;
  line-height: 1.2; cursor: pointer; transition: background 0.13s, color 0.13s; }
.dm-tool:hover { background: var(--surface-hover); color: var(--text); }
.dm-tool svg { width: 17px; height: 17px; flex-shrink: 0; fill: none; stroke: currentColor;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.dm-tool-label { flex: 1; min-width: 0; text-align: left; font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Badge nằm TRONG dòng, sát mép phải nhãn — cùng cách `.conv-item` xử lý phần đuôi.
   Bản trước ghim tuyệt đối vào góc ô nên nó lơ lửng đè lên icon. */
.dm-tool-badge { position: static; flex-shrink: 0; }

/* Hành động phụ: tạo nhóm. Icon trần + tooltip, nhạt hơn hàng chính để mắt đi vào việc
   chính trước — và chỉ sáng lên khi được trỏ tới. */
.dm-tool-add { flex-shrink: 0; width: 30px; height: 30px; display: grid; place-items: center;
  border: 0; border-radius: var(--radius-sm); background: transparent;
  color: var(--text-faint); cursor: pointer; transition: background 0.13s, color 0.13s; }
.dm-tool-add:hover { background: var(--surface-hover); color: var(--text); }
.dm-tool-add svg { width: 16px; height: 16px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

.dm-badge { margin-left: auto; min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 999px; background: #f05c5c; color: #fff; font-size: 11px;
  display: inline-flex; align-items: center; justify-content: center; font-weight: 600; }
/* BẮT BUỘC: `display: inline-flex` ở trên thắng luật `[hidden] { display: none }` của trình
   duyệt (chọn theo class mạnh hơn), nên badge vẫn hiện khi `hidden` — đó là lý do sidebar
   luôn có chấm đỏ "0" dù không có tin chưa đọc. */
.dm-badge[hidden] { display: none; }

.dm-panel { position: fixed; right: 20px; bottom: 20px; width: 360px; height: 520px;
  max-height: 76vh; display: flex; flex-direction: column; z-index: 60;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 14px; box-shadow: 0 18px 48px rgba(0,0,0,.45); overflow: hidden; }
.dm-panel[hidden] { display: none !important; }
.dm-head { min-height: 64px; display: flex; align-items: center; gap: 9px; padding: 8px 10px;
  border-bottom: 1px solid var(--border); background: color-mix(in srgb, var(--surface) 94%, var(--accent)); }
.dm-head-btn { width: 34px; height: 34px; display: grid; place-items: center; flex-shrink: 0;
  border: 0; border-radius: 9px; background: transparent; color: var(--text-muted); cursor: pointer; }
.dm-head-btn:hover { background: var(--overlay-strong); color: var(--text); }
.dm-head-btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round; }
.dm-who { min-width: 0; flex: 1; display: flex; align-items: center; gap: 10px; line-height: 1.25; }
.dm-who-copy { min-width: 0; display: flex; flex-direction: column; }
.dm-who-copy b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; }
.dm-who-copy > span { font-size: 11px; color: var(--text-muted); margin-top: 2px; }
.dm-head-avatar { display: inline-flex; flex-shrink: 0; }
.dm-ava.head { width: 36px; height: 36px; font-size: 15px; }
.dm-head-actions { display: flex; align-items: center; gap: 2px; }
.dm-body { flex: 1; overflow-y: auto; padding: 14px 12px; display: flex;
  flex-direction: column; gap: 7px; }
.dm-msg { width: fit-content; max-width: 86%; align-self: flex-start; display: grid;
  grid-template-columns: 32px minmax(0, 1fr); column-gap: 8px; position: relative; }
/* ⚠ MỌI khối nội dung phải được ghim vào cột 2. Cột 1 rộng 32px và dành cho avatar;
   phần tử nào không có trong danh sách này sẽ bị grid tự đặt vào đó và co lại còn 32px.
   `.dm-quote` (trích dẫn trả lời) và `.dm-reacts` (cảm xúc) là hai khối mới — quên chúng
   ở đây thì trong NHÓM chúng nát, còn chat hai người lại bình thường vì `.dm-msg.mine`
   dùng `display:block`. */
.dm-msg > .dm-sender, .dm-msg > .dm-bubble, .dm-msg > .dm-att, .dm-msg > .dm-time,
.dm-msg > .dm-quote, .dm-msg > .dm-reacts {
  grid-column: 2; min-width: 0; }
.dm-msg.mine { align-self: flex-end; display: block; max-width: 78%; }
.dm-msg.mine > .dm-msg-avatar { display: none; }
.dm-bubble { padding: 8px 11px; border-radius: 14px; font-size: 14px; line-height: 1.5;
  background: var(--overlay-strong); white-space: pre-wrap; word-break: break-word; }
.dm-msg.mine .dm-bubble { background: var(--accent); color: #fff; border-bottom-right-radius: 5px; }
.dm-msg:not(.mine) .dm-bubble { border-bottom-left-radius: 5px; }
/* AI đang xếp hàng sau một lượt khác trong cùng nhóm. Bong bóng trống không phân biệt được
   với hỏng — phải có chữ, và phải nhạt hơn nội dung thật để không ai đọc nhầm thành câu
   trả lời. */
.dm-queued { color: var(--text-muted); font-style: italic; }
.dm-time { font-size: 10px; color: var(--text-muted); margin-top: 3px; }
.dm-msg.mine .dm-time { text-align: right; }
.dm-input { display: flex; gap: 8px; padding: 10px; align-items: flex-end;
  border-top: 1px solid var(--border); }
/* ⚠ `min-width: 0` là BẮT BUỘC.
   Mặc định flex item không co nhỏ hơn kích thước NỘI TẠI của nó, mà <textarea> có bề ngang
   nội tại theo thuộc tính `cols` (~20 ký tự). Thiếu dòng này, textarea giữ nguyên bề ngang
   và ĐẨY NÚT GỬI RA NGOÀI khung — đúng lỗi trong ảnh chụp màn hình người dùng gửi. */
.dm-input textarea { flex: 1 1 auto; min-width: 0; box-sizing: border-box;
  resize: none; max-height: 96px; padding: 8px 10px;
  border-radius: 10px; border: 1px solid var(--border); font: inherit; font-size: 14px;
  background: var(--overlay); color: var(--text); }
/* Hai nút không được co lại khi chữ dài. */
.dm-attach, .dm-send { flex: 0 0 auto; height: 38px; }
.dm-send { width: 38px; border-radius: 10px; border: none; cursor: pointer;
  background: var(--accent); color: #fff; font-size: 15px; }
.dm-send:disabled { opacity: .5; cursor: not-allowed; }

.dm-picker { position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 70;
  display: flex; align-items: center; justify-content: center; }
.dm-picker-box { width: min(420px, 92vw); max-height: 70vh; display: flex;
  flex-direction: column; background: var(--surface);
  border: 1px solid var(--border); border-radius: 14px; padding: 14px; }
.dm-picker-head { display: flex; align-items: center; font-size: 15px; font-weight: 600;
  margin-bottom: 10px; }
.dm-x { margin-left: auto; background: none; border: none; color: var(--text-muted);
  cursor: pointer; font-size: 15px; }
.dm-picker-box input { padding: 8px 10px; border-radius: 8px; font: inherit; font-size: 14px;
  border: 1px solid var(--border); background: var(--overlay);
  color: var(--text); margin-bottom: 10px; }
.dm-picker-list { overflow-y: auto; }
.dm-user { display: flex; align-items: center; gap: 10px; padding: 9px 8px;
  border-radius: 8px; cursor: pointer; font-size: 14px; }
.dm-user:hover { background: var(--overlay-strong); }
.dm-ava { width: 28px; height: 28px; border-radius: 50%; display: inline-flex;
  align-items: center; justify-content: center; background: var(--accent);
  color: #fff; font-size: 12px; font-weight: 600; }
.dm-empty { color: var(--text-muted); font-size: 13px; text-align: center; padding: 16px; }

@media (max-width: 600px) {
  .dm-panel { right: 0; bottom: 0; width: 100%; height: 100%; max-height: 100%;
    border-radius: 0; }
}

/* đính kèm trong tin nhắn */
.dm-attach { width: 38px; border-radius: 10px; border: 1px solid var(--border);
  background: transparent; color: var(--text-muted); cursor: pointer; font-size: 15px; }
.dm-attach:hover { color: var(--text); border-color: var(--accent); }
.dm-files { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 10px 0; }
.dm-files[hidden] { display: none !important; }
.dm-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 12px;
  padding: 3px 8px; border-radius: 999px; background: var(--overlay-strong);
  color: var(--text-muted); max-width: 180px; }
.dm-chip button { background: none; border: none; color: inherit; cursor: pointer;
  font-size: 11px; padding: 0; }
.dm-att { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 4px; max-width: 100%; }
/* Nền sau ảnh đính kèm: dùng biến, không khoá cứng màu tối — ảnh PNG trong suốt trên giao
   diện SÁNG sẽ nằm trên một khối gần đen, trông như lỗi hiển thị. */
.dm-att > a:not(.dm-file-link) { display: block; max-width: 100%; overflow: hidden;
  border-radius: 12px; background: var(--bg); line-height: 0; }
.dm-att img { display: block; width: auto; height: auto; max-width: min(240px, 100%);
  max-height: 300px; border-radius: 12px; object-fit: contain; }
.dm-msg.mine .dm-att { justify-content: flex-end; }
.dm-file-link { display: inline-flex; align-items: center; gap: 6px; font-size: 13px;
  padding: 7px 10px; border-radius: 10px; background: var(--overlay-strong);
  color: var(--text); text-decoration: none; }
.dm-file-link:hover { background: var(--overlay-strong); }
.dm-body.over { outline: 2px dashed var(--accent); outline-offset: -6px; }

/* tin nhắn trong sidebar chung */
/* GHIM ở đầu vùng cuộn: cuộn lịch sử AI dài vẫn thấy được tin nhắn chưa đọc.
   Cần nền đục, nếu không các mục AI sẽ hiện xuyên qua khi cuộn bên dưới. */
.dm-section {
  position: sticky; top: 0; z-index: 3;
  background: var(--bg-elev);
  border-bottom: 1px solid var(--border);
  margin: 0 -8px 6px; padding: 0 8px 6px;
  /* Trần chiều cao: nhiều cuộc trò chuyện riêng cũng không được chiếm hết sidebar và đẩy
     lịch sử AI ra khỏi tầm nhìn — đúng lỗi đang sửa, chỉ đảo ngược. */
  max-height: 38vh; overflow-y: auto; overscroll-behavior: contain;
}
.dm-section .conv-list-label { padding-top: 6px; }
.dm-item { display: flex; align-items: center; gap: 8px; }
.dm-ava.sm { width: 20px; height: 20px; font-size: 10px; flex-shrink: 0; }
.dm-item .dm-badge { margin-left: auto; }
.model-select-btn.dm-mode { border-color: var(--accent); }

/* nhóm + mention */
.dm-ava.grp { background: var(--overlay-strong); }
.dm-sender { font-size: 11px; color: var(--text-muted); margin-bottom: 3px; font-weight: 600; }
.dm-msg.ai .dm-bubble { background: rgba(123,108,246,.16);
  border: 1px solid rgba(123,108,246,.3); }
.dm-check { margin-left: auto; color: var(--accent); font-weight: 700; }
.dm-ac { position: absolute; left: 10px; right: 10px; bottom: 62px; z-index: 5;
  max-height: 220px; overflow-y: auto; border-radius: 10px; padding: 4px;
  background: var(--surface); border: 1px solid var(--border);
  box-shadow: 0 -8px 24px rgba(0,0,0,.35); }
.dm-ac-label { font-size: 10px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--text-muted); padding: 6px 8px 3px; }
.dm-ac-item { padding: 7px 9px; border-radius: 7px; cursor: pointer; font-size: 13px; }
.dm-ac-item:hover { background: var(--overlay-strong); }
#dm-newgroup .dm-picker-box input { margin-bottom: 8px; }
#dm-ng-create { width: 100%; margin-top: 10px; }

/* bảng thông tin nhóm */
.dm-who.clickable { cursor: pointer; border-radius: 8px; padding: 2px 6px; margin: -2px -6px; }
.dm-who.clickable:hover { background: var(--overlay-strong); }
#dm-info[hidden] { display: none !important; }
.dm-gi-top { display: flex; align-items: center; gap: 12px; padding: 6px 2px 14px;
  border-bottom: 1px solid var(--border); margin-bottom: 10px; }
.dm-ava.big { width: 48px; height: 48px; font-size: 22px; flex-shrink: 0; }
.dm-gi-name { display: flex; flex-direction: column; line-height: 1.4; min-width: 0; }
.dm-gi-name b { font-size: 15px; }
.dm-gi-name span { font-size: 12px; color: var(--text-muted); }
.dm-gi-top .kc-mini { margin-left: auto; flex-shrink: 0; }
.dm-gi-label { display: flex; align-items: center; font-size: 11px; text-transform: uppercase;
  letter-spacing: .5px; color: var(--text-muted); padding: 4px 2px 8px; }
.dm-gi-label .kc-mini { margin-left: auto; text-transform: none; letter-spacing: 0; }
.dm-user-name em { font-style: normal; color: var(--text-muted); font-size: 12px; }
.dm-role { font-size: 10px; padding: 2px 7px; border-radius: 999px; margin-left: auto;
  background: rgba(123,108,246,.18); color: var(--accent); }
.dm-rm { margin-left: 8px; background: none; border: none; cursor: pointer;
  color: #f05c5c; font-size: 13px; padding: 2px 6px; border-radius: 6px; opacity: .6; }
.dm-user:hover .dm-rm { opacity: 1; }
.dm-role + .dm-rm { margin-left: 8px; }
#dm-gi-leave, #dm-am-ok { width: 100%; margin-top: 12px; }
.vid-btn.danger { border-color: rgba(240,92,92,.45); color: #f05c5c; }

/* chấm trạng thái trực tuyến */
.dm-ava-wrap { position: relative; display: inline-flex; flex-shrink: 0; }
.dm-dot { position: absolute; right: -1px; bottom: -1px; width: 9px; height: 9px;
  border-radius: 50%; background: var(--text-muted);
  /* Viền cùng màu nền để chấm tách khỏi avatar — không có viền thì nó lẫn vào chữ cái. */
  box-shadow: 0 0 0 2px var(--bg-elev); }
.dm-dot.on { background: #4ec98a; }
.dm-ava.sm + .dm-dot { width: 7px; height: 7px; }
.dm-on { color: #4ec98a !important; }

/* xoá & thu hồi tin nhắn */
.dm-msg { position: relative; }
.dm-msg-avatar { grid-column: 1; grid-row: 1 / span 4; align-self: end; display: inline-flex;
  margin-bottom: 14px; }
.dm-ava.message-avatar { width: 30px; height: 30px; padding: 0; flex: 0 0 30px;
  font-size: 10px; box-shadow: 0 0 0 2px var(--bg-elev); }
.dm-ava.message-avatar.ai { background: linear-gradient(135deg, var(--accent), #5c9cf0); letter-spacing: -.4px; }
/* `.dm-more` giờ là một nút trong `.dm-actions`, không còn tự định vị. Giữ lại tên lớp
   vì mã và test đang bám vào `[data-more]`. */
/* `position: fixed` + toạ độ do JS tính, gắn vào PANEL — giống thanh chọn cảm xúc.
   Đặt tuyệt đối bên trong `.dm-actions` thì menu chui xuống dưới hàng viên cảm xúc
   (`.dm-actions` có `transform` -> tự tạo ngữ cảnh xếp chồng, `z-index: 10` của menu chỉ
   còn tác dụng bên trong đó) và xuống dưới cả tin nhắn kế tiếp; tin cuối danh sách thì bị
   `.dm-body` cắt cụt vì khối đó cuộn được. */
.dm-menu { position: fixed; z-index: 70;
  min-width: 168px;
  display: flex; flex-direction: column; padding: 4px; border-radius: 9px;
  background: var(--surface); border: 1px solid var(--border);
  box-shadow: 0 8px 24px rgba(0,0,0,.4); }
.dm-menu button { background: none; border: none; text-align: left; cursor: pointer;
  color: var(--text); font: inherit; font-size: 13px; padding: 7px 9px;
  border-radius: 6px; white-space: nowrap; }
.dm-menu button:hover { background: var(--overlay-strong); }
.dm-msg.recalled .dm-bubble { background: transparent;
  border: 1px dashed var(--border); color: var(--text-muted);
  font-style: italic; font-size: 13px; }

/* ── Trả lời tin nhắn ─────────────────────────────────────────────────────
   Trích dẫn nằm TRONG khối tin, phía trên bong bóng: đặt ngoài thì khi cuộn nhanh
   người đọc không biết nó thuộc tin nào. */
.dm-quote { display: flex; flex-direction: column; gap: 1px; width: 100%;
  text-align: left; cursor: pointer; margin-bottom: 3px; padding: 5px 9px;
  border: none; border-left: 3px solid var(--accent); border-radius: 7px;
  background: var(--overlay-strong); color: var(--text-muted); font: inherit; }
.dm-quote:hover { background: var(--accent-soft); }
.dm-quote-who { font-size: 11.5px; font-weight: 600; color: var(--accent); }
.dm-quote-text { font-size: 12px; line-height: 1.35; overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
/* Nháy khi nhảy tới tin gốc — không có tín hiệu này thì cuộn xong không biết nhìn đâu. */
.dm-msg.flash .dm-bubble { animation: dm-flash 1.2s ease-out; }
@keyframes dm-flash {
  0%, 40% { box-shadow: 0 0 0 3px var(--accent-soft); }
  100%    { box-shadow: 0 0 0 3px transparent; }
}

/* Thanh xem trước phía trên ô nhập */
.dm-reply-bar { display: flex; align-items: center; gap: 8px; padding: 7px 12px;
  border-top: 1px solid var(--border); background: var(--overlay-strong); }
.dm-reply-mark { width: 3px; align-self: stretch; border-radius: 2px;
  background: var(--accent); }
.dm-reply-copy { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.dm-reply-copy b { font-size: 12px; color: var(--accent); }
.dm-reply-copy span { font-size: 12px; color: var(--text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Nhãn báo trước "AI sẽ trả lời": dùng biến màu của theme, KHÔNG ghi cứng — ghi cứng là
   vỡ ngay khi đổi giao diện Sáng/Tối. */
.dm-reply-copy .dm-reply-ai { color: var(--accent); font-weight: 600; }

/* ── Khoá hội thoại bằng mật khẩu (v2.19) ─────────────────────────────────
   Hộp thoại riêng thay vì `prompt()`: `prompt()` hiện mật khẩu dạng chữ thường ngay giữa
   màn hình — đúng thứ tính năng này sinh ra để tránh. Toàn bộ màu lấy từ biến theme. */
.dm-lock-overlay { position: fixed; inset: 0; z-index: 10000; display: flex;
  align-items: center; justify-content: center; padding: 16px;
  background: rgba(0, 0, 0, .55); }
.dm-lock-box { width: min(420px, 100%); display: flex; flex-direction: column; gap: 10px;
  padding: 18px; border-radius: 12px; border: 1px solid var(--border);
  background: var(--bg-elev); color: var(--text);
  box-shadow: 0 12px 40px rgba(0, 0, 0, .35); }
.dm-lock-box h3 { margin: 0; font-size: 16px; }
/* `pre-line` để xuống dòng trong phần mô tả hiện đúng. HTML gộp mọi xuống dòng thành một
   dấu cách, nên không có dòng này thì đoạn giải thích dính liền thành một khối khó đọc. */
.dm-lock-desc { margin: 0; font-size: 12px; line-height: 1.5; color: var(--text-muted);
  white-space: pre-line; }
.dm-lock-field { display: flex; flex-direction: column; gap: 4px; font-size: 12px;
  color: var(--text-muted); }
.dm-lock-field input { padding: 9px 11px; border-radius: 8px; font-size: 14px;
  border: 1px solid var(--border); background: var(--bg); color: var(--text); }
.dm-lock-field input:focus { outline: none; border-color: var(--accent); }
.dm-lock-err { font-size: 12px; color: var(--danger); }
.dm-lock-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; }
.dm-lock-actions button { padding: 8px 16px; border-radius: 8px; cursor: pointer;
  font-size: 13px; border: 1px solid var(--border); background: transparent;
  color: var(--text); }
.dm-lock-actions .dm-lock-ok { border-color: var(--accent); background: var(--accent);
  color: #fff; font-weight: 600; }
/* Ổ khoá ở đầu khung sáng lên khi hội thoại đang khoá — người dùng cần thấy trạng thái
   mà không phải mở menu ra kiểm tra. */
#dm-lock.on { color: var(--accent); }

/* Chuông thông báo: sáng khi đang bật, mờ khi chưa cấp quyền hoặc đã tắt. Trạng thái phải
   nhìn thấy được mà không cần mở menu — nếu không người dùng tưởng đã bật rồi ngồi chờ một
   thông báo không bao giờ tới. */
#dm-bell.on { color: var(--accent); }
#dm-bell.off { color: var(--text-faint); }
.dm-reply-x { background: none; border: none; cursor: pointer;
  color: var(--text-muted); font-size: 14px; padding: 2px 4px; line-height: 1; }
.dm-reply-x:hover { color: var(--text); }

/* ── Cảm xúc — bố cục theo Messenger ──────────────────────────────────────
   Ba phần: hàng nút hiện khi rê chuột (cạnh bong bóng), thanh chọn cảm xúc nổi lên
   phía trên, và viên cảm xúc ĐÈ LÊN mép dưới bong bóng thay vì nằm thành một dòng
   riêng bên dưới. */
.dm-actions { position: absolute; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; gap: 1px; opacity: 0;
  transition: opacity .12s; }
.dm-msg:not(.mine) .dm-actions { left: 100%; margin-left: 3px; }
/* Tin của mình: hàng nút sang trái, và đảo thứ tự để nút mặt cười luôn nằm SÁT bong
   bóng — quãng đường chuột ngắn nhất cho thao tác hay dùng nhất. */
.dm-msg.mine .dm-actions { right: 100%; margin-right: 3px; flex-direction: row-reverse; }
.dm-msg:hover .dm-actions, .dm-actions:focus-within { opacity: 1; }
.dm-act { width: 22px; height: 22px; display: grid; place-items: center; padding: 0;
  border: none; border-radius: 50%; background: none; cursor: pointer;
  color: var(--text-muted); }
.dm-act:hover { background: var(--overlay-strong); color: var(--text); }
.dm-act svg { width: 15px; height: 15px; fill: none; stroke: currentColor;
  stroke-width: 1.9; stroke-linecap: round; }

/* `position: fixed` + toạ độ tính bằng JS: thanh chọn phải nằm NGOÀI `.dm-body`, vì
   khối đó cuộn được nên cắt mất mọi thứ nhô ra khỏi nó. */
/* Lưới 8 cột thay cho một hàng ngang: 24 biểu tượng xếp một hàng sẽ rộng hơn cả khung
   chat và tràn ra ngoài màn hình hẹp. Ba hàng 8 cái vẫn gọn và liếc một cái là thấy hết.
   Đo thật: 278px — vừa cả điện thoại 320px (còn dư chỗ cho 6px lề mỗi bên mà `datChoPicker`
   chừa ra), nên KHÔNG cần breakpoint riêng cho màn hình hẹp. */
.dm-react-pop { position: fixed; z-index: 70;
  display: grid; grid-template-columns: repeat(8, auto); gap: 1px;
  padding: 5px 6px; border-radius: 14px;
  background: var(--surface); border: 1px solid var(--border);
  box-shadow: 0 6px 22px rgba(0,0,0,.45); }
/* 🔴 CẦU NỐI VÔ HÌNH. Thanh chọn nổi cách nút mặt cười 6px, nên con trỏ đi từ nút lên nó
   phải băng qua một khe không thuộc phần tử nào — `mouseleave` bắn ra giữa đường và thanh
   chọn biến mất trước khi tới nơi. Dải trong suốt này nối liền hai vùng hover.
   (Phần ân hạn 400ms bên JS vẫn giữ: cầu nối lo con chuột đi thẳng, ân hạn lo con chuột
   vòng vèo hoặc rê ra rìa bo góc.) */
.dm-react-pop::after { content: ""; position: absolute; left: 0; right: 0; height: 10px; }
.dm-react-pop[data-huong="tren"]::after { top: 100%; }
.dm-react-pop[data-huong="duoi"]::after { bottom: 100%; }
.dm-react-pop button { background: none; border: none; cursor: pointer; line-height: 1;
  font-size: 19px; padding: 3px; border-radius: 50%;
  transition: transform .12s ease-out; }
.dm-react-pop button:hover { transform: scale(1.35) translateY(-2px); }
.dm-react-pop button.dang-chon { background: var(--accent-soft); }


/* Margin âm kéo viên cảm xúc đè lên mép dưới bong bóng — đây là thứ làm nó trông
   "dính" vào tin nhắn thay vì là một dòng rời phía dưới. */
/* Viên cảm xúc bám cạnh TRONG của bong bóng — hướng vào giữa hội thoại, đúng như
   Messenger: tin nhận thì góc dưới-phải, tin gửi thì góc dưới-trái. Đặt ra cạnh ngoài
   sẽ đẩy nó ra sát mép khung và trông như một dòng rời. */
.dm-reacts { display: flex; flex-wrap: wrap; gap: 3px; margin: -9px 8px 0 0;
  justify-content: flex-end; position: relative; z-index: 3; }
.dm-msg.mine .dm-reacts { justify-content: flex-start; margin-right: 0; margin-left: 8px; }
.dm-react-chip { display: inline-flex; align-items: center; gap: 3px;
  padding: 1px 6px; border-radius: 999px; cursor: pointer; font-size: 11px;
  background: var(--surface); border: 1px solid var(--border); color: var(--text-muted);
  box-shadow: 0 1px 4px rgba(0,0,0,.32); }
.dm-react-chip span { font-size: 10.5px; font-weight: 600; }
.dm-react-chip.mine { border-color: var(--accent); color: var(--text); }
.dm-react-chip:hover { border-color: var(--border-strong); }

/* ── Tin chưa đọc ─────────────────────────────────────────────────────────
   Vạch nằm TRONG dòng tin nhắn, băng thì nổi phía trên ô nhập: vạch trả lời câu
   "đọc tới đâu rồi", băng trả lời câu "có muốn nhảy tới đó không". */
.dm-unread-line { display: flex; align-items: center; gap: 8px; margin: 4px 0;
  color: #e0574f; font-size: 11.5px; font-weight: 600; }
.dm-unread-line::before, .dm-unread-line::after {
  content: ""; flex: 1; height: 1px; background: currentColor; opacity: .45; }
.dm-unread-bar { display: flex; align-items: center; gap: 8px; justify-content: center;
  padding: 6px 12px; border-top: 1px solid var(--border);
  background: var(--accent-soft); font-size: 12.5px; color: var(--text); }
.dm-unread-bar button { background: none; border: none; cursor: pointer;
  color: var(--accent); font: inherit; font-weight: 600; padding: 2px 4px; }
.dm-unread-bar button:hover { text-decoration: underline; }
.dm-unread-bar .dm-unread-x { color: var(--text-muted); font-weight: 400; }

/* ---- Dải "đang tải tin cũ" ----
   Khung chat chỉ giữ khoảng trăm tin gần nhất cho nhẹ; vuốt lên là nạp tiếp trang cũ hơn.
   Phải có dấu hiệu nhìn thấy được, không thì người dùng tưởng hội thoại chỉ có bấy nhiêu. */
.dm-older { display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 8px 0; font-size: 12px; color: var(--text-muted); }
.dm-older-dot { width: 12px; height: 12px; border-radius: 50%;
  border: 2px solid var(--border); border-top-color: var(--accent);
  animation: dm-older-quay .7s linear infinite; }
@keyframes dm-older-quay { to { transform: rotate(360deg); } }
/* Ai đặt hệ điều hành ở chế độ giảm chuyển động thì vòng này đứng yên. */
@media (prefers-reduced-motion: reduce) { .dm-older-dot { animation: none; } }

/* ---- Nút "↓ N tin mới" (Zalo/Messenger) ----
   Chỉ hiện khi người dùng đã cuộn LÊN khỏi đáy. Nó là lối quay lại — thứ thay thế cho việc
   giật màn hình xuống sau lưng họ. `.dm-panel` đã `position: fixed` nên đây là mốc định vị;
   nút nổi ngay trên khu vực nhập, không đè lên tin nhắn cuối. */
.dm-jump { position: absolute; right: 14px; bottom: 76px; z-index: 4;
  min-width: 30px; height: 30px; padding: 0 8px; border-radius: 15px;
  border: 1px solid var(--border); background: var(--bg-elev, var(--overlay-strong));
  color: var(--text); font-size: 12.5px; font-weight: 700; line-height: 28px;
  cursor: pointer; box-shadow: 0 2px 8px rgba(0, 0, 0, .18); }
.dm-jump:hover { border-color: var(--accent); }
/* Có tin chưa xem thì đổi màu — con số một mình không đủ nổi để mắt bắt được khi
   đang mải đọc. */
.dm-jump.co-tin { background: var(--accent); color: #fff; border-color: var(--accent); }
.dm-jump[hidden] { display: none !important; }

/* ---- Avatar thật ---- */
.dm-ava img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block; }
.dm-ava { overflow: hidden; }
.dm-group-photo { position: relative; display: inline-flex; flex-shrink: 0; }
.dm-photo-edit { position: absolute; right: -4px; bottom: -4px; width: 22px; height: 22px;
  display: grid; place-items: center; padding: 0; border-radius: 50%; border: 2px solid var(--surface);
  background: var(--accent); color: #fff; cursor: pointer; font-size: 12px; }
.dm-photo-edit:hover { filter: brightness(1.12); }

/* ---- Biểu tượng cảm xúc ---- */
.dm-emoji-pop { position: absolute; left: 10px; bottom: 62px; z-index: 9; width: 268px;
  max-height: 260px; overflow-y: auto; padding: 8px; border-radius: 10px;
  background: var(--surface); border: 1px solid var(--border);
  box-shadow: 0 -8px 24px rgba(0,0,0,.4); }
.dm-emoji-label { font-size: 10px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--text-muted); padding: 6px 2px 4px; }
.dm-emoji-grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; }
.dm-emoji-grid button { background: none; border: none; cursor: pointer; font-size: 19px;
  padding: 3px; border-radius: 6px; line-height: 1.2; }
.dm-emoji-grid button:hover { background: var(--overlay-strong); }

/* ---- Thu phóng khung chat ----
   Phóng to = chiếm trọn vùng chat AI, KHÔNG phủ cả trang: phủ hết sẽ che sidebar và người
   dùng mất đường chuyển sang cuộc trò chuyện khác. */
.dm-panel.zoomed {
  position: fixed;
  left: var(--sidebar-w, 260px); right: 0; top: 0; bottom: 0;
  width: auto; height: auto; max-height: none;
  border-radius: 0; border: none; border-left: 1px solid var(--border);
  box-shadow: none;
}
/* Khung chat AI bị che khi phóng to — hai khung chồng nhau thì cuộn nhầm chỗ. */
.main.dm-bi-che { visibility: hidden; }
/* Ở chế độ phóng to, tận dụng bề ngang: bong bóng rộng hơn và ảnh lớn hơn, giống chat AI. */
.dm-panel.zoomed .dm-body { padding: 20px 12%; gap: 12px; }
.dm-panel.zoomed .dm-msg { max-width: 72%; }
.dm-panel.zoomed .dm-msg:not(.mine) { grid-template-columns: 36px minmax(0, 1fr); column-gap: 10px; }
.dm-panel.zoomed .dm-ava.message-avatar { width: 34px; height: 34px; flex-basis: 34px; }
.dm-panel.zoomed .dm-att img { max-width: 380px; max-height: 400px; }
.dm-panel.zoomed .dm-input { padding: 14px 12%; }
.dm-panel.zoomed .dm-bubble { font-size: 15px; line-height: 1.6; }
.dm-panel.zoomed .dm-emoji-pop { left: 12%; }
@media (max-width: 900px) {
  .dm-panel.zoomed { left: 0; }
  .dm-panel.zoomed .dm-body, .dm-panel.zoomed .dm-input { padding-left: 14px; padding-right: 14px; }
  .dm-panel.zoomed .dm-msg { max-width: 86%; }
}
.dm-ava.big img { width: 48px; height: 48px; }
#dm-profile .dm-picker-box input[type="text"], #dm-pf-name {
  padding: 8px 10px; border-radius: 8px; font: inherit; font-size: 14px;
  border: 1px solid var(--border); background: var(--overlay);
  color: var(--text); margin-bottom: 10px; }
#dm-pf-save { width: 100%; }

/* ---- Nội dung markdown trong bong bóng tin nhắn ----
   Dùng lại renderer của chat AI, nên phải chỉnh lại vài chỗ cho vừa bong bóng hẹp. */
.dm-bubble pre { margin: 6px 0; max-width: 100%; overflow-x: auto; font-size: 12.5px;
  border-radius: 8px; }
.dm-bubble code { font-size: 12.5px; }
.dm-bubble p { margin: 0 0 6px; }
.dm-bubble p:last-child { margin-bottom: 0; }
.dm-bubble ul, .dm-bubble ol { margin: 4px 0 6px; padding-left: 20px; }
.dm-bubble table { font-size: 12.5px; display: block; overflow-x: auto; max-width: 100%; }
.dm-bubble blockquote { margin: 6px 0; padding-left: 10px;
  border-left: 2px solid var(--border); color: var(--text-muted); }
.dm-bubble h1, .dm-bubble h2, .dm-bubble h3 { font-size: 14px; margin: 8px 0 4px; }
.dm-bubble a { color: inherit; text-decoration: underline; }
/* Bong bóng của MÌNH có nền tím — khối mã phải tối lại để chữ còn đọc được. */
.dm-msg.mine .dm-bubble pre { background: rgba(0, 0, 0, .28); }
.dm-msg.mine .dm-bubble blockquote { border-left-color: rgba(255, 255, 255, .4); }
/* Tin nhắn dài không được kéo giãn khung: cho phép cuộn ngang trong chính bong bóng. */
.dm-bubble { max-width: 100%; overflow-wrap: anywhere; }

/* ===== Modal API key (AI Gateway) — static/js/api_keys.js ===== */
#apikey-modal .modal-box { max-width: 720px; }
.ak-note {
  font-size: 13px; line-height: 1.55; color: var(--text-muted);
  padding: 10px 12px; background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; margin-bottom: 14px;
}
.ak-warn { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, var(--border)); }
.ak-section { margin: 16px 0 4px; }
.ak-section h4 {
  margin: 0 0 10px; font-size: 13px; font-weight: 600; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.ak-form { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 8px; }
.ak-form input, .ak-form select {
  padding: 9px 11px; border-radius: 9px; border: 1px solid var(--border);
  background: var(--bg); color: var(--text); font-size: 13.5px; font-family: inherit;
}
.ak-form input { flex: 1 1 220px; min-width: 0; }
.ak-form input:focus, .ak-form select:focus { outline: none; border-color: var(--accent); }
.ak-inline { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-muted); }
.ak-hint { font-size: 12px; color: var(--text-faint); line-height: 1.5; }
.ak-hint code, .ak-note code { font-size: 11.5px; }
.ak-empty { font-size: 13px; color: var(--text-faint); padding: 10px 2px; }
.ak-dim { font-size: 11.5px; color: var(--text-faint); }

/* Hộp key vừa tạo: phải NỔI BẬT — đây là lần duy nhất người dùng thấy chuỗi này. */
.ak-new {
  border: 1px solid color-mix(in srgb, var(--success) 55%, var(--border));
  background: color-mix(in srgb, var(--success) 9%, var(--surface));
  border-radius: 12px; padding: 12px 14px; margin-bottom: 8px;
}
.ak-new-head { font-size: 13.5px; margin-bottom: 8px; }
.ak-key-row { display: flex; gap: 8px; align-items: stretch; margin-bottom: 6px; }
.ak-key-row code {
  flex: 1; min-width: 0; padding: 9px 11px; border-radius: 8px; background: var(--bg);
  border: 1px solid var(--border); font-size: 13px; word-break: break-all; user-select: all;
}

.ak-tabs { display: flex; gap: 4px; flex-wrap: wrap; margin: 4px 0 8px; }
.ak-tab {
  padding: 6px 11px; border-radius: 8px; font-size: 12.5px; color: var(--text-muted);
  border: 1px solid var(--border); background: var(--surface);
}
.ak-tab.active { color: var(--text); border-color: var(--accent); background: var(--accent-soft); }
.ak-snippet-wrap { position: relative; margin-bottom: 6px; }
.ak-snippet {
  margin: 0; padding: 12px 14px; padding-right: 70px; border-radius: 10px;
  background: var(--bg); border: 1px solid var(--border); font-size: 12.5px;
  line-height: 1.6; white-space: pre-wrap; word-break: break-all;
}
.ak-snippet-wrap .chip-btn { position: absolute; top: 8px; right: 8px; }

/* Bảng key cuộn NGANG trong chính nó — không đẩy vỡ modal trên màn hình hẹp. */
.ak-table-wrap { overflow-x: auto; }
.ak-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.ak-table th {
  text-align: left; font-weight: 600; font-size: 11.5px; color: var(--text-faint);
  padding: 7px 8px; border-bottom: 1px solid var(--border); white-space: nowrap;
}
.ak-table td { padding: 8px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.ak-table tr:last-child td { border-bottom: none; }
.ak-name { font-weight: 550; }
.ak-prefix { font-size: 11.5px; color: var(--text-faint); }

@media (max-width: 560px) {
  .ak-key-row { flex-direction: column; }
  .ak-form select, .ak-form .primary-btn { flex: 1 1 100%; }
}
