/* 聊明天 — 温暖纸笺
 *
 * Visual thesis: 旭日黄柔化纸底 + 深墨字 + 马尔斯绿主强调（--cinnabar* 整族）+ 灰青陪伴色；
 * 朱砂红（--seal-red）收缩到印章/通知红点/危险动作。注：下文部分注释沿用旧「朱砂」表述，
 * 主强调实际已渲染为 teal（见 token 重映射），仅印章/红点/危险为朱砂红。
 * 安静像一封手写信，聊天区更轻，适合长期咨询和日常陪伴。
 *
 * Interaction: 所有按钮 active:scale-0.97；input focus 180ms 过渡到灰青；
 * 错误一次性微 shake（160ms）。
 *
 * 适配：iPhone Safari + Android Chrome，360px 起。
 */

/* 自托管 web 字体（subset，墙内外都本地直出，不依赖 Google Fonts）。
   字符集与生成见 scripts/subset-web-fonts.sh。Noto Serif SC 缺字时逐字
   回落系统宋体，不会破。字体按 immutable 长缓存，URL 的 `?v=1785980919` 由
   服务端替换为静态资源最大 mtime——重新 subset 后版本前移、旧缓存失效。 */
@font-face {
  font-family: "Inter";
  src: url("/static/inter-subset.woff2?v=1785980919") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Noto Serif SC";
  src: url("/static/noto-serif-sc-subset.woff2?v=1785980919") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}
/* 装饰档：马善政楷书，仅章节标题/封面/品牌等少量固定展示字（subset 见
   scripts/subset-web-fonts.sh）。缺字逐字回落 serif，加载失败也不破。 */
@font-face {
  font-family: "Ma Shan Zheng";
  src: url("/static/mashanzheng-deco-subset.woff2?v=1785980919") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: light; /* 原生控件（checkbox/scrollbar/autofill）按主题渲染 */
  /* 色板——OKLCH 等价值见行尾注释，浏览器兼容用 hex */
  /* 马尔斯绿 × 旭日黄 × 朱砂印：黄底-绿构-红点。--cinnabar* 整族=主强调(teal)，
     红收缩到 --seal-red 仅印章用。旭日黄柔化做底。 */
  --paper: #fbf4cc;          /* 柔化旭日黄页底 */
  --card: #fffdf2;           /* 暖白卡，从黄底浮起 */
  --ink: #1e2521;            /* 近黑墨绿正文 */
  --ink-soft: #5d675f;       /* 次文 / label */
  --ink-faint: #8a948b;      /* 提示 / meta */
  --rule: #e7e1bd;           /* 黄染边线 */
  --rule-soft: #f1ecd2;      /* 更淡的分隔 */
  --cinnabar: #007067;       /* 马尔斯绿—主强调填充/边框（配白字、描边） */
  --cinnabar-text: #007067;  /* teal 当文字：~6:1 over 黄底 */
  --cinnabar-deep: #005d55;  /* 提亮…实为压深 teal：hover 文字/描边 */
  --cinnabar-hover: #005d55; /* 主按钮 hover 填充：反白字安全 */
  --cinnabar-mute: #9cc4be;  /* disabled（淡 teal） */
  --cinnabar-wash: #e2efeb;  /* 极淡 teal 染—高亮底 / 选中底 */
  --sage: #6f8f84;           /* 灰青—聊天陪伴色，与 teal 同族 */
  --sage-deep: #5f8176;      /* 灰青 hover/press */
  --sage-line: #cbd9d2;      /* 用户气泡边线 */
  --sage-wash: #edf3ee;      /* 用户气泡底 / 轻提示 */
  --warning: #b5402c;        /* 错误文（红系，与 seal 同暖红族、独立语义） */
  --seal-red: #c0402a;       /* 朱砂—印章/印记/危险文字：黄底文字 4.7:1、印章白字 5.2:1 过 AA */
  --seal-ink: #fffefb;       /* teal/sage/朱砂底上的反白字，两主题恒定 */
  --overlay: rgb(20 28 24 / 0.45);       /* modal 遮罩 */
  --bar-wash: rgb(251 244 204 / 0.92);   /* 输入条半透明黄底 */

  /* 字体栈——标题用宋体气质，正文用 system sans 保证移动可读。
     Inter / Noto Serif SC 自托管（见顶部 @font-face）：拉丁字形走 Inter
     （可变 opsz），CJK 逐字回落到 PingFang / 宋体。 */
  --font-serif: "Noto Serif SC", "Source Han Serif SC", "Songti SC",
    "STSong", "SimSun", "Source Serif Pro", Georgia, serif;
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "PingFang SC",
    "HarmonyOS Sans SC", "Hiragino Sans GB", "Microsoft YaHei",
    "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  /* 装饰档：标题/封面/品牌用楷书，与内容档(serif)/操作档(sans)三档分明。
     缺字回落 serif 全栈（var 文本展开）。 */
  --font-display: "Ma Shan Zheng", var(--font-serif);

  /* 度量 */
  --radius: 8px;             /* input / button / card 一致 */
  --radius-pill: 999px;      /* 仅聊天 bubble / 输入条 */
  --press-scale: 0.97;       /* 按下缩放（克制，纸笺感） */
  --press-ms: 100ms;
  --focus-ms: 180ms;

  /* 阴影—纸感浮起，不是 SaaS 卡。近距柔影 + 远距漫射，暖墨调不发灰 */
  --shadow-card: 0 1px 2px rgb(31 27 22 / 0.06),
    0 5px 14px rgb(31 27 22 / 0.07);
  /* 卡片顶缘微高光（贴合「压在宣纸上抬起」的纸感），叠在投影后 */
  --edge-hi: inset 0 1px 0 rgb(255 255 255 / 0.6);
  /* 按下压回纸面：影收近、去高光（暗色覆盖成黑色系，与 --shadow-card 一致） */
  --shadow-pressed: 0 1px 2px rgb(31 27 22 / 0.06);
  --shadow-modal: 0 4px 12px rgb(31 27 22 / 0.08),
    0 24px 48px rgb(31 27 22 / 0.12);
}

/* 繁体 locale：仅覆盖字体变量前置 TC 族，各处 font-family: var(--font-*) 自动跟随。 */
:root[data-locale="tw"],
:root[data-locale="hk"] {
  --font-serif: "Noto Serif TC", "Noto Serif SC", "Source Han Serif SC",
    "Songti SC", "STSong", "SimSun", "Source Serif Pro", Georgia, serif;
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "PingFang TC",
    "Noto Sans TC", "PingFang SC", "HarmonyOS Sans SC", "Hiragino Sans GB",
    "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
}

/* 夜里的信纸——暗色 token 覆盖。data-theme 由 theme.js 在 head 同步
   设置（localStorage 优先，否则跟随系统），CSS 只认这一个开关。
   烛下暖墨：底色保持纸的暖棕调；朱砂按钮底不变，hover 在暗底改提亮；
   sage 提亮一档保证气泡边线/文字可读。 */
[data-theme="dark"] {
  color-scheme: dark;
  /* 暗色=茶褐/沉香暖深色，非反相黑：朱砂落上去像「印泥在夜里的旧纸上」，
     不压抑、红褐同属暖色不冲。朱砂在暗底降饱和+提明度成暖陶/砖红。 */
  /* 夜墨绿：底色沉绿暖深，teal 强调提亮过 AA，印章红降饱和成暖砖红，旭日黄做暖光点。 */
  --paper: #15211e;          /* 沉墨绿暗底 */
  --card: #1e2d29;           /* 抬升面，绿一档 */
  --ink: #ece9d8;            /* 暖白正文，对比 ~12:1 */
  --ink-soft: #a8b0a6;       /* 次文 ~6.5:1 */
  --ink-faint: #828a80;      /* meta，过 AA */
  --rule: #34433d;           /* 墨绿分隔线 */
  --rule-soft: #283531;
  --cinnabar: #2c7d71;       /* 暗底 teal 填充（印章/书脊/主按钮底）：反白字 ~4.9:1 过 AA */
  --cinnabar-text: #6cc0b2;  /* teal 文字专用提亮：纸上过 AA */
  --cinnabar-deep: #7fcabd;  /* 更亮 teal：描边/胶囊/active 文字 */
  --cinnabar-hover: #266e64; /* 主按钮 hover 填充：深一档，反白字过 AA */
  --cinnabar-mute: #45615b;
  --cinnabar-wash: #1c2d29;
  --sage: #8aa89c;
  --sage-deep: #9ab8ab;
  --sage-line: #3a4a43;
  --sage-wash: #232b27;
  --warning: #e8917b;        /* 暗底错误文（暖红，提亮过 AA） */
  --seal-red: #d66a48;       /* 暗底印章红：降饱和提明度的暖砖红 */
  --overlay: rgb(0 0 0 / 0.55);
  --bar-wash: rgb(21 33 30 / 0.94);
  --shadow-card: 0 1px 3px rgb(0 0 0 / 0.3),
    0 8px 24px rgb(0 0 0 / 0.3);
  --shadow-modal: 0 4px 12px rgb(0 0 0 / 0.4),
    0 24px 48px rgb(0 0 0 / 0.5);
  /* 暗底卡顶缘高光收到极弱暖光，只勾边不发亮 */
  --edge-hi: inset 0 1px 0 rgb(255 250 240 / 0.05);
  --shadow-pressed: 0 1px 2px rgb(0 0 0 / 0.3);
}

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

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--paper);
  /* 轻纸纹—靠 SVG noise 即可，不依赖 backdrop-filter */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.12 0 0 0 0 0.10 0 0 0 0 0.08 0 0 0 0.05 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-repeat: repeat;
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  display: flex;
  flex-direction: column;
  /* 撑满动态视口高，tabbar 才贴底——web-view 里 html/body height:100% 常失效
     （WKWebView 把 html 高当成内容高），用 dvh 直接对齐可视视口。100vh 兜底。 */
  min-height: 100vh;
  min-height: 100dvh;
}

/* ---------- 全站签名细节 ---------- */

/* 选中文字：朱砂淡染——纸上划重点的感觉 */
::selection {
  background: var(--cinnabar-wash);
  color: var(--ink);
}

/* 滚动条：细轨 + 边线色，融进纸面（默认系统灰太突兀） */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--rule) transparent;
}

::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

::-webkit-scrollbar-thumb {
  background: var(--rule);
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--ink-faint);
}

::-webkit-scrollbar-track {
  background: transparent;
}

/* 键盘焦点统一 sage 系 ring（与 input focus 同语言），盖掉浏览器默认
   蓝圈。朱砂主按钮用同色系 ring，避免红绿撞色 */
.btn-icon:focus-visible,
.btn-send:focus-visible,
.btn-send-msg:focus-visible,
.btn-fu:focus-visible,
.btn-close:focus-visible,
.empty-suggestion:focus-visible,
.msg-followup:focus-visible,
.msg-revert:focus-visible,
.brand-home:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgb(111 143 132 / 0.25);
}

.btn-primary:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgb(200 71 44 / 0.28);
}

/* 盖章反馈：完成型动作（设定保存成功 / 登录成功）右上角落一枚章，
   1s 自然淡出。失败 / 发送 / 加载不用——章只对应"落定" */
#seal-flash {
  position: fixed;
  top: calc(16px + env(safe-area-inset-top));
  right: calc(20px + env(safe-area-inset-right));
  z-index: 300;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--cinnabar);
  color: var(--seal-ink);
  font-family: var(--font-serif);
  font-size: 16px;
  font-weight: 500;
  border-radius: 5px;
  box-shadow:
    inset 0 0 0 1px rgb(255 254 251 / 0.35),
    0 2px 6px rgb(31 27 22 / 0.15);
  pointer-events: none;
  animation: seal-flash 1050ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

@keyframes seal-flash {
  0% {
    opacity: 0;
    transform: rotate(-2.5deg) scale(1.4);
  }
  18% {
    opacity: 1;
    transform: rotate(-2.5deg) scale(1);
  }
  72% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: rotate(-2.5deg) scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  #seal-flash {
    animation: seal-flash-static 1050ms step-end forwards;
  }
}

@keyframes seal-flash-static {
  0% {
    opacity: 1;
    transform: rotate(-2.5deg);
  }
  100% {
    opacity: 0;
  }
}

/* ---------- 顶栏 ---------- */

.topbar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
  background: transparent;     /* 不再用白底切，让纸面贯通 */
  border-bottom: 1px solid var(--rule-soft);
}
/* 小程序去掉顶栏：首页有 hero、底部有 tab 栏，相处设定/退出/深浅色挪到个人中心。
   元素留在 DOM（app-core 仍绑定，无害），仅 mini 隐藏整条；web 保留顶栏。 */
html[data-shell="mini"] #topbar {
  display: none;
}

.topbar .brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-serif);
  font-size: 19px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--ink);
  /* 品牌名不随操作区挤压换行（>380px 时 phone-tag 仍在，曾把"聊明天"挤成两行） */
  flex-shrink: 0;
  white-space: nowrap;
}

.topbar .brand-link {
  text-decoration: none;
  color: inherit;
}

/* web 顶栏品牌回首页：印章+文字可点；btn-tip 仍是 .brand 兄弟，不包进本按钮。
   flex/gap 承接原 .brand 对印章与文字的间距，视觉与改动前一致。 */
.topbar .brand-home {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  letter-spacing: inherit;
  color: inherit;
  cursor: pointer;
  transition: opacity 160ms ease-out;
}

@media (hover: hover) and (pointer: fine) {
  .topbar .brand-home:hover {
    opacity: 0.85;
  }
}

/* topbar 品牌章：与 welcome 落款印章同语言（替代旧聊天气泡 icon；
   favicon 仍是 icon.svg，品牌资产替换另行处理） */
.brand-seal {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  flex: 0 0 26px;
  background: var(--cinnabar);
  color: var(--seal-ink);
  font-size: 15px;
  font-weight: 500;
  border-radius: 5px;
  transform: rotate(-2.5deg);
  box-shadow: inset 0 0 0 1px rgb(255 254 251 / 0.35);
}

/* 添福缘按钮：紧挨品牌名右侧，纸笺风格 — 朱砂"福"字 SVG，
   无背景，hover/active 轻微反馈。点击热区 36x36 保证移动端可点 */
.topbar .btn-fu {
  background-color: transparent;
  border: none;
  padding: 0;
  margin-left: 2px;
  width: 36px;
  height: 36px;
  border-radius: var(--radius);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition:
    transform var(--press-ms) ease,
    background-color var(--press-ms) ease;
}

