/* ══════════════════════════════════════════════════════════
   泽霖AI短剧大师 · AI 短剧创作平台
   设计基调：浅色玻璃拟态 + 青紫渐变，清爽明亮
   ══════════════════════════════════════════════════════════ */

/* ---------- 设计令牌 ---------- */
:root {
  /* 背景层次：0 是页面底 → 3 是浮层，越大越亮 */
  --bg-0: #f1f4fa;
  --bg-1: #fbfcfe;
  --bg-2: #ffffff;
  --bg-3: #ffffff;
  --bg-hover: #e8eefb;

  /* 描边 */
  --line: rgba(16, 24, 48, 0.09);
  --line-strong: rgba(16, 24, 48, 0.15);

  /* 文字 */
  --text-1: #141a2b;
  --text-2: #4d566e;
  --text-3: #8b93a8;

  /* 品牌色 */
  --brand: #3b6bf5;
  --brand-2: #7c3aed;
  --brand-glow: rgba(59, 107, 245, 0.18);
  --accent: #0e8fa8;
  --warm: #f59e0b;             /* 渐变里的橙：品牌蓝/紫/青之外补一档暖色，
                                  用在 Hero 标题渐变与创作流程那条连接线上，
                                  相邻色差更大 → 一眼能看出从左到右的走向 */

  /* 语义色 */
  --warn: #b45309;
  --danger: #dc2626;

  /* 原生控件（滚动条、输入光标、autofill）跟随亮色 */
  color-scheme: light;

  /* 尺寸 */
  --radius-sm: 8px;
  --radius: 14px;
  --radius-lg: 22px;
  --sidebar-w: 274px;

  /* 全站思源黑体。第一位是项目自带的 Noto Sans SC webfont
     （见 public/fonts/noto-sans-sc/；Noto Sans SC 与 Adobe 思源黑体是同一套字形的
     两个发行名，字形完全一致），所有访客都能拿到同一个字形，不受本机字体影响。
     后面是降级链：webfont 没加载出来时，依次退回本机可能装的思源黑体与常见黑体。
     --mono 保留系统等宽（代码对齐需要），其中的中文回退到同一套思源黑体。 */
  --font: "Noto Sans SC", "Source Han Sans SC", "Source Han Sans CN", "思源黑体",
          "思源黑体 CN", "PingFang SC", "Microsoft YaHei", "Hiragino Sans GB",
          system-ui, -apple-system, sans-serif;
  --mono: "Noto Sans Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo,
          Consolas, "Noto Sans SC", monospace;

  /* 排版基调：正文 15px、标题 20px 粗体、行高统一 1.5 倍 */
  --body-size: 15px;
  --title-size: 18px;
  --title-weight: 700;
  /* ── 行高令牌：这里是 --line-height，**不是 --line** ──
     早先它也叫 --line，和上面的描边色同名，同名后定义者胜 → 全站
     `border: 1px solid var(--line)` 拿到的其实是行高值 1.5，颜色部分无效、
     回退成 currentColor（侧栏右边框实测是正文色而非设计的淡灰）。已拆成两个变量。
     值用无单位 1.5，不是 1.5em —— 无单位是「比例」，每个元素按各自字号换算：
     正文 15px → 22.5px、标题 20px → 30px；写成 1.5em 会变成「按父元素字号先算成
     像素再继承」，20px 的标题只会拿到正文那 22.5px，标题行会挤在一起。 */
  --line-height: 1.5;
  /* 页脚/辅助文字：与正文同号（15px），靠颜色而不是字号做层级 */
  --foot-size: 15px;
  --meta-size: 13px;           /* 辅助信息一档（侧栏会话列表的 .s-meta 用它）。
                                 ⚠️ 全站 UI 文字**只有 13 / 15 / 20 三档**（用户明确的口径），
                                 行高一律 1.5。新增文字请挑现有令牌，别写裸数值。
                                  ⚠️ 它是白名单里的第三档，typo-check 已同步允许 13 —— 
                                  不要再往其它地方随手写 13px，要小字就用这个令牌 */

  --shadow: 0 12px 34px rgba(17, 24, 39, 0.10), 0 2px 8px rgba(17, 24, 39, 0.05);
  /* 循环 / 背景类动画用的对称曲线 */
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  /* 交互缓动（hover / focus / 展开）：强减速曲线 —— 起步快、收尾极长。
     对称的 --ease 在 0.15s 这种短时长里会一路「加速到底再急停」，
     观感就是「啪」一下到位；换成这条 + 稍长的时长后是「滑」进去的。
     全站 hover 类过渡一律用它。 */
  --ease-soft: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---------- 复位 ---------- */
*, *::before, *::after { box-sizing: border-box; }

/* ⚠️ 关键：保证 [hidden] 一定生效。
   本文件里多处组件设了 display:flex/grid（.modal、.view-chat …），
   它们的优先级高于浏览器默认的 [hidden]{display:none}，
   会让带 hidden 属性的元素依然显示出来。
   这条 !important 统一兜底，所有 `el.hidden = true` 都能可靠隐藏。 */
[hidden] { display: none !important; }

html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}

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

/* 表单控件默认不带字体继承：只写 font-family/font-size 是不够的 ——
   浏览器对 button/input/textarea 的 UA 样式里 line-height 是 normal，
   而 line-height 不在 font-family/font-size 的继承范围内，会一路保持 normal（≈1.2），
   于是按钮里的文字行高比周围小一圈。必须显式 inherit 才能并入全局 1.5。 */
button { font-family: inherit; font-size: inherit; line-height: inherit; cursor: pointer; border: none; background: none; color: inherit; }
input, textarea { font-family: inherit; font-size: inherit; line-height: inherit; color: inherit; }
ul { list-style: none; margin: 0; padding: 0; }
/* 标题统一 20px / 700 / 行高 1.5 倍。
   这里在基础规则上就写死字号，是为了兜住「没挂到具体组件类上」的裸标题 ——
   否则会落到浏览器默认的 h1=32px、h2=24px、h3=18.7px，与设计不一致。 */
h1, h2, h3, h4 { margin: 0; font-size: var(--title-size); font-weight: var(--title-weight); line-height: var(--line-height); }
p { margin: 0; }
/* 链接：hover **不加下划线**（用户明确要求）。可点击性改用颜色加深来表达 ——
   下划线会带动整行文字重排基线，颜色过渡是纯合成层的，视觉更安静。
   ⚠️ hover 必须写成 `a:where(:hover)`：直接写 `a:hover` 特异性是 (0,1,1)，
   会压过 `.lp-btn-primary` / `.lp-logo` / `.lp-btn-white` 这些 (0,1,0) 的规则 ——
   首页那个白字主按钮和 LOGO 文字会跟着被染成紫色。加上 `:where()` 把特异性降到
   (0,0,1)，就只对「裸链接」生效，带类的链接（按钮 / 导航 / 页脚）各自保持自己的配色。
   老浏览器不支持 `:where()` 时整条规则被丢弃 —— 只是少一层变色反馈，不会破坏任何东西。 */
a { color: var(--brand); text-decoration: none; transition: color 0.24s var(--ease-soft); }
a:where(:hover) { color: var(--brand-2); text-decoration: none; }

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(16,24,48,0.16); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: rgba(16,24,48,0.3); }

.view { height: 100vh; height: 100dvh; }
/* [hidden] 的隐藏由文件顶部的全局兜底规则统一处理，此处无需重复 */

/* ══════════════════════════════════════════════════════════
   一、登录 / 注册视图
   ══════════════════════════════════════════════════════════ */

