/* =========================================================
   ai-chat-sidebar.css
   ChatGPT-style 3-section layout (Header / Body / Footer)
   ========================================================= */

:root {
  --sidebar-width: 250px;
  --sidebar-width-collapsed: 60px;
  --sidebar-bg: #fcfcfc; /* Slightly cleaner than f9f9f9 */
  --sidebar-border: 1px solid var(--color-border);
  --sidebar-item-height: 44px;
  --sidebar-gutter: 12px;   /* 侧栏内容离边的距离(单一真源):列表自己的 padding,header/footer 的右缘也从它算 */
  --sidebar-radius: var(--radius-list-row);
  --sidebar-hover: rgba(0, 0, 0, 0.04);
  --sidebar-active: rgba(0, 0, 0, 0.06);
  --sidebar-text-main: rgba(0, 0, 0, 0.85);
  --sidebar-text-sub: rgba(0, 0, 0, 0.45);
  --sidebar-icon-color: rgba(0, 0, 0, 0.70);
}

/* =========================
   🚀 CRITICAL: First Paint Anti-FOUC
   ========================= */
/* ✅ 初始化状态：隐藏sidebar直到JS设置正确状态
   防止首帧渲染错误状态（文字叠在一起）
   inline style设置visibility:hidden，这里禁用所有transition */
.sidebar-initializing,
.sidebar-initializing * {
  transition: none !important;
  animation: none !important;
}

/* ✅ JS移除.sidebar-initializing后，恢复正常渲染和transition */

/* =========================
   ⚡ Critical Styles (Anti-FOUC)
   ========================= */
/* ✅ 确保图标和文字在 CSS 加载时就有正确尺寸，防止抖动 */
.sidebar-item {
  min-height: 44px !important;
}

.sidebar-item-icon {
  width: var(--icon-size) !important;
  height: var(--icon-size) !important;
  flex-shrink: 0 !important;
  overflow: hidden !important;
}

.sidebar-item svg {
  width: var(--icon-size) !important;
  height: var(--icon-size) !important;
  display: block !important;
}

/* Action button icon - keep original 16px size and inherit color from button (matches project) */
.sidebar-item .chat-history-action-btn svg {
  width: var(--icon-size-sm) !important;
  height: var(--icon-size-sm) !important;
  color: inherit !important; /* Override --sidebar-icon-color (0.7) to use button's color (0.4) */
}

.sidebar-item-text {
  white-space: nowrap !important;
  overflow: hidden !important;
}

/* Keyboard shortcut hint — right-aligned, visible on hover */
.sidebar-shortcut {
  margin-left: auto;
  font-size: 11px;
  font-weight: 400;
  color: rgba(0,0,0,0.3);
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.15s;
  flex-shrink: 0;
  padding-left: 8px;
}
html:not([data-input="touch"]) .sidebar-item:hover .sidebar-shortcut{ opacity: 1; }
.dark-mode .sidebar-shortcut { color: rgba(255,255,255,0.3); }
/* 移动端隐藏快捷键提示（无键盘） */
@media (max-width: 768px), (max-height: 500px) {
  .sidebar-shortcut { display: none; }
}
/* sidebar 折叠时隐藏快捷键 */
.chat-sidebar.collapsed .sidebar-shortcut { display: none; }

/* =========================
   1. Shell & Layout
   ========================= */
.chat-sidebar {
  display: flex;
  flex-direction: column;
  font-size: 14px;
  width: var(--sidebar-width);
  height: 100vh; /* Fallback */
  height: 100dvh;
  background: var(--sidebar-bg);
  border-right: var(--sidebar-border);
  transition: width 0.3s cubic-bezier(0.2, 0, 0, 1);
  position: relative;
  z-index: 110; /* ✅ Higher than .chat-header (100) */
  flex-shrink: 0;
}

/* Collapsed State */
.chat-sidebar.collapsed {
  width: var(--sidebar-width-collapsed);
}

/* =========================
   2. Sections (Header / Body / Footer)
   ========================= */

/* --- Header (Fixed) --- */
.sidebar-header {
  flex: 0 0 var(--duo-header-h);   /* 单一真源,见 ai-chat-base.css --duo-header-h */
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 14px;             /* 退回整体右移3px（含 logo）：左 17→14 */
  border-bottom: var(--sidebar-border);
}

/* ── 桌面展开态:整条侧栏只有【一条右缘】────────────────────────────────────────────────
   根因:能滚的 .sidebar-body 被 8px 滚动条(.duo-scroll)向内挤,不滚的 header / footer 不被挤 —— 三者
   各自算各自的右内边距,就会长出三条右缘(实测 227 / 229 / 237)。上一版只补了 header,而且补的是
   "body 14 + 滚动条 8 = 22";后来 body 改成 12,这个手算出来的 22 就再没人跟着改 —— 页脚的收起钮
   从头到尾没进过这套算术,单独凸出 8px(用户 2026-09-04 指:工作室按钮没跟收起钮右对齐)。
   修法:右内边距只算一次 = 列表自己的 --sidebar-gutter 加上给滚动条留的 --duo-scrollbar-w,
   header 和 footer 都读这一个式子;scrollbar-gutter:stable 让那 8px 恒定预留(短列表也不跳)。
   手机滚动条 width:0、无此偏移,故仅 min-width:769px + 展开态生效。 */
@media (min-width: 769px) and (min-height: 501px) {
  .chat-sidebar:not(.collapsed) .sidebar-body { scrollbar-gutter: stable; }
  .chat-sidebar:not(.collapsed) .sidebar-header,
  .chat-sidebar:not(.collapsed) .sidebar-footer {
    padding-right: calc(var(--sidebar-gutter) + var(--duo-scrollbar-w));
  }
}