.topbar .btn-fu:hover {
  background-color: var(--rule-soft);
}

.topbar .btn-fu:active {
  transform: scale(var(--press-scale));
  background-color: var(--rule);
}

.topbar .btn-fu .fu-icon {
  display: block;
  width: 24px;
  height: 24px;
}

.topbar .actions {
  display: flex;
  gap: 4px;
  align-items: center;
}

/* 顶栏式小按钮基础样式。全局作用域：welcome 浮动主题钮等
   topbar 之外的入口也要用；topbar 专属的只剩移动端挤压规则 */
.btn-icon {
  background-color: transparent;
  border: none;
  padding: 6px 10px;
  font-size: 14px;
  font-family: inherit;
  color: var(--ink-soft);
  cursor: pointer;
  border-radius: var(--radius);
  white-space: nowrap; /* 窄屏下也不让"相处设定/退出"竖排成单字 */
  transition:
    transform var(--press-ms) ease,
    background-color var(--press-ms) ease,
    color var(--press-ms) ease;
}


.btn-icon:hover {
  color: var(--ink);
  background-color: var(--rule-soft);
}

.btn-icon:active {
  transform: scale(var(--press-scale));
  background-color: var(--rule);
}

/* 小程序 web-view（手机宽）：原生导航条已显标题/身份，H5 顶栏省去手机号 + 品牌字号
   收一档，给「相处设定/退出」腾横向空间。限手机宽（既有 380px 断点漏了 390px+ 的 iPhone，
   这里用 480px 覆盖全部手机；平板/桌面 mini 不缩）。仅 mini，不动 web「聊明天」。 */
@media (max-width: 480px) {
  html[data-shell="mini"] #phone-tag {
    display: none;
  }
  html[data-shell="mini"] .topbar .brand {
    font-size: 16px;
  }
}

/* topbar 右组：登录态 actions + 日夜切换钮。包成一个子元素，
   space-between 才能保持 brand 左 / 操作区右 */
.topbar-right {
  display: flex;
  align-items: center;
  gap: 4px;
}

/* 日夜切换：线条月/日图标，按当前主题显隐 */
.btn-theme {
  display: inline-flex;
  align-items: center;
}

/* welcome/login 态 topbar 整条隐藏时的日夜切换入口。fixed 挂
   viewport 右上（与 topbar padding 对齐）；z-index 盖过 login
   overlay(50)，让登录卡打开时也能切 */
.btn-theme-floating {
  position: fixed;
  top: 14px;
  right: 20px;
  z-index: 60;
}

/* chat 态浮动切换钮退场（topbar 自带钮）。原用 `:has()`，但小程序 web-view
   的 iOS<15.4 webkit 不支持 → 两个月亮。改由 render.js 直接 toggle .hidden。 */

.btn-theme svg {
  width: 18px;
  height: 18px;
  display: block;
}

.btn-theme .icon-sun {
  display: none;
}

[data-theme="dark"] .btn-theme .icon-moon {
  display: none;
}

[data-theme="dark"] .btn-theme .icon-sun {
  display: block;
}

/* 相处设定入口：未设置态（onboardingPending）带朱砂小圆点提示 */
.topbar .btn-icon.attn::after {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-left: 5px;
  border-radius: 50%;
  background: var(--cinnabar);
  vertical-align: 2px;
}

/* ---------- 容器 + 居中 ---------- */

/* main 不再限宽——welcome / login / chat 各自控宽：
 * - welcome 是 flex center 整屏，.welcome-inner 内部限 440px
 * - login modal overlay 全屏覆盖，.login-card 居中限 420px
 * - chat 桌面宽屏读着舒服，单独限 880px（移动端 fill）
 */
main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  width: 100%;
}

/* ---------- 欢迎页 ----------
 *
 * 首屏单 CTA，未登录用户先看品牌主张再进登录。
 * 视觉上沿用登录卡的"现代纸笺"——但更大字、更多留白、无卡，
 * 让品牌主张直接落在纸面上。
 */

/* mini 退出引导页：整屏居中纸感卡片（替代 web 手机登录页） */
.mini-logout {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px 24px;
  min-height: 0;
}
.mini-logout-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
  max-width: 300px;
}
.mini-logout-card .home-seal {
  margin-bottom: 6px;
}
.mini-logout-card h1 {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 20px;
  color: var(--ink);
}
.mini-logout-card p {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-soft);
}

.welcome {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px 24px;
  min-height: 0;
}

.welcome-inner {
  width: 100%;
  max-width: 440px;
  text-align: center;
}

.welcome-title {
  margin: 0 0 18px;
  font-family: var(--font-serif);
  font-size: 44px;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--ink);
  line-height: 1.15;
}

/* 落款印章：手写信的签名时刻。开场动效最后"盖"下来（seal-stamp），
   内描边模拟印泥边缘 */
.welcome-title::after {
  content: "聊";
  display: block;
  width: 38px;
  height: 38px;
  margin: 22px auto 0;
  background: var(--cinnabar);
  color: var(--seal-ink);
  font-size: 21px;
  font-weight: 500;
  line-height: 38px;
  letter-spacing: 0;
  border-radius: 6px;
  transform: rotate(-2.5deg);
  box-shadow:
    inset 0 0 0 1.5px rgb(255 254 251 / 0.35),
    0 1px 2px rgb(31 27 22 / 0.12);
  animation: seal-stamp 380ms cubic-bezier(0.22, 1, 0.36, 1) 620ms backwards;
}

/* 开场编排：标题 → tagline → 印章 → CTA 错峰浮现。backwards 只管
   delay 期间的 from 帧，结束后恢复自然样式——不锁 transform，
   :active 缩放不受影响 */
.welcome-title {
  animation: rise-in 480ms cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

/* 品牌装饰档只在 mini（九龙明盏，全字在 deco subset 内）；web welcome 已被游客
   落地首页取代（门面自带楷书品牌），此处维持 serif 不动。楷书仅 400，固定字重。 */
html[data-shell="mini"] .welcome-title {
  font-family: var(--font-display);
  font-weight: 400;
}

.welcome-tagline {
  animation: rise-in 480ms cubic-bezier(0.16, 1, 0.3, 1) 140ms backwards;
}

.welcome-sub {
  animation: rise-in 480ms cubic-bezier(0.16, 1, 0.3, 1) 220ms backwards;
}

.welcome .btn-primary {
  animation: rise-in 480ms cubic-bezier(0.16, 1, 0.3, 1) 340ms backwards;
}

@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes seal-stamp {
  from {
    opacity: 0;
    transform: rotate(-2.5deg) scale(1.5);
  }
  60% {
    opacity: 1;
  }
  to {
    opacity: 1;
    transform: rotate(-2.5deg) scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .welcome-title,
  .welcome-title::after,
  .welcome-tagline,
  .welcome-sub,
  .welcome .btn-primary {
    animation: none;
  }
}

.welcome-tagline {
  margin: 28px 0 10px;
  font-size: 16px;
  line-height: 1.7;
  color: var(--ink-soft);
  letter-spacing: 0.02em;
}

/* 信息句：告诉新访客这是什么——氛围句（tagline）之下、决定（CTA）之上 */
.welcome-sub {
  margin: 0 0 36px;
  font-size: 14px;
  line-height: 1.7;
  color: var(--ink-soft);
  letter-spacing: 0.02em;
}

.welcome .btn-primary {
  display: inline-block;
  width: auto;
  min-width: 200px;
  padding: 14px 36px;
}

@media (max-width: 480px) {
  .welcome {
    padding: 32px 20px;
  }
  .welcome-title {
    font-size: 36px;
  }
  .welcome-tagline {
    font-size: 15px;
    margin: 22px 0 28px;
  }
}

/* ---------- 登录 modal ----------
 *
 * 浮层覆盖在 welcome 之上：背景半透墨色，卡居中。
 * 关闭：右上角按钮 / 点 overlay 背景 / Esc 键。
 */

.login-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--overlay);
  z-index: 50;
  /* 四边都按 safe-area 兜底：横屏 / 刘海机型还有左右切口 */
  padding-top: max(20px, env(safe-area-inset-top));
  padding-bottom: max(20px, env(safe-area-inset-bottom));
  padding-left: max(20px, env(safe-area-inset-left));
  padding-right: max(20px, env(safe-area-inset-right));
  /* 短屏 / 软键盘弹起：overlay 内能滚动，避免 modal 卡溢出无法
   * 访问底部按钮。dvh 让 iOS 软键盘弹起时 viewport 缩小后 modal
   * 不会被键盘遮一半。 */
  overflow-y: auto;
  animation: overlay-fade 160ms ease-out;
}

@keyframes overlay-fade {
  from { background: transparent; }
  to { background: var(--overlay); }
}

.login-overlay .login-card {
  position: relative;
  width: 100%;
  max-width: 420px;
  /* 防止内容比视口高（短屏 + 键盘 / 大字体）时溢出无法访问。
   * dvh 优先（新 iOS 软键盘弹起会缩 viewport），vh 兜底。 */
  max-height: calc(100dvh - 40px);
  overflow-y: auto;
  padding: 36px 28px 32px;
  background: var(--card);
  border-radius: 12px;
  box-shadow: var(--shadow-modal);
  animation: card-rise 220ms cubic-bezier(0.16, 1, 0.3, 1);
}

@supports not (height: 100dvh) {
  .login-overlay .login-card {
    max-height: calc(100vh - 40px);
  }
}

@keyframes card-rise {
  from { transform: translateY(12px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

.login-card .btn-close {
  position: absolute;
  top: 10px;
  right: 14px;
  background: transparent;
  border: none;
  font-size: 22px;
  font-family: inherit;
  line-height: 1;
  color: var(--ink-soft);
  cursor: pointer;
  width: 34px;
  height: 34px;
  border-radius: 17px;
  transition:
    transform var(--press-ms) ease,
    background-color var(--press-ms) ease,
    color var(--press-ms) ease;
}

.login-card .btn-close:hover {
  color: var(--ink);
  background: var(--rule-soft);
}

.login-card .btn-close:active {
  transform: scale(var(--press-scale));
  background: var(--rule);
}

@media (max-width: 480px) {
  .login-overlay .login-card {
    padding: 28px 22px 24px;
    border-radius: 10px;
  }
  .login-card .btn-close {
    top: 8px;
    right: 10px;
  }
}

.login-card h1 {
  margin: 0 0 28px;
  font-family: var(--font-serif);
  font-size: 30px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink);
  line-height: 1.2;
}

/* 朱砂印记——welcome 落款印章的迷你版（同倾角），登录卡与门面同语言 */
.login-card h1::after {
  content: "";
  display: block;
  width: 9px;
  height: 9px;
  margin-top: 12px;
  background-color: var(--cinnabar);
  border-radius: 2px;
  transform: rotate(-2.5deg);
}

.login-card p.lead {
  margin: 18px 0 28px;
  color: var(--ink-soft);
  font-size: 14px;
  line-height: 1.6;
}

.field {
  margin-bottom: 16px;
}

.field label {
  display: block;
  margin-bottom: 8px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  text-transform: none;
}

.input,
.input-code {
  width: 100%;
  padding: 12px 14px;
  font-family: inherit;
  font-size: 16px;        /* >= 16px 防 iOS Safari 自动缩放 */
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background-color: var(--paper); /* 输入框比卡更深一点，回到纸底 */
  color: var(--ink);
  outline: none;
  min-height: 44px;
  transition:
    border-color var(--focus-ms) ease,
    background-color var(--focus-ms) ease;
}

.input::placeholder,
.input-code::placeholder {
  color: var(--ink-soft);
}

/* focus 统一 sage 系（同 composer）——朱砂留给"决定"（按钮/勾选），
   输入态是陪伴色 */
.input:focus,
.input-code:focus {
  border-color: var(--sage);
  background-color: var(--card);  /* focus 时回到卡底，更亮 */
  box-shadow: 0 0 0 3px rgb(111 143 132 / 0.14);
}

.input-code {
  letter-spacing: 6px;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  text-align: left;
}

.field-row {
  display: flex;
  gap: 10px;
}

.field-row .input,
.field-row .input-code {
  flex: 1;
}

.btn-send {
  flex-shrink: 0;
  padding: 0 16px;
  min-height: 44px;
  background-color: transparent;
  border: 1px solid var(--cinnabar);
  color: var(--cinnabar-text);
  font-family: inherit;
  border-radius: var(--radius);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition:
    transform var(--press-ms) ease,
    background-color var(--press-ms) ease,
    color var(--press-ms) ease;
  white-space: nowrap;
}

.btn-send:hover:not(:disabled) {
  background-color: var(--cinnabar-wash);
}

.btn-send:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  border-color: var(--cinnabar-mute);
  color: var(--cinnabar-mute);
}

.btn-send:active:not(:disabled) {
  transform: scale(var(--press-scale));
}

.checkbox-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 18px 0 24px;
  font-size: 13px;
  color: var(--ink-soft);
  line-height: 1.55;
}

.checkbox-row input[type="checkbox"] {
  margin-top: 2px;
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  accent-color: var(--cinnabar);
  cursor: pointer;
}

/* 协议链接用墨色下划线（链接本义），朱砂只留给登录卡里真正的
   决定：发送验证码、勾选、登录 */
.checkbox-row a {
  color: var(--ink-soft);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color var(--focus-ms) ease;
}

.checkbox-row a:hover {
  color: var(--ink);
}

.btn-primary {
  width: 100%;
  padding: 14px;
  font-family: inherit;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.08em;       /* 中文宽字距，主按钮 */
  background-color: var(--cinnabar);
  color: var(--seal-ink);           /* 反白偏暖，更纸感 */
  border: none;
  border-radius: var(--radius);
  cursor: pointer;
  min-height: 48px;
  transition:
    transform var(--press-ms) ease,
    background-color var(--press-ms) ease;
}

.btn-primary:hover:not(:disabled) {
  /* 填充 hover 专用色：反白字仍要过 AA，不能复用文字用的亮 --cinnabar-deep */
  background-color: var(--cinnabar-hover);
}

.btn-primary:disabled {
  background-color: var(--cinnabar-mute);
  cursor: not-allowed;
}

.btn-primary:active:not(:disabled) {
  transform: scale(var(--press-scale));
}

