/* ============ Main ============ */
.main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  position: relative;
  background: var(--bg);
}
/* 拖拽上传 overlay：
   非 project 视图 → .main.is-dragover::before/::after 盖整屏，提示"添加到当前对话"。
   project 视图 → 两个 overlay 同时出现：
     - #cecpsProjView.is-dragover::before 盖三栏，提示"添加到项目资料"（project.css）
     - .main.is-dragover 的 overlay 只盖 footer.composer 区域（子选择器实现），
       提示"添加到当前对话"。两者并列，让用户自己选择拖到哪个区域。
   两种落点的 drop 路由靠 cecpsProjView.drop stopPropagation 分发：
   三栏内 drop → project-level；其余 → 冒泡到 .main → chat-level。 */
.main.is-dragover::before {
  content: "";
  position: absolute;
  inset: 12px;
  background: var(--ink-soft);
  border: 2px dashed var(--ink);
  border-radius: 14px;
  z-index: 50;
  pointer-events: none;
}
.main.is-dragover::after {
  content: "松开即添加到当前对话";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  font-weight: 500;
  color: var(--ink);
  letter-spacing: 0.02em;
  z-index: 51;
  pointer-events: none;
}
/* project 视图：.main 的 overlay 收窄到 footer.composer 区域，不再盖整个三栏。
   footer.composer 需要 position:relative 才能成为 ::before/::after 的定位根。 */
body[data-view="project"] .main.is-dragover::before,
body[data-view="project"] .main.is-dragover::after { display: none; }
body[data-view="project"] .main.is-dragover > footer.composer { position: relative; z-index: 0; }
body[data-view="project"] .main.is-dragover > footer.composer::before {
  content: "";
  position: absolute;
  inset: 6px;
  background: var(--ink-soft);
  border: 2px dashed var(--ink);
  border-radius: 14px;
  z-index: 50;
  pointer-events: none;
}
body[data-view="project"] .main.is-dragover > footer.composer::after {
  content: "添加到当前对话";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  letter-spacing: 0.02em;
  z-index: 51;
  pointer-events: none;
}
.main-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px var(--gutter-main);
  height: 56px;
  flex-shrink: 0;
  border-bottom: 1px solid transparent;
  transition: border-color 200ms;
}
.main-header.with-border { border-bottom-color: var(--border-soft); }
.header-btn {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-3);
  transition: background 120ms, color 120ms;
}
.header-btn:hover { background: var(--hover); color: var(--text); }
/* 高危操作按钮：默认跟其他按钮一样克制，hover 才显示警示色，
   提醒这不是普通刷新而是会真的重启服务进程的操作。 */