/* --- Logo (Wordmark) --- */
.sidebar-logo {
  display: flex;
  align-items: center;
  color: var(--sidebar-text-main);
  font-size: 18px;
  font-weight: 500;
  text-decoration: none;
  transition: opacity 0.2s, width 0.2s;
  /* The stem of the D lands on the icon column below it. Measured, not guessed: the rows put their
     icons at body padding 12 + row padding 14 = 26px, and the icons themselves start about 2.75px
     inside their own 24 box at 22px rendered, so the ink column begins at 28.75px. The header pads
     14, and the wordmark svg is drawn tight to its ink, so 15px here puts the stem on 29px. Keep the
     svg tight: a margin baked into the artwork makes this number lie. */
  padding-left: 15px;
  height: 30px; /* ✅ 固定高度防止加载时抖动 */
  min-width: 75px; /* ✅ 最小宽度防止加载时抖动 */
}
.sidebar-logo svg {
  /* Size lives on the snippet itself, like every other icon here. This rule used to say 30px while
     the snippet said something else - the inline value won and the rule sat there lying about it. */
  display: block;
  max-width: 100%;
}

/* --- Toggle Wrapper (Contains the mark & the button) --- */
.sidebar-toggle-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

/* --- Mark (Collapsed only) --- */
.sidebar-collapsed-logo {
  display: none;
  width: 22px;
  height: 22px;
  color: var(--sidebar-text-main);
  align-items: center;
  justify-content: center;
  transition: opacity 0.2s ease;
  pointer-events: none;
}
.sidebar-collapsed-logo svg {
  /* Size lives on the snippet, as with the wordmark: the D is set to the same cap height as the
     expanded mark so the sidebar does not change size when it collapses. A number here would beat
     that and put the two out of step. */
  display: block;
}

/* --- Collapsed State Logic --- */
.chat-sidebar.collapsed .sidebar-logo {
  display: none;
}

.chat-sidebar.collapsed .sidebar-header {
  justify-content: center; /* Center the wrapper */
  padding: 0;
}

/* 折叠成一条竖栏时,栏里每颗按钮的宽度只有这一个值:收起钮和上面的聊天/工作室共用它,
   两边边缘才对得齐(线上实测 left 109 / right 141)。各写各的 32 = 迟早只改一处。 */
:root { --sidebar-rail-btn: 32px; }
.sidebar-toggle-btn {
  width: var(--sidebar-rail-btn);
  height: var(--sidebar-rail-btn);
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  border-radius: calc(6px * var(--corner-k));
  cursor: pointer;
  color: var(--color-text-tertiary); /* ✅ Lighter color for subtle appearance */
  transition: opacity 0.2s ease, background 0.2s ease, color 0.2s ease;
}

.chat-sidebar.collapsed .sidebar-toggle-wrapper {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
}
.chat-sidebar.collapsed .sidebar-toggle-wrapper > * {
  grid-area: 1 / 1;
}
/* Collapsed: the mark shows, the button hides under it, and the mark takes no pointer events - so a
   press lands on the button below. That is what pressing the D to reopen the sidebar actually is. */
.chat-sidebar.collapsed .sidebar-collapsed-logo {
  display: flex;
  opacity: 1;
}
.chat-sidebar.collapsed .sidebar-toggle-wrapper .sidebar-toggle-btn {
  opacity: 0;
}
html:not([data-input="touch"]) .chat-sidebar.collapsed .sidebar-toggle-wrapper:hover .sidebar-collapsed-logo {
  opacity: 0;
}
html:not([data-input="touch"]) .chat-sidebar.collapsed .sidebar-toggle-wrapper:hover .sidebar-toggle-btn {
  opacity: 1;
}
/* ✅ Only enable hover effects on devices with true hover support (desktop with mouse) */
/* Hover rules ride UNGATED :hover — media flags misreport on some machines
   (probed all-false three times 2026-08-06) while the pseudo-class stays true */
html:not([data-input="touch"]) .sidebar-toggle-btn:hover{
  background: var(--sidebar-hover);
  color: var(--sidebar-text-main);
}

/* --- Body (scrollable) --- */
.sidebar-body {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
  padding: var(--sidebar-gutter);
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* ✅ Collapsed Body: Reduce padding to allow square items (60px - 16px = 44px width) */
.chat-sidebar.collapsed .sidebar-body {
  padding-left: 8px;
  padding-right: 8px;
}

/* Scrollbar：统一走 .duo-scroll 模板（见 ai-chat-base.css），此处不再单独定义 */

/* --- Footer (Fixed) --- */
.sidebar-footer {
  flex: 0 0 auto;
  padding: 12px;
  border-top: var(--sidebar-border);
}

/* ✅ Collapsed Footer: Reduce padding to allow square items */
.chat-sidebar.collapsed .sidebar-footer {
  padding-left: 8px;
  padding-right: 8px;
}

/* 账号列占满剩下的宽度,折叠按钮贴右。折叠时列表整条居中,按钮跟着回到中间。 */
.sidebar-account-wrap {
  flex: 1;
  min-width: 0;
}

/* Account / Settings / Edit Profile → ai-chat-sidebar-account.css */

/* =========================
   3. Items & Navigation
   ========================= */

.sidebar-nav-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sidebar-item {
  display: flex;
  align-items: center;
  justify-content: flex-start; /* ✅ Force left alignment (fixes button centering) */
  text-align: left;
  gap: 5px; /* ✅ Icon-text spacing */
  width: 100%; /* ✅ Ensure full width for centering in footer */
  border: none; /* ✅ Reset default button border */
  background: transparent; /* ✅ Reset default button bg */
  height: var(--sidebar-item-height);
  padding: 0 14px; /* ✅ 左右等宽 14px（用户要按钮左右一样宽）：左保持 14 对齐其它行，右 12→14 补齐 */
  border-radius: var(--sidebar-radius);
  cursor: pointer;
  text-decoration: none;
  color: var(--sidebar-text-main);
  font-weight: 400;
  transition: background 0.15s;
  position: relative;
  touch-action: manipulation; /* ✅ Prevent double-tap delay on touch devices */
}

.sidebar-item.active {
  background: var(--sidebar-active);
  font-weight: 400;
}

/* Your Chats 聊天条目：文字对齐 Projects/组名 的左列(15px)，不跟带图标的 New Chat 那列；
   左右都 15px → 圆角按钮对称 */
.sidebar-item[data-chat-id] {
  padding-left: 15px;
  padding-right: 6px;   /* 右 14→6：聊天条三点对齐顶部 toggle（中心距右缘 30px）；横条宽不变 */
}

/* ✅ Fixed width icon container for perfect vertical alignment */
.sidebar-item-icon {
  width: var(--icon-size);
  height: var(--icon-size);
  display: flex;
  justify-content: center;
  align-items: center;
  flex-shrink: 0;
  overflow: hidden; /* ✅ Safety net: clip any oversized content immediately */
}

.sidebar-item svg {
  width: var(--icon-size);
  height: var(--icon-size);
  flex-shrink: 0;
  color: inherit;
  max-width: 100%; /* ✅ Prevent explosion */
  max-height: 100%; /* ✅ Prevent explosion */
}

.sidebar-item-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  opacity: 1;
  transition: opacity 0.2s;
  margin-left: 0; /* ✅ Removed offset since icon is gone */
  font-size: 14px;
}