.error {
  margin-top: 14px;
  padding: 10px 14px;
  background: var(--cinnabar-wash);
  color: var(--warning);
  border-radius: var(--radius);
  font-size: 13px;
  line-height: 1.5;
  animation: shake 160ms ease-in-out;
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}

.hint {
  margin: 14px 0 0;
  color: var(--ink-soft);
  font-size: 12px;
  line-height: 1.6;
  text-align: center;
}

/* ---------- 聊天页 ---------- */

.chat-area {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* 桌面端中央居中：720px——user 右 / assistant 左的对读距离更亲密
   * （880px 时视线横跨太远）。移动端 fill 屏宽。 */
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
}

/* 对象条+大师条合并一行容器（mini 专用）。裸 flex 壳：自身无 padding/背景/边框，
   bar chrome（纸感背景/底分隔/纵向内距）下沉到子条。两子条都 .hidden 时容器零
   flex item 自然塌缩到 0 高，无需 :has()（兼容老 WebView）。position:relative
   让两段下拉以整条为定位基准、跨全宽展开。 */
.chat-context-bar {
  position: relative;
  display: flex;
  align-items: stretch;
  flex-shrink: 0;
}
.chat-context-bar > .chat-subject-bar,
.chat-context-bar > .chat-master-bar {
  flex: 1;
  min-width: 0; /* 否则长盘名按内容撑破半宽栏 → 横向溢出/挤掉切换 */
}
/* 半宽栏内：当前项省略号截断，切换按钮固定不被挤 */
.csb-cur,
.cmb-cur {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cmb-switch {
  flex: 0 0 auto;
}
/* 左右两段之间加分隔 */
.chat-context-bar > .chat-subject-bar:not(.hidden) + .chat-master-bar:not(.hidden) {
  border-left: 1px solid var(--rule-soft);
}

/* 对话大师选择条：自带 chrome（合并条里也成立，使单段显示时即有纸感/底分隔） */
.chat-master-bar {
  padding: 8px 16px;
  background: var(--bar-wash);
  border-bottom: 1px solid var(--rule-soft);
}
.cmb-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.cmb-cur {
  font-size: 13px;
  color: var(--ink-soft);
}
.cmb-switch {
  margin-left: auto;
  border: none;
  background: none;
  font-family: inherit;
  font-size: 13px;
  color: var(--cinnabar-text);
  cursor: pointer;
}
.cmb-chips {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 10;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 8px 16px;
  background: var(--bar-wash);
  border-bottom: 1px solid var(--rule-soft);
  box-shadow: 0 4px 8px rgba(0,0,0,.06);
}
.cmb-chip {
  padding: 5px 12px;
  border: 1px solid var(--rule);
  border-radius: 14px;
  background: var(--card);
  font-family: inherit;
  font-size: 13px;
  color: var(--ink);
  cursor: pointer;
}
.cmb-chip.on {
  border-color: var(--cinnabar);
  color: var(--cinnabar-text);
}

/* 聊天对象切换器：基本盘选单。0 盘时 JS 保持 .hidden。
   独立 web 壳（index.html，无 context-bar）：position:relative 让下拉以本条为基准。 */
#chat-subject-bar {
  position: relative;
  flex-shrink: 0;
  padding: 8px 16px;
  background: var(--bar-wash);
  border-bottom: 1px solid var(--rule-soft);
}
/* mini 壳：在 context-bar 内，自带 chrome（裸壳容器不再提供），但定位基准让给
   context-bar（position:static），使下拉跨整条全宽展开。 */
.chat-context-bar > #chat-subject-bar {
  position: static;
  flex-shrink: unset;
}
.csb-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.csb-cur {
  font-size: 13px;
  color: var(--ink-soft);
}
/* 主体（标签+箭头）占左、可点开盘列表；[起盘]/[再起一盘] 动作靠右 */
.csb-main {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 1;
  min-width: 0;
  padding: 0;
  border: none;
  background: none;
  font-family: inherit;
  font-size: 13px;
  color: var(--ink-soft);
  text-align: left;
  cursor: pointer;
}
.csb-main:disabled {
  cursor: default;
}
.csb-caret {
  flex: 0 0 auto;
  color: var(--cinnabar-text);
}
.csb-action {
  flex: 0 0 auto;
  border: none;
  background: none;
  font-family: inherit;
  font-size: 13px;
  color: var(--cinnabar-text);
  cursor: pointer;
}
.csb-action:disabled {
  color: var(--cinnabar-mute);
  cursor: default;
}
.csb-list {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 10;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px 16px;
  background: var(--bar-wash);
  border-bottom: 1px solid var(--rule-soft);
  box-shadow: 0 4px 8px rgba(0,0,0,.06);
}
.csb-item {
  padding: 4px 12px;
  border: 1px solid var(--rule);
  border-radius: 14px;
  background: var(--card);
  font-family: inherit;
  font-size: 13px;
  color: var(--ink);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.csb-item.on {
  border-color: var(--cinnabar);
  color: var(--cinnabar-text);
}
.csb-item-danger {
  color: var(--seal-red);
}
/* 展开列表中盘的辨识小字 */
.csb-item-label {
  font-size: 13px;
}
.csb-item-desc {
  font-size: 11px;
  color: var(--ink-faint, var(--ink-soft));
  margin-top: 1px;
}

.messages {
  flex: 1;
  overflow-y: auto;
  padding: 16px 20px 4px;
  -webkit-overflow-scrolling: touch;
}

/* mini 聊天 tab：排盘表单+消息合成单一滚动区，表单展开较高时整体滚动，
   不再顶穿底部输入框/tab 栏（图层错乱根因）。AIGC 提示与输入框留在 .chat-area
   底部固定（比原型滚动输入框更贴合键盘场景）。 */
.chat-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
}
/* 滚动交给 .chat-scroll，内层消息不再独立滚动（避免嵌套滚动条）。
   margin-top:auto + flex 不伸展 → 少量消息时贴底（靠近输入框），符合对话
   从底部累积的直觉；消息多到溢出时 auto margin 自动 collapse，从顶正常滚。 */
.chat-scroll .messages {
  overflow: visible;
  flex: 0 1 auto;
  margin-top: auto;
}

/* 历史拉取中：弱网下消息区不留盲区（composer 同时是禁用态） */
.history-loading-hint {
  margin: 24px 0 0;
  font-size: 14px;
  color: var(--ink-soft);
}

/* 空状态引导：登录后 history 拉完没消息时显示。用第一条助手气泡建立
   陪伴感，再给三条低压力开口建议。主聊天与设定视图共用。
   三段错峰浮现（rise-in 定义在 welcome 段）。 */
.empty-state {
  max-width: 560px;
  margin: 24px 0 0;
  padding: 18px 0;
  color: var(--ink-soft);
  line-height: 1.7;
}

.empty-state .empty-intro {
  animation: rise-in 360ms cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

.empty-state .empty-prompt {
  animation: rise-in 360ms cubic-bezier(0.16, 1, 0.3, 1) 100ms backwards;
}

.empty-state .empty-suggestions {
  animation: rise-in 360ms cubic-bezier(0.16, 1, 0.3, 1) 180ms backwards;
}

@media (prefers-reduced-motion: reduce) {
  .empty-state .empty-intro,
  .empty-state .empty-prompt,
  .empty-state .empty-suggestions {
    animation: none;
  }
}

.empty-intro {
  display: inline-block;
  max-width: 90%;
  margin: 0 0 16px;
  padding: 13px 16px;
  background: var(--card);
  border-radius: 14px 14px 14px 4px;
  box-shadow: var(--shadow-card);
  font-size: 15px;
  color: var(--ink-soft);
}

.empty-prompt {
  margin: 2px 0 10px;
  font-size: 14px;
  color: var(--ink-soft);
}

.empty-suggestions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
}

.empty-suggestion {
  padding: 7px 12px;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 13px;
  line-height: 1.4;
  cursor: pointer;
  transition:
    transform var(--press-ms) ease,
    border-color var(--press-ms) ease,
    background-color var(--press-ms) ease,
    color var(--press-ms) ease;
}

.empty-suggestion:hover {
  border-color: var(--sage);
  background: var(--sage-wash);
  color: var(--ink);
}

.empty-suggestion:active {
  transform: scale(var(--press-scale));
}

/* 日期落款分隔：跨自然日时的信纸落款「五月廿三 · 夜」。
   宋体小字居中，像信纸换页的日期题头 */
.msg-date-seal {
  margin: 26px 0 10px;
  text-align: center;
  font-family: var(--font-serif);
  font-size: 13px;
  letter-spacing: 0.12em;
  color: var(--ink-soft);
}

/* 新消息入场：只有刚 push 的消息带 .msg-enter（justAdded 标记，渲染
   一次即清），历史加载/重渲染不闪 */
.msg-enter {
  animation: rise-in 240ms cubic-bezier(0.16, 1, 0.3, 1);
}

@media (prefers-reduced-motion: reduce) {
  .msg-enter {
    animation: none;
  }
}

.msg {
  margin: 8px 0;
  display: flex;
  /* column 排列：bubble + meta + 撤回按钮 自然垂直堆叠。
   * 用 align-items 决定每行子元素的横向对齐（user 靠右、assistant 靠左）。
   * 之前是 row + justify-content，撤回按钮会和 bubble 并排到旁边而非下方，
   * Copilot review 指出 align-self: flex-end 在 row 容器里管的是 cross axis
   * 不会让按钮换行到 bubble 下面。 */
  flex-direction: column;
}

.msg.user {
  align-items: flex-end;
}

.msg.assistant {
  align-items: flex-start;
}

.msg .bubble {
  position: relative;
  padding: 11px 16px;
  border-radius: 14px;
  font-size: 15px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
}

/* 保存失败角标：气泡右上角，朱砂圆点 + ! 字，hover 弹原生 tooltip
   （title 属性）。不占行，对话流保持紧凑 */
.msg .msg-warn {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background-color: var(--cinnabar);
  color: var(--seal-ink);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: help;
  box-shadow: 0 1px 2px rgb(31 27 22 / 0.18);
  user-select: none;
}

.msg.user .bubble {
  max-width: 78%;
  background-color: var(--sage-wash);
  color: var(--ink);
  border: 1px solid var(--sage-line);
  border-bottom-right-radius: 4px;
  box-shadow: 0 1px 2px rgb(79 111 101 / 0.10);
}

.msg.assistant .bubble {
  max-width: 90%;
  background: var(--card);
  color: var(--ink);
  border-bottom-left-radius: 4px;
  box-shadow: var(--shadow-card);
}

/* 气泡内 markdown：紧凑、贴主题，避免默认巨大 margin / 字号的报告腔。 */
.bubble.md > :first-child {
  margin-top: 0;
}
.bubble.md > :last-child {
  margin-bottom: 0;
}
.bubble.md .md-p {
  margin: 0 0 8px;
}
.bubble.md .md-h {
  margin: 10px 0 6px;
  font-weight: 600;
  color: var(--ink);
}
.bubble.md .md-ul,
.bubble.md .md-ol {
  margin: 4px 0 8px;
  padding-left: 20px;
}
.bubble.md .md-ul li,
.bubble.md .md-ol li {
  margin: 2px 0;
}
.bubble.md strong {
  font-weight: 600;
}
.bubble.md code {
  font-family: var(--font-mono);
  font-size: 0.92em;
  padding: 1px 4px;
  border-radius: 4px;
  background: var(--rule-soft);
}
.bubble.md hr {
  border: none;
  border-top: 1px solid var(--rule);
  margin: 8px 0;
}

.msg .meta {
  font-size: 11px;
  color: var(--ink-soft);
  margin: 2px 8px 0;
}

/* 引用回复（v1）：抄微信样式 —— 新消息 bubble 在上为主体，引用紧贴
   下方一张轻量小卡片，单行内联展示，超过 2 行省略。颜色统一比正文淡
   一档（--ink-soft）。 */
.msg-quote-card {
  max-width: 78%;
  margin-top: 4px;
  padding: 6px 10px;
  background-color: var(--rule-soft);
  border-radius: 6px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-soft);
  /* 超过 2 行省略，避免大段引用把对话流挤散。
     -webkit-line-clamp 在 WebKit/Blink + Firefox 132+ 支持，老 Firefox
     退化到 max-height 硬截（无 … 但不溢出）。1.5 * 2 行 = 3em 兜底 */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  max-height: 3em;
  word-break: break-word;
}

.msg-quote-label {
  color: var(--ink-soft);
  margin-right: 2px;
}

.msg-quote-text {
  white-space: pre-wrap;
}

/* 消息菜单（点击 bubble 弹出）：浮在 bubble 下方，"引用 / 复制"两项。
   fixed 定位由 JS 算好相对 anchor 的位置。 */
.msg-menu {
  background: var(--card);
  border-radius: 8px;
  box-shadow: var(--shadow-modal);
  padding: 4px;
  display: flex;
  gap: 2px;
  z-index: 50;
  font-size: 14px;
}

.msg-menu-btn {
  background-color: transparent;
  border: none;
  color: var(--ink);
  font: inherit;
  padding: 8px 14px;
  border-radius: 6px;
  cursor: pointer;
  transition:
    background-color var(--press-ms) ease,
    transform var(--press-ms) ease;
}

.msg-menu-btn:hover {
  background-color: var(--rule-soft);
}

.msg-menu-btn:active {
  background-color: var(--rule);
  transform: scale(var(--press-scale));
}

/* 撤回按钮：附在最后一条 user 消息下（仅 chatting 期间显示）。
 * user message 靠右气泡，撤回按钮也右对齐贴在气泡下方。
 * 低调灰色文字按钮，避免抢镜 user 消息本身。 */
.msg-revert {
  align-self: flex-end;
  margin: 6px 4px 0 0;
  padding: 2px 8px;
  font-size: 12px;
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  cursor: pointer;
  transition: color 120ms, border-color 120ms, background 120ms;
}

.msg-revert:hover {
  color: var(--ink);
  border-color: var(--line);
  background: var(--card);
}

.msg-revert:active {
  transform: scale(0.96);
}

.typing-bubble {
  display: inline-flex;
  gap: 5px;
  padding: 12px 16px;
  background: var(--card);
  border-radius: 14px;
  border-bottom-left-radius: 4px;
  box-shadow: var(--shadow-card);
}

/* 快捷追问按钮托盘：附在 assistant bubble 下方。row + wrap 让移动端
 * 自然换行；max-width 跟 .bubble 同（78%）避免横向把 assistant 撑得比
 * 主气泡还宽。低调样式，不抢正文。 */
