:root {
  --grad: linear-gradient(135deg, #6c6ff5 0%, #8b5cf6 55%, #c084fc 100%);
  --bg: #080c16;
  --panel: rgba(13, 19, 34, 0.92);
  --line: rgba(255, 255, 255, 0.08);
  --brand: #6c6ff5;
  --safe-b: env(safe-area-inset-bottom, 12px);
  color-scheme: dark;
}

* {
  -webkit-tap-highlight-color: transparent;
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: #e2e8f0;
  font-family:
    "Be Vietnam Pro",
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    sans-serif;
}

button,
a,
label,
summary {
  touch-action: manipulation;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(
      750px 380px at 12% -8%,
      rgba(99, 102, 241, 0.22),
      transparent 72%
    ),
    radial-gradient(
      850px 420px at 88% -10%,
      rgba(168, 85, 247, 0.18),
      transparent 72%
    ),
    radial-gradient(
      650px 360px at 50% 112%,
      rgba(56, 189, 248, 0.12),
      transparent 72%
    );
}

::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  background: rgba(148, 163, 184, 0.22);
  border-radius: 9999px;
}
::-webkit-scrollbar-thumb:hover {
  background: rgba(148, 163, 184, 0.4);
}

.btn-grad {
  background: var(--grad);
  box-shadow: 0 4px 14px -4px rgba(108, 111, 245, 0.5);
  transition:
    transform 0.15s ease,
    filter 0.15s ease;
}
.btn-grad:active {
  transform: scale(0.97);
  filter: brightness(0.95);
}

.user-bubble {
  background: var(--grad);
  box-shadow: 0 4px 20px -5px rgba(108, 111, 245, 0.4);
}

html.light {
  color-scheme: light;
}
html.light body {
  background: #f6f8fc;
  color: #0f172a;
}
html.light body::before {
  background:
    radial-gradient(750px 380px at 12% -8%, rgba(99, 102, 241, 0.13), transparent 72%),
    radial-gradient(850px 420px at 88% -10%, rgba(168, 85, 247, 0.1), transparent 72%),
    radial-gradient(650px 360px at 50% 112%, rgba(56, 189, 248, 0.09), transparent 72%);
}
html.light [class*="bg-surface-950"] {
  background-color: #f6f8fc !important;
}
html.light [class*="bg-surface-900"] {
  background-color: rgba(255, 255, 255, 0.94) !important;
}
html.light [class*="bg-surface-850"] {
  background-color: #f8fafc !important;
}
html.light [class*="bg-white/"] {
  background-color: rgba(15, 23, 42, 0.05) !important;
}
html.light [class*="border-white/"] {
  border-color: rgba(15, 23, 42, 0.12) !important;
}
html.light .text-white,
html.light .text-slate-100,
html.light .text-slate-200,
html.light .text-slate-300 {
  color: #1e293b !important;
}
html.light .text-slate-400 {
  color: #475569 !important;
}
html.light .text-slate-500 {
  color: #64748b !important;
}
html.light .placeholder-slate-500::placeholder {
  color: #94a3b8 !important;
}

/* Tông nhấn nhạt (200/300) chỉ đủ tương phản trên nền tối. Trên nền sáng phải
   hạ xuống mức 600–700 cùng họ màu, nếu không chữ gần như chìm vào nền trắng.
   Khối này đặt trước các luật "nền tối giữ chữ sáng" phía dưới để những vùng
   đó (bong bóng người dùng, khung xem code) vẫn thắng khi cùng độ ưu tiên. */
html.light .text-indigo-200,
html.light .text-indigo-300 {
  color: #4338ca !important;
}
/* Biểu tượng đầu mục trong Cấu hình viết bằng `text-indigo-300/80` — trên thẻ
   trắng thì gần như tàng hình, nên hạ xuống tông đậm hơn ở chế độ sáng. */
html.light [class*="text-indigo-300/"] {
  color: #4f46e5 !important;
}
html.light .text-sky-200 {
  color: #0369a1 !important;
}
html.light .text-emerald-200 {
  color: #047857 !important;
}
html.light .text-amber-200,
html.light .text-amber-300 {
  color: #b45309 !important;
}
html.light .text-indigo-400 {
  color: #4f46e5 !important;
}
html.light .text-sky-400 {
  color: #0284c7 !important;
}
html.light .text-emerald-400 {
  color: #059669 !important;
}
html.light .text-amber-400 {
  color: #d97706 !important;
}
html.light .text-rose-400 {
  color: #e11d48 !important;
}