/* Collapsed Item Logic */
.chat-sidebar.collapsed .sidebar-item-text,
.chat-sidebar.collapsed .sidebar-section-title,
.chat-sidebar.collapsed .sidebar-group-label {
  display: none;
}

/* ✅ Hide entire sections (Projects, History) in collapsed mode to prevent whitespace */
.chat-sidebar.collapsed .sidebar-section {
  display: none;
}

.chat-sidebar.collapsed .sidebar-item {
  justify-content: center;
  padding: 0; /* ✅ Reset padding for centering */
}

/* Tooltip for Collapsed State - moved to hover media query below */

/* =========================
   5. Projects & History Groups
   ========================= */
.sidebar-section {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.sidebar-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 6px 0 12px;       /* 右 12→6：段头三点对齐顶部 toggle（中心距右缘 30px）；左保持 12 对齐标题列 */
  height: 32px;
  font-size: 14px;
  font-weight: 400;
  /* text-transform: uppercase; ✅ Removed */
  color: var(--sidebar-text-sub);
}

.sidebar-section-header button {
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px;
  color: inherit;
}

/* Projects Toggle Chevron */
.projects-toggle {
  opacity: 0;
  transition: opacity .15s ease;
  margin-right: -5px;
}

.projects-toggle .chevron-icon {
  display: block;
  width: var(--icon-size);
  height: var(--icon-size);
  transition: transform .2s ease;
}
/* Open state: show chevron on hover (pointing up) */
html:not([data-input="touch"]) .projects-section:hover .projects-toggle{
  opacity: 1;
}
.projects-section:active .projects-toggle {
  opacity: 1;
}

.projects-section .projects-toggle .chevron-icon {
  transform: rotate(180deg); /* up arrow when open */
}

/* Collapsed state: always show chevron (pointing down) */
.projects-section.collapsed .projects-toggle {
  opacity: 1;
}

.projects-section.collapsed .projects-toggle .chevron-icon {
  transform: rotate(0deg); /* down arrow when collapsed */
}

/* Hide project list when collapsed */
.projects-section.collapsed .project-list {
  display: none;
}

/* Projects List */
.project-list {
}

/* History Section */
.history-section {
}

/* Chat History Grouping */
.history-group {
  margin-bottom: 16px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  padding-bottom: 8px;
}
.history-group .sidebar-nav-list {
  width: 100%;
}

.history-group-label {
  padding: 0 0 0 12px;
  height: 32px;                 /* = Projects 的 .sidebar-section-header 高度，文字居中，下方自带呼吸 → 行间距跟 Projects↔群组 一致 */
  display: flex;
  align-items: center;
  font-size: 14px;
  font-weight: 400;
  color: var(--sidebar-text-sub);
  letter-spacing: 0.5px;
  flex: 1;
}

/* Mark all read button — very subtle, hover only */
.mark-all-read-btn {
  display: none;
  width: 24px;
  height: 24px;
  border: none;
  background: transparent;
  border-radius: calc(6px * var(--corner-k));
  cursor: pointer;
  color: var(--sidebar-text-sub);
  padding: 0;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-right: 6px;   /* 真机实测:行内 ⋮(.sidebar-item-actions)离行右边缘 6px(cx=211);✓ 也设 6 → cx=211 正对 ⋮。原 12/14 都偏左 */
  opacity: 0;
  transition: opacity 0.15s;
}
.mark-all-read-btn.has-unread {
  display: flex;
}
/* The tick is the size of the row ⋮ it sits above (same column, same 24px box): at the full 20px icon size it read
   as the loudest thing in the section header for an action that is meant to be barely there (owner 2026-09-18). */
.mark-all-read-btn svg { width: var(--icon-size-sm); height: var(--icon-size-sm); }
/* Hover-triggered reveal stays UNGATED: media flags misreport on some machines
   while :hover itself only fires on real hovering — so the pseudo-class alone
   already encodes "this device can hover". :active twin covers taps. */
html:not([data-input="touch"]) .history-group:hover .mark-all-read-btn.has-unread{
  opacity: 0.5;
}
html:not([data-input="touch"]) .mark-all-read-btn:hover,
html:not([data-input="touch"]) .mark-all-read-btn:active{
  opacity: 1 !important;
  background: var(--color-bg-hover);
}

/* =========================
   6. Sidebar Item Actions (Menu)
   ========================= */
.sidebar-item-actions {
  position: relative;
  display: flex;
  align-items: center;
  margin-left: auto;
  flex-shrink: 0;
}