.view-auth {
  position: relative;
  /* 纵向 flex：卡片垂直居中，站点页脚独占页面底部一行 */
  display: flex;
  flex-direction: column;
  align-items: center;
  /* 顶部要空出固定导航那一条，否则卡片会被导航压住 */
  padding: calc(var(--lp-nav-h) + 16px) 24px 24px;
  overflow-y: auto;
  /* 静态背景：两层径向渐变 + 纯色底（与首页 .lp-bg 用的是同一组色值）。
     曾把渐变挪到固定层上做过缓慢漂移，用户要求去掉背景动画后已还原到这里 ——
     元素自身的 background 不占额外图层，是最省的写法。 */
  background: radial-gradient(1200px 700px at 15% 10%, #dae5ff 0%, transparent 55%),
              radial-gradient(900px 600px at 88% 88%, #e7dcff 0%, transparent 55%),
              var(--bg-0);
}

/* 背景光斑：只负责形状 / 颜色 / 模糊，**保持静止**
   （原先挂过 float 浮动动画，用户要求去掉背景动画后已移除；首页 .lp-bg .orb
   用的是同一组 .orb 基础样式，改这里两个页面同时生效）。
   想恢复浮动：把 animation 加回 .orb，并补回 @keyframes float。 */
.auth-bg { position: fixed; inset: 0; pointer-events: none; overflow: hidden; }
.orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(80px);
  opacity: 0.24;
}
.orb-1 { width: 420px; height: 420px; background: #3b6bf5; top: -120px; left: -100px; }
.orb-2 { width: 380px; height: 380px; background: #7c3aed; bottom: -140px; right: -80px; }
.orb-3 { width: 300px; height: 300px; background: #0e8fa8; top: 45%; left: 52%; opacity: 0.14; }

/* 卡片容器 */
.auth-wrap {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 940px;
  /* 上下 auto 边距 = 垂直居中；高度超出视口时自动退化为 0，不会裁掉卡片顶部 */
  margin: auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: rgba(255, 255, 255, 0.78);
  backdrop-filter: blur(22px);
  -webkit-backdrop-filter: blur(22px);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
  /* ⚠️ 必须 flex-shrink:0：本卡是 .view-auth（flex column, overflow-y:auto）的子项，
     而 overflow:hidden 会让 flex 的 min-height:auto 失效 —— 手机端内容超屏时卡片
     会被压缩、表单溢出与页脚重叠（2026-09-23）。禁收缩后由 .view-auth 正常滚动。 */
  flex-shrink: 0;
}

/* ---- 左侧品牌 ----
   背景走「视频 + 磨砂覆盖」共用媒体层（.lp-cta-video / .lp-cta-veil，
   与首页 CTA 那套完全同一份样式，定义在第十二节）。
   position/overflow 是给媒体层铺满 + 裁掉溢出用的；底色保留品牌渐变，
   视频没解码完 / 被 reduce 隐藏 / 加载失败时靠它兜住。
   磨砂层用的是「浅色玻璃」变体（.lp-cta-veil--light，白 0.2），底子被抬得很亮，
   所以文字反而要落回深色 —— 白玻璃上再放白字就读不出来了。 */
.auth-brand {
  position: relative;
  overflow: hidden;
  padding: 52px 44px;
  /* 兜底底色跟着磨砂层一起转浅：现在是「浅色玻璃」（白 0.2），若仍用深蓝兜底，
     ① 视频没解码完时左栏会先闪一块深蓝；② 下面 border-right 那 1px 落在媒体层
     的裁切区之外（overflow:hidden 裁的是 padding box，缝不到边框），深蓝底会从
     这条缝里透出来，变成一条深色细线 —— 看着就像多了道边。 */
  background: linear-gradient(160deg, #e9f0ff, #e8f8fb);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  color: var(--text-1);
}
/* ---- 右侧表单 ---- */
.auth-panel { padding: 52px 44px; display: flex; flex-direction: column; justify-content: center; }

.panel-head { margin-bottom: 30px; }
.panel-head h2 { font-size: var(--title-size); font-weight: var(--title-weight); margin-bottom: 8px; }
.panel-head p { color: var(--text-3); font-size: var(--body-size); }

.field { position: relative; margin-bottom: 20px; }
.field label {
  display: block;
  font-size: var(--body-size);
  color: var(--text-2);
  margin-bottom: 8px;
  font-weight: 500;
}

.input-shell {
  display: flex;
  align-items: center;
  gap: 10px;
  background: #ffffff;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: 0 14px;
  transition: border-color 0.26s var(--ease-soft), box-shadow 0.26s var(--ease-soft);
}
.input-shell:focus-within {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-glow);
}
.input-shell.has-error { border-color: var(--danger); }

.input-shell .prefix {
  color: var(--text-3);
  font-size: var(--body-size);
  padding-right: 10px;
  border-right: 1px solid var(--line);
  flex: 0 0 auto;
}

.input-shell input {
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  outline: none;
  padding: 14px 0;
  font-size: var(--body-size);
}
.input-shell input::placeholder { color: var(--text-3); }
#code { font-family: var(--mono); }

.btn-send {
  flex: 0 0 auto;
  padding: 7px 14px;
  border-radius: 9px;
  font-size: var(--body-size);
  font-weight: 500;
  color: var(--brand);
  background: rgba(59, 107, 245, 0.12);
  border: 1px solid rgba(59, 107, 245, 0.28);
  transition: all 0.24s var(--ease-soft);
  white-space: nowrap;
}
.btn-send:hover:not(:disabled) { background: rgba(59, 107, 245, 0.22); }
.btn-send:disabled { color: var(--text-3); background: rgba(16,24,48,0.05); border-color: var(--line); cursor: not-allowed; }

.field-err { font-size: var(--body-size); color: var(--danger); margin-top: 6px; min-height: 0; }
.field-err:empty { display: none; }
/* 登录页报错文案：绝对定位到输入框右上角，不占文档流高度（不拉高卡片）。
   只对登录页 .field 生效；注销弹窗 .del-field .field-err 仍是流内元素，不受影响 */
.field .field-err {
  position: absolute;
  top: 0;
  right: 0;
  margin-top: 0;
  white-space: nowrap;
}
/* 报错文案出现时配一次很短的淡入（高度补间那套已删，不再配合） */
.field-err:not(:empty) { animation: authPaneIn 0.24s var(--ease-soft); }
@keyframes authPaneIn {
  from { opacity: 0; transform: translateY(-3px); }
  to   { opacity: 1; transform: none; }
}

.btn-primary {
  position: relative;
  width: 100%;
  padding: 14px;
  border-radius: var(--radius);
  font-size: var(--body-size);
  font-weight: 600;
  color: #fff;
  background: linear-gradient(100deg, var(--brand), var(--brand-2));
  box-shadow: 0 8px 22px rgba(59, 107, 245, 0.32);
  transition: transform 0.22s var(--ease-soft), box-shadow 0.26s var(--ease-soft), opacity 0.26s var(--ease-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
}
.btn-primary:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 12px 28px rgba(59, 107, 245, 0.42); }
.btn-primary:active:not(:disabled) { transform: translateY(0); }
.btn-primary:disabled { opacity: 0.62; cursor: not-allowed; }

.btn-spinner {
  width: 15px; height: 15px;
  border: 2px solid rgba(255,255,255,0.32);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.agree { font-size: var(--body-size); color: var(--text-3); text-align: center; margin-top: 16px; }
/* 年龄门槛提示：单独一行，前面挂一个 18+ 小标，比协议那行更容易被看到。
   ⚠️ 小标的字号/行高必须走站内令牌（`--body-size` + 1.5），
   写 12px / 1.6 会被 typo-check 判为「字号与行高掉出体系」。 */
.agree-note { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 10px; }
.age-badge {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 7px;
  border-radius: 100px;
  font-size: var(--body-size);
  font-weight: 700;
  line-height: 1.5;
  color: #fff;
  background: linear-gradient(135deg, var(--brand), var(--brand-2));
}

/* ══════════════════════════════════════════════════════════
   二、AI 对话视图
   ══════════════════════════════════════════════════════════ */

.view-chat { display: flex; flex-direction: column; background: var(--bg-0); }

/* 侧边栏 + 主对话区的横向容器。
   min-height:0 是关键：不加的话内部 .messages 的 overflow 滚动会失效。
   页脚已经挪进 .chat-main，所以这一行会一直撑到窗口底部 —— 侧边栏因此能「一插到底」。 */
.chat-shell { display: flex; flex: 1; min-height: 0; }

/* ---- 侧边栏 ---- */
.sidebar {
  flex: 0 0 var(--sidebar-w);
  width: var(--sidebar-w);
  display: flex;
  flex-direction: column;
  background: var(--bg-1);
  border-right: 1px solid var(--line);
  z-index: 20;
}

.side-head { padding: 18px 16px 12px; }

.side-logo {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: var(--body-size);
  font-weight: 600;
  margin-bottom: 16px;
  padding: 0 4px;
}
.side-logo svg, .side-logo img { width: 22px; height: 22px; display: block; flex: 0 0 auto; }

.btn-new {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 11px;
  border-radius: var(--radius);
  font-size: var(--body-size);
  font-weight: 500;
  color: var(--text-1);
  background: rgba(59, 107, 245, 0.12);
  border: 1px solid rgba(59, 107, 245, 0.26);
  transition: all 0.24s var(--ease-soft);
}
.btn-new:hover { background: rgba(59, 107, 245, 0.22); border-color: rgba(59, 107, 245,0.45); }
.btn-new svg { width: 16px; height: 16px; }

.side-sessions { flex: 1; overflow-y: auto; padding: 14px 10px; }
.side-label {
  font-size: var(--body-size);
  text-transform: uppercase;
  color: var(--text-3);
  padding: 0 8px;
  margin-bottom: 9px;
  font-weight: 600;
}

#session-list li {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 11px;
  margin-bottom: 3px;
  border-radius: var(--radius-sm);
  font-size: var(--body-size);
  color: var(--text-2);
  cursor: pointer;
  transition: background 0.22s var(--ease-soft), color 0.22s var(--ease-soft);
  overflow: hidden;
}
#session-list li:hover { background: var(--bg-hover); color: var(--text-1); }
#session-list li.is-active { background: rgba(59, 107, 245, 0.16); color: var(--text-1); }

/* 标题 + 副行（消息条数 · 最后活动时间）上下排布 */
#session-list li .s-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
#session-list li .s-title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#session-list li .s-meta {
  font-size: var(--meta-size);
  color: var(--text-3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#session-list li .s-del {
  opacity: 0;
  flex: 0 0 auto;
  padding: 2px;
  border-radius: 5px;
  color: var(--text-3);
  transition: opacity 0.22s var(--ease-soft), color 0.22s var(--ease-soft);
  font-size: var(--body-size);
  line-height: var(--line-height);
  background: none;
  border: none;
  cursor: pointer;
}
#session-list li:hover .s-del { opacity: 1; }
#session-list li .s-del:hover { color: var(--danger); }

.side-empty { font-size: var(--body-size); color: var(--text-3); padding: 8px; text-align: center; }

.side-foot {
  /* 纵向排布：上面一行是「用户卡片 + 退出登录」，下面按需展开「注销账号」 */
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 13px 16px;
  border-top: 1px solid var(--line);
}
.user-row { display: flex; align-items: center; gap: 10px; }

/* 用户卡片本体是按钮：点击展开/收起下方的账号操作区 */
.user-card {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
  min-width: 0;
  padding: 5px 6px;
  margin: 0 -6px;
  border-radius: 10px;
  text-align: left;
  background: none;
  border: none;
  transition: background 0.22s var(--ease-soft);
}
.user-card:hover { background: var(--bg-hover); }
.user-card[aria-expanded="true"] { background: var(--bg-hover); }
.user-card:focus-visible { outline: 2px solid rgba(59, 107, 245, 0.5); outline-offset: 1px; }

/* 展开箭头：收起时朝上（还能点开），展开时翻转向下 */
.user-caret {
  flex: 0 0 auto;
  width: 15px; height: 15px;
  color: var(--text-3);
  transition: transform 0.26s var(--ease-soft), color 0.22s var(--ease-soft);
}
.user-card[aria-expanded="true"] .user-caret { transform: rotate(180deg); color: var(--text-2); }

/* 用户头像：统一使用 /assets/user.svg —— 那个图形**自带一个 r=256 的圆**，
   所以既不需要圆角、也不需要兜底底色（留底色的话，去掉圆角后四角会露出来）。
   去掉后外观与之前完全一致。 */
.avatar {
  flex: 0 0 auto;
  width: 33px; height: 33px;
  display: block;
  object-fit: cover;
}
.user-meta { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.user-name { font-size: var(--body-size); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-phone { font-size: var(--body-size); color: var(--text-3); font-family: var(--mono); }

/* ---- 账号操作区（点击用户卡片后展开） ---- */
.user-actions {
  display: flex;
  flex-direction: column;
  gap: 6px;
  /* 高度补间时裁掉内容：JS 用 WAAPI 从 0 补到目标高度（app.js setUserActions） */
  overflow: hidden;
  /* 提示浏览器高度/透明度动画走合成优化，减少补间抖动 */
  will-change: height, opacity;
}
.btn-danger-ghost {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 9px;
  border-radius: var(--radius-sm);
  font-size: var(--body-size);
  font-weight: 500;
  color: var(--danger);
  background: rgba(220, 38, 38, 0.06);
  border: 1px solid rgba(220, 38, 38, 0.26);
  transition: all 0.22s var(--ease-soft);
}
.btn-danger-ghost:hover { background: rgba(220, 38, 38, 0.13); border-color: rgba(220, 38, 38, 0.46); }
.btn-danger-ghost svg { width: 15px; height: 15px; flex: 0 0 auto; }
/* 清空全部对话记录：删数据但保留账号，比注销账号轻一档，
   所以走中性灰而不是危险红 —— 别和注销抢同一个警示位。 */
.btn-neutral-ghost {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 9px;
  border-radius: var(--radius-sm);
  font-size: var(--body-size);
  font-weight: 500;
  color: var(--text-2);
  background: rgba(16, 24, 48, 0.04);
  border: 1px solid var(--line);
  transition: all 0.22s var(--ease-soft);
}
.btn-neutral-ghost:hover { color: var(--danger); background: rgba(220, 38, 38, 0.08); border-color: rgba(220, 38, 38, 0.3); }
.btn-neutral-ghost svg { width: 15px; height: 15px; flex: 0 0 auto; }

.btn-logout {
  flex: 0 0 auto;
  padding: 7px;
  border-radius: 8px;
  color: var(--text-3);
  transition: all 0.22s var(--ease-soft);
}
.btn-logout:hover { color: var(--danger); background: rgba(220, 38, 38,0.1); }
.btn-logout svg { width: 17px; height: 17px; display: block; }

.sidebar-mask {
  position: fixed; inset: 0;
  background: rgba(17,24,39,0.34);
  z-index: 15;
  backdrop-filter: blur(2px);
}

/* ---- 主区 ---- */
.chat-main { flex: 1; display: flex; flex-direction: column; min-width: 0; position: relative; }

.chat-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 20px;
  border-bottom: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.86);
  backdrop-filter: blur(14px);
  z-index: 10;
}

.btn-icon {
  flex: 0 0 auto;
  padding: 8px;
  border-radius: 9px;
  color: var(--text-2);
  transition: all 0.22s var(--ease-soft);
}
.btn-icon:hover { background: var(--bg-hover); color: var(--text-1); }
.btn-icon svg { width: 19px; height: 19px; display: block; }

#btn-toggle-sidebar { display: none; }

.chat-head-title { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; }
.chat-head-title h2 {
  font-size: 18px;
  font-weight: var(--title-weight);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- 消息区 ---- */
.messages {
  flex: 1;
  overflow-y: auto;
  padding: 26px 20px 12px;
  scroll-behavior: smooth;
}

.msg {
  display: flex;
  gap: 13px;
  max-width: 820px;
  margin: 0 auto 24px;
  animation: msgIn 0.3s var(--ease);
}
@keyframes msgIn {
  from { opacity: 0; transform: translateY(9px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* 头像一律不做圆角（用户要求）：AI 头像用的正是 /assets/logo.svg，
   那个图形是直角矩形，套 9px 圆角会把四个角削掉。 */
.msg-avatar {
  flex: 0 0 auto;
  width: 32px; height: 32px;
  display: grid;
  place-items: center;
  font-size: var(--body-size);
  font-weight: 600;
}
/* 用户消息头像：与侧边栏同一个 /assets/user.svg。
   ⚠️ 那个图形**自带一个 r=256 的圆**（四角透明），所以 50% 圆角本来就是冗余的；
   而底下那层渐变兜底底色必须一起去掉 —— 不留圆角时，图形盖不到的那四个角
   会把渐面露出来、变成四个小三角。去掉后外观与之前完全一致（还是圆的）。 */
.msg-user .msg-avatar {
  color: #fff;
}
/* AI 消息头像：品牌 LOGO（与欢迎区、侧边栏同一个文件）。
   LOGO 自带彩色断环 + 深色钢笔，底色必须透明才能让线条颜色如实呈现；
   套原来那层蓝紫渐变会把蓝、靛两段弧线糊进底色里。 */
.msg-ai .msg-avatar { background: transparent; }
.msg-avatar img {
  width: 100%; height: 100%;
  display: block;
  object-fit: contain;
}

.msg-body { flex: 1; min-width: 0; }

.msg-role {
  font-size: var(--body-size);
  color: var(--text-3);
  margin-bottom: 6px;
  font-weight: 500;
}

.msg-content {
  font-size: var(--body-size);
  line-height: var(--line-height);
  color: var(--text-1);
  word-wrap: break-word;
  overflow-wrap: break-word;
}
.msg-user .msg-content {
  background: #eaf0ff;
  border: 1px solid var(--line);
  border-radius: 4px var(--radius) var(--radius) var(--radius);
  padding: 11px 15px;
  display: inline-block;
  white-space: pre-wrap;
}

/* Markdown 样式 */
.msg-content > *:first-child { margin-top: 0; }
.msg-content > *:last-child { margin-bottom: 0; }
.msg-content p { margin: 0 0 12px; }
.msg-content h1, .msg-content h2, .msg-content h3, .msg-content h4 {
  margin: 20px 0 10px;
  line-height: var(--line-height);
  font-size: var(--title-size);
  font-weight: var(--title-weight);
}
.msg-content h1 { font-size: var(--title-size); }
.msg-content h2 { font-size: var(--title-size); }
.msg-content h3 { font-size: var(--title-size); }
.msg-content h4 { font-size: var(--title-size); }
.msg-content ul, .msg-content ol { margin: 0 0 12px; padding-left: 22px; }
.msg-content ul { list-style: disc; }
.msg-content ol { list-style: decimal; }
.msg-content li { margin-bottom: 5px; }
.msg-content li::marker { color: var(--brand); }
/* AI 回复里只有 H 标题加粗，其余一律不加粗（2026-09-24 用户要求）。
   .msg-content 内的加粗来源只有三个：strong（**粗体**）、b（模型直接输出的 <b>）、
   th（表格表头），这里统一压成 400；H1~H4 仍用 --title-weight（见上面的标题规则）。
   strong 的 color 保留 —— .msg-content 本身已是 text-1，仅在引用块(text-2)里会略深一档。 */
.msg-content strong { color: var(--text-1); font-weight: 400; }
.msg-content b { font-weight: 400; }
.msg-content em { color: var(--text-2); }

.msg-content code {
  font-family: var(--mono);
  font-size: var(--body-size);
  padding: 2px 6px;
  border-radius: 5px;
  background: rgba(124, 58, 237, 0.09);
  color: #6d28d9;
}
.msg-content pre {
  margin: 0 0 14px;
  padding: 14px 16px;
  border-radius: var(--radius);
  background: #f7f9fc;
  border: 1px solid var(--line-strong);
  overflow-x: auto;
  position: relative;
}
.msg-content pre code {
  padding: 0;
  background: none;
  color: #334155;
  font-size: var(--body-size);
  line-height: var(--line-height);
}
.msg-content blockquote {
  margin: 0 0 12px;
  padding: 8px 15px;
  border-left: 3px solid var(--brand);
  background: rgba(59, 107, 245, 0.07);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  color: var(--text-2);
}
/* ⚠️ 引用块内的末段必须清掉下边距（2026-09-24 用户反馈文字没垂直居中）：
   `.msg-content p { margin: 0 0 12px }` 对引用块内部的 <p> 同样生效，而上面那条
   `.msg-content > *:last-child` 只作用于 .msg-content 的**直接子元素**、管不到这里 ——
   结果是上留白 8px、下留白 8+12=20px，整块文字看起来偏上（实测偏差 12px）。
   注意 blockquote 有 padding，子元素 margin 不会塌陷到外面，所以这 12px 是实打实占位的。 */
.msg-content blockquote > *:last-child,
.msg-content blockquote li:last-child { margin-bottom: 0; }   /* 末段 + 末列表项（li 自带 5px） */
.msg-content table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 14px;
  font-size: var(--body-size);
  display: block;
  overflow-x: auto;
}
.msg-content th, .msg-content td {
  padding: 8px 12px;
  border: 1px solid var(--line-strong);
  text-align: left;
}
.msg-content th { background: #f5f8fd; font-weight: 400; }   /* 表头也不加粗（2026-09-24） */
.msg-content a { color: var(--accent); }
.msg-content hr { border: none; border-top: 1px solid var(--line); margin: 16px 0; }

/* 打字机光标 */
.cursor {
  display: inline-block;
  width: 8px; height: 16px;
  vertical-align: text-bottom;
  margin-left: 2px;
  background: var(--brand);
  border-radius: 2px;
  animation: blink 1s step-end infinite;
}
@keyframes blink { 50% { opacity: 0; } }

/* 等待占位：三个跳动的点（AI 思考期间 / 加载历史时共用） */
.thinking { display: flex; align-items: center; gap: 5px; padding: 6px 0; }
.thinking i {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--text-3);
  animation: bounce 1.3s infinite;
}
.thinking i:nth-child(2) { animation-delay: 0.16s; }
.thinking i:nth-child(3) { animation-delay: 0.32s; }
@keyframes bounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
  30% { transform: translateY(-6px); opacity: 1; }
}

/* 消息操作条 */
.msg-actions {
  display: flex;
  gap: 4px;
  margin-top: 9px;
  opacity: 0;
  transition: opacity 0.26s var(--ease-soft);
}
.msg-ai:hover .msg-actions { opacity: 1; }
.msg-actions button {
  padding: 4px 9px;
  border-radius: 7px;
  font-size: var(--body-size);
  color: var(--text-3);
  border: 1px solid transparent;
  transition: all 0.22s var(--ease-soft);
}
.msg-actions button:hover {
  color: var(--text-1);
  background: var(--bg-hover);
  border-color: var(--line);
}

/* ---- 欢迎空态 ---- */
.welcome {
  max-width: 700px;
  margin: 5vh auto 0;
  text-align: center;
  animation: msgIn 0.45s var(--ease);
}
.welcome-icon { width: 62px; height: 62px; margin: 0 auto 20px; }
.welcome-icon img { width: 100%; height: 100%; display: block; }
.welcome h3 { font-size: var(--title-size); font-weight: var(--title-weight); margin-bottom: 10px; }
.welcome > p { color: var(--text-2); font-size: var(--body-size); margin-bottom: 30px; line-height: var(--line-height); }

.suggest-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 11px;
  text-align: left;
}
.suggest {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 15px;
  border-radius: var(--radius);
  background: var(--bg-2);
  border: 1px solid var(--line);
  transition: all 0.26s var(--ease-soft);
}
.suggest:hover {
  border-color: rgba(59, 107, 245, 0.42);
  background: #f7f9ff;
  transform: translateY(-2px);
  box-shadow: 0 8px 22px rgba(17, 24, 39, 0.09);
}
.s-icon { font-size: var(--body-size); line-height: var(--line-height); flex: 0 0 auto; }
.s-text { font-size: var(--body-size); color: var(--text-2); line-height: var(--line-height); }
.suggest:hover .s-text { color: var(--text-1); }

/* ---- 输入区 ---- */
.composer-wrap {
  padding: 12px 20px 16px;
  background: linear-gradient(to top, var(--bg-0) 55%, transparent);
}

.composer {
  display: flex;
  /* 垂直居中：输入框多行撑高时，发送按钮始终停在右侧中线，不会被甩到底边 */
  align-items: center;
  gap: 16px;
  max-width: 820px;
  margin: 0 auto;
  /* 四边统一 16px */
  padding: 16px;
  border-radius: var(--radius-lg);
  background: var(--bg-2);
  border: 1px solid var(--line-strong);
  transition: border-color 0.26s var(--ease-soft), box-shadow 0.26s var(--ease-soft);
}
.composer:focus-within {
  border-color: rgba(59, 107, 245, 0.55);
  box-shadow: 0 0 0 4px rgba(59, 107, 245, 0.1);
}

#input {
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  outline: none;
  resize: none;
  padding: 8px 0;
  /* 固定 3 行高（3 × 行高 + 上下各 8px 内边距），超过 3 行内部滚动（2026-09-23 用户要求） */
  height: calc(var(--body-size) * var(--line-height) * 3 + 16px);
  overflow-y: auto;
  line-height: var(--line-height);
  font-size: var(--body-size);
  text-align: justify;   /* 两端对齐（而非左对齐） */
}
#input::placeholder { color: var(--text-3); }

.btn-send-msg {
  flex: 0 0 auto;
  width: 38px; height: 38px;
  border-radius: 11px;
  display: grid;
  place-items: center;
  color: #fff;
  background: linear-gradient(135deg, var(--brand), var(--brand-2));
  transition: all 0.24s var(--ease-soft);
  box-shadow: 0 4px 14px rgba(59, 107, 245, 0.3);
}
.btn-send-msg svg { width: 17px; height: 17px; }
.btn-send-msg:disabled { opacity: 0.34; cursor: not-allowed; box-shadow: none; }
.btn-send-msg.is-stop {
  background: linear-gradient(135deg, #ef4444, #f97316);
  box-shadow: 0 4px 14px rgba(239, 68, 68, 0.3);
}

.composer-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  max-width: 820px;
  margin: 8px auto 0;
  padding: 0 6px;
  font-size: var(--body-size);
  color: var(--text-3);
}
#char-count.is-warn { color: var(--warn); }

/* ══════════════════════════════════════════════════════════
   三、通用组件
   ══════════════════════════════════════════════════════════ */

/* ---- 站点页脚（登录页 + 对话页共用）：备案信息 / 上线编号 ----
   跟随布局流放在各视图最底部，不用 fixed，不会被内容遮挡。
   两侧文案都带中文标签，窄屏靠 flex-wrap 自动折成两行。 */
.site-footer {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 4px 10px;
  padding: 10px 20px;
  font-size: var(--foot-size);
  line-height: var(--line-height);
  color: var(--text-3);
  text-align: center;
  /* 上线编号是一长串英文，窄屏必须允许在任意位置断行，否则会撑破布局 */
  overflow-wrap: anywhere;
}
.site-footer .foot-item { color: var(--text-3); }
.site-footer .foot-sep { color: var(--text-3); opacity: 0.55; }
.site-footer a { color: var(--text-3); }
.site-footer a:hover { color: var(--brand); }

/* 对话页（登录后）页脚无上边框，而且**就是 .chat-main 的一个子元素** ——
   宽度天然等于对话区，居中轴也和消息区完全重合，不需要再补任何左侧留白。
   ⚠️ 别再加 `.view-chat .site-footer` 的 padding-left：页脚已经不在
   #view-chat 直接子级上了，再加会把内容整体右推一个侧栏宽。 */

.toast-box {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 9999;
  display: flex;
  flex-direction: column;
  gap: 9px;
  align-items: center;
  pointer-events: none;
}
.toast {
  padding: 11px 19px;
  border-radius: var(--radius);
  font-size: var(--body-size);
  background: var(--bg-3);
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow);
  animation: toastIn 0.28s var(--ease);
  max-width: 88vw;
}
.toast.is-ok { border-color: rgba(5, 150, 105,0.4); color: #047857; }
.toast.is-err { border-color: rgba(220, 38, 38,0.4); color: #b91c1c; }
.toast.is-out { animation: toastOut 0.24s var(--ease) forwards; }
@keyframes toastIn { from { opacity: 0; transform: translateY(-14px); } }
@keyframes toastOut { to { opacity: 0; transform: translateY(-14px); } }

.modal { position: fixed; inset: 0; z-index: 9998; display: grid; place-items: center; padding: 22px; }
.modal-mask { position: absolute; inset: 0; background: rgba(17,24,39,0.34); backdrop-filter: blur(3px); }
.modal-body {
  position: relative;
  width: 100%;
  max-width: 560px;
  max-height: 78vh;
  overflow-y: auto;
  padding: 28px;
  border-radius: var(--radius-lg);
  background: var(--bg-2);
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow);
  animation: msgIn 0.28s var(--ease);
}
/* 带底部操作条的弹窗：body 不再留底部内边距，交给 sticky 操作条自己撑
   （否则滚动内容会从按钮下面穿过去）。「清空记录」与「注销」两个弹窗共用这一条，
   保证两处间距一致（2026-09-24 用户反馈两处 padding 不统一）。 */
.modal-body.modal--with-actions { padding-bottom: 0; }
.modal-body h3 { font-size: var(--title-size); font-weight: var(--title-weight); margin-bottom: 16px; }
.modal-content { font-size: var(--body-size); color: var(--text-2); line-height: var(--line-height); margin-bottom: 22px; }
.modal-content p { margin-bottom: 12px; }
.modal-content strong { color: var(--text-1); }

/* ---- 注销账号弹窗：危险态 ---- */
.modal-danger {
  max-width: 520px;
  /* 窄屏下比默认的 78vh 再放开一点（手机号输入框 + 吸底操作条要放得下）。
     底部内边距已抽成通用规则 .modal-body.modal--with-actions（见上方）。 */
  max-height: 86vh;
}
.modal-danger h3 { color: var(--danger); }

/* 注销提示块：红调底 + 两行短文案，一眼看清后果 */
.danger-note {
  padding: 15px 17px;
  margin-bottom: 20px;
  border-radius: var(--radius);
  background: rgba(220, 38, 38, 0.05);
  border: 1px solid rgba(220, 38, 38, 0.22);
  font-size: var(--body-size);
  line-height: var(--line-height);
  color: var(--text-2);
}
.danger-note .dn-lead { color: #b91c1c; font-weight: 500; margin-bottom: 12px; }
.danger-note .dn-sub { margin-bottom: 0; }

.del-field { margin-bottom: 16px; }
.del-field label {
  display: block;
  font-size: var(--body-size);
  color: var(--text-2);
  margin-bottom: 8px;
}
.del-field .field-err { margin: 4px 0 0; }

/* 操作条吸在弹窗底部：窄屏内容超长需要滚动时，
   「确认注销」始终可见，不会被顶到折线以下。 */
.modal-actions {
  position: sticky;
  bottom: 0;
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 12px 0 24px;
  background: var(--bg-2);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}
.btn-ghost {
  padding: 10px 20px;
  border-radius: var(--radius);
  font-size: var(--body-size);
  font-weight: 500;
  color: var(--text-2);
  background: var(--bg-1);
  border: 1px solid var(--line-strong);
  transition: all 0.22s var(--ease-soft);
}
.btn-ghost:hover { background: var(--bg-hover); color: var(--text-1); }
.btn-danger {
  padding: 10px 22px;
  border-radius: var(--radius);
  font-size: var(--body-size);
  font-weight: 600;
  color: #fff;
  background: linear-gradient(135deg, #ef4444, #b91c1c);
  box-shadow: 0 4px 14px rgba(220, 38, 38, 0.28);
  transition: all 0.22s var(--ease-soft);
}
.btn-danger:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(220, 38, 38, 0.34); }
.btn-danger:disabled { opacity: 0.4; cursor: not-allowed; box-shadow: none; }

/* ---- 弹窗操作条里的按钮（2026-09-24 修「退出登录弹窗好丑」）----
   ① 操作条是 flex 行，按钮必须显式 `flex: 0 0 auto` + `nowrap`：
      否则被同行按钮挤压时，「取消」会被压成一列**竖排**的字。
   ② 非危险确认用 `.btn-accent` —— 品牌渐变的**行内**按钮。
      🚫 别复用 `.btn-primary`：那是登录表单的整宽按钮（`width:100%` + `padding:14px`），
      塞进 flex 操作条会吃掉整行宽度、把「取消」挤扁 —— 这就是那个丑弹窗的根因。
   ③ `min-width` 让「取消 / 退出」成为等宽的一对，看起来是设计过的，而不是两个尺寸随机的块。 */
.modal-actions .btn-ghost,
.modal-actions .btn-danger,
.modal-actions .btn-accent {
  flex: 0 0 auto;
  white-space: nowrap;
  min-width: 84px;
}
.btn-accent {
  padding: 10px 22px;
  border-radius: var(--radius);
  font-size: var(--body-size);
  font-weight: 600;
  color: #fff;
  background: linear-gradient(100deg, var(--brand), var(--brand-2));
  box-shadow: 0 4px 14px rgba(59, 107, 245, 0.26);
  transition: all 0.22s var(--ease-soft);
}
.btn-accent:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(59, 107, 245, 0.34); }
.btn-accent:disabled { opacity: 0.45; cursor: not-allowed; box-shadow: none; }

/* ══════════════════════════════════════════════════════════
   四、响应式
   ══════════════════════════════════════════════════════════ */

@media (max-width: 860px) {
  .auth-wrap { grid-template-columns: 1fr; max-width: 460px; }
  .auth-brand {
    padding: 34px 30px 26px;
    border-right: none;
    border-bottom: 1px solid var(--line);
    /* 手机端左栏是顶部横条：内容只剩绝对定位的品牌图标（不占文档流），
       不给高度整条只剩 padding 高、图标被裁。2026-09-23 用户要求栏高减半
       （260→130px），图标也等比缩到 100px，保持完整居中 */
    min-height: 130px;
  }
  .auth-brand .auth-brand-icon { width: 100px; height: 100px; }
  .auth-panel { padding: 30px 30px 36px; min-width: 0; }
  .panel-head { margin-bottom: 22px; }
}

@media (max-width: 768px) {
  #btn-toggle-sidebar { display: block; }
  /* 手机端隐藏 .view-auth 的滚动条占位：否则滚动条宽度会让居中卡片视觉偏左
     （实测 375 视口左边距 14 / 右边距 22，2026-09-23） */
  .view-auth { scrollbar-width: none; }
  .view-auth::-webkit-scrollbar { display: none; }

  .sidebar {
    position: fixed;
    top: 0; bottom: 0; left: 0;
    transform: translateX(-100%);
    transition: transform 0.34s var(--ease-soft);
    box-shadow: var(--shadow);
  }
  .sidebar.is-open { transform: translateX(0); }

  .messages { padding: 18px 14px 8px; }
  .msg { gap: 10px; margin-bottom: 20px; }
  .msg-avatar { width: 29px; height: 29px; font-size: var(--body-size); }

  .suggest-grid { grid-template-columns: 1fr; }
  .welcome { margin-top: 3vh; }
  .welcome h3 { font-size: var(--title-size); }

  .composer-wrap { padding: 10px 12px 12px; }
  /* 「内容由 AI 生成」提示手机端也要显示（2026-09-23 用户要求），允许换行防挤 */
  .composer-foot { flex-wrap: wrap; row-gap: 2px; }
  .chat-head { padding: 11px 14px; }
  /* 窄屏：两项各占一行，去掉行内分隔点，避免出现「悬挂在行尾的 · 」 */
  .site-footer { flex-direction: column; flex-wrap: nowrap; gap: 2px; padding: 8px 14px; }
  .site-footer .foot-sep { display: none; }
}

@media (max-width: 420px) {
  /* 窄屏卡片不再贴边：留出左右边距、恢复圆角与描边（2026-09-23 用户要求） */
  .view-auth { padding: var(--lp-nav-h) 14px 24px; }
  .auth-wrap { border-radius: var(--radius-lg); border: 1px solid var(--line-strong); min-height: auto; }
  .auth-brand { padding: 28px 22px 22px; }
  .auth-panel { padding: 26px 22px 32px; }
  .btn-send { padding: 7px 10px; font-size: var(--body-size); }
}

/* 登录页与对话页隐藏站点页脚（2026-09-23 用户要求；首页 .lp-foot 保留，
   AI 生成提示保留在对话输入框下方的 .composer-foot 里） */
#view-auth .site-footer,
.chat-main .site-footer { display: none; }

/* 减少动效偏好 */
/* 登录页左栏磨砂参数（压深 + 饱和）由 video 自身的 filter 提供 */
.auth-brand .lp-cta-video { filter: blur(7px) saturate(1.5) brightness(0.88); }
/* 登录页左栏品牌图标：白色用户头像 SVG，200px 居中，盖在磨砂层(z1)之上 */
.auth-brand-icon {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 200px;
  height: 200px;
  z-index: 2;
  pointer-events: none;
  /* 淡阴影沿图标轮廓走（drop-shadow 而非 box-shadow，否则阴影打在矩形框上） */
  filter: drop-shadow(0 10px 28px rgba(16, 24, 48, 0.20));
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ══════════════════════════════════════════════════════════
   十、站点导航 / 版心（首页与登录页共用）
   这套样式原先长在 home.html 的 <style> 里，登录页也要用同一个导航，
   所以整体提到这里 —— **只此一份**，以后改导航只改这一段。
   （类名仍是 .lp- 前缀，是历史原因；两个页面的调用点都按这套类名写。）
   ══════════════════════════════════════════════════════════ */
:root {
  --lp-hair: rgba(16, 24, 48, 0.08);        /* 极浅分隔线 */
  --lp-nav-h: 66px;                         /* 导航高度，页面靠它让出顶部空间 */
  --lp-max: 1180px;                         /* 版心最大宽度 */
  /* 按钮阴影：静置一份、hover 一份，**所有变体共用同一份** ——
     用户明确要求「两者 hover 只产生阴影，阴影保持一致」。改这里全站生效。 */
  --lp-btn-shadow: 0 8px 22px rgba(43, 74, 168, 0.22);
  --lp-btn-shadow-hover: 0 16px 34px rgba(43, 74, 168, 0.3);
  /* 媒体层（视频 + 磨砂，第十二节）：
     --lp-media-bleed 向外溢出的量 —— backdrop-filter 在自身边界取不到外侧像素，
                      只能钳制后再模糊，边界处会留一圈和内部不同的带；把层撑大，
                       这圈带就落到父容器的 overflow:hidden 之外被裁掉；
     --lp-media-zoom  取景放大倍率 —— 源视频是高调构图，四边有大片近白留白，
                       直接 cover 会在没被裁掉的那两条边露出白边（看着像「一层边框」）。 */
  --lp-media-bleed: 36px;
  --lp-media-zoom: 1.22;
}

/* ---------- 版心 ---------- */
.lp-wrap { width: 100%; max-width: var(--lp-max); margin: 0 auto; padding: 0 24px; }

/* ---------- 顶部导航 ---------- */
.lp-nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  height: var(--lp-nav-h);
  display: flex;
  align-items: center;
  background: rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(24px) saturate(180%);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  /* 独立合成层隔离：hover 下拉选项时导航内部重绘，不向外波及下方视频磨砂层
     （否则会触发视频背景重新采样、闪一条横线 —— 2026-09-22 修的渲染 bug） */
  transform: translateZ(0);
  will-change: backdrop-filter;
  border-bottom: 1px solid transparent;
  transition: background 0.26s var(--ease-soft), border-color 0.26s var(--ease-soft), box-shadow 0.26s var(--ease-soft);
}
/* 滚动之后（首页由 JS 加类；登录页常驻）稍微加厚一点，但仍保留磨砂透明感 */
.lp-nav.is-solid {
  background: rgba(255, 255, 255, 0.7);
  border-bottom-color: var(--lp-hair);
  box-shadow: 0 8px 30px rgba(16, 24, 48, 0.055);
}
.lp-nav .lp-wrap { display: flex; align-items: center; gap: 28px; }

.lp-logo { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--text-1); flex: 0 0 auto; }
.lp-logo img { width: 30px; height: 30px; display: block; }
.lp-logo b { font-size: 18px; font-weight: 700; white-space: nowrap; }

.lp-menu { display: flex; align-items: center; gap: 4px; margin-left: 10px; flex: 1; }
.lp-menu a {
  display: inline-block;
  padding: 7px 14px;
  border-radius: 8px;
  color: var(--text-2);
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.22s var(--ease-soft), background 0.22s var(--ease-soft);
}
.lp-menu a:hover { color: var(--brand); background: rgba(59, 107, 245, 0.08); }

/* ---------- 「功能介绍」下拉（把原来 4 个平铺菜单收进来） ----------
   开合纯 CSS（:hover / :has(:focus-visible)）：不依赖 JS，键盘 Tab 进去面板也留得住，
   触屏点按钮会 focus 到它、点到别处自动收。JS 只负责同步 aria-expanded。 */
.lp-drop { position: relative; flex: 0 0 auto; }
.lp-drop-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border: 0;
  border-radius: 8px;
  background: none;
  font-family: inherit;
  font-size: var(--body-size);
  line-height: inherit;
  color: var(--text-2);
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.22s var(--ease-soft), background 0.22s var(--ease-soft);
}
.lp-drop-btn svg { width: 14px; height: 14px; transition: transform 0.22s var(--ease-soft); }
.lp-drop:hover .lp-drop-btn,
.lp-drop:has(:focus-visible) .lp-drop-btn { color: var(--brand); background: rgba(59, 107, 245, 0.08); }
.lp-drop:hover .lp-drop-btn svg,
.lp-drop:has(:focus-visible) .lp-drop-btn svg { transform: rotate(180deg); }

.lp-drop-panel {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  /* 用户反馈「四个选项太宽」：原来是 min-width:178px 定宽 + 文字左对齐，
     右侧空一大片。改成按内容收缩（max-content，不再被 .lp-drop 那个窄盒子限制），
     面板宽度就跟「功能介绍」按钮差不多，四项文字在面板里居中。 */
  width: max-content;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px;
  border-radius: 12px;
  background: #fff;              /* 下拉面板纯白底（2026-09-22 用户要求，去掉磨砂半透明） */
  border: 1px solid var(--lp-hair);
  box-shadow: 0 16px 36px rgba(16, 24, 48, 0.12);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 0.2s var(--ease-soft), transform 0.2s var(--ease-soft), visibility 0.2s;
}
/* 与按钮之间那 8px 空隙：鼠标横穿时不能掉出 :hover，否则面板会先关掉。
   给面板垫一块透明的桥，桥是面板的子元素 → 指针在桥上就等于还在 .lp-drop 里。 */
.lp-drop-panel::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: -10px;
  height: 10px;
}
.lp-drop:hover .lp-drop-panel,
.lp-drop:has(:focus-visible) .lp-drop-panel,
.lp-drop.is-open .lp-drop-panel { opacity: 1; visibility: visible; transform: translateY(0); }
.lp-drop-panel a { display: block; padding: 9px 16px; border-radius: 8px; text-align: center; }

.lp-nav-cta { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.lp-login { color: var(--text-2); text-decoration: none; padding: 7px 12px; border-radius: 8px; white-space: nowrap; }
.lp-login:hover { color: var(--brand); }

.lp-burger {
  display: none;
  width: 40px; height: 40px;
  align-items: center; justify-content: center;
  border-radius: 10px;
  color: var(--text-1);
  border: 1px solid var(--lp-hair);
  background: rgba(255, 255, 255, 0.7);
  transition: color 0.22s var(--ease-soft), border-color 0.22s var(--ease-soft), background 0.22s var(--ease-soft);
}
.lp-burger svg { width: 20px; height: 20px; }

@media (max-width: 820px) {
  :root { --lp-nav-h: 60px; }
  .lp-menu {
    display: none;
    position: absolute;
    top: var(--lp-nav-h);
    left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    margin: 0;
    padding: 10px 16px 16px;
    background: rgba(255, 255, 255, 0.96);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    border-bottom: 1px solid var(--lp-hair);
    box-shadow: 0 14px 30px rgba(16, 24, 48, 0.08);
  }
  .lp-menu.is-open { display: flex; }
  .lp-menu a { padding: 11px 12px; }
  /* 窄屏导航本身已经是纵向面板，下拉再叠一层就绕 —— 直接摊平成一组子项 */
  .lp-drop { position: static; }
  .lp-drop-btn { width: 100%; justify-content: flex-start; padding: 11px 12px; cursor: default; }
  .lp-drop-btn svg { display: none; }
  .lp-drop-panel {
    position: static;
    min-width: 0;
    opacity: 1;
    visibility: visible;
    transform: none;
    padding: 0 0 0 10px;
    background: none;
    border: 0;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .lp-drop-panel::before { display: none; }
  .lp-drop-panel a { padding: 9px 12px; color: var(--text-2); }
  .lp-nav .lp-wrap { gap: 12px; }
  /* 手机端 header 极简（2026-09-23）：保留左上角 LOGO+品牌名，首页只留「开始创作」、
     登录页只留「返回首页」，都定位到右上角；折叠导航按钮（汉堡）收掉 ——
     落地页滚动即可浏览，登录页左栏本身有品牌展示，导航没有存在必要。 */
  .lp-burger { display: none; }
  .lp-nav-cta { margin-left: auto; }
  .lp-nav-cta .lp-login { display: inline-flex; }
}

/* ---------- 站点按钮（首页 / 登录页共用，与上面的导航同一批） ----------
   访客页的行动按钮（现在文案统一是「开始创作」）：**一律没有边框**，
   hover **只出阴影** —— 不换底色、不换字色、不位移，而且各变体用的是同一份阴影
   （--lp-btn-shadow-hover），这样并排两个按钮的 hover 手感完全一致。
   ⚠️ 别再往 .lp-btn:hover 里加 background / color / border-color / transform。 */
.lp-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 26px;
  border-radius: 11px;
  font-size: var(--body-size);
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  /* 透明而不是删掉：几何尺寸不变，视觉上没有任何边框 */
  border: 1px solid transparent;
  box-shadow: var(--lp-btn-shadow);
  transition: box-shadow 0.26s var(--ease-soft), transform 0.22s var(--ease-soft);
}
.lp-btn-primary {
  color: #fff;
  background: linear-gradient(100deg, var(--brand), var(--accent));
}
.lp-btn:hover { box-shadow: var(--lp-btn-shadow-hover); }
.lp-btn-sm { padding: 8px 18px; border-radius: 9px; }
.lp-btn-lg { padding: 14px 32px; border-radius: 12px; }
/* 按下时轻微回收：先给出「按到了」的即时反馈，松手再用柔和曲线浮回 hover 态。
   ⚠️ 必须写在上面所有 :hover 规则之后 —— 两者特异性相同（都是类 + 伪类），
   后定义者胜，写在前面会被 :hover 的 translateY(-1px) 压掉。 */
.lp-btn:active { transform: translateY(0) scale(0.985); }


/* ══════════════════════════════════════════════════════════
   十一、文字不可选中（登录页）
   访客页是「读」的页面：允许拖选会在点击/滑动时选中文字、留下蓝色高亮，观感很差。
   对话页是「写」的页面，**不动**。
   输入类元素必须放行 —— 否则手机号 / 验证码没法选中、拖动编辑。
   ══════════════════════════════════════════════════════════ */
#view-auth {
  user-select: none;
  -webkit-user-select: none;
}
#view-auth input,
#view-auth textarea,
#view-auth [contenteditable] {
  user-select: text;
  -webkit-user-select: text;
}