/* Nút chỉ có icon: ở chế độ tối hover sáng lên thành trắng, nhưng nền sáng thì
   "hover:text-white" làm icon biến mất hẳn. Đảo lại thành chữ đậm, còn những
   nút giữ nền tối/tím khi hover thì vẫn giữ chữ sáng. */
html.light [class*="hover:text-white"]:hover {
  color: #0f172a !important;
}
html.light .btn-grad:hover,
html.light .btn-grad:hover *,
html.light .user-bubble:hover,
html.light .user-bubble:hover * {
  color: #ffffff !important;
}
html.light [class*="hover:text-indigo-300"]:hover,
html.light [class*="hover:text-indigo-400"]:hover {
  color: #4338ca !important;
}
html.light [class*="hover:text-amber-300"]:hover {
  color: #b45309 !important;
}
html.light [class*="hover:text-rose-400"]:hover {
  color: #be123c !important;
}
html.light .ai-card {
  background: rgba(255, 255, 255, 0.94);
  border-color: rgba(15, 23, 42, 0.08);
  color: #1e293b;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}

/* Chế độ sáng: thanh bên và khung nhập tách khỏi nền chung bằng nền trắng +
   bóng mềm, tránh kiểu trắng trên trắng phẳng lì, khó nhìn. */
html.light #sidebar {
  background-color: #ffffff !important;
  border-right-color: rgba(15, 23, 42, 0.08) !important;
}
html.light .composer {
  background-color: #ffffff !important;
  border-color: rgba(15, 23, 42, 0.1) !important;
  box-shadow:
    0 1px 2px rgba(15, 23, 42, 0.04),
    0 14px 32px -20px rgba(15, 23, 42, 0.35) !important;
}

/* Vùng phủ trong Canvas vẫn cố tình để nền tối ở chế độ sáng (khung xem code
   và màn hình trống), nên chữ bên trong phải giữ tông sáng. */
html.light #canvas-empty-state,
html.light #canvas-empty-state * {
  color: #cbd5e1 !important;
}
html.light .think-panel,
html.light .think-body {
  background: rgba(241, 245, 249, 0.8);
  border-color: rgba(15, 23, 42, 0.1);
  color: #475569;
}
/* Chân thanh bên vốn là một dải tối (`bg-black/20`) để chìm vào nền tối; ở
   chế độ sáng nó thành một vệt xám đục khác hẳn mọi mặt phẳng trắng quanh
   nó, nên trả về nền của chính thanh bên. */
html.light .sidebar-footer {
  background-color: transparent !important;
}
html.light .sidebar-tools-card {
  background: rgba(255, 255, 255, 0.94);
  border-color: rgba(15, 23, 42, 0.08);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}
html.light .sidebar-tools-grid,
html.light .user-file-open {
  border-color: rgba(15, 23, 42, 0.12);
}
html.light .sidebar-tools-grid .sidebar-utility-btn,
html.light .sidebar-utility-btn:hover {
  background: rgba(15, 23, 42, 0.05);
}
html.light .user-bubble,
html.light .user-bubble * {
  color: #fff !important;
}
html.light .btn-grad,
html.light .btn-grad * {
  color: #fff !important;
}
html.light #canvas-code-wrapper {
  background: #0a0f1d;
}
html.light #canvas-code-wrapper,
html.light #canvas-code-wrapper * {
  color: #e2e8f0 !important;
}