/* Note: Base styles for .chat-history-action-btn are defined together with .project-action-btn below */
.chat-history-action-btn {
  opacity: 0; /* Hidden by default on desktop (project uses same pattern) */
  transition: background 0.15s, color 0.15s, opacity 0.2s;
}

/* ✅ Keep hover effect when menu is open */
.sidebar-item-actions:has(.sidebar-action-menu.active) .chat-history-action-btn {
  opacity: 1;
  background: rgba(0, 0, 0, 0.08);
  color: rgba(0, 0, 0, 0.7);
}
.dark-mode .sidebar-item-actions:has(.sidebar-action-menu.active) .chat-history-action-btn {
  background: rgba(255, 255, 255, 0.06);
  color: rgba(255, 255, 255, 0.7);
}

/* ✅ Keep hover effect on entire row when menu is open */
.sidebar-item:has(.sidebar-action-menu.active) {
  background: var(--sidebar-hover);
}

/* Action button hover - moved to hover media query below */

.sidebar-action-menu {
  display: none;
  position: fixed;
  background: var(--color-bg-panel);
  box-shadow: var(--menu-shadow);
  border-radius: var(--menu-radius);
  padding: 4px;
  z-index: 9999;
  min-width: 160px;
  max-width: calc(100vw - 16px);
}

.sidebar-action-menu.active {
  display: block;
}

.action-item {
  padding: 8px 12px;
  font-size: 14px;
  color: var(--sidebar-text-main);
  cursor: pointer;
  border-radius: var(--radius-menu-row);
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 8px;
}
.action-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: var(--icon-size);
  height: var(--icon-size);
}
.action-icon svg {
  width: var(--icon-size) !important;
  height: var(--icon-size) !important;
  display: block;
}

.action-item.text-red {
  color: #d32f2f;
}
.action-item.text-red .action-icon,
.action-item.text-red .action-icon svg {
  color: #d32f2f;
  stroke: #d32f2f;
}
html:not([data-input="touch"]) .action-item.text-red:hover{
  background: rgba(211, 47, 47, 0.08);
}
.action-item.text-red:active {
  background: rgba(211, 47, 47, 0.08);
}
/* =========================
   6. Hover Effects (ungated: :hover only fires on real hovering; media flags
   misreport on some machines — a tap applying these briefly is harmless)
   ========================= */
html:not([data-input="touch"]) .sidebar-item:hover{
  background: var(--sidebar-hover);
}
/* Tooltip for Collapsed State */
html:not([data-input="touch"]) .chat-sidebar.collapsed .sidebar-item:hover::after{
  content: attr(aria-label);
  position: absolute;
  left: 100%;
  top: 50%;
  transform: translateY(-50%);
  margin-left: 10px;
  background: #000;
  color: #fff;
  padding: 4px 8px;
  border-radius: calc(4px * var(--corner-k));
  font-size: 14px;
  white-space: nowrap;
  z-index: 100;
  pointer-events: none;
}
html:not([data-input="touch"]) .sidebar-item:hover .chat-history-action-btn{
  opacity: 1;
}
html:not([data-input="touch"]) .chat-history-action-btn:hover{
  background: rgba(0, 0, 0, 0.08); /* ✅ Match project action button */
  color: rgba(0, 0, 0, 0.7); /* ✅ Match project action button */
}
html:not([data-input="touch"]) .action-item:hover{
  background: var(--sidebar-hover);
}

/* =========================
   6.5. Touch Device Fixes (All Screen Sizes)
   ========================= */
/* ✅ On touch devices, always show toggle button instead of F logo hover effect.
   This prevents double-tap issues on mobile landscape / tablets. */
@media (hover: none) and (pointer: coarse) {
  .chat-sidebar.collapsed .sidebar-collapsed-logo {
    display: none !important;
  }
  .chat-sidebar.collapsed .sidebar-toggle-btn {
    opacity: 1 !important;
  }
  .chat-sidebar.collapsed .sidebar-toggle-wrapper {
    display: flex !important;
    width: auto !important;
    height: auto !important;
  }

  /* ✅ Fix header layout on touch devices when collapsed */
  .chat-sidebar.collapsed .sidebar-header {
    justify-content: flex-end !important;
    padding: 0 14px !important;
  }

  /* ✅ Always show action button (three-dot menu) on touch devices */
  .chat-history-action-btn {
    opacity: 1 !important;
    color: var(--color-text-secondary) !important;
  }
  .dark-mode .chat-history-action-btn {
    color: rgba(255, 255, 255, 0.35) !important;
  }

  /* ✅ Touch feedback for buttons */
  .sidebar-toggle-btn:active {
    background: var(--sidebar-hover);
    color: var(--sidebar-text-main);
  }

  .sidebar-item:active {
    background: var(--sidebar-hover); /* ✅ Match project item style */
  }

  /* ✅ Show hover effect on entire row when action button is active */
  .sidebar-item:has(.chat-history-action-btn:active) {
    background: var(--sidebar-hover);
  }

  .chat-history-action-btn:active {
    background: rgba(0, 0, 0, 0.08);
    color: rgba(0, 0, 0, 0.7);
  }
  .dark-mode .chat-history-action-btn:active {
    background: rgba(255, 255, 255, 0.06) !important;
    color: rgba(255, 255, 255, 0.7) !important;
  }
}

/* =========================
   7. Mobile / Responsive
   ========================= */