.msg-followups {
  align-self: flex-start;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  max-width: 78%;
  margin: 6px 0 0 0;
}

.msg-followup {
  padding: 4px 12px;
  font-size: 13px;
  line-height: 1.4;
  color: var(--ink-soft, var(--ink));
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 999px;
  cursor: pointer;
  transition: color 120ms, border-color 120ms, background 120ms, transform 80ms;
  /* 长项允许在按钮内部换行（保险，单条 30 字撞窄屏不至于撑爆） */
  white-space: normal;
  text-align: left;
}

.msg-followup:hover {
  color: var(--ink);
  border-color: var(--rule);
  background: var(--bg, var(--card));
}

.msg-followup:active {
  transform: scale(0.97);
}

.typing-bubble span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ink-faint);
  animation: blink 1.4s infinite both;
}

.typing-bubble span:nth-child(2) { animation-delay: 0.2s; }
.typing-bubble span:nth-child(3) { animation-delay: 0.4s; }

@keyframes blink {
  0%, 80%, 100% { opacity: 0.25; }
  40% { opacity: 1; }
}

/* 「趣文哲理」触发行：对话区底部、输入坞之上。轻量 chip，仅通用线显示
   （hidden 由 chat.js gate 控）；点击后一段趣文+哲理作为 assistant 消息进对话流。 */
.chat-quickbar {
  flex-shrink: 0;
  display: flex;
  padding: 8px 12px;
}
.btn-fun {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 12px;
  background: var(--sage-wash);
  border: 1px solid var(--rule-soft);
  border-radius: 999px;
  font-family: inherit;
  font-size: 12.5px;
  color: var(--cinnabar-text);
  cursor: pointer;
  transition:
    opacity var(--press-ms) ease,
    transform var(--press-ms) ease;
}
.btn-fun:active {
  opacity: 0.8;
  transform: scale(var(--press-scale));
}
.btn-fun:disabled {
  opacity: 0.5;
  cursor: default;
}
/* AIGC 显式标识：贴在输入区上沿，与 composer 同底色连成一块输入坞。
   平台要求"显著"——用正文墨色而非弱化灰，不许压小。 */
.aigc-disclaimer {
  flex-shrink: 0;
  margin: 0;
  padding: 6px 18px 0;
  text-align: center;
  font-size: 12px;
  line-height: 1.4;
  color: var(--ink);
  background: var(--bar-wash);
  border-top: 1px solid var(--rule-soft);
}

/* mini 游客态：聊天面板登录引导卡（未登录时替代消息流） */
.chat-guest-gate {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
  margin: 48px auto 24px;
  max-width: 300px;
}
.chat-guest-gate .home-seal {
  margin-bottom: 6px;
}
.cgg-title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: var(--ink);
}
.cgg-sub {
  margin: 0 0 8px;
  font-size: 13px;
  color: var(--ink-soft);
}

.composer {
  flex-shrink: 0;
  display: flex;
  gap: 10px;
  padding: 14px 18px;
  background: var(--bar-wash);
  /* 安全区下边距由底部 tabbar 承担（composer 不再是最底元素），这里只留常规 */
}

/* ---------- 底部 tab 栏（H5 内部导航） + tab 面板 ---------- */

.tab-placeholder {
  margin: 0;
  color: var(--ink-faint);
  font-size: 14px;
  text-align: center;
}

/* ---------- 首页 tab ---------- */
/* 深链防闪：index.html 让 #tab-home 默认可见（静态品牌/宣言/大师卡不等 JS），
   非 "/" 路径由 head 内联脚本给 html 打 deep-link。用 display:none（非
   visibility）避免占位；JS 在首次 switchTab（cub:tab）后移除该类，否则
   之后点「首页」会被本规则盖过 .hidden 切换，首页永远打不开。 */
html.deep-link #tab-home {
  display: none;
}
.home-panel {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* 底 padding 置 0，底部留白只由 ::after 实体占位给（小而稳）：滚到底时内容更贴
     近 tab 栏，不留大空当；in-flow 高度 WKWebView 也认（不被滚动容器吃掉）。 */
  padding: 16px 16px 0;
}
.home-panel::after {
  content: "";
  display: block;
  height: 12px;
}
/* hero：实心马尔斯绿卡，白标题居中，朱砂印盖右上角 */
.home-hero {
  position: relative;
  text-align: center;
  background: var(--cinnabar);
  border-radius: 16px;
  padding: 14px 22px 12px; /* 中等薄 banner：一屏装下全部功能 */
  margin-bottom: 10px;
  box-shadow: var(--shadow-card); /* 主题 token，自适配 light/dark */
}
.home-seal {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 10px;
  background: var(--cinnabar); /* 末尾 seal-red 覆盖为朱砂红 */
  color: #fff;
  font-family: var(--font-serif);
  font-size: 24px;
}
.home-hero .home-seal {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  font-size: 16px;
  transform: rotate(-3deg);
  box-shadow: 0 3px 8px rgb(0 0 0 / 0.22);
}
.home-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400; /* 楷书仅 400，避免 faux bold 笔画变形 */
  font-size: 22px;
  letter-spacing: 3px;
  color: #fff;
  line-height: 1.2;
}
.home-slogan {
  margin: 4px 0 0;
  font-size: 13px;
  letter-spacing: 1px;
  color: rgb(255 255 255 / 0.82);
}
.home-manifesto {
  margin: 0 0 4px;
  padding: 2px 8px;
  text-align: left;
}
.home-manifesto p {
  margin: 0 0 8px;
  font-size: 13px;
  line-height: 1.85;
  color: var(--ink-soft);
}
.home-manifesto .home-coda {
  margin: 0; /* coda 现是首行（宣言全文收进折叠） */
  font-family: var(--font-serif);
  font-size: 17px;
  letter-spacing: 1px;
  color: var(--cinnabar-text);
}
/* 轻按钮：低调、不抢 coda */
.home-manifesto-toggle {
  margin: 6px 0 0;
  padding: 2px 0;
  border: none;
  background: none;
  font-family: inherit;
  font-size: 13px;
  color: var(--ink-faint);
  cursor: pointer;
}
.home-manifesto-full {
  margin-top: 10px;
}
/* 今日黄历卡片：信纸感卡片，干支/节气作题头，宜=teal 角标 忌=朱砂角标 */
.home-almanac {
  margin: 0 0 4px;
}
/* 今日黄历：信息条（非卡片）——去边框/大圆角/重内边距，底部分隔线收束 */
.alm-card {
  margin-top: 2px;
  padding: 4px 2px 10px;
  border-bottom: 1px solid var(--rule-soft);
}
.alm-head {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding-bottom: 6px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--rule-soft);
}
.alm-gz {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 0;
}
.alm-ganzhi {
  font-family: var(--font-serif);
  font-size: 18px;
  letter-spacing: 1px;
  color: var(--ink);
  white-space: nowrap; /* 干支整串不在空格处折行（窄屏） */
}
.alm-jieqi {
  flex: 0 0 auto;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--cinnabar-wash);
  color: var(--cinnabar-text);
  font-size: 12px;
}
.alm-date {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
  font-size: 11.5px;
  color: var(--ink-faint);
}
.alm-nong {
  color: var(--ink-soft);
}
.alm-yiji {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.alm-line {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.alm-badge {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  font-family: var(--font-serif);
  font-size: 13px;
  color: #fff;
}
.alm-yi {
  background: var(--cinnabar);
}
.alm-ji {
  background: var(--seal-red);
}
.alm-line .alm-v {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  line-height: 1.7;
  color: var(--ink-soft);
}
.alm-dir {
  display: flex;
  gap: 16px;
  margin-top: 10px;
  font-size: 12.5px;
  color: var(--ink-soft);
}
.alm-care {
  margin-top: 0;
}
.alm-care-h {
  margin-bottom: 6px;
  font-family: var(--font-serif);
  font-size: 13px;
  color: var(--cinnabar-text);
}
.alm-row {
  display: flex;
  gap: 8px;
  margin-bottom: 5px;
  font-size: 12.5px;
  line-height: 1.7;
}
.alm-row .alm-k {
  flex: 0 0 auto;
  color: var(--ink-faint);
}
.alm-row .alm-v {
  flex: 1;
  min-width: 0;
  color: var(--ink-soft);
}
/* 信息条上节气建议 gist 截 1 行（饮食·穿衣首句） */
.alm-v.alm-clamp {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
  max-height: 1.8em; /* 非 WebKit 兜底（.alm-row line-height 1.7，1 行硬截） */
}
.alm-more {
  display: inline-block;
  margin-top: 8px;
  padding: 0;
  background: none;
  border: none;
  font-family: inherit;
  font-size: 12.5px;
  color: var(--cinnabar-text);
  cursor: pointer;
}
/* toggle 并进区头时右对齐、去独立行高 */
.home-sect .alm-more {
  margin: 0 0 0 auto;
}
.alm-detail {
  margin-top: 8px;
  padding-top: 10px;
  border-top: 1px solid var(--rule);
}
.alm-note {
  margin: 12px 0 0;
  font-size: 11px;
  line-height: 1.6;
  color: var(--ink-faint);
}
/* 区头：朱砂衬线标 + 底部发丝分隔线（编辑式分区，比纯文字更立得住） */
.home-sect {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 12px 0 4px; /* 收紧块间距：一屏装下全部 */
  padding-bottom: 7px;
  border-bottom: 1px solid var(--rule);
  font-family: var(--font-serif);
  font-size: 14px;
  letter-spacing: 0.06em;
  color: var(--cinnabar-text);
}
.home-sect small {
  font-family: var(--font-sans);
  font-size: 11px;
  letter-spacing: 0;
  color: var(--ink-faint);
}
/* 大师：3 列卡网格（按 mockup），整卡可点 */
.home-masters {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.home-master {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  min-width: 0; /* 允许 3 列网格在窄屏(≤320px)收缩，名按字换行不溢出 */
  padding: 9px 4px 8px; /* 小卡 + 压扁：一屏装下全部 */
  background: var(--sage-wash);
  border: 1px solid var(--rule-soft);
  border-radius: 14px;
  font-family: inherit;
  text-align: center;
  cursor: pointer;
  transition: opacity var(--press-ms) ease, transform var(--press-ms) ease;
}
.home-master:active {
  opacity: 0.75;
  transform: scale(var(--press-scale));
}
.home-master:focus-visible,
.home-nudge:focus-visible,
.home-manifesto-toggle:focus-visible,
.book-item:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgb(111 143 132 / 0.25);
}
/* 头像：teal 圆章 */
.hm-avatar {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--cinnabar-wash);
  color: var(--cinnabar-text);
  font-family: var(--font-serif);
  font-size: 16px;
  margin-bottom: 5px;
}
.hm-name {
  display: block;
  font-family: var(--font-serif);
  font-size: 14px;
  color: var(--ink);
  line-height: 1.3;
}
.hm-desc {
  display: block;
  margin-top: 4px;
  font-size: 11.5px;
  color: var(--ink-faint);
}
/* 相处设定引导卡：teal 描边细条，大师区下方；未设定(onboardingPending) JS 显示。
   单行细条——压低占高，避免下推经典横行出首屏（见 PR #580 review）。 */
.home-nudge {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin: 8px 0 4px;
  padding: 8px 12px;
  background: var(--card);
  border: 1.5px solid var(--cinnabar);
  border-radius: 10px;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: opacity var(--press-ms) ease, transform var(--press-ms) ease;
}
.home-nudge:active {
  opacity: 0.8;
  transform: scale(var(--press-scale));
}
.home-nudge .hn-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 7px;
  background: var(--cinnabar-wash);
  color: var(--cinnabar-text);
  font-family: var(--font-serif);
  font-size: 14px;
}
/* 标题+副标题同一行，超宽副标题先省略号截断 */
.home-nudge .hn-text {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.home-nudge .hn-text b {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
}
.home-nudge .hn-text span {
  margin-left: 8px;
  font-size: 12px;
  color: var(--ink-faint);
}
.home-nudge .hn-go {
  flex: 0 0 auto;
  color: var(--cinnabar-text);
  font-size: 20px;
}
/* 古籍：横向滚动一行小卡（一屏装下全部，左右滑看全）；teal 书脊作视觉锚点 */
.home-books {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  gap: 10px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 2px;
}
/* 立着的古籍：去边框盒，书脊作主视觉（书本样 + 微 3D），名/作者衬于下 */
.book-item {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: 78px;
  padding: 4px 2px 2px;
  background: none;
  border: none;
  font-family: inherit;
  text-align: center;
  cursor: pointer;
  transition: opacity var(--press-ms) ease, transform var(--press-ms) ease;
}
.book-item:active {
  opacity: 0.8;
  transform: translateY(1px);
}
.book-spine {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 58px;
  border-radius: 2px 5px 5px 2px; /* 右缘微圆=书口，左缘方=书脊装订侧 */
  background: var(--cinnabar);
  color: #fff;
  font-family: var(--font-serif);
  font-size: 16px;
  writing-mode: vertical-rl;
  letter-spacing: 3px;
  padding: 8px 0;
  /* 微 3D：抬起阴影 + 左侧装订暗线 + 内侧高光 */
  box-shadow:
    0 3px 7px rgb(0 0 0 / 0.2),
    inset 3px 0 0 rgb(0 0 0 / 0.14),
    inset -1px 0 0 rgb(255 255 255 / 0.12);
}
/* 书脊深浅交替（同 teal 族，不动印章红）：书架不单调 */
.book-item:nth-child(even) .book-spine {
  background: var(--cinnabar-deep);
}
.book-meta {
  width: 100%;
  min-width: 0;
}
.book-name {
  font-family: var(--font-serif);
  font-size: 12.5px;
  color: var(--ink);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.book-note {
  margin-top: 1px;
  font-size: 10.5px;
  color: var(--ink-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 横向小卡里多余，整卡可点 */
.book-arrow {
  display: none;
}

/* ---------- 古籍阅读页 ---------- */
.reader-view {
  display: flex;
  flex-direction: column;
}
/* 返回头常驻顶部：读到深处也能直接返回，不用翻回头部 */
.reader-head {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  background: var(--paper);
}
.reader-back {
  border: none;
  background: none;
  padding: 4px 2px;
  font-family: inherit;
  font-size: 14px;
  color: var(--ink-soft);
  cursor: pointer;
}
.reader-title {
  font-family: var(--font-serif);
  font-size: 16px;
  color: var(--ink);
}
.reader-body {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.reader-seg {
  margin-bottom: 18px;
}
.reader-src {
  font-family: var(--font-serif);
  font-size: 16px;
  line-height: 2;
  color: var(--ink);
  white-space: pre-wrap;
}
/* 白话与原文格式分明：浅底 + 朱红左条 + 「白话」标签 */
.reader-trans {
  margin-top: 8px;
  padding: 8px 12px;
  border-left: 3px solid var(--cinnabar);
  border-radius: 0 8px 8px 0;
  background: var(--bar-wash);
  font-size: 14px;
  line-height: 1.8;
  color: var(--ink-soft);
  white-space: pre-wrap;
}
.reader-trans::before {
  content: "白话";
  display: inline-block;
  margin-right: 6px;
  padding: 0 5px;
  border-radius: 4px;
  background: var(--cinnabar);
  color: #fff;
  font-family: var(--font-sans);
  font-size: 11px;
}
.reader-more {
  display: block;
  width: 100%;
  margin: 6px 0 4px;
  padding: 10px;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 10px;
  font-family: inherit;
  font-size: 14px;
  color: var(--ink-soft);
  cursor: pointer;
}

.tabbar {
  flex-shrink: 0;
  display: flex;
  background: var(--bar-wash);
  border-top: 1px solid var(--rule-soft);
  /* 安全区下边距由 body 的 padding-bottom 统一承担，这里不重复加 */
}

/* mini：tabbar 是最底元素。body 的 padding-bottom: env(safe-area) 会把整条 tabbar
   往上顶、下方露出页面背景——微信 web-view（env>0）里就是「tab 栏下方那段空白」。
   改由 tabbar 自己承担安全区：负 margin 抵消 body 的 padding-bottom 让其铺到物理屏底，
   再用等高 padding-bottom 把按钮顶进安全区内，bar-wash 背景延伸到底、不露白。
   web 无 tabbar，安全区仍由 body 承担，不受影响。 */
html[data-shell="mini"] .tabbar {
  /* 纯减法（0px - env）而非 calc(-1 * env) 乘法：减法在老 iOS/微信 web-view
     兼容性更稳，避免规则被丢弃导致 34px 空白回归 */
  margin-bottom: calc(0px - env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
}

.tabbar .tab {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 11px 0;
  background: none;
  border: none;
  font-family: inherit;
  font-size: 12px;
  color: var(--ink-faint);
  cursor: pointer;
  transition: color var(--press-ms) ease;
}

.tabbar .tab:active {
  transform: scale(var(--press-scale));
}

/* 减少动态效果：禁用按压缩放（阴影态保留，无运动）。须置于上述三个 :active
   规则之后，否则同特异度被后面的 scale 覆盖回去（tab 这条尤其）。 */
@media (prefers-reduced-motion: reduce) {
  .tabbar .tab:active,
  .home-master:active,
  .book-item:active {
    transform: none;
  }
}

.tabbar .tab.on {
  color: var(--cinnabar-text);
  font-weight: 600;
}

/* 选中分栏：顶缘一道朱砂短条作「当前位置」标记，比单纯变色更突出 */
.tabbar .tab.on::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 18px;
  height: 2px;
  border-radius: 0 0 2px 2px;
  background: var(--cinnabar);
}

/* ---------- 排盘表单（聊天 tab 顶部） ---------- */

.chart-form {
  flex-shrink: 0;
  background: var(--card);
  border-bottom: 1px solid var(--rule-soft);
  padding: 12px 16px;
}

.cf-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.cf-title {
  font-family: var(--font-serif);
  font-size: 15px;
  color: var(--ink);
}

.cf-toggle {
  background: none;
  border: none;
  color: var(--sage);
  font-size: 13px;
  cursor: pointer;
}

.cf-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.cf-row {
  display: flex;
  gap: 8px;
  align-items: center;
}

.cf-input,
.cf-select {
  flex: 1;
  min-width: 0;
  padding: 8px 12px;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--paper);
  color: var(--ink);
  font-family: inherit;
  font-size: 14px;
}

.cf-gender {
  display: flex;
  gap: 10px;
}

.cf-g {
  flex: 1;
  text-align: center;
  padding: 9px;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--paper);
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 14px;
  cursor: pointer;
}

.cf-g.on {
  background: var(--sage-wash);
  border-color: var(--sage);
  color: var(--sage-deep);
}

/* 历法切换：与性别同款分段控件 */
.cf-cal {
  display: flex;
  gap: 10px;
}

.cf-cal-btn {
  flex: 1;
  text-align: center;
  padding: 9px;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--paper);
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 14px;
  cursor: pointer;
}

.cf-cal-btn.on {
  background: var(--sage-wash);
  border-color: var(--sage);
  color: var(--sage-deep);
}

/* 日期/时间选择器：套 .cf-input 主题，native 弹层跟随当前明暗（color-scheme），
   暗色下日历/时钟图标不至于白底刺眼。 */
.cf-input[type="date"],
.cf-input[type="time"] {
  width: 100%;
  color-scheme: light;
}

[data-theme="dark"] .cf-input[type="date"],
[data-theme="dark"] .cf-input[type="time"] {
  color-scheme: dark;
}


/* ---------- 排盘表单：对齐原型 docs/miniapp-preview.html（带标签的 form-row） ---------- */

.form-row {
  margin-bottom: 14px;
}

.form-row label {
  display: block;
  font-size: 12px;
  color: var(--ink-soft);
  margin-bottom: 6px;
}

/* 一行内并排的下拉（年月日 / 时分 / 省市） */
.selects {
  display: flex;
  gap: 8px;
}

/* 下拉框 + 框外常驻单位：选项保持纯数字，单位（年/月/日/时/分）常驻框右，
   收起态/展开列表都清爽，任何时候都标明哪个框是年/月/日。 */
.cf-sel {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 4px;
}
.cf-unit {
  flex-shrink: 0;
  font-style: normal;
  font-size: 13px;
  color: var(--ink-soft);
}

/* 出生地警示：橙色纸笺，提示真太阳时影响 */
.warn-note {
  margin-bottom: 14px;
  padding: 9px 11px;
  border: 1px solid #f0d9b5;
  border-radius: 8px;
  background: #fef3e2;
  font-size: 11px;
  line-height: 1.7;
  color: #b45309;
}

/* 子时勾选行 */
.check-row {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 14px;
  font-size: 12px;
  line-height: 1.6;
  color: var(--ink-soft);
  cursor: pointer;
}

.check-row input {
  flex-shrink: 0;
}

.cf-city-row {
  position: relative;
}

.cf-city-list {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 20;
  margin-top: 4px;
  max-height: 220px;
  overflow-y: auto;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 8px;
  box-shadow: var(--shadow-card);
}

.cf-city-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 10px 12px;
  background: none;
  border: none;
  color: var(--ink);
  font-family: inherit;
  font-size: 14px;
  cursor: pointer;
}

.cf-city-item:active {
  background: var(--sage-wash);
}

.cf-submit {
  margin-top: 4px;
}

.cf-error {
  margin-top: 4px;
}

/* ---------- 排盘报告 tab：记录列表 ---------- */

.report-panel {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  padding: 16px;
}

.report-head {
  flex-shrink: 0;
  font-family: var(--font-serif);
  font-size: 16px;
  color: var(--ink);
  margin-bottom: 12px;
}

.report-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  /* 同 dossier-body：列表长到滚动时，WKWebView 吃掉 report-panel 的 padding-bottom，
     用 in-flow 尾边距保证最后一张卡片不贴 tab 栏。 */
  padding-bottom: 20px;
}