.header-btn-danger:hover {
  background: rgba(220, 38, 38, 0.10);
  color: #dc2626;
}
html[data-theme="dark"] .header-btn-danger:hover {
  background: rgba(248, 113, 113, 0.14);
  color: #f87171;
}
.header-title {
  font-size: 14px;
  font-weight: 500;
  color: var(--text-2);
  display: inline-flex;
  align-items: center;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  max-width: 60%;
}
/* 普通对话视图（非 welcome / project / chat-in-project）下，标题可点击编辑 */
body[data-view="chat"] .header-title {
  cursor: pointer;
  padding: 2px 6px;
  margin: -2px -6px;
  border-radius: 6px;
  transition: background 120ms;
}
body[data-view="chat"] .header-title:hover {
  background: var(--hover, rgba(0,0,0,0.04));
}
/* chat-in-project 视图：只让会话标题 span 可点击编辑，项目名面包屑保持原状 */
.cip-header-sess {
  cursor: pointer;
  padding: 2px 6px;
  margin: -2px -6px;
  border-radius: 6px;
  transition: background 120ms;
}
.cip-header-sess:hover {
  background: var(--hover, rgba(0,0,0,0.04));
}
/* 编辑模式：input 替换 div content，视觉跟 header-title 完全一致 */
.header-title-input {
  font: inherit;
  color: inherit;
  background: transparent;
  border: 0;
  outline: 0;
  padding: 0;
  margin: 0;
  width: 100%;
  min-width: 120px;
  letter-spacing: inherit;
}
.header-title > * {
  /* button / span 都按基线居中，避免 button 自带 padding 造成的视觉错位 */
  display: inline-flex;
  align-items: center;
}
/* 项目页面包屑：点击回到该项目主页，加 chip 化 hover 提示可点 */
.cip-header-proj {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 10px 4px 6px;
  margin: -4px -6px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  font: inherit;
  color: inherit;
  cursor: pointer;
  transition: background 140ms, border-color 140ms;
}
.cip-header-proj:hover {
  background: var(--hover);
  border-color: var(--border-soft);
}
.cip-header-proj-name { font-weight: 600; color: var(--ink); }
.cip-header-sep { margin: 0 6px; color: var(--text-4); }
.cip-header-sess { color: var(--text-2); }
/* AI 提示：跟在标题右侧，灰色小字。把"内容由 AI 生成"从底部
   挪到顶部 —— 用户始终能看到这个提醒，不被"对话太长底部看不见"
   挡住。flex:1 让它占据中段空间把右侧按钮推到尾部。 */