.user-file-list {
  display: grid;
  gap: 0.45rem;
  margin-top: 0.65rem;
}
.user-file-card {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.6rem 0.7rem;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 0.8rem;
  color: #fff;
  background: rgba(22, 18, 65, 0.25);
  text-align: left;
  transition: background 0.16s ease, border-color 0.16s ease, transform 0.16s ease;
}
.user-file-card:hover {
  background: rgba(22, 18, 65, 0.42);
  border-color: rgba(255, 255, 255, 0.5);
  transform: translateY(-1px);
}
.user-file-card:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}
.user-file-icon {
  width: 1.85rem;
  height: 1.85rem;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  border-radius: 0.6rem;
  background: rgba(255, 255, 255, 0.16);
}
.user-file-name {
  min-width: 0;
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.75rem;
  font-weight: 600;
}
.user-file-size {
  flex: 0 0 auto;
  color: rgba(255, 255, 255, 0.7);
  font-size: 0.65rem;
}
.user-file-open {
  flex: 0 0 auto;
  padding-left: 0.55rem;
  border-left: 1px solid rgba(255, 255, 255, 0.24);
  color: rgba(255, 255, 255, 0.85);
  font-size: 0.65rem;
  font-weight: 700;
}

.sidebar-tools-card {
  padding: 0.35rem;
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 0.9rem;
  background: rgba(255, 255, 255, 0.035);
  box-shadow: inset 0 1px rgba(255, 255, 255, 0.025);
}
.sidebar-utility-btn {
  transition: color 0.16s ease, background 0.16s ease;
}
.sidebar-utility-btn:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.075);
}
.sidebar-utility-btn:focus-visible {
  outline: 2px solid rgba(129, 140, 248, 0.9);
  outline-offset: -1px;
}
.sidebar-tools-grid {
  margin: 0.25rem 0;
  padding: 0.25rem 0;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}
.sidebar-tools-grid .sidebar-utility-btn {
  background: rgba(255, 255, 255, 0.025);
}

.ai-card {
  background: rgba(17, 24, 39, 0.72);
  border: 1px solid var(--line);
  contain: layout style;
}

.msg-enter {
  animation: msg-up 0.28s cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes msg-up {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .msg-enter,
  .think-chevron,
  .btn-grad {
    animation: none !important;
    transition: none !important;
  }
}

#messages-container {
  overflow-anchor: none;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-gutter: stable;
}

.markdown-content {
  word-break: break-word;
  font-size: 0.925rem;
  line-height: 1.65;
}
.markdown-content > * + * {
  margin-top: 0.75rem;
}
.markdown-content p {
  margin: 0 0 0.75rem;
  color: #e2e8f0;
}
.markdown-content p:last-child {
  margin-bottom: 0;
}
.markdown-content ul,
.markdown-content ol {
  padding-left: 1.25rem;
  margin: 0 0 0.75rem;
}
.markdown-content ul {
  list-style: disc;
}
.markdown-content ol {
  list-style: decimal;
}
.markdown-content li {
  margin-bottom: 0.25rem;
}
.markdown-content h1,
.markdown-content h2,
.markdown-content h3 {
  font-weight: 700;
  margin: 1rem 0 0.5rem;
  color: #f8fafc;
}
.markdown-content h1 {
  font-size: 1.25rem;
}
.markdown-content h2 {
  font-size: 1.1rem;
}
.markdown-content h3 {
  font-size: 1rem;
}
.markdown-content blockquote {
  border-left: 3px solid #8b93ff;
  padding: 0.4rem 0.8rem;
  color: #94a3b8;
  margin: 0.75rem 0;
  background: rgba(108, 111, 245, 0.06);
  border-radius: 0 0.5rem 0.5rem 0;
}
.markdown-content table {
  width: 100%;
  border-collapse: collapse;
  margin: 0.75rem 0;
  display: block;
  overflow-x: auto;
  font-size: 0.825rem;
}
.markdown-content th,
.markdown-content td {
  border: 1px solid rgba(148, 163, 184, 0.15);
  padding: 6px 10px;
  text-align: left;
}
.markdown-content th {
  background: rgba(255, 255, 255, 0.05);
  color: #f1f5f9;
}
.markdown-content pre {
  position: relative;
  background: #090d16 !important;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 0.85rem;
  padding: 0 !important;
  margin: 0.85rem 0;
  overflow: hidden;
}