@media (max-width: 768px), (max-height: 500px) {
  .chat-sidebar {
    position: fixed !important; /* ✅ Force fixed to prevent layout ghosting */
    left: 0;
    top: 0;
    bottom: 0;
    transform: translateX(-100%) !important; /* ✅ Force off-canvas */
    transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
    width: 70vw !important; /* ✅ Narrower width (30-40% reduction) */
    max-width: 280px !important;
    z-index: 9999 !important; /* ✅ Ensure it covers Header/Safe-area */
    box-shadow: none;
    border-right: none;
  }

  .chat-sidebar.mobile-open {
    transform: translateX(0) !important;
    box-shadow: 2px 0 12px var(--color-shadow);
  }

  /* Overlay */
  .sidebar-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.4);
    z-index: 9998 !important; /* ✅ Just below sidebar */
    opacity: 0;
    visibility: hidden; /* ✅ Hide completely when closed */
    pointer-events: none;
    /* ✅ Instant hide on close to prevent "gray flash" or residue */
    transition: none;
    /* ✅ Ensure full coverage including safe-area */
    top: 0;
    bottom: 0;
    height: 100dvh;
  }

  .sidebar-overlay.active {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition: opacity 0.3s ease; /* ✅ Fade in only */
  }
  
  /* Mobile Toggle Button (on main page) */
  .mobile-menu-trigger {
    display: flex !important;
    position: fixed;
    top: 10px; /* ✅ Centered with 60px header: (60-40)/2 = 10 */
    left: 12px;
    z-index: 150;

    width: 40px;
    height: 40px;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    border: none;
    align-items: center;
    justify-content: center;
    color: #333;
    padding: 0;
    cursor: pointer;
  }

  /* ✅ Fix icon size inside mobile toggle (Override base 18px) */
  .mobile-menu-trigger svg {
    width: var(--icon-size);
    height: auto;
  }

  /* ============================================================
     ✅ MOBILE RESET: Override Desktop Collapsed Logic
     Ensure sidebar is always "expanded" visually inside the drawer
     ============================================================ */
  
  /* 1. Reset Width & Padding */
  .chat-sidebar.collapsed {
    width: 70vw !important;
    max-width: 280px !important;
  }
  .chat-sidebar.collapsed .sidebar-body,
  .chat-sidebar.collapsed .sidebar-footer {
    padding-left: 12px !important;
    padding-right: 12px !important;
  }
  .sidebar-footer {
    padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px)) !important;
  }

  /* 2. Force Show Content (Text, Sections, Search) */
  .chat-sidebar.collapsed .sidebar-item-text,
  .chat-sidebar.collapsed .sidebar-section-title,
  .chat-sidebar.collapsed .sidebar-group-label {
    display: block !important;
    opacity: 1 !important;
  }

  /* ✅ Restore flex layout for sections (fix gap issue) */
  .chat-sidebar.collapsed .sidebar-section {
    display: flex !important;
    opacity: 1 !important;
  }

  /* 3. Reset Item Alignment */
  .chat-sidebar.collapsed .sidebar-item {
    justify-content: flex-start !important;
    padding: 0 12px 0 14px !important;
  }
  /* 聊天条三点对齐顶部 toggle（中心距右缘 30px）：覆盖上面 !important 的右 padding */
  .chat-sidebar.collapsed .sidebar-item[data-chat-id] {
    padding-right: 6px !important;
  }

  /* 3b. Footer: 账号列满宽已归到上面的【折叠】规则(与视口宽度无关),这里不再重复一份 */

  /* 4. Reset Logo State (Show full logo, hide F-mark) */
  .chat-sidebar.collapsed .sidebar-logo {
    display: flex !important;
  }
  .chat-sidebar.collapsed .sidebar-collapsed-logo {
    display: none !important;
  }
  .chat-sidebar.collapsed .sidebar-toggle-btn {
    display: flex !important; /* Keep toggle btn visible if needed, or hide if you prefer */
    opacity: 1 !important;
  }
  .chat-sidebar.collapsed .sidebar-toggle-wrapper {
    display: flex !important;
    width: auto !important;
    height: auto !important;
  }

  /* ✅ Reset header layout on mobile (fix logo pushed to right on touch devices) */
  .chat-sidebar.collapsed .sidebar-header {
    justify-content: space-between !important;
    padding: 12px 12px 8px 16px !important;
  }
  /* ✅ Fix iOS overscroll: force background when drawer is closed */
  html,
  body:not(.drawer-open) {
    background-color: #fff !important;
  }
  html.dark-mode-active,
  html.dark-mode-active body:not(.drawer-open) {
    background-color: #171717 !important;
  }
}

/* Desktop: Hide mobile trigger */
.mobile-menu-trigger {
  display: none;
}

/* =========================
   Finalized Chat Indicator
   ========================= */
.sidebar-item.is-finalized .sidebar-item-text {
  color: rgba(0, 0, 0, 0.45);
}

.sidebar-item.is-finalized::before {
  content: '';
  position: absolute;
  left: 4px;
  top: 50%;
  transform: translateY(-50%);
  width: 4px;
  height: 4px;
  border-radius: 50%;
  corner-shape: round;
  background: rgba(0, 0, 0, 0.25);
}

/* Project styles moved to ai-chat-sidebar-projects.css */

/* =========================
   Unread Blue Dot Indicator
   ========================= */
.unread-dot {
  display: none;
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
}
.unread-dot::after {
  content: '';
  display: block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  corner-shape: round;
  background: #2563eb;
}
.unread-dot.visible {
  display: flex;
}
/* Unread dot takes the three-dot slot; a REAL hover reverses them (dot hides,
   three-dot shows). Ungated — one copy for every device; the dot itself is
   clickable (opens the menu and marks read) so no affordance is lost anywhere. */
.sidebar-item-actions:has(.unread-dot.visible) .chat-history-action-btn {
  display: none;
}
html:not([data-input="touch"]) .sidebar-item:hover .unread-dot.visible{
  display: none;
}
html:not([data-input="touch"]) .sidebar-item:hover .sidebar-item-actions:has(.unread-dot.visible) .chat-history-action-btn{
  display: flex;
}
.unread-dot.visible {
  cursor: pointer;
}
/* Active session never shows dot */
.sidebar-item.active .unread-dot {
  display: none !important;
}