.report-empty {
  margin: 32px 0;
  text-align: center;
  font-size: 14px;
  color: var(--ink-faint);
}

/* 排盘记录卡片：结构对齐原型 docs/miniapp-preview.html 的 .report-card */
.report-card {
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 12px;
  padding: 14px 16px;
}

.report-card .r-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 8px;
  gap: 8px;
}

.report-card .r-name {
  font-family: var(--font-serif);
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
}

.report-card .r-date {
  flex-shrink: 0;
  font-size: 11px;
  color: var(--ink-faint);
}

.report-card .r-sub {
  font-size: 12px;
  color: var(--ink-soft);
  line-height: 1.7;
  margin-bottom: 10px;
}

.report-card .r-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 8px;
}

/* tag inline 编辑输入框：复用 cf-input 主题，覆盖 flex:1 避免撑满整行 */
.r-tag-input {
  flex: 0 1 180px;
  font-size: 12px;
  padding: 4px 8px;
}

.report-card .r-foot {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap; /* 按钮多时整条换行，pill 作为整体换，不词中断行 */
  row-gap: 8px;
}

.pill-btn {
  display: inline-flex;
  align-items: center;
  padding: 5px 12px;
  font-family: inherit;
  font-size: 12px;
  line-height: 1.4;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink-soft);
  cursor: pointer;
  white-space: nowrap; /* 标签文字不在 pill 内部断行（修「查看报↵告」） */
}

/* 主操作：填充 teal，每卡一个，确立视觉重心 */
.pill-btn-primary {
  background: var(--cinnabar);
  border-color: var(--cinnabar);
  color: #fff;
}

.pill-btn-cinnabar {
  color: var(--cinnabar-text);
  border-color: #ecc8bc;
}

/* 标签/删除：弱化 + 靠右成一簇，避免与查看/更新争视觉重心；hover 才显丹砂示警 */
.pill-btn-ghost {
  margin-left: auto;
  border-color: transparent;
  background: transparent;
  color: var(--ink-faint, var(--ink-soft));
}

/* 只首个 ghost 吃 auto-margin，后续 ghost 紧随成簇（否则换行时多个 auto 把它们撑散） */
.r-foot .pill-btn-ghost ~ .pill-btn-ghost {
  margin-left: 0;
}

.pill-btn-ghost:hover {
  color: var(--cinnabar-text);
  border-color: #ecc8bc;
}

/* ---------- 底稿展示页（2b-2） ---------- */

.dossier-view {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.dossier-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}

.dossier-back {
  border: none;
  background: none;
  padding: 4px 2px;
  font-family: inherit;
  font-size: 14px;
  color: var(--ink-soft);
  cursor: pointer;
}

.dossier-title {
  font-family: var(--font-serif);
  font-size: 16px;
  color: var(--ink);
}

/* 分享海报入口：推到报告头右侧 */
.dossier-share {
  margin-left: auto;
  border: 1px solid var(--cinnabar);
  background: none;
  color: var(--cinnabar-text);
  font-family: inherit;
  font-size: 13px;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  cursor: pointer;
}
.dossier-share:active {
  transform: scale(var(--press-scale));
}
.dossier-share:disabled {
  opacity: 0.4;
  cursor: default;
}

/* 海报弹层：遮罩 + 居中图 + 长按提示。图本身走微信原生长按「保存图片」。 */
.poster-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: var(--overlay);
  display: flex;
  flex-direction: column;
  align-items: center;
  /* flex-start + 卡片 margin:auto：短海报居中；长图(可高达 1500px+)超视口时从顶起、
     可滚到顶不裁切。不用 justify-content:center——它让超高内容顶部不可滚，且 safe center
     在老 WebView 不支持时整条被丢弃、失去居中。margin:auto 全引擎通用。 */
  justify-content: flex-start;
  overflow-y: auto;
  gap: 14px;
  padding: 24px;
}
.poster-card {
  margin: auto 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}
.poster-img {
  width: min(78vw, 340px);
  height: auto;
  border-radius: 10px;
  box-shadow: 0 10px 40px rgb(0 0 0 / 0.5);
}
.poster-tip {
  margin: 0;
  color: var(--seal-ink);
  font-size: 13px;
  letter-spacing: 0.04em;
}
.poster-close {
  border: 1px solid rgb(255 255 255 / 0.5);
  background: none;
  color: var(--seal-ink);
  font-family: inherit;
  font-size: 14px;
  padding: 7px 22px;
  border-radius: var(--radius-pill);
  cursor: pointer;
}

.dossier-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

/* 尾部占位：WKWebView（微信）会吃掉滚动容器自身的 padding-bottom，滚到底时
   最后元素（换大师 chip）贴住 tab 栏。改用在流的 ::after 实体高度——WebKit 一定
   认 in-flow 盒子的 height，保证底部留白稳定。 */
.dossier-body::after {
  content: "";
  display: block;
  height: 20px;
}

.dossier-year {
  display: inline-block;
  margin-bottom: 14px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--bar-wash);
  border: 1px solid var(--rule-soft);
  font-size: 12px;
  color: var(--ink-soft);
}

.dossier-section {
  margin-bottom: 16px;
}

.dossier-label {
  font-family: var(--font-serif);
  font-size: 14px;
  color: var(--cinnabar-text);
  margin-bottom: 6px;
}

.dossier-text {
  margin: 0;
  font-size: 14px;
  line-height: 1.7;
  color: var(--ink);
}

/* 命格卡开场：格局名大字 + 旺衰 + 用神五行 + 落款——报告第一眼即结论。 */
.dossier-hero {
  margin-bottom: 18px;
  padding: 18px 16px 12px;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 12px;
  text-align: center;
}
.dh-kic {
  font-size: 11px;
  letter-spacing: 0.5em;
  color: var(--ink-faint);
}
.dh-geju {
  margin: 8px 0 14px;
  font-family: var(--font-serif);
  font-size: 21px;
  letter-spacing: 0.06em;
  line-height: 1.45;
  color: var(--ink);
}
.dossier-hero .dossier-str {
  margin: 0 6px 12px;
}
.dh-elems {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-bottom: 12px;
}
.dh-elems .dl-label {
  width: auto;
}
.dh-meta {
  padding-top: 10px;
  border-top: 1px solid var(--rule-soft);
  font-size: 12px;
  color: var(--ink-soft);
  letter-spacing: 0.06em;
}

/* 维度组章节头：serif 居中 + 细线，与盘面屏 cr-chap 同版式语言（色随纸底）。
   标识 19 张子节卡各属哪一章。 */
.dossier-chap {
  text-align: center;
  margin: 26px 0 14px;
}
.dossier-chap-t {
  font-family: var(--font-serif);
  font-size: 17px;
  letter-spacing: 0.14em;
  color: var(--ink);
}
.dossier-chap-line {
  width: 44px;
  height: 1px;
  background: var(--cinnabar);
  margin: 8px auto 0;
}