.markdown-content pre .code-head {
  position: relative;
  width: 100%;
  height: 2.1rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 0.5rem 0 0.85rem;
  background: rgba(255, 255, 255, 0.05);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  font-family: "Fira Code", ui-monospace, monospace;
  font-size: 11px;
  color: #a5b4fc;
}
.markdown-content pre code {
  display: block;
  padding: 0.85rem;
  overflow-x: auto;
}
.markdown-content :not(pre) > code {
  background: rgba(108, 111, 245, 0.15);
  border: 1px solid rgba(108, 111, 245, 0.25);
  padding: 1.5px 5px;
  margin: 0 3px;
  border-radius: 5px;
  color: #c7d2fe;
  font-size: 0.85em;
  font-family: "Fira Code", ui-monospace, monospace;
  display: inline-block;
  line-height: 1.2;
}

.code-action-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.08);
  color: #cbd5e1;
  font-size: 10px;
  font-weight: 500;
  cursor: pointer;
  border: 0;
}
.code-action-btn:hover {
  background: rgba(255, 255, 255, 0.18);
  color: #fff;
}
.preview-btn-highlight {
  background: rgba(108, 111, 245, 0.25);
  border: 1px solid rgba(108, 111, 245, 0.4);
  color: #c7d2fe;
}

.stream-plain {
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 0.925rem;
  line-height: 1.65;
  color: #e2e8f0;
  min-height: 1.25em;
  contain: content;
}

.think-panel {
  margin-bottom: 0.65rem;
  border: 1px solid var(--line);
  border-radius: 0.85rem;
  background: rgba(0, 0, 0, 0.32);
  overflow: hidden;
  contain: layout paint;
}
.think-toggle {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 0.45rem 0.75rem;
  background: transparent;
  border: 0;
  color: #94a3b8;
  font-size: 11px;
  cursor: pointer;
  font-family: inherit;
}
.think-toggle:hover {
  color: #e2e8f0;
  background: rgba(255, 255, 255, 0.03);
}
.think-chevron {
  transition: transform 0.18s ease;
  flex-shrink: 0;
}
.think-panel.is-open .think-chevron {
  transform: rotate(180deg);
}
.think-body {
  display: none;
  max-height: min(38vh, 280px);
  overflow: auto;
  overflow-anchor: none;
  padding: 0.75rem;
  border-top: 1px solid var(--line);
  background: rgba(0, 0, 0, 0.22);
  color: #94a3b8;
  font-family: "Fira Code", ui-monospace, monospace;
  font-size: 12px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
}
.think-panel.is-open .think-body {
  display: block;
}
.think-panel.is-live.is-open .think-body {
  height: auto;
  max-height: min(38vh, 280px);
  contain: content;
}
.think-live {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #818cf8;
  opacity: 0.45;
  animation: think-pulse 1.2s ease-in-out infinite;
}
@keyframes think-pulse {
  50% {
    opacity: 1;
  }
}

.typing-dots span {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #8b93ff;
  display: inline-block;
  animation: bounce 1.2s infinite;
}
.typing-dots span:nth-child(2) {
  animation-delay: 0.15s;
}
.typing-dots span:nth-child(3) {
  animation-delay: 0.3s;
}
@keyframes bounce {
  0%,
  60%,
  100% {
    transform: none;
    opacity: 0.3;
  }
  30% {
    transform: translateY(-4px);
    opacity: 1;
  }
}

.icon {
  width: 1em;
  height: 1em;
  display: inline-block;
  vertical-align: -0.125em;
  flex-shrink: 0;
}

/* Thông báo nổi: nền và chữ do CSS quyết theo từng chế độ, không dựa vào
   `text-white` của Tailwind — chính lớp đó bị luật sáng đảo thành chữ đậm
   nên ở chế độ sáng thông báo biến mất khỏi màn hình. */
.toast-item {
  animation: toast-in 0.22s ease both;
  background: #182032;
  border-color: rgba(99, 102, 241, 0.5);
  color: #ffffff;
}
.toast-item.toast-error {
  background: rgba(136, 19, 55, 0.9);
  border-color: rgba(244, 63, 94, 0.5);
}
.toast-item.toast-success {
  background: rgba(6, 78, 59, 0.9);
  border-color: rgba(16, 185, 129, 0.5);
}

/* Chế độ sáng: thông báo cũng là một thẻ trắng nổi trên nền sáng, chỉ khác
   ở viền và chữ mang màu của loại thông báo. */