/* =========================================================
   DARK MODE
   ========================================================= */
.ai-design-section.dark-mode {
  --sidebar-bg: #171717;
  --sidebar-border: 1px solid var(--color-border);
  --sidebar-hover: rgba(255,255,255,0.06);
  --sidebar-active: rgba(255,255,255,0.1);
  --sidebar-text-main: rgba(255,255,255,0.9);
  --sidebar-text-sub: rgba(255,255,255,0.45);
  --sidebar-icon-color: rgba(255,255,255,0.65);
}

/* --- Global bg --- */
.ai-design-section.dark-mode {
  background-color: #212121;
}

/* --- Sidebar --- */
/* ✅ Sidebar items, section headers, history labels, footer border, chat-sidebar bg/border:
   all use --sidebar-* variables which are overridden in .dark-mode block above.
   No explicit dark-mode rules needed. */
.dark-mode .chat-history-action-btn {
  color: rgba(255,255,255,0.4);
}
html:not([data-input="touch"]) .dark-mode .chat-history-action-btn:hover{
  color: rgba(255,255,255,0.8);
  background: rgba(255,255,255,0.08);
}
.dark-mode .chat-history-action-btn:active {
  color: rgba(255,255,255,0.8);
  background: rgba(255,255,255,0.06);
}

/* --- Chat header --- */
.dark-mode .chat-header {
  background: #212121;
  border-bottom-color: var(--color-border);
}
.dark-mode .version-dropdown {
  background: #2a2a2a;
  box-shadow: 0 4px 24px rgba(0,0,0,0.4);
}
.dark-mode .version-dropdown-title {
  color: rgba(255,255,255,0.4);
}
.dark-mode .version-dropdown-item {
  color: rgba(255,255,255,0.9);
}
html:not([data-input="touch"]) .dark-mode .version-dropdown-item:hover{
  background: rgba(255,255,255,0.06);
}
.dark-mode .version-dropdown-item:active {
  background: rgba(255,255,255,0.06);
}
.dark-mode .version-dropdown-check {
  color: rgba(255,255,255,0.9);
}
.dark-mode .chat-header-btn {
  color: rgba(255,255,255,0.6);
}
html:not([data-input="touch"]) .dark-mode .chat-header-btn:hover{
  background: rgba(255,255,255,0.06);
  color: rgba(255,255,255,0.9);
}
.dark-mode .chat-header-btn:active {
  background: rgba(255,255,255,0.06);
  color: rgba(255,255,255,0.9);
}
.dark-mode .chat-header-menu {
  background: #2a2a2a;
  border-color: rgba(255,255,255,0.1);
  box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.dark-mode .chat-menu-item {
  color: rgba(255,255,255,0.85);
}
html:not([data-input="touch"]) .dark-mode .chat-menu-item:hover{
  background: rgba(255,255,255,0.06);
}
.dark-mode .chat-menu-item:active {
  background: rgba(255,255,255,0.06);
}
.dark-mode .chat-menu-item.danger {
  color: #ef5350;
}

/* --- Chat messages area --- */
.dark-mode .chat-container {
  background: #212121;
}
.dark-mode .chat-messages {
  background: #212121;
}

/* --- Welcome / initial message --- */
.dark-mode #initial-message {
  color: rgba(255,255,255,0.85);
}
.dark-mode #initial-message .title {
  color: rgba(255,255,255,0.9);
}
.dark-mode #initial-message .description {
  color: rgba(255,255,255,0.5);
}

/* --- Bubbles --- */
.dark-mode .ai-text {
  color: rgba(255,255,255,0.9);
}
.dark-mode .msg.user .bubble .bubble-text {
  color: rgba(255,255,255,0.9);
}
.dark-mode .chat-messages .msg.assistant:where(:not(.studio-meeting-msg)) .bubble:has(img) {
  background: #2a2a2a;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.08) inset;
}
.dark-mode .msg.user .bubble .bubble-attachment {
  background: transparent;
  box-shadow: none;
}
.dark-mode .msg.user:where(:not(.studio-meeting-msg)) .bubble:has(img):has(.bubble-text),
.dark-mode .msg.user:where(:not(.studio-meeting-msg)) .bubble:has(img):has(.bubble-content),
.dark-mode .msg.user:where(:not(.studio-meeting-msg)) .bubble:has(.bubble-attachments):has(.bubble-text),
.dark-mode .msg.user:where(:not(.studio-meeting-msg)) .bubble:has(.bubble-attachments):has(.bubble-content) {
  background: #333;
}
.dark-mode .chat-messages .bubble img.chat-image {
  background: transparent;
}

/* Thinking bubble */
.dark-mode .chat-messages .msg.assistant .bubble.thinking {
  background: #2a2a2a;
  border-color: rgba(255,255,255,0.1);
  color: rgba(255,255,255,0.6);
}
.dark-mode .chat-messages .bubble.thinking::after {
  background: linear-gradient(90deg, rgba(42,42,42,0) 0%, rgba(60,60,60,0.8) 45%, rgba(42,42,42,0) 80%);
}