/* 人生维度折叠卡：收起态显标题 + 首句预览（单行省略），点开显全文、隐预览 */
.dossier-fold {
  border: 1px solid var(--rule);
  border-radius: 10px;
  margin-bottom: 10px;
  overflow: hidden;
}
.dossier-fold-h {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  background: var(--card);
  border: 0;
  cursor: pointer;
  text-align: left;
}
.dossier-fold-h:focus-visible {
  outline: 2px solid var(--cinnabar-text);
  outline-offset: -2px;
}
.dossier-fold-t {
  font-family: var(--font-serif);
  font-size: 14px;
  color: var(--cinnabar-text);
}
.dossier-fold-ar {
  color: var(--ink-faint);
  font-size: 16px;
  transition: transform 0.2s;
}
.dossier-fold.open .dossier-fold-ar {
  transform: rotate(90deg);
}
.dossier-fold-pv {
  margin: 0;
  padding: 0 14px 12px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--ink-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dossier-fold-b {
  padding: 0 14px 14px;
  display: none;
}
.dossier-fold.open .dossier-fold-b {
  display: block;
}
.dossier-fold.open .dossier-fold-pv {
  display: none;
}

.dossier-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.dossier-tag {
  padding: 3px 12px;
  border-radius: 999px;
  background: var(--card);
  border: 1px solid var(--rule);
  font-size: 13px;
  color: var(--ink);
}

.dossier-by {
  margin-bottom: 14px;
  font-size: 13px;
  color: var(--ink-soft);
}

/* 经典原文题注（Phase2）：逐章挂一句真实古籍原句。朱砂左栏 = 经典批注感；
   正文走 serif 全覆盖（楷书档是 subset、任意引文字会缺字混排，不能用）。 */
.dossier-cite {
  margin: 2px 0 16px;
  padding: 2px 0 2px 14px;
  border-left: 3px solid var(--seal-red);
}
.dossier-cite-text {
  display: block;
  font-family: var(--font-serif);
  font-size: 15px;
  line-height: 1.7;
  color: var(--ink);
}
.dossier-cite-src {
  display: block;
  margin-top: 4px;
  font-size: 12px;
  color: var(--seal-red);
}

/* 日主旺衰刻度（Phase3）：5 段累积填充，弱→强。 */
.dossier-str {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ds-bar {
  display: flex;
  gap: 4px;
}
.ds-seg {
  flex: 1;
  height: 8px;
  border-radius: 4px;
  background: var(--rule);
}
.ds-seg.on {
  background: var(--cinnabar);
}
.ds-ends {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--ink-faint);
}
.ds-cur {
  color: var(--cinnabar-text);
  font-weight: 600;
}

/* 低谷提振专区（可选）：温和卡底，四件套小标+正文 */
.dossier-lowtide {
  margin-top: 12px;
  padding: 14px 16px;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 12px;
}
.dlt-title {
  font-family: var(--font-serif);
  font-size: 14px;
  color: var(--cinnabar-text);
  margin-bottom: 2px;
}
.dlt-k {
  margin: 10px 0 4px;
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--cinnabar-text);
}
.dlt-k:first-child {
  margin-top: 0;
}

/* 开运锦囊（Phase3）：用神五行确定性算出的幸运色/方位/数字/材质速查块。 */
.dossier-lucky {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.dl-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.dl-label {
  flex: 0 0 auto;
  width: 60px;
  font-size: 13px;
  color: var(--ink-soft);
}
.dl-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.dl-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 11px;
  border-radius: 999px;
  background: var(--card);
  border: 1px solid var(--cinnabar);
  font-size: 13px;
  color: var(--cinnabar-text);
}
/* 幸运色 chip 的真实色点：说「红」得看见红（白等浅色靠描边成形） */
.dl-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 1px solid rgb(0 0 0 / 0.18);
  flex: 0 0 auto;
}

/* 生成长图（Phase4）：离屏克隆报告→展开折叠卡、去交互按钮、加品牌头尾→html2canvas。 */
.report-holder {
  position: fixed;
  left: -10000px;
  top: 0;
  z-index: -1;
  pointer-events: none;
}
.report-capture {
  width: 380px;
  padding: 20px 18px 28px;
  background: var(--paper);
}
.report-capture .dossier-fold-b {
  display: block;
} /* 展开正文 */
.report-capture .dossier-fold-pv,
.report-capture .dossier-fold-ar,
.report-capture .dossier-btn,
.report-capture .vp-btn,
.report-capture .dossier-empty {
  display: none;
} /* 收起预览/折叠箭头/交互按钮/空态：出图不需要 */
.rc-brand {
  text-align: center;
  padding-bottom: 14px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--rule);
}
.rc-brand-t {
  font-family: var(--font-display);
  font-size: 26px;
  color: var(--ink);
}
.rc-brand-s {
  margin-top: 4px;
  font-size: 12px;
  letter-spacing: 4px;
  color: var(--ink-soft);
}
.rc-foot {
  margin-top: 18px;
  padding-top: 12px;
  border-top: 1px solid var(--rule);
  text-align: center;
  font-size: 11px;
  color: var(--ink-faint);
}
/* 长图落款印：分享面上的品牌签名（与海报印章同语义） */
.rc-seal {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  margin-bottom: 8px;
  border: 1.5px solid var(--seal-red);
  border-radius: 6px;
  color: var(--seal-red);
  font-family: var(--font-display);
  font-size: 13px;
  letter-spacing: 1px;
  transform: rotate(-3deg);
}
.rc-cta {
  margin-top: 8px;
  font-size: 12px;
  color: var(--cinnabar-text);
  letter-spacing: 0.04em;
}

/* 长图里的盘面段：clone 自 .cr-deck（那里的 --cr-* 是暗底墨金），在此重映射为
   纸底配色——同一渲染逻辑、两套材质。横滑分页在长图里改流式。 */
.report-capture .rc-panel {
  --cr-bg: transparent;
  --cr-card: var(--card);
  --cr-ink: var(--ink);
  --cr-ink-soft: var(--ink-soft);
  --cr-ink-faint: var(--ink-faint);
  --cr-teal: var(--cinnabar);
  --cr-teal-wash: rgb(0 112 103 / 0.08);
  --cr-gold: #7d6420;
  --cr-gold-soft: #9c8544;
  --cr-seal: var(--seal-red);
  --cr-rule: var(--rule);
  --cr-w-mu: #3a8f4a;
  --cr-w-huo: #c05a2a;
  --cr-w-tu: #b18a1e;
  --cr-w-jin: #a08c50;
  --cr-w-shui: #2f6bab;
  flex: none;
  width: auto;
  height: auto;
  overflow: visible;
  padding: 10px 0 20px;
  background: transparent;
  color: var(--cr-ink);
}
.report-capture .rc-panel .cr-cover {
  flex: none;
  padding: 6px 0 4px;
}

.dossier-pick-label {
  margin-top: 8px;
  font-size: 13px;
  color: var(--ink-faint);
}

/* 大师选择条：点 chip 用该师生成；当前师高亮 */
.dossier-masters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.dossier-master-chip {
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid var(--rule);
  background: var(--paper);
  color: var(--ink);
  font-family: inherit;
  font-size: 14px;
  cursor: pointer;
}

.dossier-master-chip.on {
  border-color: var(--cinnabar);
  color: var(--cinnabar-text);
}

.dossier-luck {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.dossier-luck-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 10px;
}

.dossier-luck-span {
  font-size: 13px;
  color: var(--cinnabar-text);
  letter-spacing: 0.04em;
}

.dossier-luck-sum {
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink);
}

.dossier-vps {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* 校准深链定位提示：短暂描边，无位移、不闪烁；≤600ms 由 JS 摘 class */
.vp-focus-hint {
  outline: 2px solid var(--cinnabar);
  outline-offset: 2px;
  animation: vp-focus-hint-fade 600ms ease-out forwards;
}
@keyframes vp-focus-hint-fade {
  from { outline-color: var(--cinnabar); }
  to { outline-color: transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .vp-focus-hint {
    animation: none;
  }
}

.dossier-vp {
  padding: 10px 12px;
  border: 1px solid var(--rule-soft);
  border-radius: 10px;
  background: var(--card);
}
.dossier-vp.vp-confirmed {
  border-color: var(--cinnabar);
}
.dossier-vp.vp-denied {
  opacity: 0.55;
}
.vp-text {
  margin: 0 0 8px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink);
}
.vp-acts {
  display: flex;
  gap: 8px;
}
.vp-btn {
  padding: 4px 12px;
  border: 1px solid var(--rule);
  border-radius: 14px;
  background: none;
  font-family: inherit;
  font-size: 13px;
  color: var(--ink-soft);
  cursor: pointer;
}
.vp-btn.on {
  border-color: var(--cinnabar);
  color: var(--cinnabar-text);
}

.dossier-btn {
  margin-top: 8px;
  padding: 11px 16px;
  width: 100%;
  border: none;
  border-radius: 10px;
  background: var(--cinnabar);
  color: #fff;
  font-family: inherit;
  font-size: 15px;
  cursor: pointer;
}

.dossier-btn-ghost {
  margin-top: 18px;
  background: var(--paper);
  border: 1px solid var(--rule);
  color: var(--ink-soft);
}

.dossier-empty {
  margin: 28px 0;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 16px;
  align-items: center;
}

.dossier-empty .dossier-text {
  color: var(--ink-soft);
}

.dossier-msg {
  margin: 28px 0;
  text-align: center;
  font-size: 14px;
  color: var(--ink-soft);
}

.dossier-loading {
  color: var(--cinnabar-text);
}

.dossier-err {
  color: var(--ink-soft);
}

.composer textarea {
  flex: 1;
  resize: none;
  padding: 12px 18px;
  font-size: 16px;
  font-family: inherit;
  line-height: 1.5;
  border: 1px solid var(--rule);
  border-radius: 18px;
  background: var(--card);
  color: var(--ink);
  outline: none;
  max-height: 120px;
  min-height: 48px;
  box-shadow: 0 1px 2px rgb(31 27 22 / 0.04);
  transition:
    border-color var(--focus-ms) ease,
    box-shadow var(--focus-ms) ease,
    background-color var(--focus-ms) ease;
}

.composer textarea::placeholder {
  color: var(--ink-soft);
}

.composer textarea:focus {
  border-color: var(--sage);
  background: var(--card);
  box-shadow:
    0 1px 2px rgb(31 27 22 / 0.05),
    0 0 0 3px rgb(111 143 132 / 0.14);
}

.btn-send-msg {
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  background-color: var(--sage);
  color: var(--seal-ink);
  border: none;
  border-radius: 18px;
  font-family: inherit;
  font-size: 18px;
  font-weight: 600;
  cursor: pointer;
  align-self: flex-end;
  transition:
    transform var(--press-ms) ease,
    background-color var(--press-ms) ease;
}

.btn-send-msg:disabled {
  background-color: var(--rule);
  color: var(--ink-faint);
  cursor: not-allowed;
}

.btn-send-msg:hover:not(:disabled) {
  background-color: var(--sage-deep);
}

.btn-send-msg:active:not(:disabled) {
  transform: scale(var(--press-scale));
}

.banner {
  padding: 10px 16px;
  background: var(--cinnabar-wash);
  color: var(--warning);
  border-bottom: 1px solid var(--rule-soft);
  font-size: 13px;
  text-align: center;
}

/* ---------- 打赏弹层 ---------- */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: var(--overlay);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 100;
  /* 入场与 login modal 同节奏（keyframes 在 login 段定义） */
  animation: overlay-fade 160ms ease-out;
}

.modal {
  animation: card-rise 220ms cubic-bezier(0.16, 1, 0.3, 1);
}

@media (prefers-reduced-motion: reduce) {
  .modal-overlay,
  .modal {
    animation: none;
  }
}

.modal {
  background: var(--card);
  border-radius: 12px;
  padding: 28px 24px 24px;
  max-width: 320px;
  width: 100%;
  text-align: center;
  position: relative;
  box-shadow: var(--shadow-modal);
}

.modal h3 {
  margin: 0 0 8px;
  font-family: var(--font-serif);
  font-size: 20px;
  font-weight: 500;
  letter-spacing: 0.02em;
}

.modal p {
  margin: 0 0 20px;
  font-size: 13px;
  color: var(--ink-soft);
}

.modal img.qr {
  width: 220px;
  height: auto;
  max-width: 100%;
  border-radius: 8px;
  margin: 0 auto;
  display: block;
}

/* 打赏文案——比默认 .modal p 略大、行距更松，呼应 "现代纸笺" 排版气质 */
.modal p.tip-blessing {
  font-size: 14px;
  line-height: 1.75;
  color: var(--ink-soft);
  letter-spacing: 0.02em;
}

.modal .btn-close {
  position: absolute;
  top: 8px;
  right: 12px;
  background-color: transparent;
  border: none;
  font-size: 22px;
  font-family: inherit;
  color: var(--ink-soft);
  cursor: pointer;
  width: 36px;
  height: 36px;
  border-radius: 18px;
  transition:
    transform var(--press-ms) ease,
    background-color var(--press-ms) ease,
    color var(--press-ms) ease;
}

.modal .btn-close:hover {
  color: var(--ink);
  background-color: var(--rule-soft);
}

.modal .btn-close:active {
  transform: scale(var(--press-scale));
  background-color: var(--rule);
}

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

  .btn-icon:active,
  .topbar .btn-fu:active,
  .btn-send:active:not(:disabled),
  .btn-primary:active:not(:disabled),
  .btn-send-msg:active:not(:disabled),
  .empty-suggestion:active,
  .msg-menu-btn:active,
  .modal .btn-close:active,
  .msg-followup:active {
    transform: none;
  }
}

/* ---------- 静态文档页 ---------- */

article.doc {
  max-width: 720px;
  margin: 0 auto;
  padding: 32px 24px 60px;
  font-size: 15px;
  line-height: 1.75;
  color: var(--ink);
}

article.doc h1 {
  font-family: var(--font-serif);
  font-size: 28px;
  font-weight: 500;
  letter-spacing: 0.04em;
  margin: 0 0 8px;
}

article.doc h1::after {
  content: "";
  display: block;
  width: 32px;
  height: 2px;
  margin: 14px 0 0;
  background: var(--cinnabar);
  border-radius: 1px;
}