html.light .toast-item {
  background: rgba(255, 255, 255, 0.97);
  border-color: rgba(99, 102, 241, 0.35);
  color: #3730a3;
}
html.light .toast-item.toast-error {
  border-color: rgba(225, 29, 72, 0.35);
  color: #be123c;
}
html.light .toast-item.toast-success {
  border-color: rgba(5, 150, 105, 0.35);
  color: #047857;
}
@keyframes toast-in {
  from {
    opacity: 0;
    transform: translateY(-8px);
  }
}

.cmdk {
  backdrop-filter: blur(10px);
}

.jump-latest {
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}

.composer {
  transition:
    border-color 0.18s ease,
    box-shadow 0.18s ease;
}
.composer:focus-within {
  border-color: #6c6ff5;
  box-shadow:
    0 0 0 3px rgba(108, 111, 245, 0.22),
    0 10px 30px -12px rgba(0, 0, 0, 0.6),
    0 0 22px -6px rgba(108, 111, 245, 0.5);
}

.pin-on {
  color: #fbbf24;
}

.chat-group-label {
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #64748b;
  padding: 10px 10px 4px;
}

/* Branded Avatars */
.ai-avatar {
  width: 32px;
  height: 32px;
  border-radius: 11px;
  background: #ffffff;
  border: 1.5px solid rgba(255, 255, 255, 0.7);
  box-shadow:
    0 4px 14px rgba(0, 0, 0, 0.45),
    0 0 12px rgba(99, 102, 241, 0.35);
  overflow: hidden;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease;
}
.ai-avatar:hover {
  transform: scale(1.06);
  box-shadow:
    0 6px 18px rgba(0, 0, 0, 0.5),
    0 0 16px rgba(99, 102, 241, 0.5);
}
.ai-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Microphone Recording Animation */
.mic-recording {
  color: #f43f5e !important;
  background: rgba(244, 63, 94, 0.18) !important;
  border: 1px solid rgba(244, 63, 94, 0.5) !important;
  animation: mic-pulse 1.2s infinite ease-in-out;
}
@keyframes mic-pulse {
  0%,
  100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(244, 63, 94, 0.5);
  }
  50% {
    transform: scale(1.08);
    box-shadow: 0 0 0 6px rgba(244, 63, 94, 0);
  }
}

/* Hàng thông tin dưới khung nhập: phím tắt dạng viên phím nhỏ, gọn. */
.kbd {
  display: inline-flex;
  align-items: center;
  height: 16px;
  padding: 0 5px;
  border-radius: 5px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.05);
  color: #94a3b8;
  font-family: "Fira Code", ui-monospace, monospace;
  font-size: 9px;
  line-height: 1;
  white-space: nowrap;
}
html.light .kbd {
  border-color: rgba(15, 23, 42, 0.12);
  background: rgba(15, 23, 42, 0.05);
  color: #475569;
}

/* Thẻ V-AI đứng cạnh khối thương hiệu: một viên thuốc cỡ vừa, nền chuyển
   sắc rất nhẹ, viền mảnh cùng họ indigo và chữ in hoa giãn nhẹ. Cao bằng
   hai phần ba khối chữ bên cạnh nên đọc ra là nhãn phiên bản của thương
   hiệu chứ không phải một nút bấm lạc lõng. */
.brand-badge {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 10px;
  border-radius: 999px;
  border: 1px solid rgba(139, 147, 255, 0.34);
  background: linear-gradient(
    180deg,
    rgba(139, 147, 255, 0.26),
    rgba(108, 111, 245, 0.12)
  );
  color: #d9ddff;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.11em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    0 1px 2px rgba(0, 0, 0, 0.28);
}
/* Trên nền trắng, tông nhạt của chế độ tối mất hẳn độ tương phản: đậm lại
   viền và dùng tông đậm hơn cho chữ. */
html.light .brand-badge {
  border-color: rgba(87, 84, 232, 0.3);
  background: linear-gradient(
    180deg,
    rgba(108, 111, 245, 0.17),
    rgba(108, 111, 245, 0.07)
  );
  color: #4540c9;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    0 1px 2px rgba(15, 23, 42, 0.06);
}