.header-ai-note {
  flex: 1;
  font-size: 12px;
  color: var(--text-4);
  margin-left: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 主题切换：单图标 toggle。当前 light → 渲染月亮（点击切 dark），
   当前 dark → 渲染太阳。靠 [data-theme] 选择性显示一个，另一
   个 display:none 不占空间。

   上色：填充色让图标在 hover 之外也有明确的视觉重量。月亮用
   indigo（暗色含义）、太阳用 amber（暖光含义）—— 跟 macOS /
   Tailwind 等业界配色对齐。深色态颜色再亮一档保证对比度。 */
.theme-icon-moon, .theme-icon-sun { display: none; }
/* icon 跟随当前主题：浅色显示太阳（白天）、深色显示月亮（夜晚）。
   按钮的语义是"状态指示"，hover/click 才是切换动作。 */
html[data-theme="light"] .theme-icon-sun { display: block; }
html[data-theme="dark"] .theme-icon-moon { display: block; }
.theme-icon-moon {
  color: #6366f1;  /* indigo-500 */
  fill: currentColor;
}
.theme-icon-sun {
  color: #f59e0b;  /* amber-500 */
}
.theme-icon-sun circle {
  fill: currentColor;
}
html[data-theme="dark"] .theme-icon-moon { color: #818cf8; }
html[data-theme="dark"] .theme-icon-sun { color: #fbbf24; }
/* hover 时按钮整体描边色仍走 .header-btn 的逻辑，不打扰图标本身
   的填充色 —— 让图标颜色稳定可识别，避免 hover 一闪一变。 */
#themeToggle:hover .theme-icon-moon,
#themeToggle:hover .theme-icon-sun {
  filter: brightness(1.1);
}

/* ── 右上角按钮自定义 hover 气泡 ──
   浏览器原生 title tooltip 要等 500ms+ 才弹、样式丑，用户分不清按钮
   做什么。给 .main-header 下带 data-tip 的按钮加一个轻量 CSS 气泡，
   hover 立刻显示。startup JS 会把这些按钮的 title 转成 data-tip。 */
.main-header [data-tip] { position: relative; }
.main-header [data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  top: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%) translateY(-2px);
  padding: 5px 9px;
  font-size: 12px;
  font-weight: 500;
  color: #fff;
  background: rgba(20, 23, 26, 0.92);
  border-radius: 6px;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 120ms, transform 120ms;
  z-index: 70;
  box-shadow: 0 4px 10px rgba(0,0,0,0.18);
}
html[data-theme="dark"] .main-header [data-tip]::after {
  background: rgba(245, 245, 245, 0.95);
  color: #14171a;
}
.main-header [data-tip]:hover::after,
.main-header [data-tip]:focus-visible::after {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
/* 最右侧按钮的气泡贴着边，让箭头不超出窗口 */
.main-header > [data-tip]:last-child::after,
.main-header .notice-wrap:last-child [data-tip]::after { transform: translateX(-80%) translateY(-2px); }
.main-header > [data-tip]:last-child:hover::after,
.main-header .notice-wrap:last-child [data-tip]:hover::after { transform: translateX(-80%) translateY(0); }

/* ── 通知中心（铃铛 + 浮层） ── */
.notice-wrap { position: relative; }
.notice-dot {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #dc2626;
  border: 2px solid var(--bg);
  box-sizing: content-box;
  pointer-events: none;
}
html[data-theme="dark"] .notice-dot { background: #f87171; }
.notice-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 360px;
  max-height: min(70vh, 560px);
  display: flex;
  flex-direction: column;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 12px 28px rgba(0,0,0,0.12), 0 2px 6px rgba(0,0,0,0.06);
  z-index: 60;
  overflow: hidden;
}
/* hidden HTML 属性默认是 display:none，但被上面的 display:flex
   覆盖了。显式让 [hidden] 赢，否则面板"打开就关不掉"。 */
.notice-panel[hidden] { display: none; }
html[data-theme="dark"] .notice-panel {
  box-shadow: 0 12px 28px rgba(0,0,0,0.45), 0 2px 6px rgba(0,0,0,0.30);
}
.notice-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  border-bottom: 1px solid var(--border-soft);
  flex-shrink: 0;
}
.notice-refresh {
  width: 24px;
  height: 24px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-3);
}
.notice-refresh:hover { background: var(--hover); color: var(--text); }
.notice-list {
  flex: 1;
  overflow-y: auto;
  padding: 6px 0;
}
.notice-empty {
  padding: 24px 16px;
  text-align: center;
  font-size: 12.5px;
  color: var(--text-4);
}
.notice-item {
  position: relative;
  padding: 10px 14px 10px 18px;
  border-bottom: 1px solid var(--border-soft);
}
.notice-item:last-child { border-bottom: none; }
.notice-item::before {
  content: "";
  position: absolute;
  left: 8px;
  top: 14px;
  bottom: 14px;
  width: 3px;
  border-radius: 2px;
  background: var(--text-4);
}
.notice-item.lvl-info::before    { background: #3b82f6; }
.notice-item.lvl-success::before { background: #10b981; }
.notice-item.lvl-warning::before { background: #f59e0b; }
.notice-item-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  margin-right: 60px;
  word-break: break-word;
  display: flex;
  align-items: center;
  gap: 6px;
}
/* 未读小红点：跟铃铛上的红点同款，加一圈 bg 描边让它在标题旁
   视觉上"浮"出来。已读项不渲染这个点。 */
.notice-item.unread .notice-item-title::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #dc2626;
  flex-shrink: 0;
}
html[data-theme="dark"] .notice-item.unread .notice-item-title::before {
  background: #f87171;
}
.notice-item-body {
  font-size: 12.5px;
  color: var(--text-2);
  margin-top: 4px;
  white-space: pre-wrap;
  word-break: break-word;
}
.notice-item-time {
  position: absolute;
  top: 10px;
  right: 14px;
  font-size: 11px;
  color: var(--text-4);
}
.notice-item-del {
  position: absolute;
  bottom: 8px;
  right: 10px;
  font-size: 11px;
  color: var(--text-4);
  padding: 2px 6px;
  border-radius: 4px;
  display: none;
}
.notice-item-del:hover { color: #dc2626; background: rgba(220, 38, 38, 0.08); }
.notice-panel.can-publish .notice-item-del { display: inline-block; }
.notice-publish {
  border-top: 1px solid var(--border-soft);
  padding: 10px 12px;
  background: var(--hover);
  flex-shrink: 0;
}
.notice-publish-row {
  display: flex;
  gap: 6px;
  margin-bottom: 6px;
}
.notice-publish input,
.notice-publish textarea,
.notice-publish select {
  width: 100%;
  font: inherit;
  font-size: 12.5px;
  padding: 6px 8px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--card-bg);
  color: var(--text);
  outline: none;
  box-sizing: border-box;
}
.notice-publish select { width: 90px; flex-shrink: 0; }
.notice-publish input:focus,
.notice-publish textarea:focus,
.notice-publish select:focus { border-color: var(--ink); }
.notice-publish textarea { resize: vertical; min-height: 36px; }
.notice-publish-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 6px;
}
.notice-publish-hint { font-size: 11px; color: var(--text-4); }
.notice-publish-btn {
  font-size: 12px;
  padding: 5px 12px;
  border-radius: 6px;
  background: var(--ink);
  color: #fff;
  font-weight: 500;
}
html[data-theme="dark"] .notice-publish-btn { color: #14171a; }
.notice-publish-btn:hover:not(:disabled) { filter: brightness(1.08); }
.notice-publish-btn:disabled { opacity: 0.55; cursor: default; }

/* ============ Theme switcher ============ */
.theme-seg {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  background: var(--hover);
  border-radius: 10px;
}
.theme-seg-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 28px;
  height: 26px;
  padding: 0;
  font-size: 11.5px;
  color: var(--text-3);
  border-radius: 7px;
  transition: background 150ms, color 150ms;
}
.theme-seg-btn:hover { color: var(--text); }
.theme-seg-btn.active {
  background: var(--card-bg);
  color: var(--text);
  box-shadow: 0 1px 2px rgba(0,0,0,0.08);
}