article.doc h2 {
  font-family: var(--font-serif);
  font-size: 19px;
  font-weight: 500;
  margin: 32px 0 12px;
  color: var(--ink);
}

article.doc blockquote {
  margin: 16px 0;
  padding: 12px 16px;
  background: var(--cinnabar-wash);
  color: var(--warning);
  border-left: 2px solid var(--cinnabar);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: 13px;
}

article.doc ul {
  padding-left: 22px;
}

article.doc li {
  margin: 4px 0;
}

article.doc a {
  color: var(--cinnabar-text);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color var(--focus-ms) ease;
}

article.doc a:hover {
  border-bottom-color: var(--cinnabar);
}

/* ---------- util ---------- */

.hidden {
  display: none !important;
}

/* ---------- 小屏顶栏挤压防护（<= 380px） ---------- */

@media (max-width: 380px) {
  #phone-tag {
    display: none !important;
  }
  .topbar {
    padding: 12px 14px;
  }
  .topbar .btn-icon {
    padding: 6px 8px;
    font-size: 13px;
  }
  .topbar .brand {
    font-size: 17px;
  }
  .topbar .actions {
    flex-shrink: 1;
    min-width: 0;
  }
  .topbar .brand {
    flex-shrink: 0;
  }
}

/* ---------- 相处设定全屏视图 ---------- */

.settings-overlay {
  position: fixed;
  inset: 0;
  /* 移动浏览器上 inset:0 的隐式高度按「大视口」算（地址栏/工具栏收起时的
     高度），工具栏展开时底部内容被遮——输入框看不见的根因。dvh 跟随动态
     视口，工具栏收展都能把 composer 留在可视区内。 */
  height: 100dvh;
  z-index: 200; /* 盖过打赏 modal（z100）和 login（z50） */
  display: flex;
  flex-direction: column;
  background: var(--paper);
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
  animation: fade-in 200ms ease-out;
}

/* 入场过场：整页 fade + 头/设定墙/对话三段轻浮现 */
.settings-head {
  animation: rise-in 320ms cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

.settings-bubbles {
  animation: rise-in 320ms cubic-bezier(0.16, 1, 0.3, 1) 40ms backwards;
}

#settings-chat {
  animation: rise-in 320ms cubic-bezier(0.16, 1, 0.3, 1) 80ms backwards;
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .settings-overlay,
  .settings-head,
  .settings-bubbles,
  #settings-chat {
    animation: none;
  }
}

.settings-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  max-width: 720px; /* 与 .chat-area 对齐 */
  margin: 0 auto;
  padding: 12px 20px 8px;
}

.settings-head h2 {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 18px;
  font-weight: 600;
  color: var(--ink);
}

.settings-close {
  background: transparent;
  border: none;
  font-size: 22px;
  font-family: inherit;
  line-height: 1;
  color: var(--ink-soft);
  cursor: pointer;
  width: 34px;
  height: 34px;
  border-radius: 17px;
  transition:
    transform var(--press-ms) ease,
    background-color var(--press-ms) ease,
    color var(--press-ms) ease;
}

.settings-close:hover {
  color: var(--ink);
  background-color: var(--rule-soft);
}

.settings-close:active {
  transform: scale(var(--press-scale));
}

/* 上区偏好气泡：纸卡浮起（与 empty-intro / fallback 同语言），可滚，
   给下区对话留主空间 */
/* 相处设定弹层内的消息区：flex 子项 min-height 默认 auto，内容比分配空间高
   时会撑开父容器、overflow 形同虚设、底部 composer 被顶出视口。只作用于本
   弹层——mini 的 .chat-scroll .messages 靠父级滚，不动它的假定（grok P2）。 */
#settings-chat .messages {
  min-height: 0;
}

.settings-bubbles {
  /* 可收缩：屏幕再矮也先保住下方输入框，气泡区自己让位（内部可滚） */
  flex-shrink: 1;
  min-height: 0;
  width: calc(100% - 40px);
  max-width: 680px; /* chat-area 720 减两侧 20px padding */
  margin: 2px auto 6px;
  max-height: 30dvh;
  overflow-y: auto;
  padding: 16px 18px;
  background: var(--card);
  border-radius: 12px;
  box-shadow: var(--shadow-card);
}

/* label 与 chip 行基线对齐（profile-label 的 8px padding 是为 modal
   input 行高设计的，chip 行更矮） */
.settings-bubbles .profile-label {
  padding-top: 3px;
}

.settings-bubbles .profile-row {
  margin-bottom: 12px;
}

.settings-bubbles .profile-row:last-child {
  margin-bottom: 0;
}

/* focus ring 与 input 同套 sage 系，盖掉浏览器默认蓝圈 */
.settings-close:focus-visible,
.settings-chip-btn:focus-visible,
.settings-bubbles .profile-chip-x:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgb(111 143 132 / 0.25);
}

.settings-hint {
  margin: 0;
  color: var(--ink-soft);
  font-size: 13px;
}

/* 称呼气泡是 button（可点击改）：常驻 sage 边 + ✎ 后缀标明可编辑
   （note chip 无边框无 ✎，区分"可改"与"可删"） */
.settings-chip-btn {
  font-family: inherit;
  cursor: pointer;
  border-color: var(--sage-line);
  transition:
    border-color var(--press-ms) ease,
    background-color var(--press-ms) ease;
}

.settings-chip-btn::after {
  content: "✎";
  margin-left: 5px;
  font-size: 12px;
  color: var(--sage);
}

.settings-chip-btn:hover:not(:disabled) {
  border-color: var(--sage);
  background: var(--sage-wash);
}

.settings-chip-btn:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

.settings-nick-input {
  max-width: 240px;
}

.profile-chip-x:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

/* LLM 不可用时的降级快捷表单（消息流里以卡片呈现） */
.settings-fallback {
  max-width: 420px;
  margin: 8px 0;
  padding: 14px 16px;
  background: var(--card);
  border-radius: 12px;
  box-shadow: var(--shadow-card);
}

/* 救急表单不用主 CTA 重量：收窄、不全宽 */
.settings-fallback .btn-primary {
  width: auto;
  min-height: 40px;
  padding: 8px 28px;
}

/* 个性化 chip / 行样式（设定视图与 fallback 表单使用） */
.profile-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 16px;
}
.profile-label {
  flex: 0 0 40px;
  color: var(--ink-soft);
  font-size: 14px;
  padding-top: 8px;
}
.profile-nick-input,
.profile-add-input {
  flex: 1;
  min-width: 0;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 8px 10px;
  font: inherit;
  color: var(--ink);
  background: var(--card);
}
.profile-nick-input:focus,
.profile-add-input:focus {
  outline: none;
  border-color: var(--sage);
}
.profile-notes-row .profile-notes {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.profile-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.profile-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--sage-wash);
  border: 1px solid var(--sage-line);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 13px;
  color: var(--ink);
}
.profile-chip-x {
  border: none;
  background: none;
  color: var(--ink-soft);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  padding: 0;
}
.profile-chip-x:hover {
  color: var(--warning);
}
.profile-error {
  color: var(--warning);
  font-size: 13px;
  margin-bottom: 12px;
}

/* 备案页脚：法规要求首页展示 ICP 号。钉在 welcome 落地页底部，
   极淡、不抢视觉。绝对定位避免扰乱 .welcome-inner 的居中。 */
.welcome {
  position: relative;
}
.site-beian {
  position: absolute;
  left: 50%;
  bottom: 16px;
  transform: translateX(-50%);
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: 12px;
  line-height: 1.6;
}
.beian-link {
  color: var(--ink-faint);
  text-decoration: none;
  white-space: nowrap;
}
.beian-link:hover {
  color: var(--ink-soft);
}
/* 公安备案号未配置（env 空 → token 替换为空串）时整条隐藏 */
.site-beian a:empty {
  display: none;
}

/* 首页理念：CTA 下方安静的小字块。淡色、限宽、克制，立产品调性不抢 CTA。 */
.welcome-manifesto {
  margin: 36px auto 0;
  max-width: 30em;
  padding-top: 26px;
  border-top: 1px solid var(--rule-soft);
  color: var(--ink-soft);
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 1.9;
  text-align: center;
}
.welcome-manifesto p {
  margin: 0 0 10px;
}
.welcome-manifesto-coda {
  margin: 16px 0 0;
  text-align: center;
  color: var(--cinnabar-text);
  letter-spacing: 0.08em;
}
/* 收尾三段（心存敬畏=态度 / 自强不息=行为 / 有德载福=结果）朱砂红突出 */
.coda-em {
  color: var(--cinnabar-text);
  font-weight: 600;
}
/* 矮屏（横屏手机）藏起理念，避免与底部备案 footer 挤压重叠 */
@media (max-height: 640px) {
  .welcome-manifesto {
    display: none;
  }
}

/* ====== 个人中心 me tab ====== */
.me-panel { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; }
.me-content { width: 100%; padding: 12px 16px 24px; }
.me-head { display: flex; align-items: center; gap: 14px; padding: 18px 4px; }
.me-avatar {
  width: 56px; height: 56px; border-radius: 50%;
  background: var(--rule-soft); border: 1px solid var(--rule);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-serif); font-size: 22px; color: var(--ink-soft);
  flex-shrink: 0;
}
.me-nick { font-family: var(--font-serif); font-size: 18px; font-weight: 600; color: var(--ink); }
.me-sub { font-size: 11px; color: var(--ink-faint); margin-top: 3px; }
.me-card {
  background: var(--card); border: 1px solid var(--rule); border-radius: 12px;
  padding: 2px 14px; margin-top: 12px;
}
.list-row {
  display: flex; align-items: center; justify-content: space-between;
  width: 100%; padding: 14px 2px; font-size: 14px; color: var(--ink);
  border-bottom: 1px solid var(--rule-soft); cursor: pointer;
  background: none; border-top: none; border-left: none; border-right: none;
  font-family: inherit; text-align: left; text-decoration: none;
}
.list-row:last-child { border-bottom: none; }
.list-row:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgb(111 143 132 / 0.25);
}
.list-row-danger { color: var(--seal-red); }
.pii-note { font-size: 11px; color: var(--ink-faint); line-height: 1.6; padding: 0 2px 8px; }
.modal-title { font-family: var(--font-serif); font-size: 18px; color: var(--ink); margin: 4px 0 10px; }
.delete-warn { font-size: 13px; color: var(--ink-soft); line-height: 1.7; margin-bottom: 12px; }
.btn-danger { background: var(--seal-red); }

/* 红系收口：--cinnabar 整族已转 teal 做主强调；印章/通知点/危险动作单独回红。
   置文件末尾，后置覆盖早先同特异性的 --cinnabar 定义。书脊/头像/按钮保持 teal。 */
#seal-flash,
.brand-seal,
.welcome-title::after,
.home-seal {
  background: var(--seal-red);
}
.topbar .btn-icon.attn::after {
  background: var(--seal-red);
}

/* ─── 命盘报告·盘面分页（固定深色古籍，scoped 在 .cr-deck，不随全局明暗）─── */
.cr-deck {
  --cr-bg: #15120c;
  --cr-card: #211c14;
  --cr-ink: #ece0cb;
  --cr-ink-soft: #c3b69b;
  --cr-ink-faint: #857a66;
  --cr-teal: #46b3a2;
  --cr-teal-wash: #15302c;
  --cr-gold: #c9a84c;
  --cr-gold-soft: #9c8336;
  --cr-seal: #bf463c;
  --cr-rule: #332c20;
  --cr-w-mu: #5fb872;
  --cr-w-huo: #e0814f;
  --cr-w-tu: #d8b048;
  --cr-w-jin: #d2bd82;
  --cr-w-shui: #6398cc;
  flex: 1;
  min-height: 0;
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  background: var(--cr-bg);
  color: var(--cr-ink);
  border-radius: 12px 12px 0 0;
}
.cr-deck::-webkit-scrollbar {
  display: none;
}
.cr-page {
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  scroll-snap-align: center;
  display: flex;
  flex-direction: column;
  padding: 30px 24px 40px;
  overflow-y: auto;
}
.cr-page::-webkit-scrollbar {
  display: none;
}
.cr-chap {
  text-align: center;
  margin-bottom: 24px;
}
.cr-no {
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.3em;
  color: var(--cr-gold-soft);
}
.cr-ti {
  font-family: var(--font-display);
  font-size: 20px;
  letter-spacing: 0.14em;
  color: var(--cr-gold);
  margin-top: 8px;
}
.cr-line {
  width: 44px;
  height: 1px;
  background: var(--cr-gold-soft);
  margin: 12px auto 0;
}
.cr-body {
  margin: 0;
}
.cr-cover {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
}
.cr-kic {
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.5em;
  color: var(--cr-ink-faint);
}
.cr-bz {
  font-family: var(--font-serif);
  font-size: 28px;
  letter-spacing: 0.14em;
  line-height: 1.7;
  margin: 20px 0 8px;
}
.cr-who {
  font-size: 13px;
  color: var(--cr-ink-soft);
  letter-spacing: 0.08em;
}
.cr-seal {
  width: 46px;
  height: 46px;
  margin-top: 28px;
  border: 1.5px solid var(--cr-seal);
  border-radius: 7px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--cr-seal);
  font-family: var(--font-display);
  font-size: 13px;
  writing-mode: vertical-rl;
  letter-spacing: 0.05em;
  transform: rotate(-4deg);
}
/* 五行字色：长图 .rc-panel 里的 clone 不在 .cr-deck 内，须同族覆盖（变量已随
   .rc-panel 重映射为纸底色，这里只补作用域）。 */