/* Nút Canvas trên header: bình thường trung tính như các icon khác, chỉ
   mang màu nhấn khi Canvas đang mở. */
#toggle-canvas-top-btn.is-on {
  background: rgba(108, 111, 245, 0.12);
  border-color: rgba(108, 111, 245, 0.35);
  color: #8b93ff;
}
#toggle-canvas-top-btn.is-on:hover {
  color: #ffffff;
  background: rgba(108, 111, 245, 0.18);
}
html.light #toggle-canvas-top-btn.is-on {
  /* Luật sáng `[class*="bg-white/"]` khớp cả `hover:bg-white/5` nên phải
     ghi đè bằng !important để trạng thái mở vẫn ra màu nhấn. */
  background: rgba(108, 111, 245, 0.14) !important;
  border-color: rgba(108, 111, 245, 0.45);
  color: #5754e8 !important;
}
html.light #toggle-canvas-top-btn.is-on:hover {
  color: #4540c9 !important;
}

/* Canvas Device Modes */
#canvas-frame-wrap {
  transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  width: 100%;
  position: relative;
}
/* Tailwind `.hidden` chỉ là class nên thua ID selector ở trên — khai báo rõ
   để khung iframe ẩn hẳn khi Canvas chưa có nội dung. */
#canvas-frame-wrap.hidden {
  display: none;
}
#canvas-frame-wrap.device-desktop {
  width: 100%;
  height: 100%;
  padding: 0;
  border-radius: 0;
  border: 0;
  box-shadow: none;
}
#canvas-frame-wrap.device-tablet {
  width: 768px;
  max-width: 95%;
  height: 94%;
  border-radius: 20px;
  border: 2px solid rgba(255, 255, 255, 0.2);
  box-shadow:
    0 25px 50px -12px rgba(0, 0, 0, 0.8),
    0 0 25px rgba(99, 102, 241, 0.25);
  overflow: hidden;
}
#canvas-frame-wrap.device-mobile {
  width: 375px;
  max-width: 92%;
  height: 92%;
  border-radius: 32px;
  border: 3px solid rgba(255, 255, 255, 0.25);
  box-shadow:
    0 25px 60px -15px rgba(0, 0, 0, 0.9),
    0 0 30px rgba(99, 102, 241, 0.35);
  overflow: hidden;
}

/* Math (KaTeX) Styling */
.katex-display {
  overflow-x: auto;
  overflow-y: hidden;
  padding: 0.6rem 0;
  margin: 0.75rem 0;
  scrollbar-width: thin;
}
.katex {
  color: #e0e7ff;
  font-size: 1.05em;
}

/* TTS Speaking Indicator */
.is-speaking {
  color: #38bdf8 !important;
  animation: speak-pulse 1s infinite alternate ease-in-out;
}
@keyframes speak-pulse {
  from {
    opacity: 0.55;
    transform: scale(0.98);
  }
  to {
    opacity: 1;
    transform: scale(1.02);
  }
}

/* Connection status indicator: distinguishes "checking" (amber) from
   "offline" (red) with a soft pulse, so the sidebar communicates the real
   state at a glance instead of only changing color. */
.conn-dot-pulse {
  animation: conn-pulse 1.4s ease-in-out infinite;
}
@keyframes conn-pulse {
  0%,
  100% {
    opacity: 1;
    box-shadow: 0 0 0 0 currentColor;
  }
  50% {
    opacity: 0.55;
    box-shadow: 0 0 0 3px transparent;
  }
}

/* API Endpoint field in Settings */
#endpoint-input {
  transition: border-color 0.15s ease, background 0.15s ease;
}
#endpoint-input:focus {
  background: rgba(0, 0, 0, 0.3);
}
#endpoint-reset-btn {
  transition: color 0.15s ease;
}
#endpoint-test-btn {
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
#endpoint-test-btn:active {
  transform: scale(0.97);
}

/* Model refresh button: quick spin while (re)loading the model list */
#model-refresh-btn {
  transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
#model-refresh-btn[data-loading="true"] svg {
  animation: spin-refresh 0.8s linear infinite;
}
@keyframes spin-refresh {
  to {
    transform: rotate(360deg);
  }
}