/* --- Composer --- */
.dark-mode .composer-pill {
  background: #2a2a2a;
  border-color: var(--color-border);
  box-shadow: none;
}
.dark-mode .composer-pill:focus-within {
  box-shadow: 0 2px 8px rgba(0,0,0,0.3);
  border-color: rgba(255,255,255,0.2);
}
.dark-mode .chat-input {
  color: rgba(255,255,255,0.9);
}
.dark-mode .typing-placeholder {
  color: rgba(255,255,255,0.35);
}
.dark-mode .chat-button .send-bg {
  fill: #666;
}
.dark-mode .chat-button.has-text .send-bg {
  fill: #fff;
}
.dark-mode .chat-button.has-text svg path:not(.send-bg) {
  fill: #000 !important;
}
.dark-mode .chat-button.is-generating .send-bg {
  fill: #fff;
}
.dark-mode .chat-button.is-generating svg path:not(.send-bg) {
  fill: #000 !important;
}
html:not([data-input="touch"]) .dark-mode .chat-button:hover .send-bg{ fill: #555; }
html:not([data-input="touch"]) .dark-mode .chat-button.has-text:hover .send-bg{ fill: #e0e0e0; }
html:not([data-input="touch"]) .dark-mode .chat-button.is-generating:hover .send-bg{ fill: #e0e0e0; }
.dark-mode .attachment-chip {
  background: transparent;
}
.dark-mode .composer-bar {
  background-color: #212121;
  border-top-color: #212121;
}
.dark-mode .plus-menu__divider {
  background: rgba(255,255,255,0.1);
}

/* Composer scrollbar */
.dark-mode .chat-input::-webkit-scrollbar-track {
  background: #2a2a2a;
  box-shadow: none;
}
.dark-mode .chat-input::-webkit-scrollbar-thumb {
  background-color: rgba(255,255,255,0.15);
}

/* --- Mobile sidebar overlay --- */
.dark-mode .sidebar-overlay {
  background: rgba(0,0,0,0.5);
}

/* --- Search modal --- */
.dark-mode .search-modal-header {
  border-bottom-color: var(--color-border);
}
.dark-mode .search-modal-input-wrap {
  background: rgba(255,255,255,0.08);
}
.dark-mode .search-modal-icon {
  color: rgba(255,255,255,0.35);
}
.dark-mode .search-modal-input {
  background: transparent;
  color: rgba(255,255,255,0.9);
}
.dark-mode .search-modal-input::placeholder {
  color: rgba(255,255,255,0.35);
}
.dark-mode .search-modal-empty {
  color: rgba(255,255,255,0.35);
}
.dark-mode .search-modal-empty-icon {
  color: rgba(255,255,255,0.35);
}
.dark-mode .search-result-item {
  color: rgba(255,255,255,0.85);
}
html:not([data-input="touch"]) .dark-mode .search-result-item:hover{
  background: rgba(255,255,255,0.06);
}
.dark-mode .search-result-item:active,
.dark-mode .search-result-item.active {
  background: rgba(255,255,255,0.06);
}
.dark-mode .search-result-icon {
  color: rgba(255,255,255,0.3);
}
.dark-mode .search-result-title {
  color: rgba(255,255,255,0.9);
}
.dark-mode .search-result-snippet {
  color: rgba(255,255,255,0.5);
}
.dark-mode .search-result-date {
  color: rgba(255,255,255,0.35);
}
.dark-mode .search-highlight {
  background: rgba(255,200,0,0.25);
}
.dark-mode .search-no-results {
  color: rgba(255,255,255,0.4);
}

/* --- Loading text --- */
.dark-mode .loading {
  color: rgba(255,255,255,0.5);
}

/* sidebar / chat-messages 暗色滚动条：统一走 .duo-scroll 模板（ai-chat-base.css），此处不再单独定义 */

/* --- User bubble --- */
.dark-mode .chat-messages .bubble {
  border-color: rgba(255,255,255,0.1);
  background: #2a2a2a;
  color: rgba(255,255,255,0.9);
}
.dark-mode .chat-messages .msg.assistant .bubble {
  background: transparent;
  border-color: transparent;
}
.dark-mode .chat-messages .msg.user .bubble {
  background: #303030;
  border-color: transparent;
}
.dark-mode .chat-messages .msg.user:where(:not(.studio-meeting-msg)) .bubble:has(img),
.dark-mode .chat-messages .msg.user:where(:not(.studio-meeting-msg)) .bubble:has(.bubble-attachments) {
  background: transparent;
  box-shadow: none;
}

/* --- Danger menu item --- */
.dark-mode .chat-menu-item--danger {
  color: #ef5350;
}
.dark-mode .chat-menu-item--danger .action-icon,
.dark-mode .chat-menu-item--danger .action-icon svg {
  color: #ef5350;
  stroke: #ef5350;
}
html:not([data-input="touch"]) .dark-mode .chat-menu-item--danger:hover{
  background: rgba(239, 83, 80, 0.1);
}
.dark-mode .chat-menu-item--danger:active {
  background: rgba(239, 83, 80, 0.1);
}

/* --- Image mode chip color (keep gold) --- */
.dark-mode .image-mode-chip {
  color: #C9B27C;
}

/* --- Finalized composer --- */
.dark-mode .composer-pill.finalized,
.dark-mode .composer-bar.is-finalized .composer-pill {
  background: #1a1a1a;
  border-color: var(--color-border);
  opacity: var(--dim);
}
.dark-mode .composer-pill.finalized .typing-placeholder,
.dark-mode .composer-bar.is-finalized .typing-placeholder {
  color: rgba(255,255,255,0.2);
}
.dark-mode .finalized-badge {
  color: rgba(255,255,255,0.4);
}

/* --- Mobile: hamburger menu button --- */
.dark-mode .mobile-menu-trigger {
  color: rgba(255,255,255,0.7) !important;
}

/* --- Sidebar toggle button --- */
.dark-mode .sidebar-toggle-btn {
  color: rgba(255,255,255,0.4);
}

/* --- Three-dot action button (history items + project folders + project chats + dropdown chats) --- */
.dark-mode .chat-history-action-btn,
.dark-mode .project-action-btn,
.dark-mode .project-chat-action-btn,
.dark-mode .project-dropdown-chat-dots {
  color: rgba(255,255,255,0.35) !important;
}
html:not([data-input="touch"]) .dark-mode .chat-history-action-btn:hover,
html:not([data-input="touch"]) .dark-mode .project-action-btn:hover,
html:not([data-input="touch"]) .dark-mode .project-chat-action-btn:hover,
html:not([data-input="touch"]) .dark-mode .project-dropdown-chat-dots:hover{
  color: rgba(255,255,255,0.7) !important;
  background: rgba(255,255,255,0.08) !important;
}
.dark-mode .chat-history-action-btn:active,
.dark-mode .project-action-btn:active,
.dark-mode .project-chat-action-btn:active,
.dark-mode .project-dropdown-chat-dots:active {
  color: rgba(255,255,255,0.7) !important;
  background: rgba(255,255,255,0.06) !important;
}
.dark-mode .action-item {
  color: rgba(255,255,255,0.85);
}
.dark-mode .action-item.text-red {
  color: #ef5350;
}
.dark-mode .action-item.text-red .action-icon,
.dark-mode .action-item.text-red .action-icon svg {
  color: #ef5350;
  stroke: #ef5350;
}
html:not([data-input="touch"]) .dark-mode .action-item.text-red:hover{
  background: rgba(239, 83, 80, 0.1);
}
.dark-mode .action-item.text-red:active {
  background: rgba(239, 83, 80, 0.1);
}
.dark-mode .project-menu-item {
  color: rgba(255,255,255,0.85);
}
html:not([data-input="touch"]) .dark-mode .project-menu-item:hover{
  background: rgba(255,255,255,0.06);
}
.dark-mode .project-menu-item:active {
  background: rgba(255,255,255,0.06);
}
.dark-mode .project-menu-item--danger {
  color: #ef5350;
}

/* --- Plus button (composer) --- */
.dark-mode .plus-button {
  background: #2a2a2a;
  border-color: var(--color-border);
}
.dark-mode .plus-icon {
  color: rgba(255,255,255,0.85);
}
html:not([data-input="touch"]) .dark-mode .plus-button:hover{
  background: rgba(255,255,255,0.08);
}

/* --- Plus menu dropdown: surface fully token-driven (panel bg + --menu-shadow) --- */
.dark-mode .plus-menu__icon {
  color: rgba(255,255,255,0.6);
}
.dark-mode .plus-menu__label {
  color: rgba(255,255,255,0.85);
}

/* --- Finalized sidebar item --- */
.dark-mode .sidebar-item.is-finalized .sidebar-item-text {
  color: rgba(255,255,255,0.4);
}
.dark-mode .sidebar-item.is-finalized::before {
  background: rgba(255,255,255,0.25);
}
/* --- Unread dot (dark mode) --- */
.dark-mode .unread-dot::after {
  background: #60a5fa;
}

/* Account / Settings dark mode → ai-chat-sidebar-account.css */

/* ── Surface switch (Chat | Studio) ─────────────────────────────────────────────────────────────
   Two products, one control, beside the wordmark: identity and which face of it read as one thing,
   and two icons here cost nothing from the list below. Sizes and colours are the toggle button's own,
   so the header holds one kind of control at one size.
   Desktop only: on a phone the sidebar is a drawer, and the Studio row in the nav list is the way in. */
.surface-switch {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
}
.surface-switch-btn {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  border-radius: calc(6px * var(--corner-k));
  color: var(--color-text-tertiary);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
/* 22 = 侧栏列表图标那一档(见上面 .sidebar-item svg)。折叠态这两颗带 sidebar-item、本来就吃那条规则,
   展开态不带,过去自己写了 20 —— 同一颗按钮换个状态就换个大小(实测墨迹 15.5 对 17)。 */
.surface-switch-btn svg { width: var(--icon-size); height: var(--icon-size); display: block; }
.surface-switch-btn.is-active {
  background: var(--sidebar-active);
  color: var(--sidebar-text-main);
}
html:not([data-input="touch"]) .surface-switch-btn:hover,
.surface-switch-btn:active {
  background: var(--sidebar-hover);
  color: var(--sidebar-text-main);
}

/* Collapsed keeps the mark and drops the pair - four things do not fit in 60px, and which surface you
   are in is still legible from what the sidebar is listing. */
.chat-sidebar.collapsed .surface-switch { display: none; }
/* ...and the column one takes over, laid out like the rows under it. */
.surface-switch--collapsed { display: none; flex-direction: column; gap: 2px; margin-bottom: 2px; }
.chat-sidebar.collapsed .surface-switch--collapsed { display: flex; }
/* 宽度跟收起钮同一个值(--sidebar-rail-btn):折叠栏里三颗按钮左右边缘要齐。
   高度仍是行高 —— 它们是列表里的一行,收起钮是页脚里的一颗。 */
.surface-switch--collapsed .surface-switch-btn { width: var(--sidebar-rail-btn); height: var(--sidebar-item-height); border-radius: var(--sidebar-radius); }


.sidebar-footer:has(.sidebar-footer-toggle) { display: flex; align-items: center; }
.sidebar-footer-toggle { margin-left: auto; }
/* Collapsed: the footer stacks and the button sits above the avatar - 60px is not wide enough for
   both side by side, and it stays reachable without opening anything. */
.chat-sidebar.collapsed .sidebar-footer:has(.sidebar-footer-toggle) { flex-direction: column-reverse; gap: 4px; }
.chat-sidebar.collapsed .sidebar-footer-toggle { margin-left: 0; }
.chat-sidebar.collapsed .sidebar-account-wrap { flex: 0 0 auto; width: 100%; }
/* Expanded on a desktop, the header button is not needed - the footer one is the collapse control. */
@media (min-width: 769px) and (min-height: 501px) {
  .chat-sidebar:not(.collapsed) .sidebar-toggle-wrapper { display: none; }
}
/* A phone has no collapsed state and no footer button: the header one, as always. */
@media (max-width: 768px), (max-height: 500px) {
  .surface-switch { display: none; }
  .sidebar-footer-toggle { display: none; }
}
/* Desktop reaches Studio through the pair in the header, in every state - the row is the phone's. */
@media (min-width: 769px) and (min-height: 501px) {
  #btnStudio { display: none; }
}