/* 视图切换 cross-fade：旧容器淡出（is-fading-out）+ 新容器淡入（viewFadeIn）
   两者同时跑，效果接近切 session 时的流畅感。位移加大到 6px 增强可感知度。
   util.js fadeOutAndHide 给被切走的容器加 .is-fading-out，160ms 后 display:none。 */
@keyframes viewFadeIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes viewFadeOut {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(-2px); }
}
#welcomeScreen,
.messages,
#cecpsProjView {
  animation: viewFadeIn 240ms var(--ease) both;
}
.is-fading-out {
  animation: viewFadeOut 160ms var(--ease) both !important;
  pointer-events: none;
}
/* M1 关键：fade-out 期间，旧容器（messages/welcome/projView）必须脱离 flex 流，
   否则它和入场容器同时 flex:1 占高度，会把入场容器（justify-content:center）的
   内容挤压到上半部分——160ms 后旧容器 display:none，内容才"回弹"到正中。
   用 absolute + inset:0 让它在视觉上覆盖 .main 但不参与 flex 高度分配。
   .main 本来就是 position:relative（main.css:7）—— absolute 定位有锚点。 */
.main > .is-fading-out {
  position: absolute !important;
  inset: 0 !important;
  z-index: 1;
}
/* hidden 时不要让 animation 占位，否则下次显示时浏览器可能跳过重启 */
#cecpsProjView[hidden] { display: none !important; animation: none; }

/* ── 通用 modal 蒙层 ──
   .modal-backdrop 是所有弹窗（usageModal、proj-modal 等）共用的基类。
   缺这套样式时 backdrop 会被 body[display:flex] 当成兄弟节点挤进主流，
   把侧栏和主区压扁。.proj-modal-backdrop 在 project.css 有自己的 fixed
   覆盖，本规则只兜底「只设了 modal-backdrop 但没特化」的场景（如 usageModal）。
   display 由 inline style / JS 控制（none ↔ flex），这里只兜定位/层级。 */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: var(--modal-backdrop, rgba(20, 22, 20, 0.42));
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  z-index: 250;
  align-items: center;
  justify-content: center;
  padding: 24px;
  box-sizing: border-box;
}