/* Consistent, visible keyboard focus across interactive controls that don't
   already define their own focus-visible treatment. */
button:focus-visible,
select:focus-visible,
input:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid rgba(129, 140, 248, 0.85);
  outline-offset: 2px;
}

/* Image Thumbnail in Message */
.msg-thumb-preview {
  max-width: 220px;
  max-height: 160px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  object-fit: cover;
  margin-top: 6px;
  cursor: pointer;
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease;
}
.msg-thumb-preview:hover {
  transform: scale(1.02);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}

/* Logo ở màn hình chào: bấm/chạm chỉ để focus ô nhập, không phóng to.
   touch-action ngăn trình duyệt tự zoom trang khi double-tap trên thiết bị cảm ứng. */
.empty-logo {
  touch-action: manipulation;
}
.empty-logo img {
  pointer-events: none;
}

/* Thanh bên thu gọn (chỉ trên desktop): ẩn sidebar, hiện dải icon 56px */
#sidebar-rail {
  display: none;
}
.rail-btn {
  width: 2.5rem;
  height: 2.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 0.85rem;
  background: transparent;
  color: #94a3b8;
  cursor: pointer;
  transition:
    color 0.16s ease,
    background 0.16s ease;
}
.rail-btn:hover {
  color: #ffffff;
  background: rgba(255, 255, 255, 0.09);
}
.rail-btn:focus-visible {
  outline: 2px solid rgba(108, 111, 245, 0.7);
  outline-offset: 2px;
}
html.light .rail-btn {
  color: #475569;
}
html.light .rail-btn:hover {
  color: #0f172a;
  background: rgba(15, 23, 42, 0.08);
}

@media (min-width: 768px) {
  body.sidebar-collapsed #sidebar {
    display: none;
  }
  body.sidebar-collapsed #sidebar-rail {
    display: flex;
  }
}

/* Công tắc trong Cấu hình: gói cả rãnh, núm và icon vào MỘT svg nên mỗi công
   tắc chỉ tốn một phần tử, nét sắc ở mọi tỉ lệ màn hình, và đổi trạng thái
   hoàn toàn bằng CSS — JS chỉ cần đọc checkbox như trước. */
.switch {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
  cursor: pointer;
}
.switch-svg {
  display: block;
}
.sw-track {
  fill: rgba(100, 116, 139, 0.32);
  stroke: rgba(255, 255, 255, 0.1);
  stroke-width: 1;
  transition:
    fill 0.18s ease,
    stroke 0.18s ease;
}
.sw-knob {
  fill: #ffffff;
  transition: transform 0.18s ease;
}
/* Icon nằm trong núm: bản "tắt" hiện sẵn, bản "bật" ẩn; bật thì đổi vai trò
   và cả hai cùng trượt sang phải theo núm. */
.sw-ico {
  fill: none;
  stroke: #94a3b8;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition:
    opacity 0.16s ease,
    transform 0.18s ease,
    stroke 0.18s ease;
}
/* Icon mặt trăng: dựng theo đúng tỉ lệ bộ icon Lucide (khung 24) rồi thu nhỏ
   còn một nửa quanh tâm núm, nên hộp bao của hình nằm cân đối quanh (12,12)
   chứ không lệch như bản vẽ tay trước. Vì hình to hơn hai icon kia nên nét
   mảnh hơn cho khỏi dày. */
.sw-moon {
  stroke-width: 1.3;
}
.sw-ico-on {
  opacity: 0;
}
.sw-ico-off {
  opacity: 1;
}
.switch input:checked ~ .switch-svg .sw-knob,
.switch input:checked ~ .switch-svg .sw-ico-on,
.switch input:checked ~ .switch-svg .sw-ico-off {
  transform: translateX(20px);
}
.switch input:checked ~ .switch-svg .sw-track {
  fill: #6c6ff5;
  stroke: #6c6ff5;
}
.switch input:checked ~ .switch-svg .sw-ico-on {
  opacity: 1;
  stroke: #6c6ff5;
}
.switch input:checked ~ .switch-svg .sw-ico-off {
  opacity: 0;
}
.switch input:focus-visible ~ .switch-svg {
  outline: 2px solid rgba(108, 111, 245, 0.6);
  outline-offset: 3px;
  border-radius: 999px;
}
html.light .sw-track {
  fill: rgba(15, 23, 42, 0.16);
  stroke: rgba(15, 23, 42, 0.14);
}
html.light .sw-ico {
  stroke: #475569;
}
html.light .switch input:checked ~ .switch-svg .sw-ico-on {
  stroke: #5754e8;
}