/* ══════════════════════════════════════════════════════════
   十二、媒体背景层（视频 + 磨砂覆盖）
   首页 CTA 块与登录页 .auth-brand 共用同一套：视频铺满容器，上面盖一层磨砂。
   原先长在 home.html 的 <style> 里，登录页也要用就整体提到这里 —— 只此一份。
   ⚠️ backdrop-filter 必须有东西在它背后才看得见，所以它不能盖在纯色底上；
   顺序必须是 video(z0) → veil(z1) → 内容(z2+)，调用方负责把内容抬上去。
   ══════════════════════════════════════════════════════════ */
.lp-cta-video {
  position: absolute;
  /* ⚠️ 这里不能用 inset:0 + width/height:100% —— 绝对定位元素上两者会打架
     （right/bottom 被忽略），撑不出四周均匀的外溢。用显式 calc 最稳。
     外溢的量见 --lp-media-bleed 的说明。 */
  top: calc(-1 * var(--lp-media-bleed));
  left: calc(-1 * var(--lp-media-bleed));
  width: calc(100% + 2 * var(--lp-media-bleed));
  height: calc(100% + 2 * var(--lp-media-bleed));
  z-index: 0;
  display: block;
  object-fit: cover;
  /* 源视频是高调构图，四边有大片近白留白；放大一档把留白推出可见区，
     否则没被裁掉的那两条边会露出一条白边，看着像「一层边框」。 */
  transform: scale(var(--lp-media-zoom));
  filter: blur(7px) saturate(135%);
}
.lp-cta-veil {
  position: absolute;
  top: calc(-1 * var(--lp-media-bleed));
  left: calc(-1 * var(--lp-media-bleed));
  width: calc(100% + 2 * var(--lp-media-bleed));
  height: calc(100% + 2 * var(--lp-media-bleed));
  z-index: 1;
  background: linear-gradient(120deg,
              rgba(47, 90, 224, 0.5),
              rgba(59, 107, 245, 0.5) 45%,
              rgba(14, 143, 168, 0.5));
}
/* 浅色玻璃变体（登录页左栏用）。
   用户反馈「画面偏淡」，所以做了两处加深：
   ① 白层从纯白 0.5 收到 **0.42** —— 少压一点白，视频的颜色能透出来；
   ② 给 backdrop 补 **brightness(0.92)**（把视频整体压深）+
      **saturate(1.5)**（花与茎的颜色立得住，不再是一片灰白）。
   实测左栏内部亮度 242 → 约 222（其余边界台阶仍 <12）。
   底色仍保留 .auth-brand 的浅渐变兜底：视频没解码完时不会变白板。 */