.cr-deck .e-mu,
.report-capture .rc-panel .e-mu {
  color: var(--cr-w-mu);
}
.cr-deck .e-huo,
.report-capture .rc-panel .e-huo {
  color: var(--cr-w-huo);
}
.cr-deck .e-tu,
.report-capture .rc-panel .e-tu {
  color: var(--cr-w-tu);
}
.cr-deck .e-jin,
.report-capture .rc-panel .e-jin {
  color: var(--cr-w-jin);
}
.cr-deck .e-shui,
.report-capture .rc-panel .e-shui {
  color: var(--cr-w-shui);
}
.cr-pillars {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}
.cr-pcard {
  background: var(--cr-card);
  border: 1px solid var(--cr-rule);
  border-radius: 11px;
  padding: 12px 3px 10px;
  text-align: center;
}
.cr-pn {
  font-size: 11px;
  color: var(--cr-ink-faint);
  margin-bottom: 6px;
}
.cr-gz {
  font-family: var(--font-serif);
  font-size: 27px;
  line-height: 1.25;
}
.cr-gz span {
  display: block;
}
.cr-sg {
  font-size: 10.5px;
  color: var(--cr-ink-soft);
  margin-top: 7px;
  min-height: 14px;
}
.cr-na {
  font-size: 10px;
  color: var(--cr-ink-faint);
  margin-top: 4px;
}
.cr-cang {
  font-size: 9.5px;
  color: var(--cr-ink-faint);
  margin-top: 7px;
  border-top: 1px dashed var(--cr-rule);
  padding-top: 5px;
}
.cr-pcard.day .cr-pn {
  color: var(--cr-teal);
}
.cr-wx {
  display: flex;
  align-items: flex-end;
  justify-content: space-around;
  gap: 12px;
  height: 170px;
  padding: 0 6px;
}
.cr-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  height: 100%;
  flex: 1;
}
.cr-bar {
  width: 62%;
  border-radius: 5px 5px 0 0;
}
.cr-cnt {
  font-size: 13px;
  color: var(--cr-ink-soft);
  margin-bottom: 5px;
}
.cr-lab {
  font-family: var(--font-serif);
  font-size: 17px;
  margin-top: 9px;
}
.cr-ssgrid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 9px;
}
.cr-sscard {
  background: var(--cr-card);
  border: 1px solid var(--cr-rule);
  border-radius: 11px;
  padding: 12px 14px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}
.cr-ssn {
  font-family: var(--font-serif);
  font-size: 16px;
}
.cr-ssc {
  font-size: 11px;
  color: var(--cr-ink-faint);
}
.cr-luck {
  display: flex;
  gap: 9px;
  overflow-x: auto;
  padding-bottom: 6px;
}
.cr-luck::-webkit-scrollbar {
  display: none;
}
.cr-lcard {
  flex: 0 0 auto;
  width: 72px;
  background: var(--cr-card);
  border: 1px solid var(--cr-rule);
  border-radius: 10px;
  padding: 10px 4px;
  text-align: center;
}
.cr-age {
  font-size: 10px;
  color: var(--cr-ink-faint);
}
.cr-lgz {
  font-family: var(--font-serif);
  font-size: 19px;
  margin: 4px 0;
}
.cr-lss {
  font-size: 10px;
  color: var(--cr-ink-soft);
}
.cr-lyr {
  font-size: 9px;
  color: var(--cr-ink-faint);
  margin-top: 2px;
}
.cr-lcard.now {
  border-color: var(--cr-teal);
}
.cr-lcard.now .cr-age {
  color: var(--cr-teal);
}
.cr-flow {
  margin-top: 13px;
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--cr-teal-wash);
  border: 1px solid var(--cr-teal);
  border-radius: 11px;
  padding: 12px 14px;
}
.cr-fyr {
  font-family: var(--font-serif);
  font-size: 21px;
  color: var(--cr-teal);
}
.cr-flab {
  font-size: 12px;
  color: var(--cr-ink-soft);
}
.cr-fss {
  font-size: 12px;
  color: var(--cr-ink-soft);
  margin-left: auto;
}
/* 点选联动：可点元素（cr-tap）+ 选中态（金边/金字盖默认 day/hot/now 态）+ 详情区。
   详情区显选中元素的事实（占位模块解读，后端补字段后再加白话） */
.cr-tap {
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.cr-tap:focus-visible {
  outline: 2px solid var(--cr-gold);
  outline-offset: 2px;
}
.cr-pcard.sel,
.cr-sscard.sel,
.cr-lcard.sel {
  border-color: var(--cr-gold);
  background: rgba(201, 168, 76, 0.1);
}
.cr-col.sel .cr-lab {
  color: var(--cr-gold);
}
.cr-col.sel .cr-bar {
  outline: 1px solid var(--cr-gold);
  outline-offset: 2px;
}
.cr-detail {
  margin-top: 16px;
  background: var(--cr-card);
  border: 1px solid var(--cr-rule);
  border-radius: 11px;
  padding: 13px 15px;
}
.cr-dt-h {
  font-family: var(--font-serif);
  font-size: 15px;
  color: var(--cr-gold);
  letter-spacing: 0.06em;
  margin-bottom: 10px;
}
.cr-dt-rows {
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.cr-dt-row {
  display: flex;
  gap: 10px;
  font-size: 13px;
  line-height: 1.5;
}
.cr-dt-k {
  flex: 0 0 38px;
  color: var(--cr-ink-faint);
}
.cr-dt-v {
  color: var(--cr-ink-soft);
}
/* 模块解读区（数据+解读同屏）：四柱屏八字概述 / 五行屏五行用神解析。空（无解读）时不显 */
.cr-module-read:empty {
  display: none;
}
.cr-module-read {
  margin-top: 18px;
}
.cr-mr-h {
  font-family: var(--font-serif);
  font-size: 14px;
  color: var(--cr-gold);
  letter-spacing: 0.08em;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--cr-rule);
  margin-bottom: 10px;
}
.cr-mr-b {
  margin: 0;
  font-size: 14px;
  line-height: 1.85;
  color: var(--cr-ink-soft);
}
/* 解读屏复用旧 dossier 组件：重映射全局 token 为深色版（继承自 .cr-deck 的 --cr-*），
   防浅色主题下旧样式用 --ink 深墨字贴在深底上不可读 */
.cr-read {
  --ink: var(--cr-ink);
  --ink-soft: var(--cr-ink-soft);
  --ink-faint: var(--cr-ink-faint);
  --card: var(--cr-card);
  --rule: var(--cr-rule);
  --rule-soft: var(--cr-rule);
  --paper: var(--cr-card);
  --bar-wash: var(--cr-teal-wash);
  --cinnabar: var(--cr-teal);
  --cinnabar-text: var(--cr-gold);
}
/* 圆点条：固定深色（.cr-* scoped 在 .cr-deck 内，sibling 拿不到，硬编码同值），
   与 deck 连续、不随全局明暗 */
.cr-dots {
  flex-shrink: 0;
  display: flex;
  justify-content: center;
  gap: 6px;
  padding: 11px 0 12px;
  background: #15120c;
  border-radius: 0 0 12px 12px;
}
.cr-dots i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #6b6250;
  opacity: 0.5;
}
.cr-dots i.on {
  background: #c9a84c;
  opacity: 1;
  width: 16px;
  border-radius: 3px;
}

/* ── mini 命盘 tab：新建按钮 + lite 文化摘要 ── */
.chart-new-btn {
  width: 100%;
  margin-bottom: 12px;
}
.dossier-lite-body {
  padding: 4px 2px 20px;
}
.dossier-sec-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 8px;
}
.dossier-card {
  background: var(--card-wash, rgba(0, 0, 0, 0.02));
  border: 1px solid var(--rule-soft);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 8px;
}
.dc-h {
  font-size: 14px;
  font-weight: 600;
  color: var(--seal-red, #b0503a);
  margin-bottom: 4px;
}
.dc-b {
  margin: 0;
  font-size: 14px;
  line-height: 1.7;
  color: var(--ink);
  white-space: pre-wrap;
}


/* 万年历入口：与「宜忌·黄历详情」/「择吉日」并进区头右侧 */
.alm-cal {
  padding: 0;
  background: none;
  border: none;
  font-family: inherit;
  font-size: 12.5px;
  letter-spacing: normal;
  color: var(--cinnabar-text);
  cursor: pointer;
  white-space: nowrap;
}
.alm-cal:hover {
  color: var(--cinnabar-deep);
}

/* 窄屏：万年历入口热区（与 web.css 黄历文字链同策略，两壳共用） */
@media (max-width: 480px) {
  .alm-cal {
    padding-block: 11px;
  }
}

/* ══════════════════════════════════════════════════════════
   万年历月历（两壳共用 overlay）：首页黄历「万年历」入口。
   纸底/墨字/朱砂点缀（原 web.css 搬迁，无壳前缀）。
   ══════════════════════════════════════════════════════════ */
.cm-overlay {
  position: fixed;
  inset: 0;
  z-index: 150;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 28px 14px;
  max-width: 100vw;
  overflow-x: hidden;
  overflow-y: auto;
  background: var(--overlay);
  animation: overlay-fade 160ms ease-out;
}
.cm-overlay.hidden {
  display: none;
}
@media (prefers-reduced-motion: reduce) {
  .cm-overlay {
    animation: none;
  }
}
.cm-sheet {
  position: relative;
  margin: auto;
  width: min(560px, 100%);
  max-width: 100%;
  min-width: 0;
  padding: 22px 18px 20px;
  overflow-x: hidden;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 14px;
  box-shadow: 0 12px 40px rgb(30 37 33 / 0.14);
  color: var(--ink);
}
.cm-close {
  position: absolute;
  top: 10px;
  right: 12px;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  background: transparent;
  font-size: 22px;
  line-height: 1;
  color: var(--ink-soft);
  cursor: pointer;
}
.cm-close:hover {
  color: var(--ink);
}
.cm-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 16px;
  margin-bottom: 14px;
  padding-right: 36px;
  min-width: 0;
  max-width: 100%;
}
.cm-title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--ink);
}
.cm-nav {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  max-width: 100%;
}
.cm-ym {
  min-width: 0;
  flex: 1 1 auto;
  text-align: center;
  font-family: var(--font-serif);
  font-size: 15px;
  color: var(--ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cm-nav-btn {
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--card);
  color: var(--ink);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}
.cm-nav-btn:hover:not(:disabled) {
  border-color: var(--cinnabar-text);
  color: var(--cinnabar-text);
}
.cm-nav-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
.cm-grid {
  display: grid;
  /* minmax(0,1fr)：列宽与格内长节日文字解耦，避免 min-content 撑破视口 */
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 4px;
  width: 100%;
  min-width: 0;
}
.cm-dow {
  padding: 4px 0 6px;
  text-align: center;
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
  min-width: 0;
  overflow: hidden;
}
.cm-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 2px;
  min-width: 0;
  min-height: 56px;
  padding: 6px 2px 4px;
  overflow: hidden;
  border: 1px solid transparent;
  border-radius: 10px;
  background: var(--card);
  color: var(--ink);
  cursor: pointer;
  font: inherit;
}
.cm-cell.cm-empty {
  background: transparent;
  cursor: default;
  pointer-events: none;
}
.cm-cell:hover:not(.cm-empty) {
  border-color: var(--rule);
}
.cm-cell.is-today {
  box-shadow: inset 0 0 0 1.5px var(--seal-red);
}
.cm-cell.is-selected {
  border-color: var(--cinnabar-text);
  background: color-mix(in srgb, var(--cinnabar-text) 8%, var(--card));
}
.cm-daynum {
  font-family: var(--font-serif);
  font-size: 16px;
  line-height: 1.2;
  color: var(--ink);
}
.cm-sub,
.cm-sub-lunar {
  display: block;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: center;
  font-size: 10.5px;
  line-height: 1.2;
  color: var(--ink-faint);
}
.cm-sub-jieqi,
.cm-sub-fest {
  color: var(--cinnabar-text);
  font-weight: 500;
}
.cm-detail {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--rule);
}
.cm-detail-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 14px;
  margin-bottom: 10px;
}
.cm-detail-date {
  font-size: 13px;
  color: var(--ink-soft);
}
.cm-detail-gz {
  font-family: var(--font-serif);
  font-size: 15px;
  color: var(--ink);
}
.cm-detail-jq {
  font-size: 13px;
  color: var(--cinnabar-text);
}
.cm-detail-row {
  display: flex;
  gap: 10px;
  margin-top: 6px;
  font-size: 13px;
  line-height: 1.65;
}
.cm-detail-k {
  flex: 0 0 1.5em;
  color: var(--seal-red);
  font-weight: 600;
}
.cm-detail-v {
  color: var(--ink-soft);
}

/* 万年历弹层「详情 ▾」扩展区（饮食/方位/冲煞/生肖…）。两壳共用；
   原在 web.css 且绑 [data-tab="home"]，overlay 与 mini 均命不中。 */
.cm-detail .alm-detail-bar,
.alm-detail-bar {
  display: flex;
  justify-content: flex-end;
  margin-top: 6px;
}

.alm-detail-tog {
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--cinnabar-text);
  cursor: pointer;
  line-height: 1.4;
  position: relative;
}

/* 12px 小字触区偏小；伪元素扩到约 64×35，不占布局。 */
.alm-detail-tog::after {
  content: "";
  position: absolute;
  inset: -9px -14px;
}

.alm-detail-tog:hover {
  color: var(--cinnabar-deep);
}

.alm-detail-panel {
  margin-top: 8px;
  padding-top: 10px;
  border-top: 1px solid var(--rule-soft);
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--ink-soft);
  min-width: 0;
}

.alm-detail-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
  overflow-wrap: anywhere;
}

.alm-detail-k {
  flex: 0 0 auto;
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 12px;
  color: var(--cinnabar-text);
  letter-spacing: 0.04em;
}

.alm-detail-v {
  min-width: 0;
  color: var(--ink);
}

/* 五方位紧凑网格，忌竖排拉长弹层 */
.alm-detail-dirs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(5.5em, 1fr));
  gap: 6px 14px;
  min-width: 0;
}

.alm-detail-dir {
  display: flex;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
  white-space: nowrap;
}

.alm-detail-dirv {
  font-family: var(--font-serif);
  font-weight: 600;
  color: var(--ink);
  letter-spacing: 0.04em;
}

.alm-detail-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  min-width: 0;
}

.alm-detail-meta-item {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
}

.cm-status {
  margin: 12px 0;
  text-align: center;
  font-size: 13px;
  color: var(--ink-faint);
}
@media (max-width: 420px) {
  .cm-sheet {
    padding: 18px 12px 16px;
  }
  .cm-cell {
    min-height: 50px;
    padding: 4px 1px;
  }
  .cm-daynum {
    font-size: 14px;
  }
  .cm-sub {
    font-size: 9.5px;
  }
}

/* Web 壳专属规则（html[data-shell="web"] …桌面/落地页/侧栏工作台）已物理拆分到 web.css，
   仅 index.html 加载；index-mini.html 不加载 → mini 壳从物理上不受 web 规则影响。
   本文件是两壳共用 base（token/@font-face/组件基础/mini 样式/keyframes）。
   新增 web-only 规则请写入 web.css，勿加回此文件。 */