/* Thanh trượt độ sáng tạo: tự vẽ lại để không dùng kiểu mặc định của trình
   duyệt (thanh xám dày, lệch tông indigo của app). Phần đã chọn lấy màu từ
   biến --fill do JS cập nhật khi kéo. */
.temperature-range {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 16px;
  background: transparent;
  cursor: pointer;
}
.temperature-range::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(
    to right,
    #6c6ff5 0 var(--fill, 47%),
    rgba(148, 163, 184, 0.28) var(--fill, 47%) 100%
  );
}
.temperature-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 14px;
  margin-top: -5px;
  border-radius: 50%;
  background: #ffffff;
  border: 2px solid #6c6ff5;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
  transition: transform 0.15s ease;
}
.temperature-range:active::-webkit-slider-thumb {
  transform: scale(1.12);
}
.temperature-range::-moz-range-track {
  height: 4px;
  border-radius: 999px;
  background: rgba(148, 163, 184, 0.28);
}
.temperature-range::-moz-range-progress {
  height: 4px;
  border-radius: 999px;
  background: #6c6ff5;
}
.temperature-range::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #ffffff;
  border: 2px solid #6c6ff5;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
}
html.light .temperature-range::-webkit-slider-runnable-track {
  background: linear-gradient(
    to right,
    #6c6ff5 0 var(--fill, 47%),
    rgba(15, 23, 42, 0.14) var(--fill, 47%) 100%
  );
}
html.light .temperature-range::-moz-range-track {
  background: rgba(15, 23, 42, 0.14);
}

/* Thẻ gợi ý ở màn hình chào. Trước đây trạng thái hover đặt thẳng bằng
   `hover:text-white` / `group-hover:text-white` nên ở chế độ sáng (nền thẻ
   trắng) tiêu đề hoá trắng trên trắng và biến mất khi rê chuột. Nay màu hover
   do CSS quyết theo từng chế độ, mỗi thẻ có một tông nhấn riêng qua data-hue. */
.prompt-card {
  transition:
    background-color 0.2s ease,
    border-color 0.2s ease,
    transform 0.2s ease;
}
.prompt-card:hover {
  border-color: rgba(108, 111, 245, 0.5);
  background-color: rgba(108, 111, 245, 0.1);
  transform: translateY(-1px);
}
.prompt-card:hover .prompt-title {
  color: #ffffff;
}
.prompt-card:hover .prompt-icon {
  color: #c7d2fe;
}
.prompt-card:focus-visible {
  outline: 2px solid rgba(108, 111, 245, 0.65);
  outline-offset: 2px;
}

html.light .prompt-card {
  background-color: #ffffff !important;
  border-color: rgba(15, 23, 42, 0.08) !important;
  box-shadow:
    0 1px 2px rgba(15, 23, 42, 0.05),
    0 12px 26px -18px rgba(15, 23, 42, 0.3) !important;
}
html.light .prompt-card:hover {
  background-color: rgba(108, 111, 245, 0.06) !important;
  border-color: rgba(108, 111, 245, 0.4) !important;
}
html.light .prompt-card:hover .prompt-title,
html.light .prompt-card:hover .prompt-icon {
  color: #3730a3 !important;
}
html.light .prompt-card[data-hue="sky"]:hover .prompt-title,
html.light .prompt-card[data-hue="sky"]:hover .prompt-icon {
  color: #075985 !important;
}
html.light .prompt-card[data-hue="emerald"]:hover .prompt-title,
html.light .prompt-card[data-hue="emerald"]:hover .prompt-icon {
  color: #065f46 !important;
}
html.light .prompt-card[data-hue="amber"]:hover .prompt-title,
html.light .prompt-card[data-hue="amber"]:hover .prompt-icon {
  color: #92400e !important;
}