.lp-cta-veil--light {
  /* 白色遮罩浓度（2026-09-24 用户指定 0.2） */
  background: rgba(255, 255, 255, 0.2);
}
@media (prefers-reduced-motion: reduce) {
  /* 背景视频不渲染 —— 只留品牌渐变底，避免动画面干扰 */
  .lp-cta-video { display: none; }
}


/* ══════════════════════════════════════════════════════════
   登录成功撒花动画（Lottie success confetti）
   全屏透明过渡层：居中一枚 360px 撒花动画，播完进入对话页。
   （2026-09-23 删了背景磨砂 + 白罩渐入过渡，直接透明显示撒花）
   ══════════════════════════════════════════════════════════ */
.login-celebration {
  /* 撒花落在左栏品牌区内居中（2026-09-24 用户要求）——节点已在 .auth-brand 内部，
     所以用 absolute 而不是 fixed；窄屏由下面的断点改回 fixed 全屏。 */
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  background: transparent;
}
.login-celebration-lottie {
  width: 360px;
  height: 360px;
}
/* 登录页提示容器：铺满品牌区、纵向居中（.toast-box 已是 flex column + align-items:center）。
   窄屏由断点改回 fixed 顶部 —— 那里品牌区只有 130px 高。 */
.toast-box--brand {
  position: absolute;
  inset: 0;
  transform: none;
  justify-content: center;
  z-index: 3;
}
/* ⚠️ 窄屏回退必须写在上面两条主规则**之后**：同特异性下靠后的声明才生效，
   放在前面的媒体查询块里会被文件尾部的主规则覆盖（2026-09-24 踩过）。
   窄屏品牌区只有 130px 高，放不下 360px 撒花与居中提示，回全屏定位。 */
@media (max-width: 860px) {
  .toast-box--brand {
    position: fixed;
    top: 20px; left: 50%; right: auto; bottom: auto;
    transform: translateX(-50%);
    justify-content: flex-start;
    z-index: 9999;
  }
  .login-celebration { position: fixed; }
}
