:root {
  --bg: #FDF8F3;
  --card: #FFFFFF;
  --ink: #3A3226;      /* 主文字 12.62:1 */
  --ink2: #6B6154;     /* 次级文字 6.06:1（R9 由 #8A7F6F/3.93:1 提升，达 AA） */
  --ink3: #7A7062;     /* 辅助小字 4.86:1（R9 由 #B5ABA0/2.26:1 提升，达 AA） */
  --line: #EDE3D8;
  --brand: #E8833A;    /* 品牌主色：用于填充 / 边框 / 大字 */
  --brand-deep: #B05A2A; /* 品牌文字色 4.84:1（R9 新增，小字与链接专用） */
  --brand2: #2E9E8F;
  --warn: #D96A5B;
  --ok: #3E8E5A;
  --hunger: #E8A33D;
  --mood: #E2728B;
  --clean: #4A9BD4;
  --energy: #5BA869;
  --bond: #9B7BC4;
  --wisdom: #4A6FA5;
  --vigor: #E8833A;
  --health: #27AE60;
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 20px;
  --border: var(--line);       /* 边框统一变量（替代散落的硬编码） */
  --bg-muted: #FDFBF8;         /* 浅背景卡片底 */
  --bg-ok: #E8F5E9;            /* 正确/成功区底色 */
  --bg-warn: #FFF8E1;          /* 警告/解析区底色 */
  --bg-error: #FDF0EF;         /* 错误区底色 */
  --sh: 0 1px 3px rgba(58,50,38,.06), 0 6px 20px rgba(58,50,38,.05);
  --transition: all .25s cubic-bezier(.4,0,.2,1);
}
/* 主题色预设 */
[data-theme="warm"] { --brand:#E8833A; --brand2:#2E9E8F; }
[data-theme="cool"] { --brand:#4A9BD4; --brand2:#5BA869; }
[data-theme="rose"] { --brand:#D96A5B; --brand2:#E2728B; }
[data-theme="forest"] { --brand:#3E8E5A; --brand2:#5BA869; }
[data-theme="lavender"] { --brand:#9B7BC4; --brand2:#4A9BD4; }
/* 迭代第2轮（#514）：主题色预设 5→9，新增 4 款 */
[data-theme="ocean"] { --brand:#1F7A8C; --brand2:#4A9BD4; }
[data-theme="gold"] { --brand:#B8862B; --brand2:#E8A33D; }
[data-theme="plum"] { --brand:#8E4B74; --brand2:#E2728B; }
[data-theme="slate"] { --brand:#5A6B7B; --brand2:#7A8FA0; }

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", sans-serif;
  background: var(--bg); color: var(--ink); font-size: 22px; line-height: 1.65;
  min-height: 100vh; transition: background .3s, color .3s;
  min-height: 100dvh; /* R25 动态视口高度 */
  -webkit-text-size-adjust: 100%;
}

/* ================= R512 显示适配：全局 base 字号按设备分级 =================
   桌面（>1200）22px / 平板横屏（769-1200）18px / 平板竖屏（768）17px
   手机（≤540）16px / 小屏（≤420）15px / 超小屏（≤360）14px
   用户字号控件（font-scale）作用于 .chat-full 局部，不受影响。 */
@media (max-width: 1200px) {
  body { font-size: 18px; }
}
@media (max-width: 768px) {
  body { font-size: 17px; }
}


/* R52: 跳过链接 - 键盘导航入口 */
.skip-link {
  position: absolute;
  top: -100%;
  left: 50%;
  transform: translateX(-50%);
  background: var(--brand);
  color: #fff;
  padding: 8px 16px;
  border-radius: 0 0 8px 8px;
  font-size: 14px;
  font-weight: 600;
  z-index: 1000;
  text-decoration: none;
  transition: top .2s;
}
.skip-link:focus {
  top: 0;
  outline: 3px solid var(--brand-deep);
  outline-offset: 2px;
}

/* R51: 屏幕阅读器专用类 */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.field-hint {
  display: block;
  font-size: 12px;
  color: var(--ink3);
  margin-top: 4px;
  line-height: 1.4;
}
button, input, textarea { font-family: inherit; font-size: inherit; }

/* ---------- 按钮统一基线 ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 12px 26px; border-radius: var(--r-md); font-size: 19px; font-weight: 600;
  background: var(--brand); color: #fff; border: 1.5px solid var(--brand);
  transition: all .2s cubic-bezier(.4,0,.2,1); cursor: pointer; white-space: nowrap; min-height: 42px; box-shadow: 0 2px 8px rgba(232,131,58,.15);
}
.btn:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(232,131,58,.3); }
.btn:active { transform: translateY(0); }
/* R5(HCI): min-height 36px → 44px，达到 WCAG 2.5.5 触控目标下限 */
.btn.sm { padding: 9px 18px; font-size: 16px; border-radius: var(--r-sm); min-height: 44px; }
.btn.ghost { background: transparent; color: var(--brand); border: 1.5px solid var(--brand); box-shadow: 0 2px 6px rgba(232,131,58,.1); }
.btn.ghost:hover { background: #FFF3E7; box-shadow: 0 4px 12px rgba(232,131,58,.2); transform: translateY(-1px); }
.btn-outline { background: var(--card); border: 1.5px solid var(--line); color: var(--ink2); box-shadow: 0 1px 4px rgba(58,50,38,.05); }
.btn-outline:hover { border-color: var(--brand); color: var(--brand); background: #FFF8F1; transform: translateY(-1px); }
.btn.xs { padding: 6px 14px; font-size: 14px; border-radius: var(--r-md); min-height: 28px; }
.btn.loading { position: relative; color: transparent; }
.btn.loading::after {
  content: ''; position: absolute; width: 16px; height: 16px;
  border: 2px solid rgba(255,255,255,.3); border-top-color: #fff;
  border-radius: 50%; animation: spin .6s linear infinite;
  top: 50%; left: 50%; margin: -8px 0 0 -8px;
}
.btn:disabled { opacity: .5; cursor: not-allowed; }
/* R44 加载态可见性修复：原 spinner 固定白色，只在 .btn 实心橙底上可见；
   而 .btn.ghost（透明底）与 .btn-outline（白底 var(--card)）上白 spinner 完全隐形，
   表现为"点击后按钮文字消失、毫无反馈"，用户会以为卡死并重复点击。
   现按变体分别指定 spinner 颜色，确保任何按钮变体都有可见的加载反馈。 */
.btn.ghost.loading::after,
.btn-outline.loading::after {
  border-color: rgba(232,131,58,.25);
  border-top-color: var(--brand);
}
/* 深色模式下 outline 卡片为深底，spinner 需提亮 */
[data-dark="1"] .btn.ghost.loading::after,
[data-dark="1"] .btn-outline.loading::after {
  border-color: rgba(240,160,92,.28);
  border-top-color: var(--brand);
}
/* xs 小按钮：spinner 缩小并修正居中，避免溢出按钮边界 */
.btn.xs.loading::after { width: 13px; height: 13px; margin: -6.5px 0 0 -6.5px; }
@keyframes spin { to { transform: rotate(360deg); } }

/* R6: 输入框验证样式 */
.field input.invalid { border-color: var(--warn); animation: shake .4s ease; }
.field input.valid { border-color: var(--ok); }
@keyframes shake { 0%,100%{transform:translateX(0)} 20%,60%{transform:translateX(-5px)} 40%,80%{transform:translateX(5px)} }
/* R29：偏好减少动效时取消标红抖动，避免循环残影 */
@media (prefers-reduced-motion: reduce) {
  .field input.invalid { animation: none; }
}

/* R7: 焦点状态增强 */
button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible,
[tabindex]:focus-visible, a:focus-visible {
  outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 4px;
}
.btn:focus-visible, .btn-solid:focus-visible { outline-color: var(--brand-deep); }
/* R9: 尊重系统「减弱动态效果」偏好 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}
/* R9: 系统「高对比度」模式下强化描边与焦点 */
@media (forced-colors: active) {
  :focus-visible { outline: 2px solid Highlight; }
}
/* R22: 持续动画元素硬件加速 */
.pet-avatar, .monster-emoji, .sky-star.lit, .dex-cell.isnew,
.status-dot.online, .tree-icon, .badge-card.unlocked, .inno-loading .il-dot,
.interact-anim, .buff-indicator, .crit-effect, .combo-display {
  will-change: transform, opacity;
}
/* R22: 滚动平滑（非强制） */
.chatbox, .right-panel { scroll-behavior: smooth; }

/* R8: 主题平滑过渡 */

/* ================= R1 骨架屏 Loading ================= */
@keyframes shimmer { 0%{background-position:-200% 0} 100%{background-position:200% 0} }
.skeleton {
  background: linear-gradient(90deg, var(--line) 25%, #F5EEE6 50%, var(--line) 75%);
  background-size: 200% 100%; animation: shimmer 1.5s infinite; border-radius: 6px;
}
.skeleton-line { height: 16px; margin-bottom: 7px; border-radius: 6px; }
.skeleton-line.w60 { width: 60%; } .skeleton-line.w80 { width: 80%; }
.loading-skeleton { display: flex; flex-direction: column; gap: 9px; padding: 14px 0; }

/* R53: 聊天框加载态（更友好） */
.chat-loading {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  flex: 1; padding: 32px; color: var(--ink2); gap: 12px;
}
.chat-loading .spinner-lg {
  width: 48px; height: 48px; border: 3px solid var(--line);
  border-top-color: var(--brand); border-radius: 50%;
  animation: spin 1s linear infinite;
}
.chat-loading p { font-size: 15px; color: var(--ink2); margin: 0; }
.chat-loading .hint { font-size: 13px; color: var(--ink3); }

/* R53: 全局加载遮罩（全屏） */
.loading-overlay {
  position: fixed; inset: 0; z-index: 9999;
  background: rgba(253,248,243,0.92);
  display: none; align-items: center; justify-content: center;
  flex-direction: column; gap: 16px;
}
.loading-overlay.on { display: flex; }
.loading-overlay .spinner-xl {
  width: 64px; height: 64px; border: 4px solid var(--line);
  border-top-color: var(--brand); border-radius: 50%;
  animation: spin 1s linear infinite;
}
.loading-overlay p { font-size: 18px; color: var(--ink); font-weight: 500; }
.loading-overlay .hint { font-size: 14px; color: var(--ink2); }

/* R53: 空状态增强 - 情感化提示 */
.empty-state {
  text-align: center; padding: 40px 20px; color: var(--ink2);
  animation: fadeIn 0.5s ease;
}
.empty-state .empty-icon { font-size: 72px; margin-bottom: 16px; opacity: 0.8; animation: bounce 2s ease infinite; }
.empty-state .empty-title { font-size: 18px; font-weight: 600; color: var(--ink); margin-bottom: 8px; }
.empty-state .empty-hint { font-size: 14px; color: var(--ink3); margin-bottom: 16px; line-height: 1.6; }
.empty-state .empty-action { margin-top: 16px; }
.empty-state .empty-action button {
  padding: 10px 24px; font-size: 15px; border-radius: var(--r-md);
  background: var(--brand); color: #fff; border: none; cursor: pointer;
  transition: all 0.2s;
}
.empty-state .empty-action button:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(232,131,58,0.3); }

@keyframes bounce {
  0%,100%{transform:translateY(0)} 50%{transform:translateY(-8px)}
}
@keyframes fadeIn { from{opacity:0;transform:translateY(12px)} to{opacity:1;transform:translateY(0)} }

/* R53: 错误状态增强 */
.error-state {
  text-align: center; padding: 32px 20px; color: var(--warn);
  background: var(--bg-error); border-radius: var(--r-md);
  border: 1px solid #F5D0CB; animation: fadeIn 0.4s ease;
}
.error-state .error-icon { font-size: 48px; margin-bottom: 12px; }
.error-state .error-title { font-size: 17px; font-weight: 600; color: var(--ink); margin-bottom: 8px; }
.error-state .error-msg { font-size: 14px; color: var(--ink2); margin-bottom: 16px; }
.error-state .error-action { margin-top: 12px; }
.error-state button {
  padding: 10px 20px; font-size: 14px; border-radius: var(--r-md);
  background: var(--warn); color: #fff; border: none; cursor: pointer;
  transition: all 0.2s;
}
.error-state button:hover { background: #c05a4d; transform: translateY(-1px); }

/* R53: 进度条样式 */
.progress-bar {
  height: 4px; background: var(--line); border-radius: 2px; overflow: hidden;
  margin: 8px 0;
}
.progress-bar .fill {
  height: 100%; background: linear-gradient(90deg, var(--brand), var(--brand2));
  border-radius: 2px; transition: width 0.3s ease;
}

/* ================= R2 空状态样式（保留兼容） ================= */

/* ---------- 登录（HCI 友好：柔和配色 · 舒适间距 · 聚焦光晕 · 友好引导） ---------- */
.login-wrap {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  min-height: 100dvh; /* R25 动态视口高度 */
  padding: 24px;
  background:
    radial-gradient(1100px 560px at 18% 8%, #FFF3E6 0%, transparent 60%),
    radial-gradient(1000px 560px at 92% 92%, #E9F5F1 0%, transparent 55%),
    linear-gradient(135deg, #FBF4EA 0%, #FDF7EF 50%, #EEF6F3 100%);
}
.login-card {
  background: rgba(255,255,255,.92);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid rgba(245,214,168,.55);
  border-radius: 28px;
  padding: 38px 32px 24px;
  width: 100%; max-width: 400px;
  text-align: center;
  box-shadow: 0 22px 54px rgba(187,126,64,.16), 0 4px 14px rgba(0,0,0,.04);
  animation: loginIn .5s ease both;
}
@keyframes loginIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.login-mascot {
  font-size: 56px; line-height: 1; margin-bottom: 8px;
  animation: floatY 3.2s ease-in-out infinite;
}
@keyframes floatY { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
.login-card h1 {
  font-size: 27px; font-weight: 800; margin-bottom: 26px;
  background: linear-gradient(135deg, var(--brand), var(--brand2));
  -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
}
.login-card .sub { color: var(--ink2); font-size: 15px; margin-bottom: 26px; }
.field { text-align: left; margin-bottom: 16px; }
.field label { display: block; font-size: 14px; color: var(--ink); font-weight: 600; margin-bottom: 8px; }
.input-wrap { position: relative; display: flex; align-items: center; }
.input-wrap .in-ic { position: absolute; left: 14px; font-size: 16px; opacity: .65; pointer-events: none; }
.field input {
  width: 100%; padding: 13px 46px 13px 42px;
  border: 1.5px solid var(--line); border-radius: 14px;
  background: #FFFBF6; outline: none; font-size: 16px; color: var(--ink);
  transition: border-color .2s, box-shadow .2s, background .2s;
}
.field input:focus { border-color: var(--brand); background: #fff; box-shadow: 0 0 0 4px rgba(232,131,58,.14); }
.field input.invalid { border-color: #e07a7a; box-shadow: 0 0 0 4px rgba(224,122,122,.14); }
.pw-toggle {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  background: none; border: none; cursor: pointer; font-size: 18px; padding: 4px;
  opacity: .7; transition: opacity .2s;
}
.pw-toggle:hover { opacity: 1; }
.remember {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  user-select: none; font-size: 14px; color: var(--ink2);
  margin: 2px 0 18px; text-align: left;
}
.remember input { position: absolute; opacity: 0; width: 0; height: 0; }
.rm-box {
  width: 20px; height: 20px; border: 2px solid var(--line); border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: all .2s; flex-shrink: 0;
}
.remember input:checked + .rm-box { background: linear-gradient(135deg, var(--brand), var(--brand2)); border-color: transparent; }
.remember input:checked + .rm-box::after { content: '✓'; color: #fff; font-size: 13px; font-weight: 700; }
.remember input:focus-visible + .rm-box { box-shadow: 0 0 0 3px rgba(232,131,58,.22); }
.login-card .btn { width: 100%; padding: 14px; font-size: 17px; border-radius: 14px; }
.hint { margin-top: 12px; font-size: 13px; color: var(--ink2); line-height: 1.6; }
.hint code { background: #F5EEE6; padding: 2px 7px; border-radius: 4px; font-size: 12px; }

/* R78: 评委演示入口（登录页，仅公网演示环境显示） */
.demo-entry {
  margin-top: 12px; padding: 10px 12px; text-align: center;
  background: linear-gradient(180deg, #F0F7FF 0%, #FFF 100%);
  border: 1.5px dashed #9FC3EE; border-radius: 12px;
}
.demo-entry-t { font-size: 14px; font-weight: 700; color: #24527E; margin-bottom: 8px; }
.demo-entry-b { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }
.demo-btn { flex: 1 1 auto; padding: 9px 10px !important; font-size: 14px !important; border-radius: 10px !important; }
.demo-btn.alt { background: #5B8DC9; }
.demo-entry-h { font-size: 12px; color: var(--ink2); margin-top: 7px; line-height: 1.5; }

/* ---------- 顶部导航栏 ---------- */
.topbar {
  background: linear-gradient(180deg, #FFF 0%, #FFFBF5 100%);
  border-bottom: 2px solid #F5D6A8;
  padding: 8px 16px;
  box-shadow: 0 2px 8px rgba(232,131,58,.08);
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  position: sticky; top: 0; z-index: 20;
}
.logo { font-size: 20px; font-weight: 700; }
.logo .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--brand); }
.spacer { flex: 1; }
.pill {
  background: linear-gradient(135deg, #FFF7EC, #FDF3E6);
  border: 1px solid #F5D6A8; border-radius: 20px;
  padding: 6px 14px; font-size: 14px;
}
.pill b { color: var(--ink); }
.chip { padding: 4px 10px; border-radius: 16px; font-size: 13px; background: #EAF6F3; color: var(--brand2); }
.chip.off { background: #F7EFE7; color: #B98A52; }

/* 状态指示器紧凑化 */
.status-indicator {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 12px; border-radius: 14px; font-size: 14px; font-weight: 500;
}
.status-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; transition: all .3s; }
.status-dot.online { background: #2ecc71; box-shadow: 0 0 0 2px rgba(46,204,113,.2); animation: pulse 2s infinite; }
.status-dot.offline { background: #95a5a6; box-shadow: none; }
@keyframes pulse { 0%,100%{opacity:1;transform:scale(1)} 50%{opacity:.8;transform:scale(1.1)} }

/* R512：顶栏小屏自适应——长文本截断、胶囊可收缩，避免移动端顶栏换行堆高 */
@media (max-width: 540px) {
  .topbar { padding: 6px 10px; gap: 4px; }
  .logo { font-size: 17px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 42vw; }
  .pill { padding: 4px 10px; font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .status-indicator { padding: 4px 9px; font-size: 12.5px; }
  .status-indicator .st-txt { max-width: 70px; overflow: hidden; text-overflow: ellipsis; }
}

/* 大模型状态指示器 */

/* 键盘导航可见性 */
kbd { background: var(--line); padding: 3px 8px; border-radius: 4px; font-size: 13px; color: var(--ink2); }

/* ---------- 主布局容器 ---------- */
.layout-shell {
  display: flex;
  flex: 1;
  min-height: 0;
  height: calc(100vh - 52px);
  /* R25：dvh = 动态视口高度。横屏平板/移动浏览器工具栏会吃掉 100vh 的一部分，
     导致底部内容被截断且无法滚动到；支持 dvh 的浏览器用更准的值，不支持的自动忽略。 */
  height: calc(100dvh - 52px);
  overflow: hidden;
}
/* 主内容区（原右侧，现为唯一子容器）—— 允许纵向滚动 */
.main-area {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 6px 8px 4px;
  overflow-y: auto;
  overflow-x: hidden;
}
.grid-new {
  display: grid;
  grid-template-columns: 32% 1fr 1fr;
  grid-template-rows: auto 1fr;   /* R479：内容行必须有确定高度，否则 func-panel 的 height:100% 无法解析而塌缩为 0 */
  gap: 8px;
  align-items: stretch;
  flex: 1 1 auto;                 /* R479：撑满主区高度 */
  min-height: 0;
  animation: pageEnter .4s ease-out;
}
@keyframes pageEnter { 0%{opacity:0} 100%{opacity:1} }

/* 第 3 列：功能面板（顶部为功能按钮栏，下方为 pane 内容） */
.func-panel {
  display: flex; flex-direction: column; gap: 8px;
  height: 100%; min-height: 0;
  overflow: hidden; padding-right: 2px;
}
/* 功能区顶部：两行按钮（基础功能 + 创新板块） */
.qn-btn-bar {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 5px;
  padding: 6px 8px;
  background: linear-gradient(180deg, #FFFBF5 0%, #FFF 100%);
  border: 2px solid #F5D6A8;
  border-radius: var(--r-md);
  box-shadow: 0 2px 8px rgba(232,131,58,.1);
  flex-shrink: 0;
}
/* 按钮均分占满整行（每个模块 3~14 个，统一单行横排，溢出自动换行） */
.qn-btn-bar .qn-btn { flex: 1 1 auto; min-width: 56px; }

/* R4(HCI)：func 组语义分区容器。
   分区标题仅 10px 的轻量标签，不抢主按钮视觉权重；每个分区内按钮横向平铺，
   保持原有点击手感与触控尺寸不变（只加结构，不改交互）。 */
.qn-sec { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.qn-sec-t {
  font-size: 10px; font-weight: 700; color: var(--ink3);
  background: rgba(232,131,58,.1); border-radius: 6px;
  padding: 2px 6px; white-space: nowrap; letter-spacing: .5px;
}
.qn-sec-b { display: flex; flex-wrap: wrap; gap: 5px; }
.qn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
/* 功能域专属总览卡片 */
.func-overview {
  flex-shrink: 0;
  padding: 10px 14px;
  background: linear-gradient(180deg, #F6FAFF 0%, #FFF 100%);
  border: 2px solid #CFE0F5;
  border-radius: var(--r-md);
}
.func-overview h3 {
  margin: 0 0 6px;
  font-size: 14px;
  color: #24527e;
}
.func-overview .ov-desc {
  margin: 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--ink2);
}
/* 测评域引导说明 */
.assess-intro {
  margin: 0 0 8px;
  padding: 8px 10px;
  font-size: 12px;
  line-height: 1.6;
  color: var(--ink2);
  background: #FBF7FF;
  border: 1px dashed var(--line);
  border-radius: var(--r-sm);
}

.qn-btn {
  flex: 1 1 auto;
  padding: 5px 2px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 600;
  background: #FDF6EE;
  border: 1.5px solid var(--line);
  color: var(--ink2);
  transition: all .2s ease;
  cursor: pointer;
  white-space: nowrap;
  /* R5(HCI): 32px → 44px。戒治场所多用触屏一体机，且戒毒人员心瘾发作时
     手指颤抖、视线不稳；WCAG 2.5.5 / iOS HIG 要求触控目标不小于 44px。
     该按钮已是 flex column + center，改高度后内容自动居中，无需改布局。 */
  min-height: 44px;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  box-shadow: 0 1px 3px rgba(58,50,38,.05);
  position: relative;
}
.qn-btn > * { pointer-events: none; }
.qn-btn .ic { font-size: 18px; line-height: 1; }
.qn-btn .lb { font-size: 11px; line-height: 1.2; }
.qn-btn:hover { border-color: var(--brand); color: var(--brand); transform: translateY(-2px); box-shadow: 0 4px 12px rgba(232,131,58,.22); background: linear-gradient(135deg, #FFF0DE, #FBEAD9); }
.qn-btn:focus-visible { outline: 2.5px solid var(--brand); outline-offset: 1px; box-shadow: 0 0 0 4px rgba(232,131,58,.15); }
.qn-btn.on { background: linear-gradient(135deg, #FFF0DE, #FBEAD9); color: #8f4a12; border-color: var(--brand); box-shadow: 0 4px 14px rgba(192,101,32,.22); font-weight: 800; }
.qn-btn.on:hover { background: linear-gradient(135deg, #FFE6CC, #F8DFC0); }
.qn-btn.on:focus-visible { outline-color: var(--brand); box-shadow: 0 4px 14px rgba(192,101,32,.22), 0 0 0 4px rgba(192,101,32,.18); }
.qn-btn.on .lb { color: #8f4a12; text-shadow: none; }
.qn-btn.on .ic { filter: none; }
/* 分组底色：基础功能（1-9）、创新板块（10-18） */
.qn-btn:nth-child(-n+9) { background: #FFF4E4; border-color: #F5D6A8; }
.qn-btn:nth-child(-n+9):hover { background: #FFEFDA; }
.qn-btn:nth-child(n+10) { background: #F5F0FA; border-color: #D4C5E8; }
.qn-btn:nth-child(n+10):hover { background: #EDE5F5; }
/* 功能内容区：pane 切换显示 */
.func-content {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: 2px;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
.func-content::-webkit-scrollbar { width: 4px; }
.func-content::-webkit-scrollbar-track { background: transparent; }
.func-content::-webkit-scrollbar-thumb { background: var(--line); border-radius: 2px; }
/* 第 2 列：聊天窗体（基态隐藏，仅 view-chat / view-funcwithchat 时显示，避免串页残留） */
.right-panel {
  display: none;
}

/* 迷你导航 */

/* ---------- 卡片 ---------- */
.card {
  background: var(--card); border-radius: var(--r-lg);
  padding: 10px 12px; margin-bottom: 3px;
  box-shadow: var(--sh); border: 1px solid var(--line);
  transition: all .25s ease;
}
.card:hover { box-shadow: 0 4px 20px rgba(58,50,38,.12); transform: translateY(-1px); }
/* R9：卡片标题与说明文字统一（10 个功能模块共用） */
.card h3 {
  font-size: 22px; font-weight: 600; line-height: 1.4; margin-bottom: 4px;
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
.card h3 .tag {
  font-size: 15px; font-weight: 500; line-height: 1.3;
  color: var(--brand-deep); background: #FFF3E7;
  border: 1px solid #F5D6A8; padding: 2px 9px; border-radius: 999px;
  white-space: nowrap; flex-shrink: 0;
}
.card h3 .tag:empty { display: none; }
.card-desc { font-size: 16px; line-height: 1.55; color: var(--ink2); margin: 0 0 10px; }

/* 提示条 */
.notice {
  background: #FFF8EF; border: 1px solid #F3E2CB; border-radius: var(--r-md);
  padding: 7px 12px; font-size: 16px; color: #7A5F3C; margin-bottom: 3px;
  display: flex; gap: 5px; align-items: center;
  /* R77: 显式收紧行高——此前继承全局 1.65（22px 基准下每行 36px），公告栏被撑得过高 */
  line-height: 1.5;
}
.affirm {
  background: #F2F9F6; border: 1px solid #D5EBE3; border-radius: var(--r-md);
  padding: 7px 12px; font-size: 16px; color: #2C6A5C; margin-bottom: 3px;
  line-height: 1.5;
}

/* Toast */
.toast {
  position: fixed; left: 50%; bottom: 34px; transform: translateX(-50%) translateY(20px);
  background: rgba(58,50,38,.94); color: #fff; padding: 14px 28px; border-radius: 24px;
  font-size: 16px; opacity: 0; transition: all .35s cubic-bezier(.4,0,.2,1); pointer-events: none; z-index: 99;
  box-shadow: 0 4px 16px rgba(0,0,0,.2);
}
.toast.on { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast.success { background: rgba(46,204,113,.94); }
.toast.error { background: rgba(231,76,60,.94); }
.toast.warning { background: rgba(243,156,18,.94); }
.toast.info { background: rgba(52,152,219,.94); }

/* Alert / Loading */
.alert-box { background: #FCEFEC; border: 1px solid #EFC9BF; border-radius: var(--r-md); padding: 8px 12px; font-size: 15px; color: #8C4A3E; line-height: 1.55; margin-bottom: 6px; animation: fadeInUp .3s ease-out; }
@keyframes fadeInUp { 0%{opacity:0;transform:translateY(10px)} 100%{opacity:1;transform:translateY(0)} }
.loading-spinner { display: flex; align-items: center; justify-content: center; padding: 14px; color: var(--ink2); font-size: 15px; }
.loading-spinner::before {
  content: ''; width: 18px; height: 18px; border: 2px solid var(--line);
  border-top-color: var(--brand); border-radius: 50%;
  animation: spin .6s linear infinite; margin-right: 8px;
}

/* 页面切换淡入（R9：动画统一由 .pane.on 承载） */
@keyframes paneEnter { 0%{opacity:0;transform:translateX(10px)} 100%{opacity:1;transform:translateX(0)} }

/* ---------- 通用弹窗 ---------- */
.modal { position: fixed; inset: 0; z-index: 200; display: none; align-items: center; justify-content: center; background: rgba(58,50,38,.45); backdrop-filter: blur(4px); }
.modal.on, .modal[style*="display:flex"] { display: flex; }
.modal-content {
  background: var(--card); border-radius: 18px; padding: 24px;
  width: 90%; max-width: 480px; max-height: 85vh; overflow-y: auto;
  box-shadow: 0 16px 48px rgba(58,50,38,.2); animation: modalIn .28s ease-out;
}
@keyframes modalIn { 0%{opacity:0;transform:scale(.93) translateY(12px)} 100%{opacity:1;transform:scale(1) translateY(0)} }

/* ---------- 路演模式提示弹窗 ---------- */
.demo-notice-box { max-width: 430px; text-align: center; padding: 28px 26px 24px; }
.demo-notice-ic { font-size: 42px; line-height: 1; margin-bottom: 12px; }
.demo-notice-t { font-size: 19px; font-weight: 800; color: var(--ink); margin-bottom: 12px; }
.demo-notice-b { font-size: 15px; line-height: 1.8; color: var(--ink2); margin-bottom: 10px; }
.demo-notice-b b { color: var(--brand); }
.demo-notice-h { font-size: 12px; color: var(--ink2); opacity: .8; line-height: 1.5; }
.demo-notice-btn { width: 100%; margin-top: 18px; }

/* ================= 宠物模块 ================= */
/* R10审计修复：此前此处写的是 border-radius: var(--r)，但 --r 从未定义
   （:root 里只有 --r-sm/--r-md/--r-lg/--r-xl）。CSS 变量未定义时
   var() 无回退值会让整条声明失效，导致**宠物舞台完全没有圆角**，
   与全站卡片风格明显不一致。统一改用已定义的 --r-lg。 */
.pet-stage {
  background: radial-gradient(120% 90% at 50% 12%, #FFF7EC 0%, #FDF3E6 55%, #F7EAD8 100%);
  border-radius: var(--r-lg); padding: 10px; text-align: center; position: relative;
  box-shadow: inset 0 0 0 1px rgba(240,194,76,.18);
}
.pet-stage::after {
  content: ""; position: absolute; inset: 10px; border-radius: calc(var(--r-lg) - 6px);
  pointer-events: none; background: radial-gradient(60% 50% at 50% 38%, rgba(255,255,255,.55), transparent 70%);
}
#petCanvas {
  width: 100%; max-width: 560px; height: auto; aspect-ratio: 640 / 520;
  display: block; margin: 0 auto;
  filter: drop-shadow(0 10px 16px rgba(184,140,60,.18));
  animation: petFloat 4.2s ease-in-out infinite; transition: opacity .3s ease;
}
#petCanvas.loading { opacity: .6; }
#petCanvas.happy { animation: petFloat 4.2s ease-in-out infinite, petHappy 0.6s ease 3; }
#petCanvas.sad { filter: drop-shadow(0 10px 16px rgba(184,140,60,.18)) grayscale(0.3); }
#petCanvas.sleeping { animation: petSleep 2s ease-in-out infinite; }
@keyframes petSleep { 0%,100%{transform:translateY(0) rotate(0deg)} 50%{transform:translateY(3px) rotate(2deg)} }
@keyframes petHappy { 0%,100%{transform:translateY(0)} 25%{transform:translateY(-8px) rotate(-5deg)} 75%{transform:translateY(-8px) rotate(5deg)} }

/* ============ 图片宠物模式 v20260925d ============ */
/* canvas 转后台（保持布局占位/状态逻辑），图片层覆盖显示对应动作帧。
   注意：visibility:hidden 是有意保留 canvas 的占位高度（aspect-ratio 撑住
   .pet-stage），让绝对定位的 #petImg(高度 72% 相对 stage) 有基准可贴；
   若改 display:none 会使 .pet-stage 塌缩、宠物图随之不可见。 */
.pet-img-mode #petCanvas { visibility: hidden; }
.pet-img-wrap { position: absolute; inset: 10px; z-index: 2; pointer-events: none; }
#petImg {
  position: absolute; left: 50%; bottom: 6%; transform: translateX(-50%);
  height: 72%; min-height: 150px; max-height: 300px; width: auto; max-width: 88%;
  object-fit: contain; display: block;
  filter: drop-shadow(0 12px 16px rgba(184,140,60,.22));
  transition: opacity .25s ease;
}
/* 动作动画 */
.pet-anim-idle   { animation: petImgIdle 3.2s ease-in-out infinite; }
.pet-anim-happy  { animation: petImgBounce .55s ease-in-out 3; }
.pet-anim-eat    { animation: petImgNod .7s ease-in-out 2; }
.pet-anim-sleep  { animation: petImgSleep 3s ease-in-out infinite; }
/* R32: 9 个互动动作专属动画（喂食/清洁/玩耍/休息/学习/摸摸/唱歌/散步/拥抱） */
.pet-anim-feed   { animation: petImgNod .7s ease-in-out 3; }
.pet-anim-clean  { animation: petImgSway 1.1s ease-in-out 2; }
.pet-anim-play   { animation: petImgBounce .55s ease-in-out 3; }
.pet-anim-rest   { animation: petImgRest 3s ease-in-out infinite; }
.pet-anim-study  { animation: petImgStudy 1.6s ease-in-out 2; }
.pet-anim-pet    { animation: petImgCozy 1.5s ease-in-out 2; }
.pet-anim-sing   { animation: petImgSing .9s ease-in-out 3; }
.pet-anim-walk   { animation: petImgWalk 1.2s ease-in-out 2; }
.pet-anim-hug    { animation: petImgHug 1.2s ease-in-out 2; }
@keyframes petImgIdle {
  0%,100% { transform: translateX(-50%) translateY(0) scale(1); }
  50%     { transform: translateX(-50%) translateY(-7px) scale(1.025); }
}
@keyframes petImgBounce {
  0%,100% { transform: translateX(-50%) translateY(0) scale(1); }
  35%     { transform: translateX(-50%) translateY(-22px) scale(1.05) rotate(-4deg); }
  70%     { transform: translateX(-50%) translateY(0) scale(.97) rotate(3deg); }
}
@keyframes petImgNod {
  0%,100% { transform: translateX(-50%) translateY(0) rotate(0deg); }
  50%     { transform: translateX(-50%) translateY(5px) rotate(4deg); }
}
@keyframes petImgSleep {
  0%,100% { transform: translateX(-50%) translateY(0) scale(1); filter: drop-shadow(0 12px 16px rgba(184,140,60,.22)) brightness(.96); }
  50%     { transform: translateX(-50%) translateY(4px) scale(.965); filter: drop-shadow(0 8px 10px rgba(184,140,60,.16)) brightness(.9); }
}
/* R32: 9 个互动动作关键帧 */
@keyframes petImgSway {
  0%,100% { transform: translateX(-50%) rotate(0deg); }
  25%     { transform: translateX(-50%) rotate(-4deg); }
  75%     { transform: translateX(-50%) rotate(4deg); }
}
@keyframes petImgRest {
  0%,100% { transform: translateX(-50%) translateY(0) scale(1); filter: drop-shadow(0 12px 16px rgba(184,140,60,.22)) brightness(.97); }
  50%     { transform: translateX(-50%) translateY(3px) scale(.975); filter: drop-shadow(0 9px 12px rgba(184,140,60,.18)) brightness(.93); }
}
@keyframes petImgStudy {
  0%,100% { transform: translateX(-50%) translateY(0) rotate(0deg); }
  50%     { transform: translateX(-50%) translateY(3px) rotate(2deg); }
}
@keyframes petImgCozy {
  0%,100% { transform: translateX(-50%) rotate(0deg); }
  30%     { transform: translateX(-50%) rotate(-3deg) translateY(-2px); }
  70%     { transform: translateX(-50%) rotate(3deg) translateY(-2px); }
}
@keyframes petImgSing {
  0%,100% { transform: translateX(-50%) translateY(0) rotate(0deg); }
  33%     { transform: translateX(-50%) translateY(-5px) rotate(-3deg); }
  66%     { transform: translateX(-50%) translateY(-2px) rotate(3deg); }
}
@keyframes petImgWalk {
  0%,100% { transform: translateX(-50%) rotate(0deg); }
  25%     { transform: translateX(calc(-50% - 6px)) rotate(-3deg); }
  75%     { transform: translateX(calc(-50% + 6px)) rotate(3deg); }
}
@keyframes petImgHug {
  0%,100% { transform: translateX(-50%) scale(1); }
  50%     { transform: translateX(-50%) scale(1.06); }
}
/* 蛋阶段：保持与正常阶段同尺寸（v20260926b 老板要求进入页面即喂食后同大小），保留摇晃动画 */
#petImg.pet-egg { height: 72%; animation: petImgWobble 2.4s ease-in-out infinite; }
/* R33：幼年阶段尺寸——越小越显幼：幼崽 58%、成长期 66%，蛋沿用 72%+摆动 */
#petImg.pet-baby   { height: 58%; }
#petImg.pet-grown  { height: 66%; }
@keyframes petImgWobble {
  0%,100% { transform: translateX(-50%) rotate(0deg); }
  25%     { transform: translateX(-50%) rotate(-5deg); }
  75%     { transform: translateX(-50%) rotate(5deg); }
}
/* 换装装饰层 */
.pet-outfit-layer { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.po-item { position: absolute; line-height: 1; filter: drop-shadow(0 2px 3px rgba(0,0,0,.18)); user-select: none; }

/* R63: 心情状态指示器 */
.mood-indicator {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 10px;
  border-radius: 12px; font-size: 12px; font-weight: 500; margin-left: 8px;
}
.mood-indicator.happy { background: rgba(46,158,143,.12); color: var(--brand2); }
.mood-indicator.normal { background: rgba(232,131,58,.1); color: var(--brand); }
.mood-indicator.sad { background: rgba(228,96,78,.1); color: var(--warn); }
.mood-indicator .mood-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: currentColor; animation: moodPulse 2s ease-in-out infinite;
}
@keyframes moodPulse { 0%,100%{opacity:1;transform:scale(1)} 50%{opacity:0.6;transform:scale(0.85)} }

/* R63: 成长进度条 */
.growth-bar-container {
  height: 6px; background: var(--line); border-radius: 3px; overflow: hidden; margin-top: 6px;
}
.growth-bar-fill {
  height: 100%; background: linear-gradient(90deg, var(--brand2), var(--brand));
  border-radius: 3px; transition: width 0.5s ease;
}
.speech {
  background: #fff; border: 1px solid var(--line); border-radius: 12px; padding: 10px 16px;
  font-size: 17px; color: var(--ink); display: inline-block; position: relative; margin-top: 2px;
  max-width: 92%;
}
.pet-name { font-size: 20px; font-weight: 600; margin-bottom: 3px; }
.pet-meta { font-size: 16px; color: var(--ink2); margin-bottom: 8px; }

/* 统一宠物模块标题与分隔 */
.pet-hub { position: relative; }
.pet-settings-btn {
  position: absolute; top: 12px; right: 12px; width: 32px; height: 32px;
  border-radius: var(--r-sm); border: 1px solid var(--line); background: #fff;
  font-size: 18px; cursor: pointer; display: flex; align-items: center; justify-content: center;
  transition: all .2s; color: var(--ink2);
}
.pet-settings-btn:hover { border-color: var(--brand); color: var(--brand); transform: rotate(45deg); }

/* 宠物类型选择器 */
.pet-type-selector { display: flex; justify-content: center; gap: 8px; margin: 10px 0 8px; }
.pet-type-btn {
  width: 54px; height: 54px; border-radius: var(--r-md); border: 2px solid var(--line);
  background: #fff; font-size: 26px; cursor: pointer; transition: all .2s;
  display: flex; align-items: center; justify-content: center;
}
.pet-type-btn:hover { border-color: var(--brand); transform: scale(1.1); }
.pet-type-btn.on { border-color: var(--brand); background: #FFF3E7; box-shadow: 0 0 0 2px rgba(232,131,58,.2); }

/* 宠物样式选择器 */
.pet-style-selector { display: flex; justify-content: center; gap: 8px; margin: 10px 0; }
.pet-style-btn {
  padding: 9px 20px; border-radius: var(--r-md); border: 2px solid var(--line);
  background: #fff; font-size: 15px; cursor: pointer; transition: all .25s cubic-bezier(.4,0,.2,1);
  display: flex; flex-direction: column; align-items: center; gap: 2px;
}
.pet-style-btn:hover { border-color: var(--brand); transform: scale(1.06); box-shadow: 0 2px 8px rgba(232,131,58,.15); }
.pet-style-btn.on { border-color: var(--brand); background: #FFF3E7; box-shadow: 0 0 0 3px rgba(232,131,58,.18); }
.pet-style-btn .style-icon { font-size: 20px; }
.pet-style-btn .style-label { font-size: 13px; color: var(--ink2); font-weight: 600; }

/* 换装选择器 */
.pet-outfit-selector { display: flex; justify-content: center; gap: 8px; margin: 10px 0; flex-wrap: wrap; }
.pet-outfit-btn {
  padding: 9px 16px; border-radius: var(--r-md); border: 2px solid var(--line);
  background: #fff; font-size: 15px; cursor: pointer; transition: all .25s cubic-bezier(.4,0,.2,1);
  display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 62px;
}
.pet-outfit-btn:hover { border-color: var(--brand); transform: scale(1.06); box-shadow: 0 2px 8px rgba(232,131,58,.15); }
.pet-outfit-btn.on { border-color: var(--brand); background: #FFF3E7; box-shadow: 0 0 0 3px rgba(232,131,58,.18); }
.pet-outfit-btn .outfit-icon { font-size: 20px; }
.pet-outfit-btn .outfit-label { font-size: 12px; color: var(--ink2); font-weight: 600; }

/* 状态条（R532 强化：加粗轨道 + 饱和填充 + 数值徽章 + 空骨架占位） */
.bars { margin: 8px 0 4px; }
.bar-row { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; min-height: 22px; }
.bar-row .lb { width: 48px; font-size: 14px; color: var(--ink2); flex-shrink: 0; font-weight: 600; }
.bar-row .track { flex: 1; height: 14px; background: rgba(255,255,255,.5); border: 1px solid rgba(0,0,0,.06); border-radius: 8px; overflow: hidden; box-shadow: inset 0 1px 2px rgba(0,0,0,.06); }
/* 关键修复：.fill 是 <span>，默认 inline 会让 width/height 完全失效
   （表现为「只有数值、没有彩色进度条」）。必须设为 block 才能按宽度渲染。 */
.bar-row .fill { display: block; height: 100%; border-radius: 8px; transition: width .6s ease, background .3s ease, box-shadow .3s ease; min-width: 2px; box-shadow: 0 1px 2px rgba(0,0,0,.12); }
/* 每项保留专属色（--hunger/--clean/... 由 JS 内联注入，此处不覆盖）；
   仅在低数值(<30)时整体转为警示红并加发光，形成「状态预警」语义。 */
.bar-row .fill.lvl-danger { background: var(--warn) !important; box-shadow: 0 0 0 2px rgba(217,106,91,.25), 0 1px 3px rgba(0,0,0,.15); }
/* 低数值时标签与数值同步高亮为警示色 */
.bar-row.low .lb, .bar-row.low .val { color: var(--warn); font-weight: 800; }
.bar-row .val { width: 36px; text-align: right; font-size: 14px; color: var(--ink); font-weight: 700; }
/* 空骨架占位：#bars 为空时显示 8 条灰色骨架，避免"只有数字没进度条" */
.bars:empty::before {
  content: ''; display: flex; flex-direction: column; gap: 6px;
}
.bars:empty::before::after { content: '加载中…'; font-size: 12px; color: var(--ink3); text-align: center; padding: 4px; }

/* 互动动作 */
.acts { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin-top: 8px; }
.act {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; padding: 8px 4px; border-radius: var(--r-md); font-size: 15px; font-weight: 500;
  background: #FDF6EE; border: 1px solid var(--line); transition: all .18s; cursor: pointer; min-height: 52px;
}
.act:hover { background: #FBEAD9; border-color: var(--brand); transform: translateY(-1px); }
.act .ic { font-size: 20px; display: block; margin-bottom: 2px; }
.act:active { transform: translateY(0); }
/* 点击反馈：短暂缩放+高亮 */
.act.act-pulse { animation: actPulse .35s ease-out; }
/* 冷却态（频率限制）：按钮置灰 + 右上角显示剩余秒数徽章
   position: relative 为徽章（绝对定位）提供锚点——.act 基类无定位，
   缺失时徽章会相对更外层容器定位而错位。只在冷却态加，不影响其它状态。 */
.act.act-cooling { position: relative; opacity: .45; cursor: not-allowed; transform: none; filter: grayscale(.6); }
.act .act-cd {
  position: absolute; top: 4px; right: 4px;
  min-width: 20px; height: 20px; padding: 0 4px;
  background: var(--warn); color: #fff; font-size: 11px; font-weight: 800;
  line-height: 20px; text-align: center; border-radius: 10px;
  box-shadow: 0 1px 3px rgba(0,0,0,.25);
}
@keyframes actPulse {
  0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(232,131,58,.5); }
  40% { transform: scale(.92); box-shadow: 0 0 0 10px rgba(232,131,58,0); }
  100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(232,131,58,0); }
}
/* 浮动效果提示 */
.float-plus {
  position: absolute; pointer-events: none; z-index: 50;
  font-size: 16px; font-weight: 800; color: #2F6B42;
  text-shadow: 0 1px 4px rgba(0,0,0,.2);
  animation: floatUp 1.4s ease-out forwards;
  white-space: nowrap;
}
.float-plus.neg { color: #C0392B; }
@keyframes floatUp {
  0% { opacity: 0; transform: translateY(0) scale(.7); }
  15% { opacity: 1; transform: translateY(-10px) scale(1.1); }
  100% { opacity: 0; transform: translateY(-52px) scale(.9); }
}

/* 宠物迷你样式
   R482：pet-hub 内部改为 flex column —— 上段是三栏 body（宠物舞台+互动按钮+状态栏），
   下段是档案区 .pet-profile-section（R482 新增，整合原 p-profile pane 内容） */
.pet-hub.mini {
  background: linear-gradient(180deg, #FFFBF5 0%, #FFF7EC 100%);
  border: 2px solid #F5D6A8;
  box-shadow: 0 4px 16px rgba(232,131,58,.12), inset 0 1px 0 rgba(255,255,255,.8);
  padding: 10px;
  overflow-y: auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* R531：宠物图只在「宠物」主页面显示。切到打卡/勋章/战斗/成长树/个性化
   等 pet 组子面板时，由 switchTab 给 .pet-hub 加 .pet-stage-hidden，
   隐藏整个宠物舞台（含 #petImg/#petCanvas），既消除宠物图悬浮遮挡子面板，
   又把空间让给子面板。回「宠物」主页时移除该类恢复显示。
   R569：acts（喂食/清洁等）与 status（状态/属性）同样只在「宠物」主页显示。
   R69：子面板切换入口已上移为主导航「宠物」按钮的二级菜单（.group-menu），
   原 .pet-subnav 移除，stage-hidden 时 .pet-hub-body 整体隐藏。 */
.pet-hub.pet-stage-hidden .pet-stage { display: none; }
.pet-hub.pet-stage-hidden .pet-hub-left { display: none; }
.pet-hub.pet-stage-hidden .pet-hub-acts { display: none; }
.pet-hub.pet-stage-hidden .pet-hub-right { display: none; }
/* R570→R69：子面板激活时改为单栏布局，子面板内容横向展开填满（原 64px 子导航列已移除） */
.pet-hub.pet-stage-hidden {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto;
  gap: 10px;
  overflow-y: auto;
}
.pet-hub.pet-stage-hidden .pet-hub-body { display: none; }
.pet-hub.pet-stage-hidden .pet-subpanes {
  grid-column: 1;
  grid-row: 1;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}
/* 宠物舞台隐藏时，档案区与子面板顶到最上，三列 body 自动收缩 */
/* 宠物 hub 三列：左宠物舞台 / 中操作按钮 / 右状态属性
   R479：三栏内容纵向居中、横向居中排布；min-width 下调避免与容器宽度冲突导致横向溢出
   R482：height:100% 改 flex:1 1 auto + min-height:0，让 body 占据除档案区外的剩余空间
   R37：min-width 合计 ≤ 483px（容器内宽），避免右栏被横向截断；右栏放宽到 200px 保证状态卡可读 */
.pet-hub-body {
  display: flex;
  gap: 12px;
  align-items: flex-start;   /* 三栏顶部对齐（R40） */
  justify-content: center;
  /* R535：flex 1 1 auto 会被同列的档案区（展开 60vh）挤压到 126px，
     三栏内容向下溢出压进档案区造成"模块重叠"。改 flex 0 0 auto 锁定内容高度，
     超出部分由 .pet-hub.mini 的 overflow-y:auto 整体滚动，三栏永不重叠 */
  flex: 0 0 auto;
  width: 100%;
  margin: 0 auto;
}
/* R567：宠物竖向子面板导航（打卡/奖状/打怪兽/我的成长/我来改/成绩单）
   - 原位于宠物舞台左侧；R67 起按老板要求移到「状态/属性」右侧，作为右侧导航栏
   - 用 order 把它排到三列网格之后（视觉最右），DOM 顺序不动以免影响 switchSubNav 逻辑
   - 锁定宽度不参与弹性分配；.pet-stage-hidden 时不隐藏本栏（导航始终可用） */
.pet-subnav {
  order: 4;                /* 排到 .pet-hub-left/.pet-hub-acts/.pet-hub-right 之后，显示在最右侧 */
  flex: 0 0 64px;
  min-width: 64px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px 6px;
  background: linear-gradient(180deg, #FFFDF9 0%, #FDF3E4 100%);
  border: 1.5px solid #F5D6A8;
  border-radius: 14px;
  align-self: stretch;
  box-shadow: 0 2px 8px rgba(232,131,58,.10);
}
.ps-nav-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 8px 4px;
  min-height: 56px;
  background: rgba(255,255,255,.6);
  border: 1.5px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
  font-size: 12px;
  color: var(--ink2);
  transition: all .18s ease;
  white-space: nowrap;
}
.ps-nav-btn .ps-ic { font-size: 20px; line-height: 1; }
.ps-nav-btn .ps-lb { font-size: 11px; font-weight: 600; }
.ps-nav-btn:hover {
  background: #FFF4E4;
  border-color: var(--brand);
  color: var(--brand-deep);
  transform: translateY(-1px);
  box-shadow: 0 3px 10px rgba(232,131,58,.18);
}
.ps-nav-btn.on {
  background: linear-gradient(135deg, #FFF0DE, #FBEAD9);
  color: #8f4a12;
  border-color: var(--brand);
  box-shadow: 0 3px 10px rgba(192,101,32,.22);
  font-weight: 800;
}
/* 移动端窄屏：子导航收为窄条 */
@media (max-width: 900px) {
  .pet-subnav { flex: 0 0 56px; min-width: 56px; }
  .ps-nav-btn { min-height: 48px; padding: 6px 2px; }
  .ps-nav-btn .ps-ic { font-size: 18px; }
  .ps-nav-btn .ps-lb { font-size: 10px; }
}
.pet-hub-left {
  flex: 1.4 1 0;
  min-width: 180px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;
}
/* 中栏：操作按钮独立成列（纵向 3 列网格） */
.pet-hub-acts {
  order: 2;               /* R68：状态/属性移到宠物右侧后，功能按钮列顺移到其后 */
  flex: 1 1 0;
  min-width: 150px;
  display: flex;
  flex-direction: column;
  width: 100%;
}
.pet-hub-acts .acts.mini {
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: auto;
  margin: 0;
  width: 100%;
}
.pet-hub-right {
  order: 1;               /* R68：按老板要求把「状态/属性」移到宠物（舞台）右侧，紧挨宠物 */
  flex: 1.2 1 0;
  min-width: 200px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}
/* 右栏状态卡：加底色区分 */
.pet-hub-right .status-strip {
  background: rgba(255,255,255,.55);
  border: 1.5px solid #F5D6A8;
  border-radius: var(--r-md);
  padding: 12px 14px;
}
/* R37：右栏对齐优化——标题缩小并置顶；状态行数值右对齐加宽，不被压缩 */
.pet-hub-right .status-strip h3 {
  font-size: 14px;
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 8px 0;
  display: flex;
  align-items: center;
  gap: 6px;
}
.pet-hub-right .status-strip h3 .ic { font-size: 15px; }
/* R38b：右栏 stat-row 多列网格——每行并排多个字段，而非每个字段独占一行 */
.pet-hub-right .status-stats {
  grid-template-columns: repeat(3, 1fr);
  gap: 5px;
}
.pet-hub-right .stat-row {
  padding: 5px 9px;
  background: #FDF6EE;
  border: 1px solid var(--line);
  border-radius: 7px;
  font-size: 13px;
  align-items: center;
  min-width: 0;
  display: flex;
  justify-content: space-between;
  white-space: nowrap;
}
.pet-hub-right .stat-row .lb {
  color: var(--ink2);
  font-weight: 500;
  font-size: 12px;
  flex: 1;
  white-space: nowrap;
}
.pet-hub-right .stat-row b {
  color: var(--brand);
  font-weight: 700;
  font-size: 13px;
  text-align: right;
  min-width: 34px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* R532：宠物页状态卡加明显彩色进度条（老板要求：饱食/心情/清洁/体力/亲密/智慧/活力/健康
   等字段"只有数字没进度条"→ 数字下方加一条 6px 彩色进度条，按数值百分比填充，
   颜色随档位 tier-warn 红 / tier-brand 橙 / tier-ok 绿 / tier-clean 蓝） */
.pet-hub-right .stat-row {
  flex-direction: column;
  align-items: stretch;
  gap: 3px;
  padding: 7px 10px;
  white-space: normal;
}
.pet-hub-right .stat-row .lb {
  flex: none;
  font-size: 12px;
  opacity: .85;
}
.pet-hub-right .stat-row b {
  flex: 1;
  text-align: left;
  font-size: 15px;
  min-width: 0;
}
/* 数字下方独立进度条：原 ::before/::after 3px 贴数字底太细，改为整行底部 6px 圆条
   颜色继承档位色（.stat-v 的 tier-* 已设色，这里用其 ::after 改形态） */
.pet-hub-right .stat-row .stat-v {
  position: relative;
  padding-bottom: 7px;
  --p: 0;
}
.pet-hub-right .stat-row .stat-v::before {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 6px;
  border-radius: 3px;
  background: var(--line);
  overflow: hidden;
}
.pet-hub-right .stat-row .stat-v::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  height: 6px;
  width: calc(var(--p) * 1%);
  max-width: 100%;
  border-radius: 3px;
  transition: width .4s ease;
}
/* 档位色（保留原 tier-* 配色，色条与数字同色） */
.pet-hub-right .stat-row .stat-v.tier-warn  { color: var(--warn); }
.pet-hub-right .stat-row .stat-v.tier-warn::after  { background: var(--warn); }
.pet-hub-right .stat-row .stat-v.tier-brand { color: var(--brand-deep); }
.pet-hub-right .stat-row .stat-v.tier-brand::after { background: var(--brand); }
.pet-hub-right .stat-row .stat-v.tier-ok     { color: var(--ok); }
.pet-hub-right .stat-row .stat-v.tier-ok::after     { background: var(--ok); }
.pet-hub-right .stat-row .stat-v.tier-clean  { color: var(--clean); }
.pet-hub-right .stat-row .stat-v.tier-clean::after  { background: var(--clean); }
/* 兜底路径 .status-stats（非 pet-hub-right 渲染时） */
.status-stats .stat-row { flex-direction: column; align-items: stretch; gap: 3px; padding: 7px 10px; }
.status-stats .stat-row .lb { flex: none; font-size: 12px; }
.status-stats .stat-row b { flex: 1; text-align: left; font-size: 15px; }
.status-stats .stat-row .stat-v { position: relative; padding-bottom: 7px; --p: 0; }
.status-stats .stat-row .stat-v::before {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0;
  height: 6px; border-radius: 3px; background: var(--line);
}
.status-stats .stat-row .stat-v::after {
  content: ''; position: absolute; left: 0; bottom: 0; height: 6px;
  width: calc(var(--p) * 1%); max-width: 100%; border-radius: 3px; transition: width .4s ease;
}
.status-stats .stat-row .stat-v.tier-warn  { color: var(--warn); }
.status-stats .stat-row .stat-v.tier-warn::after  { background: var(--warn); }
.status-stats .stat-row .stat-v.tier-brand { color: var(--brand-deep); }
.status-stats .stat-row .stat-v.tier-brand::after { background: var(--brand); }
.status-stats .stat-row .stat-v.tier-ok     { color: var(--ok); }
.status-stats .stat-row .stat-v.tier-ok::after     { background: var(--ok); }
.status-stats .stat-row .stat-v.tier-clean  { color: var(--clean); }
.status-stats .stat-row .stat-v.tier-clean::after  { background: var(--clean); }
/* 窄容器（右栏 < 360px）时退化为 2 列，避免数值被挤压 */
@media (max-width: 1200px) {
  .pet-hub-right .status-stats { grid-template-columns: repeat(2, 1fr); }
}
/* 小屏：上下堆叠（宠物在上、按钮在中、属性在下） */
@media (max-width: 760px) {
  .wcols { flex-direction: column; }
  .wcol { width: 100%; }
  .pet-hub-body { flex-direction: column; }
  .pet-hub-left, .pet-hub-right, .pet-hub-acts { flex: 1 1 auto; width: 100%; }
  .pet-hub-acts { order: 2; }
  .pet-hub-right { order: 3; }
}
.pet-hub.mini::-webkit-scrollbar { width: 4px; }
.pet-hub.mini::-webkit-scrollbar-thumb { background: var(--line); border-radius: 2px; }
.pet-stage.mini {
  background: radial-gradient(ellipse at center, #FFF9F0 0%, #FDF3E6 100%);
  border-radius: 16px; padding: 0;
  box-shadow: inset 0 2px 8px rgba(184,140,60,.1);
  border: 1px solid rgba(245,214,168,.5);
  overflow: hidden;
}
.pet-name.mini { font-size: 22px; font-weight: 700; color: var(--brand); text-shadow: 0 1px 2px rgba(232,131,58,.2); display: inline-flex; align-items: center; gap: 4px; }
.btn-icon-mini {
  font-size: 12px; padding: 2px 5px; background: #FDF6EE; border: 1px solid var(--line);
  border-radius: 6px; cursor: pointer; color: var(--ink2); transition: all .2s;
  line-height: 1;
}
.btn-icon-mini:hover { background: var(--brand); color: #fff; border-color: var(--brand); }
.speech.mini {
  background: linear-gradient(135deg, #FFF7EC, #FDF3E6);
  border: 1px solid #F5D6A8; border-radius: 11px;
  padding: 6px 14px; font-size: 14px; color: var(--ink2);
  box-shadow: 0 2px 6px rgba(232,131,58,.08);
}
/* R479：#petCanvas 用 ID 选择器，特异性高于 .pet-stage.mini canvas，故画布尺寸统一由 #petCanvas 控制 */
.pet-stage.mini canvas { filter: drop-shadow(0 12px 16px rgba(184,140,60,.2)); }

/* ---------- 宠物视觉样式切换（2d / 2.5d / 3d / pixel / cartoon / flat）---------- */
/* 迭代第6轮（#518）：新增 cartoon 卡通 / flat 扁平 两档（4→6） */
/* 2D：平面原样，柔和投影 */
.pet-stage.ps-2d { transform: none; }
.pet-stage.ps-2d canvas { image-rendering: auto; }
/* 2.5D：轻微透视抬起 + 加深投影 */
.pet-stage.ps-25d { transform: perspective(700px) rotateX(3.5deg); box-shadow: inset 0 2px 8px rgba(184,140,60,.12), 0 12px 22px rgba(184,140,60,.22); }
.pet-stage.ps-25d canvas { image-rendering: auto; filter: drop-shadow(0 12px 16px rgba(184,140,60,.28)) saturate(1.05); }
/* 3D：更强透视 + 高光边缘 */
.pet-stage.ps-3d { transform: perspective(560px) rotateX(6.5deg); box-shadow: inset 0 3px 12px rgba(184,140,60,.18), 0 20px 34px rgba(184,140,60,.3); border-color: rgba(232,131,58,.45); }
.pet-stage.ps-3d canvas { image-rendering: auto; filter: drop-shadow(0 18px 22px rgba(184,140,60,.36)) saturate(1.12) brightness(1.02); }
/* 像素风：关闭抗锯齿 + 扫描线网格叠加 */
.pet-stage.ps-pixel { image-rendering: pixelated; }
.pet-stage.ps-pixel canvas { image-rendering: pixelated; filter: drop-shadow(4px 4px 0 rgba(184,140,60,.28)); }
.pet-stage.ps-pixel::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background-image: repeating-linear-gradient(0deg, rgba(60,40,10,.06) 0 2px, transparent 2px 4px),
                    repeating-linear-gradient(90deg, rgba(60,40,10,.05) 0 2px, transparent 2px 4px);
  mix-blend-mode: multiply;
}
/* 卡通风：饱和度增强 + 粗描边感（drop-shadow 模拟描边） */
.pet-stage.ps-cartoon { transform: scale(1.04); }
.pet-stage.ps-cartoon canvas { image-rendering: auto; filter: saturate(1.5) contrast(1.08) drop-shadow(0 6px 0 rgba(184,140,60,.32)); }
/* 扁平风：去立体阴影 + 纯平填充感 */
.pet-stage.ps-flat { transform: none; box-shadow: none !important; background: rgba(255,255,255,.5) !important; }
.pet-stage.ps-flat canvas { image-rendering: auto; filter: saturate(.92) brightness(1.04) contrast(.98); }
.pet-stage { transition: transform .35s cubic-bezier(.4,0,.2,1), box-shadow .35s ease; }
.acts.mini { grid-template-columns: repeat(3, 1fr); grid-auto-rows: minmax(66px, auto); gap: 10px; margin: 12px 0 8px 0; }
.acts.mini .act { padding: 13px 6px; font-size: 18px; font-weight: 600; min-height: 68px; background: linear-gradient(135deg, #FFF7EC, #FDF3E6); border: 1.5px solid var(--line); border-radius: 13px; transition: all .2s; gap: 4px; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.acts.mini .act:hover { transform: translateY(-2px); box-shadow: 0 4px 14px rgba(232,131,58,.22); border-color: var(--brand); background: linear-gradient(135deg, #FFF0DE, #FBEAD9); }
.acts.mini .act:active { transform: translateY(0); box-shadow: 0 1px 4px rgba(232,131,58,.15); }
.acts.mini .act .ic { font-size: 34px; margin-bottom: 3px; line-height: 1; }
.bars.mini .bar-row { display: flex; align-items: center; gap: 8px; font-size: 16px; margin-bottom: 5px; }
.bars.mini .bar-fill { height: 100%; background: var(--brand); border-radius: 3px; transition: width .3s; }
.pet-settings-btn.mini { top: 8px; right: 8px; width: 32px; height: 32px; font-size: 16px; }

/* ---------- 状态面板 R2 ---------- */
/* 状态条（嵌入 pet-hub 内的紧凑展示） */
.status-strip {
  margin-top: 8px; padding-top: 8px;
  border-top: 1px dashed var(--line);
  display: flex; flex-direction: column; gap: 6px;
}
.status-strip h3 {
  font-size: 18px; font-weight: 700; color: var(--ink);
  margin: 0; display: flex; align-items: center; gap: 6px;
}
.status-stats {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px;
}
.stat-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 5px 9px; background: #FDF6EE; border: 1px solid var(--line);
  border-radius: 7px; font-size: 15px;
}
.stat-row .lb { color: var(--ink2); font-weight: 500; }
.stat-row b { color: var(--brand); font-weight: 700; font-size: 15px; }
.status-warn {
  display: none; padding: 6px 8px; background: #FFF4EC; border: 1px solid #F5C4A8;
  border-radius: 6px; font-size: 12px; color: #B05A2A; line-height: 1.5;
}
.status-warn.on { display: block; }
.status-warn.warn-mild { background: #FFF8E6; border-color: #F5D6A8; color: #8A6B2A; }
.status-warn.warn-heavy { background: #FFEEE6; border-color: #E8A48A; color: #A03A1A; }

/* 状态条内 bars 紧凑 */
.status-strip .bars.mini { margin-top: 4px; }
.status-strip .bars.mini .bar-row { margin-bottom: 6px; font-size: 15px; }
.status-strip .bars.mini .bar-row .lb { font-size: 12px; }
.status-strip .bars.mini .bar-row .val { font-size: 12px; }

/* ---------- 标签页 ---------- */
.tabs { display: flex; gap: 3px; flex-wrap: wrap; margin-bottom: 5px; }
.tab {
  padding: 10px 18px; border-radius: var(--r-md); font-size: 15px; font-weight: 600;
  color: var(--ink2); background: var(--card); border: 1.5px solid var(--line);
  transition: all .22s cubic-bezier(.4,0,.2,1); cursor: pointer; white-space: nowrap;
}
.tab:hover { border-color: var(--brand); color: var(--brand); transform: translateY(-2px); box-shadow: 0 2px 8px rgba(232,131,58,.15); }
.tab.on {
  background: linear-gradient(135deg, var(--brand), #d47632);
  color: #fff; border-color: var(--brand); box-shadow: 0 2px 8px rgba(232,131,58,.3);
}
.tab:active { transform: translateY(0); }
/* R9：10 个功能面板切换动画统一（原先仅创新舱内部区块有动画） */
.pane { display: none; }
.pane.on { display: flex; flex-direction: column; flex: 1; min-height: 0; overflow-y: auto; animation: paneEnter .28s ease-out; }

/* ---------- 四大功能主导航 + 子菜单 + 单 pane 最大化 ---------- */
.main-nav {
  grid-column: 1 / -1;              /* 横跨整行 */
  display: flex;
  gap: 10px;
  padding: 8px 10px;
  background: linear-gradient(180deg, #FFFBF5 0%, #FFF 100%);
  border: 2px solid #F5D6A8;
  border-radius: var(--r-lg);
  box-shadow: 0 2px 10px rgba(232,131,58,.12);
  flex-shrink: 0;
  position: relative;
  z-index: 5;
}
.main-nav-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 14px;
  border-radius: 12px;
  border: 2px solid var(--line);
  background: #FDF6EE;
  color: var(--ink2);
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
  transition: all .2s ease;
  position: relative;
}
.main-nav-btn .ic { font-size: 24px; line-height: 1; }
.main-nav-btn .lb { font-size: 16px; }

/* R2(HCI)：危机求助常驻按钮
   触控目标显著大于常规导航（min-height 58px vs 常规 44px）——心瘾发作时
   手指颤抖、视线模糊，Fitts 定律要求目标更大；用暖橙渐变而非警报红，
   避免触发「被管控制」的负面联想；呼吸动画只做极轻微缩放，吸引注意
   但不制造焦虑。 */
.help-btn {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 8px 14px; min-height: 58px; min-width: 84px;
  border-radius: 14px; cursor: pointer; flex-shrink: 0;
  border: 2px solid #E8792B;
  background: linear-gradient(135deg, #FF9A4D, #F07C2A);
  color: #fff; font-weight: 800; line-height: 1.15;
  box-shadow: 0 3px 10px rgba(240,124,42,.35);
  transition: transform .18s ease, box-shadow .18s ease;
  animation: helpBreath 3.6s ease-in-out infinite;
}
.help-btn .hb-ic { font-size: 22px; }
.help-btn .hb-txt { font-size: 13px; letter-spacing: .5px; }

/* 求助弹窗选项：大号易点目标（min-height 54px），选中即发送，不再二次确认 */
.help-opt {
  display: flex; align-items: center; gap: 10px; width: 100%;
  min-height: 54px; padding: 12px 16px;
  border: 2px solid var(--line); border-radius: 12px;
  background: #FDF9F3; color: var(--ink);
  font-size: 16px; font-weight: 600; text-align: left; cursor: pointer;
  transition: all .18s ease;
}
.help-opt .ho-ic { font-size: 22px; }
.help-opt:hover {
  border-color: #E8792B; background: #FFF3E6; color: var(--brand-deep);
  transform: translateX(3px);
}
.help-opt:active { transform: scale(.99); }
.help-btn:hover { transform: translateY(-2px) scale(1.03); box-shadow: 0 6px 18px rgba(240,124,42,.45); }
.help-btn:active { transform: translateY(0) scale(.98); }
@keyframes helpBreath {
  0%, 100% { box-shadow: 0 3px 10px rgba(240,124,42,.35); }
  50%      { box-shadow: 0 3px 16px rgba(240,124,42,.55); }
}
/* 尊重系统降低动效偏好（前庭障碍/易眩晕用户） */
@media (prefers-reduced-motion: reduce) {
  .help-btn { animation: none; }
}

/* R9(HCI)：极小屏保障求助入口可达。
   窄屏下 4 个导航 + 求助按钮挤在一行会互相挤压（导航文字换行、目标变小）。
   危机入口在此断点提升为「整行置顶」——最显眼、最先被看到、最易点到；
   高度调到 52px 兼顾空间，仍高于 44px 触控下限。 */
@media (max-width: 560px) {
  .main-nav { flex-wrap: wrap; }
  .help-btn { order: -1; flex: 1 1 100%; min-height: 52px; }
  .help-btn .hb-txt { font-size: 14px; }
  .help-btn .hb-txt br { display: none; }
}
.main-nav-btn .caret { font-size: 11px; color: var(--ink3); transition: transform .2s; }
.main-nav-btn:hover {
  border-color: var(--brand);
  color: var(--brand);
  transform: translateY(-2px);
  box-shadow: 0 4px 14px rgba(232,131,58,.22);
  background: linear-gradient(135deg, #FFF0DE, #FBEAD9);
}
.main-nav-btn.on {
  background: linear-gradient(135deg, #2E9E8F, #1F7A8C);
  color: #fff;
  border-color: #2E9E8F;
  box-shadow: 0 4px 14px rgba(31,122,140,.32);
}
.main-nav-btn.on .lb { color: #fff; }
.main-nav-btn.on .caret { color: rgba(255,255,255,.85); transform: rotate(180deg); }
/* R482：主导航栏「变更宠物」独立入口（直接开弹窗，不属于任何 data-group，宽度略窄于分组合键按钮） */
.main-nav-btn.pet-change-btn { flex: 0.72 1 auto; padding: 10px 12px; }
.main-nav-btn.pet-change-btn .lb { font-size: 15px; }

/* 子菜单（下拉） */
.group-menu {
  grid-column: 1 / -1;
  display: none;
  flex-wrap: wrap;
  gap: 8px;
  padding: 10px 12px;
  background: #FFFDF9;
  border: 2px solid #F5D6A8;
  border-radius: var(--r-lg);
  box-shadow: 0 4px 16px rgba(232,131,58,.14);
  flex-shrink: 0;
  position: relative;
  z-index: 4;
  animation: menuIn .22s ease-out;
}
.group-menu.on { display: flex; }
@keyframes menuIn { 0%{opacity:0;transform:translateY(-6px)} 100%{opacity:1;transform:translateY(0)} }
.gm-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 10px;
  border: 1.5px solid var(--line);
  background: #fff;
  color: var(--ink2);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: all .18s ease;
  white-space: nowrap;
}
.gm-btn .gm-ic { font-size: 18px; }
.gm-btn .gm-lb { font-size: 14px; }
.gm-btn:hover {
  border-color: var(--brand);
  color: var(--brand);
  transform: translateY(-1px);
  box-shadow: 0 3px 10px rgba(232,131,58,.18);
  background: #FFF4E4;
}
.gm-btn.on {
  background: linear-gradient(135deg, #FFF0DE, #FBEAD9);
  color: #8f4a12;
  border-color: var(--brand);
  box-shadow: 0 3px 10px rgba(192,101,32,.22);
  font-weight: 800;
}

/* 单 pane 最大化：切到某组时隐藏其他列，只显示当前组内容
   各 pane 的显隐由 JS 按分组归属控制（view-pet 只露 profile/petchange、
   view-chat 只露 talk/tools、view-func 只露本组 pane），
   这里只负责"列容器"在哪个主导航页整体可见/隐藏，避免跨页串显。 */

/* 宠物组：宠物舞台整行铺满、三栏居中撑开
   R481 关键修正：HTML 里 .right-panel / .func-panel 其实是 .main-area 的直接子元素，
   并不在 .grid-new 里面（.grid-new 只装 main-nav + pet-hub）。因此 view-* 类必须挂到
   .main-area 上、规则也必须写 .main-area.view-*，旧版 .grid-new.view-* 全部是死规则。
   R481 修正 2：.qn-btn-bar 住在 .func-panel 内部，pet 视图不能整块隐藏 func-panel，
   只能隐藏 func-overview / func-content，否则底部「小戒陪伴/我的档案/变更宠物」三按钮消失。
   R481 修正 3：.func-panel 基础样式带 height:100%，在 flex 列里会抢占全部高度把 grid-new 压成 0，
   因此 view-* 统一改用 grid + 显式 grid-row 定义，彻底绕开 height:100% 冲突。 */
/* R482：pet 视图不再需要底部按钮栏（三按钮已移除，变更宠物已迁到主导航栏），func-panel 整块隐藏 */
.main-area.view-pet { display: grid; grid-template-columns: 1fr; grid-template-rows: minmax(0, 1fr); gap: 8px; overflow: hidden; }
.main-area.view-pet .grid-new { grid-row: 1; min-height: 0; grid-template-columns: 1fr; }
.main-area.view-pet .grid-new .pet-hub { grid-column: 1 / -1; width: 100%; max-width: 1280px; margin: 0 auto; min-height: 0; justify-self: center; }
/* R533：1920×1080 宽屏适配——宠物页 hub 限宽 1280 居中，三列回合理比例；
   宠物舞台左栏设上限避免 #petCanvas/#petImg 被拉得过宽溢出，中右栏自适应铺余量 */
@media (min-width: 1400px) {
  .main-area.view-pet .pet-hub-body { justify-content: center; }
  .main-area.view-pet .pet-hub-left { flex: 0 0 460px; min-width: 0; }
  .main-area.view-pet .pet-hub-acts { flex: 1 1 280px; min-width: 220px; }
  .main-area.view-pet .pet-hub-right { flex: 1 1 320px; min-width: 240px; }
  .main-area.view-pet .pet-hub-left .pet-stage { padding: 18px; }
  .main-area.view-pet #petCanvas { max-width: 400px; }
}
.main-area.view-pet .right-panel { display: none !important; }
.main-area.view-pet .func-panel { display: none !important; }

/* 切到「我的档案 / 变更宠物」时：宠物舞台隐藏，功能面板整行铺满 */
.main-area.view-petpane { display: grid; grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); gap: 8px; overflow: hidden; }
.main-area.view-petpane .grid-new { grid-row: 1; min-height: 0; grid-template-columns: 1fr; }
.main-area.view-petpane .grid-new .pet-hub { display: none !important; }
.main-area.view-petpane .right-panel { display: none !important; }
.main-area.view-petpane .func-panel { grid-row: 2; display: flex !important; height: 100%; min-height: 0; width: 100%; }

/* 聊天组：陪伴聊天单栏占满整行（R509：去掉右侧功能面板，聊天独占） */
.main-area.view-chat { display: grid; grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); gap: 8px; overflow: hidden; }
.main-area.view-chat .grid-new { grid-row: 1; min-height: 0; grid-template-columns: 1fr; }
.main-area.view-chat .grid-new .pet-hub { display: none !important; }
.main-area.view-chat .right-panel { grid-row: 2; grid-column: 1 / -1; display: flex; flex-direction: column; gap: 8px; height: 100%; min-height: 0; overflow-y: auto; width: 100%; }
.main-area.view-chat .func-panel { display: none !important; }

/* 功能组（含测评/学习/情景等）：功能列撑满整宽 */
.main-area.view-func { display: grid; grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); gap: 8px; overflow: hidden; }
.main-area.view-func .grid-new { grid-row: 1; min-height: 0; grid-template-columns: 1fr; }
.main-area.view-func .grid-new .pet-hub,
.main-area.view-func .right-panel { display: none !important; }
.main-area.view-func .func-panel { grid-row: 2; display: flex; height: 100%; min-height: 0; width: 100%; max-width: none; }
.main-area.view-func .func-content { overflow: hidden; margin: 0 auto; }
.main-area.view-func .pane.on { overflow: hidden; }
/* R510：心理测评/工具页显示优化——内容铺满页面宽度 */
.main-area.view-func .func-content { padding: 0 12px; width: 100%; }
.main-area.view-func .func-content > .pane { width: 100%; max-width: none; margin: 0; }
/* 功能按钮栏：评估/工具组按钮均分占满整行，避免右侧留白 */
.main-area.view-func .qn-btn-bar { justify-content: center; }
/* 心理测评/工具卡片显示统一：内边距与标题间距微调，卡片间距略紧凑 */
.main-area.view-func .func-content > .pane { padding: 14px 16px; }
.main-area.view-func .func-content > .pane h3 { margin: 0 0 10px; font-size: 16px; }
/* R536：我的档案独立页——档案内容较长，本页放开纵向滚动（优先级高于 .view-func .pane.on 的 overflow:hidden） */
.main-area.view-func #p-profile { overflow-y: auto; }
.main-area.view-func #p-profile .profile-content { font-size: 14px; }
.main-area.view-func .func-overview { padding: 12px 16px; }

/* 个别谈话：保留聊天列 + 功能列里的 pane */
.main-area.view-funcwithchat { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: auto minmax(0, 1fr); gap: 8px; overflow: hidden; }
.main-area.view-funcwithchat .grid-new { grid-column: 1 / -1; grid-row: 1; min-height: 0; grid-template-columns: 1fr; }
.main-area.view-funcwithchat .grid-new .pet-hub { display: none !important; }
.main-area.view-funcwithchat .right-panel { grid-row: 2; display: flex; flex-direction: column; gap: 8px; height: 100%; min-height: 0; overflow-y: auto; width: 100%; }
.main-area.view-funcwithchat .func-panel { grid-row: 2; display: flex; height: 100%; min-height: 0; overflow: hidden; width: 100%; }

/* ---------- 横向分列容器：把模块内的按钮/字段拆成多列横排 ----------
   用法：<div class="wcols"><div class="wcol">…</div><div class="wcol">…</div></div>
   wcols=行容器，wcol=列；列内内容纵向堆叠，列间横向铺开 */
.wcols {
  display: flex;
  gap: 14px;
  margin: 8px 0;
  align-items: stretch;
}
.wcol {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
/* 两列均分（默认），可用 .wcols-3/.wcols-4 微调列数 */
.wcols .wcol { flex: 1 1 0; }
.wcols-3 .wcol { flex: 1 1 0; }
.wcols-4 .wcol { flex: 1 1 0; }
/* 列内的卡片去外层间距，紧凑排布 */
.wcol .card { margin-bottom: 6px; }
.wcol > .inno-empty { align-self: flex-start; }
/* 小屏：单列堆叠 */
@media (max-width: 760px) {
  .wcols { flex-direction: column; }
  .wcol { width: 100%; }
}

/* ---------- 聊天区域 ---------- */
.chat-header {
  padding: 8px 12px; background: linear-gradient(135deg, var(--brand), #D47632);
  color: #fff; border-radius: var(--r-lg) var(--r-lg) 0 0;
  margin: -12px -12px 4px -12px; box-shadow: 0 2px 8px rgba(232,131,58,.2); flex-shrink: 0;
  display: flex; align-items: center; gap: 10px;
}
.chat-title-grp { flex: 1; min-width: 0; overflow: hidden; }
.chat-title { font-size: 20px; font-weight: 700; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-subtitle { font-size: 12px; opacity: .85; display: block; margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 字号控制：大号白色半透明按钮，在橙底渐变上清晰可见 */
.font-control { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.fc-btn {
  /* R5(HCI): 38px → 42px。聊天头部纵向空间受限，42px 是可达标与不撑高
     标题栏之间的折衷；该组控件用于字号微调，非危机路径，可接受 42px。 */
  width: 42px; height: 42px; border-radius: 10px; cursor: pointer; font-size: 18px; font-weight: 700; line-height: 1;
  border: 2px solid rgba(255,255,255,.7); background: rgba(255,255,255,.3); color: #fff;
  display: flex; align-items: center; justify-content: center; transition: all .18s;
  box-shadow: 0 2px 6px rgba(0,0,0,.15); text-shadow: 0 1px 2px rgba(0,0,0,.2);
}
.fc-btn:hover { background: rgba(255,255,255,.55); border-color: #fff; transform: translateY(-1px); box-shadow: 0 4px 10px rgba(0,0,0,.2); }
.fc-btn:active { transform: translateY(0) scale(.95); box-shadow: 0 1px 3px rgba(0,0,0,.15); }
.fc-btn.fc-reset { font-size: 17px; }
.fc-val { font-size: 14px; font-weight: 600; min-width: 40px; text-align: center; color: #fff; font-variant-numeric: tabular-nums; text-shadow: 0 1px 2px rgba(0,0,0,.25); }
.chat-clear { flex-shrink: 0; }
.chat-clear:hover { background: rgba(255,255,255,.25); color: #fff; border-color: rgba(255,255,255,.6); }
/* 迭代第4轮（#516）：字号4档预设 / 行距3档 / 聊天专注模式 */
.font-preset-bar, .line-height-bar { display: flex; gap: 4px; align-items: center; margin: 4px 0; padding: 4px 6px; background: rgba(255,255,255,.15); border-radius: 8px; flex-wrap: wrap; }
.fp-btn, .lh-btn { min-width: 34px; height: 30px; padding: 0 10px; border-radius: 8px; border: 1.5px solid rgba(255,255,255,.55); background: rgba(255,255,255,.25); color: #fff; font-size: 13px; font-weight: 600; cursor: pointer; transition: all .18s; }
.fp-btn:hover, .lh-btn:hover { background: rgba(255,255,255,.5); border-color: #fff; transform: translateY(-1px); }
.fp-btn.on, .lh-btn.on { background: #fff; color: var(--ink); border-color: #fff; box-shadow: 0 2px 8px rgba(0,0,0,.18); }
.chat-focus-btn { flex-shrink: 0; background: rgba(255,255,255,.25); color: #fff; border-color: rgba(255,255,255,.5); }
.chat-focus-btn.on { background: #fff; color: var(--ink); border-color: #fff; }
.chat-focus-mode .right-panel { flex: 1; }
.chatbox {
  flex: 1; overflow-y: auto; padding: 8px 10px;
  background: transparent; border: none; border-radius: 0;
  box-shadow: inset 0 2px 8px rgba(0,0,0,.03);
  min-height: 0;
}
.msg { margin-bottom: 8px; display: flex; gap: 8px; align-items: flex-start; justify-content: flex-start; animation: msgIn .25s ease-out; }
@keyframes msgIn { 0%{opacity:0;transform:translateY(8px)} 100%{opacity:1;transform:translateY(0)} }
.msg.me { justify-content: flex-end; }
.msg.me .bub { margin-right: auto; }
.msg .ava {
  width: 38px; height: 38px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center;
  justify-content: center; font-size: 15px; font-weight: 600; color: #fff;
  background: linear-gradient(135deg, var(--brand2), #3BB5A3);
  box-shadow: 0 2px 8px rgba(46,158,143,.25); animation: avaPulse 2s ease-in-out infinite;
}
@keyframes avaPulse { 0%,100%{transform:scale(1)} 50%{transform:scale(1.05)} }
.msg.me .ava { background: linear-gradient(135deg, var(--brand), #D47632); order: 2; animation: none; }
.msg .bub {
  background: #fff; border: 1px solid var(--line); border-radius: 14px 14px 14px 4px;
  padding: 12px 16px; max-width: min(82%, 40em); min-width: 0; font-size: 18px; line-height: 1.65;
  white-space: pre-wrap; word-break: break-word; box-shadow: 0 1px 4px rgba(58,50,38,.06); transition: all .2s;
}
.msg .bub:hover { box-shadow: 0 2px 8px rgba(58,50,38,.1); }
/* 消息内容列：承载气泡+来源+meta，定宽避免气泡 max-width 循环依赖塌缩（修复文字几个字换行） */
/* R16(HCI)：行宽（measure）控制。
   中文阅读的最优 measure 约 30–40 字/行；此前固定 82% 在宽屏（大屏一体机）
   下会拉到 45 字以上，眼睛回扫成本上升、长文更不愿读。
   用 min() 取「比例」与「40em≈40字」的较小值：窄屏仍按比例收缩，宽屏封顶。 */
.msg-col { display: flex; flex-direction: column; min-width: 0; max-width: min(82%, 40em); align-items: flex-start; }
.msg-col .bub { max-width: 100%; }
.msg.me .msg-col { margin-left: auto; align-items: flex-end; }
.msg .bub.me { background: linear-gradient(135deg, #FFF3E7, #FFE8D0); border-color: #F6DCC4; border-radius: 14px 14px 4px 14px; }
.msg .bub.guard { background: #FFF0EE; border-color: #F3C9C2; color: #8C4A3E; }
/* R527: 打字机光标闪烁（.typ 期间尾部显示竖线） */
.msg .bub.typ { position: relative; }
.msg .bub.typ::after { content: '▌'; color: #E08C4A; margin-left: 1px; animation: typCursor 1s steps(2) infinite; opacity: .85; }
@keyframes typCursor { 0%,49% { opacity: .85; } 50%,100% { opacity: 0; } }
/* R527: guard-flag 复用 guard 配色（打字机完成后给安全类回复打标） */
.msg .bub.guard-flag { background: #FFF0EE; border-color: #F3C9C2; color: #8C4A3E; }
.msg .src { font-size: 13px; color: var(--ink2); margin-top: 4px; }

/* R7: 助手回复 meta 标签（主题/技术/阶段）与敏感告警标签 */
.meta-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 5px; }
.meta-chip {
  font-size: 12px; line-height: 1; padding: 3px 9px; border-radius: 20px;
  background: #F5EEE6; color: var(--ink2); border: 1px solid #EDE1D2;
}
.meta-chip.tech { background: #EAF4EE; color: #3E7D5B; border-color: #CBE5D5; }
.meta-chip.stage { background: #EEF1FA; color: #4A5A8C; border-color: #D5DCF2; }
.meta-chip.model { background: #F3F0FA; color: #6B5B8C; border-color: #DDD5F2; }
.meta-chip.warn {
  background: #FCEBE8; color: #B5432F; border-color: #F3C9C2;
  font-weight: 600; box-shadow: 0 1px 3px rgba(181,67,47,.15);
}

/* R61: 消息分组与时间分隔线 */
.msg-group { display: flex; flex-direction: column; gap: 2px; }
.msg-group .msg { margin-bottom: 0; }
.msg-group .msg.first .ava { display: flex; }
.msg-group .msg.first .bub { border-radius: 14px 14px 14px 4px; }
.msg-group .msg.me.first .bub { border-radius: 14px 14px 4px 14px; }
.msg-group .msg.last .ava { display: none; }
.msg-group .msg.last .bub { border-radius: 4px 14px 14px 14px; }
.msg-group .msg.me.last .bub { border-radius: 14px 4px 14px 14px; }
.msg-time-sep {
  text-align: center; font-size: 12px; color: var(--ink3);
  margin: 12px 0 8px; user-select: none;
}
.msg-time-sep span {
  background: rgba(255,255,255,.7); padding: 2px 10px;
  border-radius: 10px; border: 1px solid var(--line);
}

/* R61: 打字指示器动画 */
.typing-dots { display: inline-flex; gap: 3px; align-items: center; padding: 4px 0; }
.typing-dots span {
  width: 6px; height: 6px; border-radius: 50%; background: var(--ink2);
  animation: typingBounce 1.2s ease-in-out infinite;
}
.typing-dots span:nth-child(2) { animation-delay: .2s; }
.typing-dots span:nth-child(3) { animation-delay: .4s; }
@keyframes typingBounce { 0%,60%,100%{transform:translateY(0)} 30%{transform:translateY(-6px)} }

/* 输入行 */

/* 输入行 */
.input-row {
  display: flex; gap: 8px; padding: 10px 14px;
  background: linear-gradient(180deg, #FFF 0%, #FFFBF5 100%);
  border-top: 2px solid #F5D6A8;
  position: sticky; bottom: 0; z-index: 10;
  border-radius: 0 0 12px 12px; box-shadow: 0 -2px 8px rgba(232,131,58,.08);
}
.input-row input {
  flex: 1; padding: 10px 16px; border: 1px solid var(--line);
  border-radius: 20px; font-size: 16px; outline: none;
  transition: border-color .2s, box-shadow .2s;
}
.input-row input:focus { border-color: var(--brand); box-shadow: 0 0 0 4px rgba(232,131,58,.12); background: #fff; }

.quick { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.quick button {
  padding: 7px 14px; border-radius: 20px; background: #F5EEE6; font-size: 14px; color: var(--ink2);
  border: 1px solid transparent; transition: all .25s cubic-bezier(.4,0,.2,1);
}
.quick button:hover { border-color: var(--brand); color: var(--brand); background: #FFF3E7; transform: translateY(-1px); }

/* R6: 表情快捷区 */
.chat-emoji-row { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 6px; padding: 0; max-height: 92px; overflow-y: auto; }
.emoji-chip {
  font-size: 18px; line-height: 1; padding: 5px 8px; min-width: 34px; text-align: center;
  border-radius: 10px; background: #F5EEE6; border: 1px solid transparent; cursor: pointer;
  transition: all .18s ease; color: inherit;
}
.emoji-chip:hover { border-color: var(--brand); background: #FFF3E7; transform: translateY(-1px) scale(1.06); }
.emoji-chip:active { transform: scale(.94); }

/* R8: 聊天记录检索 */
.chat-search-row { display: flex; gap: 6px; margin-top: 8px; align-items: center; }
.chat-search-row input {
  flex: 1; padding: 8px 12px; font-size: 14px; border-radius: 12px;
  border: 1px solid #EDE1D2; background: #FAF6F0; outline: none; color: var(--ink);
}
.chat-search-row input:focus { border-color: var(--brand); box-shadow: 0 0 0 4px rgba(232,131,58,.12); background: #fff; }
.chat-search-panel {
  max-height: 220px; overflow-y: auto; margin-top: 8px;
  border: 1px solid #F0E6D8; border-radius: 12px; background: #FFFCF8; padding: 8px 4px;
}
.chat-search-head { font-size: 13px; color: var(--ink2); padding: 2px 8px 6px; border-bottom: 1px solid #F3EBDD; margin-bottom: 4px; }
.chat-search-list { list-style: none; margin: 0; padding: 0; }
.chat-search-empty { font-size: 13px; color: var(--ink3); padding: 8px; }
.chat-search-item { padding: 7px 8px; border-radius: 8px; display: flex; flex-direction: column; gap: 2px; }
.chat-search-item.me { background: #FFF7EE; }
.chat-search-item + .chat-search-item { margin-top: 3px; }
.chat-search-item .cs-who { font-size: 12px; color: var(--ink3); font-weight: 600; }
.chat-search-item .cs-text { font-size: 14px; color: var(--ink); line-height: 1.5; word-break: break-word; }
.chat-search-item .cs-time { font-size: 11px; color: var(--ink3); }
.chat-search-flag { font-size: 11px; color: #B5432F; background: #FCEBE8; padding: 1px 6px; border-radius: 8px; margin-left: 4px; }
.chat-search-item mark.kw-hit { background: #FFE28A; color: #5A4300; padding: 0 2px; border-radius: 3px; }

/* R9: 输入联想补全下拉 */
.chat-suggest {
  position: absolute; left: 0; right: 0; bottom: 100%; margin-bottom: 6px;
  max-height: 176px; overflow-y: auto; z-index: 60;
  background: #fff; border: 1px solid #F0E6D8; border-radius: 12px;
  box-shadow: 0 4px 16px rgba(80,58,38,.14); padding: 4px;
}
.chat-suggest button {
  display: block; width: 100%; text-align: left; padding: 8px 10px; font-size: 14px;
  border: none; background: transparent; cursor: pointer; border-radius: 8px; color: var(--ink);
}
.chat-suggest button:hover { background: #FFF3E7; color: var(--brand); }
.chat-suggest button mark.kw-hit { background: #FFE28A; color: #5A4300; padding: 0 2px; border-radius: 3px; }
.quick button:active { transform: translateY(0) scale(.96); }
/* 对话快捷回复区：系统快捷 + 自定义快捷 合并成一条（外层横滚） */
.chat-quick-wrap {
  display: flex; gap: 6px; align-items: center; overflow-x: auto;
  padding: 6px 12px; background: #FFFBF5; border-top: 1px solid #FAE7D3;
  scrollbar-width: thin;
}
.chat-quick-wrap::-webkit-scrollbar { height: 4px; }
.chat-quick-wrap::-webkit-scrollbar-thumb { background: #EFCBA6; border-radius: 4px; }
.chat-quick-wrap .chat-quick { display: contents; }
.chat-quick-wrap .custom-quick-container {
  display: flex; flex-wrap: nowrap; gap: 6px; flex-shrink: 0;
}
/* 自定义快捷回复按钮（与系统快捷按钮同款圆角胶囊） */
.custom-quick-container .quick {
  flex-shrink: 0; padding: 5px 12px; border-radius: 16px; background: #F3EBE0;
  font-size: 13px; color: var(--ink2); border: 1px solid var(--line); cursor: pointer;
  transition: all .2s; white-space: nowrap;
}
.custom-quick-container .quick:hover { border-color: var(--brand); color: var(--brand); background: #FFF3E7; }
.custom-quick-container .quick.del {
  padding: 2px 8px; font-size: 11px; background: #fff; color: var(--warn);
  border: 1px solid #f5c8b8; border-radius: 10px; cursor: pointer;
}
.custom-quick-container .quick.del:hover { background: var(--warn); color: #fff; }

/* 对话快捷回复条（旧独立条样式保留兼容） */
.chat-quick {
  display: flex; gap: 6px; flex-wrap: nowrap; overflow-x: auto; padding: 6px 12px;
  background: #FFFBF5; border-top: 1px solid #FAE7D3; scrollbar-width: thin;
}
.chat-quick::-webkit-scrollbar { height: 4px; }
.chat-quick::-webkit-scrollbar-thumb { background: #EFCBA6; border-radius: 4px; }
.chat-quick button {
  flex-shrink: 0; padding: 5px 12px; border-radius: 16px; background: #F5EEE6; font-size: 13px;
  color: var(--ink2); border: 1px solid transparent; cursor: pointer; transition: all .2s;
  white-space: nowrap;
}
.chat-quick button:hover { border-color: var(--brand); color: var(--brand); background: #FFF3E7; transform: translateY(-1px); }
.chat-quick button.sent {
  background: linear-gradient(135deg, var(--brand), #D47632); color: #fff; border-color: transparent;
  transform: translateY(-1px) scale(1.03); box-shadow: 0 2px 8px rgba(232,131,58,.3);
}

/* 自定义快捷回复 */
.custom-quick-item { display: flex; align-items: center; gap: 4px; }
.custom-quick-item .btn { font-size: 14px; }
/* 迭代第5轮（#517）：快捷回复拖拽排序 + 批量操作 */
.cq-drag { padding: 4px 6px; border-radius: 8px; transition: all .15s; cursor: grab; }
.cq-drag.dragging { opacity: .4; background: rgba(255,255,255,.5); }
.cq-drag.drag-over { border: 1.5px dashed var(--brand); background: rgba(255,248,241,.7); }
.cq-drag-hdl { color: var(--ink3); font-size: 14px; cursor: grab; user-select: none; }
.cq-chk { display: flex; align-items: center; }
.cq-bulk .btn { font-size: 12px; }
/* 迭代第7轮（#519）：快捷回复预设包弹窗 */
.preset-item {
  display: flex; align-items: center; gap: 12px; padding: 12px 14px;
  background: linear-gradient(135deg, #FFF8F1, #F2FAF7);
  border: 1px solid var(--line); border-radius: var(--r-md);
  cursor: pointer; transition: all .2s; text-align: left;
}
.preset-item:hover { transform: translateY(-2px); border-color: var(--brand); box-shadow: 0 6px 16px rgba(232,131,58,.2); }
.preset-item:active { transform: translateY(0); }
#quickPresetBtn { margin-top: 6px; }

/* 主题色选择器 */
.theme-selector { display: flex; justify-content: center; gap: 8px; margin: 8px 0; }
.theme-btn { width: 38px; height: 38px; border-radius: 50%; border: 2px solid var(--line); cursor: pointer; font-size: 17px; display: flex; align-items: center; justify-content: center; transition: all .2s; }
.theme-btn:hover { transform: scale(1.1); }
.theme-btn.on { border-color: var(--brand); box-shadow: 0 0 0 2px rgba(232,131,58,.3); }
.theme-btn[data-theme="warm"] { background: #E8833A; }
.theme-btn[data-theme="cool"] { background: #4A9BD4; }
.theme-btn[data-theme="rose"] { background: #D96A5B; }
.theme-btn[data-theme="forest"] { background: #3E8E5A; }
.theme-btn[data-theme="lavender"] { background: #9B7BC4; }
/* 迭代第2轮（#514）：新增 4 款主题按钮配色 */
.theme-btn[data-theme="ocean"] { background: #1F7A8C; }
.theme-btn[data-theme="gold"] { background: #B8862B; }
.theme-btn[data-theme="plum"] { background: #8E4B74; }
.theme-btn[data-theme="slate"] { background: #5A6B7B; }

/* ================= 答题 ================= */
.q-cat { display: inline-block; padding: 3px 11px; border-radius: 12px; font-size: 13px; background: #EAF6F3; color: var(--brand2); margin-bottom: 7px; }
.q-text { font-size: 19px; line-height: 1.7; margin-bottom: 6px; font-weight: 500; }
.opts { display: flex; flex-direction: column; gap: 3px; }
.opt {
  padding: 7px 12px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: #FDFBF8; text-align: left; font-size: 16px; transition: all .16s; line-height: 1.6;
}
.opt:hover { border-color: var(--brand); background: #FFF8F1; transform: translateX(3px); box-shadow: 0 2px 8px rgba(232,131,58,.1); }
.opt.right { background: #EDF7EF; border-color: #8CC79C; color: #2F6B42; }
.opt.wrong { background: #FCEFEC; border-color: #E5A99D; color: #8C4A3E; }
.opt:disabled { cursor: default; }
.explain { margin-top: 8px; padding: 7px 11px; background: #F7F4EF; border-radius: var(--r-sm); font-size: 15px; color: var(--ink2); line-height: 1.55; border-left: 3px solid var(--brand); }
.explain b { color: var(--ink); }
/* R2：解析条对错动画 */
.explain.ok-anim { border-left-color: var(--ok); background: #F0F8F1; animation: okPulse .5s ease; }
.explain.no-anim { border-left-color: var(--warn); background: #FDF3EE; animation: noShake .45s ease; }
@keyframes okPulse { 0%{transform:scale(.97);box-shadow:0 0 0 0 rgba(93,176,120,.35)} 60%{transform:scale(1.01)} 100%{transform:scale(1);box-shadow:0 0 0 10px rgba(93,176,120,0)} }
@keyframes noShake { 0%,100%{transform:translateX(0)} 20%{transform:translateX(-6px)} 40%{transform:translateX(5px)} 60%{transform:translateX(-4px)} 80%{transform:translateX(3px)} }
.explain-actions { display: flex; gap: 6px; margin-top: 8px; }
/* R2：题头统计条 */
.quiz-stats {
  display: flex; align-items: center; justify-content: space-between; gap: 4px;
  padding: 6px 10px; margin-bottom: 6px; border-radius: var(--r-sm);
  background: linear-gradient(135deg, #F2FAF7, #FFF8F1); border: 1px solid #E3EFE9;
}
.quiz-stats .qs-item { flex: 1; display: flex; flex-direction: column; align-items: center; line-height: 1.25; }
.quiz-stats .qs-num { font-size: 18px; font-weight: 700; color: var(--brand2); font-variant-numeric: tabular-nums; }
.quiz-stats .qs-lbl { font-size: 11px; color: var(--ink3); }
.quiz-stats .qs-sep { width: 1px; height: 26px; background: var(--line); }
/* R62: 错题本标签样式 */
.wrong-tag {
  display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 500;
  background: rgba(232,131,58,.1); color: var(--brand); margin-right: 4px;
}
.wrong-tag.mastered { background: rgba(46,158,143,.1); color: var(--brand2); text-decoration: line-through; }
.wrong-list-item {
  padding: 12px; border: 1px solid var(--line); border-radius: 8px; margin-bottom: 10px;
  background: #FDFBF8; transition: all 0.2s;
}
.wrong-list-item:hover { border-color: var(--brand); box-shadow: 0 2px 8px rgba(232,131,58,.1); }
.wrong-list-item.mastered { opacity: 0.6; }
.wrong-list-header {
  display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px;
}
.wrong-list-actions { display: flex; gap: 6px; }
.wrong-list-actions button { padding: 4px 10px; font-size: 12px; }
.badge-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 5px; margin-left: 6px; border-radius: 10px;
  background: #E4604E; color: #fff; font-size: 11px; font-weight: 700; vertical-align: middle;
  box-shadow: 0 1px 4px rgba(228,96,78,.4);
}
/* R2：答题整块反馈 */
#quizArea.quiz-ok { animation: okPulse .5s ease; }
#quizArea.quiz-no { animation: noShake .45s ease; }
/* R2：实心按钮（下一题主操作） */
.btn-solid { background: linear-gradient(135deg, var(--brand), #D47632); color: #fff; border: none; box-shadow: 0 2px 8px rgba(232,131,58,.25); }
.btn-solid:hover { filter: brightness(1.05); transform: translateY(-1px); }
/* R21: 品牌色按钮变体 */
.btn-brand2 { background: var(--brand2); color: #fff; border: 1.5px solid var(--brand2); }
.btn-brand2:hover { filter: brightness(1.08); transform: translateY(-1px); }
.btn-warn { background: var(--warn); color: #fff; border: 1.5px solid var(--warn); }
.btn-warn:hover { filter: brightness(1.08); transform: translateY(-1px); }
.btn-clean { background: var(--clean); color: #fff; border: 1.5px solid var(--clean); }
.btn-clean:hover { filter: brightness(1.08); transform: translateY(-1px); }
/* R21: 视觉一致性 — 工具类与通用样式 */
.text-warn    { color: var(--warn); }
.text-ok      { color: var(--ok); }
.text-brand   { color: var(--brand); }
.text-ink2    { color: var(--ink2); }
.text-ink3    { color: var(--ink3); }
.bg-muted     { background: var(--bg-muted); }
.bg-ok        { background: var(--bg-ok); }
.bg-warn      { background: var(--bg-warn); }
.bg-error     { background: var(--bg-error); }
.border-base  { border: 1px solid var(--border); }
.flex-between { display: flex; justify-content: space-between; align-items: center; }
.flex-end     { display: flex; align-items: flex-end; gap: 8px; }
.font-sm      { font-size: 12px; }
.font-xs      { font-size: 11px; }
.font-body    { font-size: 15px; }
.font-label   { font-size: 13px; }
.pt-8         { padding: 8px; }
.pt-10        { padding: 10px; }
.pd-12        { padding: 12px; }
.mb-4         { margin-bottom: 4px; }
.mb-6         { margin-bottom: 6px; }
.mb-8         { margin-bottom: 8px; }
.mb-10        { margin-bottom: 10px; }
.mt-4         { margin-top: 4px; }
.mt-6         { margin-top: 6px; }
.mt-8         { margin-top: 8px; }
.mt-10        { margin-top: 10px; }
.mt-12        { margin-top: 12px; }
.mx-auto      { margin-left: auto; margin-right: auto; }
.text-center  { text-align: center; }
.radius-sm    { border-radius: 6px; }
.radius-md    { border-radius: 8px; }
.w-100        { width: 100%; }
.h-100        { height: 100%; }
.hidden       { display: none; }
.d-flex       { display: flex; }
.btn-brand    { background: var(--brand); color: #fff; border: 1.5px solid var(--brand); box-shadow: 0 2px 8px rgba(232,131,58,.15); }
.btn-brand:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(232,131,58,.3); }
.pill-brand   { background: var(--brand); color: #fff; }
.prog-line { font-size: 14px; color: var(--ink2); margin-bottom: 7px; }
.next-row { margin-top: 8px; display: flex; gap: 4px; }

/* ================= 配对游戏 ================= */
.match-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.mcol { display: flex; flex-direction: column; gap: 6px; }
.mitem { padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: #FDFBF8; font-size: 15px; cursor: pointer; transition: all .16s; line-height: 1.5; }
.mitem:hover { border-color: var(--brand); background: #FFF8F1; transform: translateX(2px); }
.mitem.sel { background: #FFF3E7; border-color: var(--brand); box-shadow: 0 0 0 2px rgba(232,131,58,.15); }
.mitem.ok { background: #EDF7EF; border-color: #8CC79C; box-shadow: 0 0 0 2px rgba(93,176,120,.18); }
.mitem.no { background: #FCEFEC; border-color: #E5A99D; box-shadow: 0 0 0 2px rgba(228,96,78,.14); }
.mitem.locked { cursor: default; opacity: .85; }
.mitem.locked.ok { opacity: 1; }
.mitem.locked.no { opacity: 1; }
/* R3：配对进度条 */
.match-prog { margin-bottom: 10px; }
.match-prog-text { display: flex; justify-content: space-between; align-items: baseline; font-size: 13px; margin-bottom: 5px; }
.match-prog-text #matchProgText { color: var(--brand2); font-weight: 700; }
.match-prog-hint { color: var(--ink3); font-size: 12px; }
.match-prog-bar { height: 7px; background: #EFE7DE; border-radius: 4px; overflow: hidden; }
.match-prog-fill { height: 100%; border-radius: 4px; background: linear-gradient(90deg, var(--brand), #D47632); transition: width .3s ease; }

/* ================= 任务 ================= */
.task {
  display: flex; align-items: center; gap: 8px; padding: 9px 12px;
  border: 1px solid var(--line); border-radius: var(--r-lg); margin-bottom: 4px;
  background: #FDFBF8; transition: all .25s cubic-bezier(.4,0,.2,1);
}
.task:hover { box-shadow: 0 4px 16px rgba(58,50,38,.1); transform: translateY(-2px); }
.task .info { flex: 1; }
.task .nm { font-size: 16px; font-weight: 600; }
.task .ds { font-size: 14px; color: var(--ink2); line-height: 1.5; }
.task.done { background: #F3F9F4; border-color: #CBE3D2; }
.task-bar { height: 6px; background: var(--line); border-radius: 3px; margin-top: 5px; overflow: hidden; }
.task-bar-fill { height: 100%; background: linear-gradient(90deg, var(--brand), var(--brand2)); border-radius: 2px; transition: width .4s ease; }

/* ================= 徽章 ================= */
.badges { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 9px; }
.badge-card {
  padding: 10px 12px; border-radius: var(--r-md); background: #FBF3E9; border: 1px solid #EFDCC4;
  font-size: 15px; display: flex; align-items: center; gap: 9px; transition: all .2s;
}
.badge-card:hover:not(.locked) { transform: translateY(-3px); box-shadow: 0 6px 16px rgba(0,0,0,.1); }
.badge-ic { font-size: 26px; flex-shrink: 0; line-height: 1; width: 26px; text-align: center; }
.badge-info { flex: 1; min-width: 0; }
.badge-name { font-weight: 600; color: var(--ink); }
.badge-desc { font-size: 12.5px; color: var(--ink2); margin-top: 3px; line-height: 1.4; }
/* 已获得：温暖的金橙渐变 + 金色星标，视觉一眼区分 */
.badge-card.got {
  background: linear-gradient(135deg, #FFF6E9 0%, #FFE9C9 100%);
  border-color: #F2C57C; box-shadow: 0 2px 8px rgba(232,131,58,.12);
}
.badge-card.got .badge-ic { color: #E8A33A; }
.badge-card.got .badge-name { color: #8A4B12; }
.badge-card.got { animation: badgeUnlock .5s ease-out; }
/* 未获得：灰底 + 锁标，明显弱化、弱化到“未解锁”一目了然 */
.badge-card.locked { background: #F6F4F1; border-color: #E7E2DB; opacity: .92; }
.badge-card.locked .badge-ic { filter: grayscale(1) opacity(.5); }
.badge-card.locked .badge-name { color: var(--ink2); }
.badge-card.locked .badge-desc { color: var(--ink3); }
@keyframes badgeUnlock { 0%{transform:scale(0.8) rotate(-5deg);opacity:0} 60%{transform:scale(1.1) rotate(3deg)} 100%{transform:scale(1) rotate(0deg);opacity:1} }
/* R2：新解锁徽章高亮辉光（renderBadges 已打 .just-unlocked 标记，此前无样式） */
.badge-card.just-unlocked {
  animation: badgeJustUnlocked 1.2s ease-out;
  box-shadow: 0 0 0 3px rgba(232,131,58,.35), 0 6px 18px rgba(232,131,58,.25);
  border-color: var(--brand);
}
/* R6：徽章卡片可点击展开条件详情 */
.badge-card { cursor: pointer; }
.badge-card:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.badge-detail { display: none; margin-top: 6px; font-size: 12.5px; color: var(--ink2); line-height: 1.5; }
.badge-card.open .badge-detail { display: block; animation: fadeInUp .25s ease; }
@keyframes badgeJustUnlocked {
  0% { transform: scale(.85); opacity: 0; box-shadow: 0 0 0 6px rgba(232,131,58,.5); }
  50% { transform: scale(1.06); }
  100% { transform: scale(1); opacity: 1; }
}
/* R2：各徽章组完成度小进度条 */
.badge-group-bar {
  height: 6px; border-radius: 4px; background: #EFE8DE; overflow: hidden; margin: 2px 0 6px;
}
.badge-group-fill {
  height: 100%; border-radius: 4px; background: linear-gradient(90deg, #E8833A, #2E9E8F);
  transition: width .6s ease;
}
/* R2：顶部解锁率进度条过渡动画 */
.bs-fill { transition: width .6s ease; }
/* R3：战斗结果「再来一局」按钮入场 */
.battle-again-btn { animation: fadeInUp .4s ease; margin-left:auto;margin-right:auto;display:block; }

/* 任务完成动画 */

/* 数据刷新动画 */

/* ================= 民警端 ================= */
table { width: 100%; border-collapse: collapse; font-size: 16px; }
th, td { padding: 8px 10px; text-align: left; border-bottom: 1px solid var(--line); }
th { color: var(--ink2); font-weight: 500; font-size: 14px; background: #FBF7F2; }
tr:hover td { background: #FDFAF6; }
.lv { display: inline-block; padding: 3px 11px; border-radius: 11px; font-size: 14px; }
.lv.high { background: #FCE7E2; color: #A33B2A; }
.lv.medium { background: #FBF0DC; color: #96642A; }
.lv.handled { background: #EDF7EF; color: #3E8E5A; }
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin-bottom: 6px; }
@media (max-width: 700px) { .stats { grid-template-columns: repeat(2, 1fr); } }
.stat { background: var(--card); border-radius: var(--r-md); padding: 10px 12px; box-shadow: var(--sh); }
.stat .n { font-size: 28px; font-weight: 600; line-height: 1.3; }
.stat .l { font-size: 14px; color: var(--ink2); }
.admin-input { width: 100%; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--r-sm); margin-bottom: 5px; background: #fff; outline: none; font-size: 15px; }

/* ================= 数据看板 ================= */
.legend { display: flex; gap: 16px; font-size: 12px; color: var(--ink2); margin-bottom: 6px; }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
.chart { display: flex; align-items: flex-end; gap: 6px; height: 200px; padding: 10px 4px; border-bottom: 1px solid var(--line); }
.chart .col { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; }
.chart .bars { display: flex; align-items: flex-end; gap: 3px; height: 170px; width: 100%; justify-content: center; }
.chart .bars span { width: 9px; border-radius: 3px 3px 0 0; min-height: 2px; transition: height .3s; }
.chart .x { font-size: 10px; color: var(--ink2); margin-top: 5px; writing-mode: horizontal-tb; }
.dash-summary { margin-top: 12px; font-size: 13px; color: var(--ink2); }
.dash-summary b { color: var(--brand); font-size: 15px; }

/* ================= 怪兽战斗系统 ================= */
.battle-status {
  background: linear-gradient(135deg, #fff5f5 0%, #ffe8e8 100%);
  border-radius: var(--r-md); padding: 8px; margin-bottom: 4px; text-align: center;
}
.battle-status p { margin: 4px 0; font-size: 16px; color: var(--ink2); }
.battle-status b { color: var(--warn); font-size: 20px; }
#startBattleBtn {
  width: 100%; padding: 10px; font-size: 18px; font-weight: 600;
  background: linear-gradient(135deg, var(--warn) 0%, #c0392b 100%);
  color: #fff; border-radius: var(--r-lg); transition: all .3s;
}
#startBattleBtn:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(217,106,91,.4); }
#startBattleBtn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }
.monster-display {
  text-align: center; padding: 10px;
  background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
  border-radius: var(--r-lg); margin-bottom: 8px; position: relative; overflow: hidden;
}
.monster-emoji { font-size: 72px; animation: monsterFloat 2s ease-in-out infinite; display: block; }
@keyframes monsterFloat { 0%,100%{transform:translateY(0) scale(1)} 50%{transform:translateY(-10px) scale(1.05)} }
.monster-name { color: #fff; font-size: 20px; font-weight: 600; margin-top: 6px; }
.monster-desc { color: #999; font-size: 15px; margin-top: 3px; }
.monster-hp-bar { background: #333; border-radius: 10px; height: 10px; margin-top: 6px; overflow: hidden; position: relative; }
.monster-hp-fill { height: 100%; background: linear-gradient(90deg, #e74c3c 0%, #c0392b 100%); border-radius: 10px; transition: width .5s ease; }
.monster-hp-text { color: #fff; font-size: 14px; margin-top: 3px; text-align: center; }
.battle-progress {
  background: #f8f9fa; border-radius: var(--r-md); padding: 8px; margin-bottom: 8px;
  display: flex; justify-content: space-between; align-items: center;
}
.battle-progress-item { text-align: center; }
.battle-progress-item .num { font-size: 28px; font-weight: 700; color: var(--brand); }
.battle-progress-item .label { font-size: 14px; color: var(--ink2); }
.question-display {
  background: #fff; border: 2px solid var(--line); border-radius: var(--r-md); padding: 10px; margin-bottom: 4px;
  box-shadow: 0 2px 8px rgba(58,50,38,.06);
}
.question-display .q-text { font-size: 20px; font-weight: 600; margin-bottom: 8px; line-height: 1.7; }
.question-display .opts { display: flex; flex-direction: column; gap: 6px; }
.question-display .opt {
  padding: 8px 14px; border: 2px solid var(--line); border-radius: var(--r-md);
  text-align: left; font-size: 16px; transition: all .25s cubic-bezier(.4,0,.2,1); background: #fafafa;
}
.question-display .opt:hover:not(:disabled) { border-color: var(--brand); background: #FFF8F1; transform: translateX(4px); box-shadow: 0 2px 8px rgba(232,131,58,.12); }
.question-display .opt:disabled { cursor: not-allowed; opacity: 0.7; }
.question-display .opt.correct { border-color: var(--ok); background: #e8f5e9; color: var(--ok); }
.question-display .opt.wrong { border-color: var(--warn); background: #ffebee; color: var(--warn); }
#battleFeedback { margin-top: 8px; padding: 10px; border-radius: var(--r-md); font-size: 16px; }
#battleFeedback.success { background: #e8f5e9; border: 1px solid var(--ok); color: var(--ok); }
#battleFeedback.fail { background: #ffebee; border: 1px solid var(--warn); color: var(--warn); }
.battle-history h4 { font-size: 16px; color: var(--ink2); margin-bottom: 6px; }
.battle-history-item {
  background: #f8f9fa; border-radius: var(--r-md); padding: 8px 12px; margin-bottom: 4px;
  display: flex; justify-content: space-between; align-items: center; font-size: 15px;
}
.battle-history-item.win { background: #e8f5e9; border-left: 3px solid var(--ok); }
.battle-history-item.lose { background: #ffebee; border-left: 3px solid var(--warn); }

/* 战斗动画 */
.shake { animation: shakeAnim 0.3s ease-in-out; }
@keyframes shakeAnim { 0%,100%{transform:translateX(0)} 25%{transform:translateX(-5px)} 75%{transform:translateX(5px)} }
.victory { animation: victoryAnim 0.5s ease-in-out; }
@keyframes victoryAnim { 0%{transform:scale(1)} 50%{transform:scale(1.2)} 100%{transform:scale(1)} }
.opt.correct { animation: correctPulse 0.6s ease-out; background: #E8F5E9 !important; color: #2F6B42 !important; border-color: #8CC79C !important; }
@keyframes correctPulse { 0%{box-shadow:0 0 0 0 rgba(46,204,113,.7)} 70%{box-shadow:0 0 0 10px rgba(46,204,113,0)} 100%{box-shadow:0 0 0 0 rgba(46,204,113,0)} }
.opt.wrong { animation: wrongShake 0.4s ease-in-out; background: #FCEFEC !important; color: #8C4A3E !important; border-color: #E5A99D !important; }
@keyframes wrongShake { 0%,100%{transform:translateX(0)} 20%{transform:translateX(-8px)} 40%{transform:translateX(8px)} 60%{transform:translateX(-5px)} 80%{transform:translateX(5px)} }
.fade-in-up { animation: fadeInUp 0.4s ease-out; }

/* 排行榜 */
.rank-item {
  display: flex; align-items: center; gap: 8px; padding: 9px 12px;
  border-radius: var(--r-md); margin-bottom: 4px; background: #FDFBF8; border: 1px solid var(--line);
  transition: all .25s cubic-bezier(.4,0,.2,1);
}
.rank-item:hover { box-shadow: 0 4px 14px rgba(58,50,38,.1); transform: translateX(3px); }
.rank-pos { width: 32px; font-weight: 700; color: var(--brand); font-size: 18px; }
.rank-name { flex: 1; font-weight: 600; font-size: 16px; }
.rank-room { color: var(--ink2); font-size: 15px; }
.rank-score { font-weight: 700; color: var(--brand2); font-size: 17px; }
.load-more { text-align: center; padding: 8px; color: var(--ink2); cursor: pointer; border-top: 1px dashed var(--line); margin-top: 6px; font-size: 15px; }
.load-more:hover { color: var(--brand); background: #f8f9fa; }

/* 宠物状态动画 */

/* ================= 创新舱 ================= */
.inno-seg { display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: 4px; padding-bottom: 6px; border-bottom: 1px dashed var(--line); }
.inno-btn {
  padding: 8px 16px; border-radius: 20px; font-size: 14px; border: 1px solid var(--line);
  background: var(--card); color: var(--ink2); cursor: pointer; transition: var(--transition); white-space: nowrap;
}
.inno-btn:hover { border-color: var(--brand); color: var(--brand); transform: translateY(-2px); box-shadow: 0 2px 8px rgba(232,131,58,.15); }
.inno-btn.on { background: linear-gradient(135deg, #9B7BC4, #E8833A); color: #fff; border-color: transparent; box-shadow: 0 2px 8px rgba(155,123,196,.32); }
.inno-btn:active { transform: translateY(0); }
/* R3：键盘焦点环（tab/Enter/Space） */
.inno-btn:focus-visible { outline: 2.5px solid var(--brand); outline-offset: 2px; box-shadow: 0 0 0 4px rgba(232,131,58,.15); }
.inno-btn.on:focus-visible { outline-color: #fff; box-shadow: 0 2px 8px rgba(155,123,196,.32), 0 0 0 4px rgba(255,255,255,.35); }
.inno-sec:focus-visible { outline: 2.5px solid var(--brand); outline-offset: 2px; border-radius: var(--r-md); }
.inno-sec:focus { outline: none; }
.inno-sec.on:focus-visible { outline: 2.5px solid var(--brand); }
.inno-sec { display: none; animation: paneEnter .28s ease-out; }
.inno-sec.on { display: block; }
.inno-hint { font-size: 14px; color: var(--ink2); margin: 6px 0; line-height: 1.55; }
.field-in {
  padding: 11px 14px; border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--card); color: var(--ink); font-size: 15px; font-family: inherit;
  outline: none; transition: var(--transition); box-sizing: border-box;
}
.field-in:focus { border-color: var(--brand); box-shadow: 0 0 0 3px rgba(232,131,58,.12); }

/* R1 情绪气象站 */
.mood-pick { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; margin: 12px 0; }
.mood-b { padding: 10px 8px; min-width: 68px; border: 1.5px solid var(--line); border-radius: var(--r-md); background: var(--card); cursor: pointer; transition: var(--transition); display: flex; flex-direction: column; align-items: center; gap: 4px; font-size: 26px; }
.mood-b span { font-size: 13px; color: var(--ink2); }
.mood-b:hover { transform: translateY(-3px); border-color: var(--brand); }
.mood-b.on { border-color: var(--brand); background: rgba(232,131,58,.1); box-shadow: 0 3px 10px rgba(232,131,58,.22); }
.mood-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; margin-top: 10px; }
.mood-cell { aspect-ratio: 1; border-radius: 6px; display: flex; align-items: center; justify-content: center; font-size: 13px; cursor: default; transition: var(--transition); opacity: .55; }
.mood-cell.has { opacity: 1; }
.mood-cell:hover { transform: scale(1.18); z-index: 2; }
.mood-cell.has { cursor: pointer; }
.mood-cell.has:focus-visible { outline: 2.5px solid var(--brand); outline-offset: 1px; }
/* R4：情绪站视图切换 + 聚合 + 近况 */
.mood-viewseg { display: flex; gap: 6px; justify-content: center; }
.mood-viewseg .cap-p { min-width: 56px; text-align: center; padding: 5px 12px; }
.mood-aggr { margin-top: 4px; font-size: 13px; color: var(--ink2); }
.mood-aggr-sub { color: var(--ink3); font-size: 12px; }
.mood-notes { list-style: none; padding: 0; margin: 4px 0 0; }
.mood-notes-title { font-size: 13px; color: var(--ink); font-weight: 600; margin-bottom: 4px; }
.mood-notes li { display: flex; gap: 8px; align-items: flex-start; padding: 6px 8px; border-radius: 6px; background: rgba(232,131,58,.05); margin-bottom: 3px; font-size: 13px; }
.mood-notes .mn-icon { font-size: 16px; flex-shrink: 0; }
.mood-notes .mn-day { color: var(--ink3); font-size: 12px; flex-shrink: 0; min-width: 78px; }
.mood-notes .mn-note { color: var(--ink); line-height: 1.5; word-break: break-word; }

/* R3 成长树 */
.tree-box { text-align: center; padding: 12px 10px; }
.tree-icon { font-size: 100px; line-height: 1; animation: petFloat 4s ease-in-out infinite; display: inline-block; }
.tree-name { font-size: 20px; font-weight: 700; color: var(--ink); margin: 10px 0 3px; }
.tree-desc { font-size: 14px; color: var(--ink2); margin-bottom: 6px; }
.tree-bar { height: 12px; background: var(--line); border-radius: 6px; overflow: hidden; margin: 12px auto; max-width: 400px; }

/* ===== 迭代第1轮（#513）：个性化设置总览卡片 ===== */
.custom-ov-summary {
  display: flex; align-items: center; gap: 12px; padding: 10px 14px; margin-bottom: 10px;
  background: linear-gradient(135deg, #FFF8F1, #F2FAF7);
  border: 1px solid #F0E2D2; border-radius: var(--r-sm);
}
.cos-num { font-size: 30px; font-weight: 800; color: var(--brand); font-variant-numeric: tabular-nums; line-height: 1; }
.cos-txt { font-size: 12.5px; color: var(--ink2); line-height: 1.5; }
.cos-sub { font-size: 11px; color: var(--ink3); }
.custom-ov-list { display: flex; flex-direction: column; gap: 6px; }
.cov-row {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  background: rgba(255, 255, 255, .55); border: 1px solid #F0E2D2; border-radius: var(--r-sm);
}
.cov-row.applied { background: linear-gradient(135deg, rgba(255, 248, 241, .85), rgba(242, 250, 247, .85)); border-color: #E8D5BC; }
.cov-ic { font-size: 18px; line-height: 1; width: 24px; text-align: center; flex-shrink: 0; }
.cov-main { flex: 1; min-width: 0; }
.cov-lb { font-size: 13px; font-weight: 600; color: var(--ink); }
.cov-val { font-size: 11.5px; color: var(--ink2); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cov-st { font-size: 11px; font-weight: 600; color: var(--ink3); min-width: 58px; text-align: center; flex-shrink: 0; }
.cov-row.applied .cov-st { color: var(--brand); }
.cov-fix { flex-shrink: 0; }
/* 迭代第9轮（#521）：单项重置按钮 */
.cov-reset {
  flex-shrink: 0; min-width: 30px; height: 30px; padding: 0 8px;
  border-radius: 8px; font-size: 15px; line-height: 1;
}
.cov-reset:hover { background: rgba(217,106,91,.1); border-color: var(--warn); color: var(--warn); }
.custom-ov-foot { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
/* 迭代第8轮（#520）：自定义配置导出/导入（跨设备迁移） */
.custom-ov-migrate { margin-top: 12px; padding: 12px; background: rgba(255,255,255,.5); border: 1px dashed var(--line); border-radius: var(--r-md); }
.custom-ov-migrate h4 { font-size: 14px; font-weight: 700; color: var(--ink); margin-bottom: 6px; }
.cm-hint { font-size: 12px; color: var(--ink2); line-height: 1.5; margin-bottom: 10px; }
.cm-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.cm-actions .btn { font-size: 13px; }
.tree-bar-fill { height: 100%; background: linear-gradient(90deg, #5BA869, #E8833A); border-radius: 6px; transition: width .8s ease; }
.tree-fruits { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 16px; }
.fruit { padding: 6px 11px; border-radius: 14px; font-size: 13px; border: 1px solid var(--line); background: var(--card); color: var(--ink3); }
.fruit.got { background: rgba(62,142,90,.12); border-color: rgba(62,142,90,.35); color: var(--ok); font-weight: 600; }
/* R4：成长树果实图例 */
.tree-legend { display: flex; gap: 16px; justify-content: center; margin-top: 8px; font-size: 12px; color: var(--ink2); }
.tree-legend span { display: inline-flex; align-items: center; gap: 5px; }
.tree-dot { width: 11px; height: 11px; border-radius: 50%; display: inline-block; background: var(--card); border: 1px solid var(--line); }
.tree-dot.got { background: rgba(62,142,90,.5); border-color: rgba(62,142,90,.6); }
/* R8：阶段里程碑横向进度条 */
.tree-stages { display: flex; gap: 4px; justify-content: center; flex-wrap: wrap; margin: 10px 0 4px; }
.ts-node { display: flex; flex-direction: column; align-items: center; gap: 1px; padding: 5px 7px; border-radius: 10px;
  background: #F7F5F2; border: 1px solid #EDE8E1; color: var(--ink3); min-width: 52px; opacity: .7; transition: all .2s; }
.ts-node .ts-ic { font-size: 18px; line-height: 1; }
.ts-node .ts-nm { font-size: 11px; font-weight: 600; }
.ts-node .ts-need { font-size: 10px; color: var(--ink3); font-variant-numeric: tabular-nums; }
.ts-node.reached { background: rgba(62,142,90,.12); border-color: rgba(62,142,90,.35); color: var(--ok); opacity: 1; }
.ts-node.current { background: linear-gradient(135deg, #FFF0DE, #FBEAD9); border-color: var(--brand); color: #8f4a12;
  box-shadow: 0 2px 8px rgba(192,101,32,.2); opacity: 1; transform: translateY(-2px); }

/* R4 建议 */
.advice-item { display: flex; gap: 8px; padding: 13px 14px; border-radius: var(--r-md); background: var(--card); border: 1px solid var(--line); margin-bottom: 6px; transition: var(--transition); }
.advice-item:hover { border-color: var(--brand); transform: translateX(2px); }
.advice-ic { font-size: 24px; flex-shrink: 0; }
.advice-tx { font-size: 15px; color: var(--ink); line-height: 1.65; }
.advice-cat { display: inline-block; font-size: 13px; padding: 2px 8px; border-radius: 8px; background: rgba(155,123,196,.14); color: #7B5BA0; margin-right: 8px; vertical-align: 1px; }

/* R2 时光信 */
.cap-presets { display: flex; gap: 6px; flex-wrap: wrap; margin: 8px 0; }
.cap-p { padding: 7px 13px; border-radius: 14px; font-size: 14px; border: 1px solid var(--line); background: var(--card); color: var(--ink2); cursor: pointer; transition: var(--transition); }
.cap-p:hover { border-color: var(--brand); color: var(--brand); }
.cap-p.on { background: var(--brand); color: #fff; border-color: var(--brand); }
.cap-item { padding: 13px 14px; border-radius: var(--r-md); border: 1px solid var(--line); background: var(--card); margin-bottom: 6px; }
.cap-item.ready { border-color: var(--brand); background: rgba(232,131,58,.07); }
.cap-item h4 { font-size: 16px; margin: 0 0 5px; color: var(--ink); }
.cap-body { font-size: 15px; color: var(--ink); line-height: 1.7; white-space: pre-wrap; background: rgba(232,131,58,.06); padding: 11px; border-radius: var(--r-md); margin-top: 7px; }
.cap-meta { font-size: 13px; color: var(--ink3); margin-top: 6px; }
.cap-prog { height: 6px; background: var(--line); border-radius: 4px; overflow: hidden; margin-top: 8px; }
.cap-prog-fill { height: 100%; background: linear-gradient(90deg, #9B7BC4, #E8833A); }

/* R5：时光信字数统计 + 删除按钮 */
.cap-count { font-size: 12px; color: var(--ink3); text-align: right; margin: 4px 2px 2px; font-variant-numeric: tabular-nums; }
.cap-count.warn { color: var(--warn); font-weight: 600; }
.cap-count.over { color: var(--warn); font-weight: 700; }
.cap-del {
  float: right; background: none; border: none; cursor: pointer; font-size: 15px;
  padding: 2px 4px; border-radius: 4px; transition: var(--transition); line-height: 1;
}
.cap-del:hover { background: rgba(217,106,91,.12); }
.cap-archived { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-md); padding: 8px 10px; }
.cap-archived summary { cursor: pointer; font-size: 14px; color: var(--ink2); font-weight: 600; padding: 4px 0; }
.cap-archived summary:hover { color: var(--brand); }
.cap-item.cap-opened { opacity: .88; }

/* R5 互助墙 */
.wall-item { padding: 13px 15px; border-radius: var(--r-md); border: 1px solid var(--line); background: var(--card); margin-bottom: 6px; }
.wall-nick { font-size: 13px; color: #7B5BA0; font-weight: 600; margin-bottom: 5px; }
.wall-body { font-size: 16px; color: var(--ink); line-height: 1.7; }
.wall-foot { display: flex; align-items: center; gap: 8px; margin-top: 8px; font-size: 13px; color: var(--ink3); }
.wall-like { cursor: pointer; padding: 3px 11px; border-radius: 12px; border: 1px solid var(--line); background: var(--card); transition: var(--transition); font-size: 13px; }
.wall-like:hover { border-color: var(--mood); }
.wall-like.on { background: rgba(226,114,139,.12); border-color: var(--mood); color: var(--mood); }

/* R6：互助墙工具栏 + 分类/字数/举报 */
.wall-toolbar { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; }
.wall-toolbar .wall-cats, .wall-toolbar .wall-sorts { display: flex; gap: 4px; flex-wrap: wrap; }
.wall-toolbar .cap-p { padding: 5px 10px; font-size: 12.5px; min-height: auto; }
.wall-count { font-size: 12px; color: var(--ink3); text-align: right; margin: 3px 2px; font-variant-numeric: tabular-nums; }
.wall-count.warn { color: var(--warn); font-weight: 600; }
.wall-count.over { color: var(--warn); font-weight: 700; }
.wall-head { display: flex; justify-content: space-between; align-items: center; gap: 6px; margin-bottom: 4px; }
.wall-cat { font-size: 11.5px; padding: 2px 8px; border-radius: 10px; border: 1px solid var(--line); color: var(--ink3); }
.wall-cat.cat-help { background: rgba(217,106,91,.08); border-color: rgba(217,106,91,.3); color: var(--warn); }
.wall-cat.cat-cheer { background: rgba(226,114,139,.1); border-color: rgba(226,114,139,.3); color: #B8527B; }
.wall-cat.cat-share { background: rgba(74,155,212,.08); border-color: rgba(74,155,212,.3); color: #3E7BB3; }
.wall-report { background: none; border: none; cursor: pointer; font-size: 13px; padding: 2px 6px; border-radius: 4px; color: var(--ink3); transition: var(--transition); }
.wall-report:hover { background: rgba(217,106,91,.1); color: var(--warn); }
.wall-flag { font-size: 11px; color: var(--warn); padding: 2px 6px; border-radius: 4px; background: rgba(217,106,91,.1); }

/* R6 防复发 */
.risk-q { padding: 13px 0; border-bottom: 1px dashed var(--line); }
.risk-q:last-child { border-bottom: none; }
.risk-qt { font-size: 16px; color: var(--ink); margin-bottom: 9px; line-height: 1.5; }
.risk-opts { display: flex; gap: 6px; flex-wrap: wrap; }
.risk-o { padding: 7px 13px; border-radius: 14px; font-size: 14px; border: 1px solid var(--line); background: var(--card); color: var(--ink2); cursor: pointer; transition: var(--transition); }
.risk-o:hover { border-color: var(--brand); }
.risk-o.on { background: var(--brand); color: #fff; border-color: var(--brand); }
.risk-res { padding: 15px; border-radius: var(--r-md); text-align: center; margin-top: 12px; }
.risk-low { background: rgba(62,142,90,.1); border: 1px solid rgba(62,142,90,.3); }
.risk-medium { background: rgba(232,163,61,.12); border: 1px solid rgba(232,163,61,.35); }
.risk-high { background: rgba(217,106,91,.12); border: 1px solid rgba(217,106,91,.35); }
.risk-score { font-size: 36px; font-weight: 800; line-height: 1.1; }
.risk-tips { text-align: left; font-size: 14px; color: var(--ink2); line-height: 1.8; margin-top: 10px; }

/* R7 呼吸训练 */
.breath-wrap { display: flex; justify-content: center; padding: 12px 0; }
.breath-circle {
  width: 170px; height: 170px; border-radius: 50%; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 5px; color: #fff; font-size: 19px; font-weight: 600;
  background: radial-gradient(circle at 35% 32%, #7FB8D8, #4A9BD4);
  transition: transform 1s cubic-bezier(.4,0,.2,1), background 1s ease;
  box-shadow: 0 8px 26px rgba(74,155,212,.35); cursor: pointer; user-select: none;
}
.breath-circle.inhale { transform: scale(1.28); background: radial-gradient(circle at 35% 32%, #8FD3B0, #5BA869); }
.breath-circle.exhale { transform: scale(.82); background: radial-gradient(circle at 35% 32%, #6FA8CC, #3D7FA8); }
.breath-circle i { font-style: normal; font-size: 32px; font-weight: 800; }

/* R7：环形进度（SVG 圆环 + 目标时长） */
.breath-ring { display: flex; justify-content: center; padding: 4px 0; }
.breath-ring-wrap { position: relative; width: 80px; height: 80px; }
.breath-ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.breath-ring .br-bg { fill: none; stroke: var(--line); stroke-width: 6; }
.breath-ring .br-fg {
  fill: none; stroke: var(--clean); stroke-width: 6; stroke-linecap: round;
  transition: stroke-dashoffset .8s ease;
}
.breath-ring-label {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 0;
}
.breath-ring-label .br-cur { font-size: 14px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; line-height: 1.1; }
.breath-ring-label .br-tgt { font-size: 10.5px; color: var(--ink3); font-variant-numeric: tabular-nums; }
.breath-ring-pct { display: none; }  /* 百分比暂隐藏，避免视觉冗余 */

/* R8 剧情 */
.story-box {
  padding: 17px; border-radius: var(--r-lg);
  background: linear-gradient(160deg, rgba(155,123,196,.07), rgba(232,131,58,.06));
  border: 1px solid var(--line);
}
.story-title { font-size: 18px; font-weight: 700; color: var(--ink); margin-bottom: 7px; }
.story-text { font-size: 16px; color: var(--ink); line-height: 1.95; margin-bottom: 6px; text-indent: 2em; }
.story-choice {
  display: block; width: 100%; text-align: left; padding: 13px 15px; margin-bottom: 6px;
  border-radius: var(--r-md); border: 1px solid var(--line); background: var(--card);
  color: var(--ink); font-size: 15px; cursor: pointer; transition: var(--transition); font-family: inherit;
}
.story-choice:hover { border-color: #9B7BC4; background: rgba(155,123,196,.08); transform: translateX(3px); }
.story-meta { font-size: 13px; color: var(--ink3); margin-top: 9px; text-align: right; }

/* R8：剧情足迹 */
.story-hist-title { font-size: 13px; color: var(--ink); font-weight: 600; margin-bottom: 6px; }
.story-hist { list-style: none; padding: 0; margin: 0; }
.story-hist li { display: flex; gap: 8px; align-items: baseline; padding: 5px 8px; border-radius: 6px; background: rgba(155,123,196,.05); margin-bottom: 3px; font-size: 12.5px; line-height: 1.5; }
.story-hist .sh-idx { color: var(--ink3); font-size: 11.5px; flex-shrink: 0; font-variant-numeric: tabular-nums; min-width: 90px; }
.story-hist .sh-node { color: var(--brand2); font-weight: 600; flex-shrink: 0; max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.story-hist .sh-choice { color: var(--ink); flex: 1; word-break: break-word; }

/* R9 星空 */
.sky-box {
  position: relative; width: 100%; height: 340px; border-radius: var(--r-lg); overflow: hidden;
  background: radial-gradient(ellipse at 50% 30%, #2A2740, #15131F 70%);
  box-shadow: inset 0 0 60px rgba(0,0,0,.55);
}
.sky-star { position: absolute; border-radius: 50%; transition: var(--transition); }
.sky-star.dim { background: #4A4658; }
.sky-star.lit { background: #FFE9A8; box-shadow: 0 0 8px 2px rgba(255,224,138,.6); animation: twinkle 2.6s ease-in-out infinite; }
.sky-star:hover { transform: scale(1.7); z-index: 5; }
@keyframes twinkle { 0%,100%{opacity:1} 50%{opacity:.55} }

/* R9：星座连线（SVG，两端都已点亮才显示） */
.sky-edges {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; z-index: 1;
}
.sky-edges line {
  stroke: rgba(255,224,138,.55); stroke-width: 1.2;
  vector-effect: non-scaling-stroke;
  filter: drop-shadow(0 0 3px rgba(255,224,138,.5));
}
.sky-star { z-index: 2; }

/* R9：成就统计面板 */
.sky-stats {
  display: flex; flex-direction: column; gap: 4px;
  background: rgba(155,123,196,.06); border: 1px solid rgba(155,123,196,.2);
  border-radius: var(--r-md); padding: 8px 10px; margin-bottom: 8px;
}
.sky-stats .ss-row { display: flex; justify-content: space-between; align-items: center; font-size: 13px; color: var(--ink); }
.sky-stats .ss-row b { font-weight: 700; color: var(--brand); font-variant-numeric: tabular-nums; }
.sky-stats .ss-bar { height: 6px; background: var(--line); border-radius: 3px; overflow: hidden; margin-top: 4px; }
.sky-stats .ss-bar-fill { height: 100%; background: linear-gradient(90deg, #9B7BC4, #FFE9A8); transition: width .8s ease; }
.sky-recent { font-size: 12px; color: var(--ink2); margin-top: 4px; }
.sky-recent span { padding: 2px 6px; border-radius: 8px; background: rgba(255,224,138,.15); margin: 0 2px; }
.sky-legend { display: flex; gap: 10px; flex-wrap: wrap; }
.sky-lg { padding: 7px 13px; border-radius: 14px; font-size: 13px; background: var(--card); border: 1px solid var(--line); color: var(--ink2); }
.sky-lg b { color: var(--brand); }
.dream-box {
  margin-top: 14px; padding: 15px; border-radius: var(--r-md); font-size: 16px; line-height: 1.8;
  color: var(--ink); background: linear-gradient(135deg, rgba(155,123,196,.1), rgba(74,155,212,.08));
  border: 1px dashed rgba(155,123,196,.4);
}

/* ================= 宠物乐园 ================= */
.pp-card { padding: 11px 12px; border-radius: var(--r-md); border: 1px solid var(--line); background: var(--card); margin-bottom: 5px; }
.pp-card h4 { font-size: 16px; margin: 0 0 6px; color: var(--ink); }
.pp-bar { height: 10px; background: var(--line); border-radius: 5px; overflow: hidden; margin: 6px 0; }
.pp-bar-fill { height: 100%; background: linear-gradient(90deg, #E8833A, #E8A33D); border-radius: 5px; transition: width .6s ease; }
.pp-speech { padding: 12px 14px; border-radius: 13px; text-align: center; margin-bottom: 5px; background: linear-gradient(135deg, rgba(91,168,105,.12), rgba(46,158,143,.1)); border: 1px dashed rgba(91,168,105,.45); }
.pp-speech-ic { font-size: 32px; margin-bottom: 7px; }
.pp-speech-tx { font-size: 17px; color: var(--ink); line-height: 1.75; font-weight: 600; }
.pp-speech-meta { font-size: 13px; color: var(--ink3); margin-top: 7px; }
.pp-combo { display: flex; align-items: baseline; gap: 10px; margin: 5px 0; }
.pp-combo-n { font-size: 38px; font-weight: 800; color: var(--brand); line-height: 1; }
.pp-combo-x { font-size: 17px; font-weight: 700; color: var(--warn); }
.pp-combo-t { font-size: 14px; color: var(--ink2); }

/* R1 天赋 */
.talent-item { display: flex; gap: 8px; padding: 10px 12px; border-radius: var(--r-md); border: 1px solid var(--line); background: var(--card); margin-bottom: 4px; transition: var(--transition); }
.talent-item.on { border-color: rgba(232,131,58,.5); background: rgba(232,131,58,.07); }
.talent-item:not(.on) { opacity: .62; }
.talent-ic { font-size: 22px; flex-shrink: 0; }
.talent-nm { font-size: 16px; font-weight: 600; color: var(--ink); }
.talent-lv { display: inline-block; margin-left: 8px; font-size: 13px; padding: 2px 8px; border-radius: 8px; background: rgba(232,131,58,.14); color: var(--brand); font-weight: 500; }
.talent-ds { font-size: 14px; color: var(--ink2); margin-top: 3px; line-height: 1.6; }

/* R2 装备 */
.equip-item { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: var(--r-md); border: 1px solid var(--line); background: var(--card); margin-bottom: 4px; transition: var(--transition); }
.equip-item.on { border-color: var(--brand); background: rgba(232,131,58,.08); }
.equip-item.lock { opacity: .58; }
.equip-ic { font-size: 30px; flex-shrink: 0; }
.equip-info { flex: 1; min-width: 0; }
.equip-nm { font-size: 16px; font-weight: 600; color: var(--ink); }
.equip-ds { font-size: 13px; color: var(--ink2); margin-top: 2px; }
.equip-bonus { font-size: 13px; color: var(--ok); margin-top: 4px; }
.equip-act { flex-shrink: 0; }
.equip-lock { font-size: 13px; color: var(--ink3); }


/* R5: 状态趋势指示器 */

/* R6 雷达图 */
.radar-wrap { display: flex; justify-content: center; padding: 8px 0; }
.radar-svg { width: 100%; max-width: 420px; height: auto; }
.grow-row { display: flex; align-items: center; gap: 10px; margin: 6px 0; }
.grow-lb { font-size: 14px; color: var(--ink2); width: 100px; flex-shrink: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.grow-pc { font-size: 13px; color: var(--brand); text-align: right; flex-shrink: 0; }

/* R8 探险 */
.adv-on { border-color: var(--brand2); background: rgba(46,158,143,.07); }
.equip-tag { position: absolute; top: -8px; right: 8px; font-size: 12px; color: #fff; background: var(--ok); padding: 3px 9px; border-radius: 8px; font-weight: 700; z-index: 2; }
.muted { color: var(--ink3); font-size: 12px; font-weight: 400; }

/* R3 日记 */
.diary-item { padding: 10px 12px; border-radius: var(--r-md); border: 1px solid var(--line); background: var(--card); margin-bottom: 4px; }
.diary-day { font-size: 15px; font-weight: 600; color: var(--ink); display: flex; justify-content: space-between; align-items: center; }
.diary-lv { font-size: 13px; color: var(--ink3); font-weight: 400; }
.diary-note { font-size: 15px; color: var(--ink); line-height: 1.7; margin-top: 5px; padding: 8px 10px; background: rgba(232,131,58,.07); border-radius: var(--r-md); }
.diary-bars { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 7px; }
.diary-b { font-size: 13px; color: var(--ink2); background: var(--line); padding: 3px 9px; border-radius: 8px; }

/* R9 图鉴 */
.dex-new { padding: 11px 14px; border-radius: var(--r-md); margin-bottom: 7px; font-size: 15px; color: var(--ok); background: rgba(62,142,90,.1); border: 1px solid rgba(62,142,90,.3); font-weight: 600; }
.dex-cat { margin-bottom: 10px; }
.dex-cat-h { font-size: 16px; font-weight: 700; color: var(--ink); margin-bottom: 6px; }
.dex-cat-n { font-size: 13px; color: var(--brand); font-weight: 600; }
.dex-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 8px; }
.dex-cell { padding: 8px 4px; border-radius: var(--r-md); text-align: center; border: 1px solid var(--line); background: var(--card); transition: var(--transition); }
.dex-cell.on { border-color: var(--brand); background: rgba(232,131,58,.08); }
.dex-ic { font-size: 26px; }
.dex-nm { font-size: 13px; color: var(--ink2); margin-top: 3px; }
.dex-cell:not(.on) .dex-nm { color: var(--ink3); }
.dex-cell.isnew { border-color: var(--ok); animation: dexPulse 1.4s ease-in-out infinite; }
@keyframes dexPulse { 0%,100%{box-shadow:0 0 0 2px rgba(62,142,90,.18)} 50%{box-shadow:0 0 0 4px rgba(62,142,90,.35)} }
.dex-newtag { position: absolute; top: -7px; right: -4px; font-size: 11px; font-weight: 700; color: #fff; background: var(--ok); padding: 2px 6px; border-radius: 7px; z-index: 2; }

/* R512：pointer:coarse 触控规则已统一收口至「R57: 响应式与触摸优化」段，避免重复 */

@media (min-width: 1100px) {
  .grid { display: grid; grid-template-columns: minmax(360px, 420px) 1fr; gap: 14px; align-items: start; }
  .pet-stage { padding: 16px; }
  #petCanvas { max-width: 420px; }
}

@media (max-width: 820px) {
  body { font-size: 18px; }
  .btn { padding: 17px; font-size: 17px; }
  .tab { padding: 14px 14px; font-size: 15px; }
}

/* 亭模式 */
body.kiosk { cursor: none; overflow: hidden; }
body.kiosk * { -webkit-user-select: none !important; user-select: none !important; -webkit-touch-callout: none !important; }
body.kiosk input { -webkit-user-select: text !important; user-select: text !important; font-size: 18px; }

/* 通用：文字类元素默认不可选中 */
.card, .speech, .pet-name, .pet-meta, .bar-row, .tab, .msg { -webkit-user-select: none; user-select: none; }

/* ================= R10 滚动条美化 ================= */
/* R47 滚动条统一：此前全局 6px、.func-content 4px、.pet-hub.mini 4px 三套宽度并存，
   主功能区仅 4px——在所内触摸一体机上几乎无法抓握，学员不知道"还能往下滚"。
   现统一为 10px，并在触摸设备（pointer:coarse）加宽到 14px 提升可抓握性。 */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--bg); border-radius: 5px; }
::-webkit-scrollbar-thumb { background: var(--line); border-radius: 5px; min-height: 40px; }
::-webkit-scrollbar-thumb:hover { background: var(--ink3); }
/* 触摸设备：加宽到 14px，拇指可稳定拖动 */
@media (pointer: coarse) {
  ::-webkit-scrollbar { width: 14px; height: 14px; }
  ::-webkit-scrollbar-track { border-radius: 7px; }
  ::-webkit-scrollbar-thumb { border-radius: 7px; min-height: 56px; }
}
/* 统一原先被单独收窄的两个容器，跟随全局规格 */
.func-content::-webkit-scrollbar,
.pet-hub.mini::-webkit-scrollbar { width: 10px; }
.func-content::-webkit-scrollbar-thumb,
.pet-hub.mini::-webkit-scrollbar-thumb { border-radius: 5px; min-height: 40px; }
@media (pointer: coarse) {
  .func-content::-webkit-scrollbar,
  .pet-hub.mini::-webkit-scrollbar { width: 14px; }
}

/* ================= R4 法律问答历史 ================= */
.law-hist-wrap { margin-top: 10px; }
.law-hist-hdr { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; font-size: 13px; color: var(--ink2); }
.law-hist { display: flex; flex-direction: column; gap: 4px; max-height: 92px; overflow-y: auto; }
.law-hist-item {
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
  padding: 6px 10px; border-radius: 8px; background: #F7F3EC; cursor: pointer;
  border: 1px solid transparent; transition: all .18s;
}
.law-hist-item:hover { background: #FFF3E7; border-color: var(--brand); transform: translateX(2px); }
.law-hist-q { font-size: 13.5px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.law-hist-t { font-size: 11.5px; color: var(--ink3); flex-shrink: 0; }
.law-hist-empty { font-size: 12.5px; color: var(--ink3); text-align: center; padding: 8px; }

/* ================= R4 打卡汇总环 ================= */
.task-summary { display: flex; align-items: center; gap: 12px; padding: 10px 12px; margin-bottom: 8px;
  background: linear-gradient(135deg, #F2FAF7, #FFF8F1); border: 1px solid #E3EFE9; border-radius: var(--r-sm); }
.ts-ring { position: relative; width: 56px; height: 56px; flex-shrink: 0; }
.ts-ring-num { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700; color: var(--brand2); font-variant-numeric: tabular-nums; }
.ts-info { flex: 1; min-width: 0; }
.ts-line1 { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; margin-bottom: 3px; }
.ts-streak { font-size: 15px; color: var(--ink); }
.ts-streak b { font-size: 20px; color: var(--brand); font-variant-numeric: tabular-nums; }
.ts-count { font-size: 13px; color: var(--ink2); font-variant-numeric: tabular-nums; }
.ts-line2 { font-size: 12.5px; color: var(--ink3); }
.ts-line3 { font-size: 12.5px; color: var(--ink2); margin-top: 2px; font-variant-numeric: tabular-nums; }
.ts-line3 b { color: var(--brand-deep); }

/* ================= R5 勋章墙统计与分组 ================= */
.badge-summary {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px; margin-bottom: 10px;
  background: linear-gradient(135deg, #FFF8F1, #F2FAF7); border: 1px solid #F0E2D2;
  border-radius: var(--r-sm);
}
.bs-left { display: flex; align-items: baseline; gap: 4px; flex-shrink: 0; }
.bs-num { font-size: 24px; font-weight: 800; color: var(--brand); font-variant-numeric: tabular-nums; line-height: 1; }
.bs-txt { font-size: 12.5px; color: var(--ink2); }
.bs-txt b { color: var(--ink); }
.bs-bar { flex: 1; height: 8px; background: #EFE7DE; border-radius: 4px; overflow: hidden; }
.bs-fill { height: 100%; border-radius: 4px; background: linear-gradient(90deg, var(--brand), #D47632); transition: width .5s ease; }
.bs-pct { font-size: 13px; font-weight: 700; color: var(--brand2); min-width: 34px; text-align: right; font-variant-numeric: tabular-nums; }
.badge-group {
  margin-bottom: 14px; padding: 10px 12px; border-radius: var(--r-md);
  background: rgba(255,255,255,.55); border: 1px solid #F0E6D8;
}
.badge-group:last-child { margin-bottom: 0; }
.badge-group-hd {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 14.5px; font-weight: 700; color: var(--ink);
  padding: 0 0 8px; border-bottom: 1px dashed #EAD9C4; margin-bottom: 9px;
}
.badge-group-cnt { font-size: 12.5px; font-weight: 600; color: var(--brand2); font-variant-numeric: tabular-nums; }
.badges { margin-bottom: 2px; }

/* ============ 勋章页布局优化（R-fix） ============
   1) 筛选条：与统计条同风格，压在列表顶部
   2) 卡片右上角完成勾标，已解锁一眼可辨
   3) 卡片布局改为「图标 + 文字 + 勾标」三段式，文字不再被挤压换行
   4) 集齐的分组加淡金底色 + 「已集齐」标记，强化正反馈
   5) 响应式：窄屏（平板/手机）列数收敛，避免卡片过窄导致文字断裂 */
.badge-filter {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 10px; flex-wrap: wrap;
}
.bf-btn {
  padding: 6px 13px; font-size: 13.5px; font-weight: 600; cursor: pointer;
  color: var(--ink2); background: #FFFDFA; border: 1px solid #EAD9C4;
  border-radius: 999px; transition: all .2s;
}
.bf-btn:hover { border-color: var(--brand); color: var(--brand2); }
.bf-btn.on {
  background: linear-gradient(135deg, var(--brand), #D47632);
  color: #fff; border-color: transparent;
  box-shadow: 0 2px 8px rgba(232,131,58,.28);
}
.bf-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.bf-tip { font-size: 12.5px; color: var(--ink3); font-variant-numeric: tabular-nums; }

/* 勾标：绝对定位在卡片右上角，不占布局宽度 */
.badge-card { position: relative; padding-right: 30px; }
.badge-check {
  position: absolute; top: 8px; right: 9px;
  width: 17px; height: 17px; border-radius: 50%;
  background: linear-gradient(135deg, #E8A33A, #D47632); color: #fff;
  font-size: 11px; line-height: 17px; text-align: center; font-weight: 700;
}
.badge-card.locked .badge-check { display: none; }

/* 文字区：名称单行省略，描述最多两行，超出省略——防止长描述把卡片撑得高低不一 */
.badge-name {
  font-weight: 600; color: var(--ink); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.badge-desc {
  font-size: 12.5px; color: var(--ink2); margin-top: 3px; line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.badge-card.locked .badge-desc { color: var(--ink3); }

/* 集齐分组：淡金底 + 金边 */
.badge-group.complete { background: linear-gradient(135deg, #FFFBF4, #FFF4E2); border-color: #F0D9AE; }
.bg-done {
  font-style: normal; font-size: 11px; font-weight: 700; margin-left: 7px;
  padding: 1px 7px; border-radius: 999px; vertical-align: middle;
  background: linear-gradient(135deg, #E8A33A, #D47632); color: #fff;
}

/* 卡片高度对齐：同一行卡片底部齐平 */
.badges { align-items: stretch; }
.badges .badge-card { min-height: 62px; }

@media (max-width: 560px) {
  .badges { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 8px; }
  .badge-card { padding: 9px 10px; padding-right: 27px; font-size: 14px; }
  .badge-ic { font-size: 22px; width: 22px; }
  .badge-summary { flex-wrap: wrap; }
  .bs-bar { order: 3; flex-basis: 100%; }
}

/* ================= R5 排行榜 ================= */
.rank-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.rank-hint { font-size: 12.5px; color: var(--ink3); }
.rank-item.top1 { background: linear-gradient(90deg, #FFF6E0, #FFFDF7); border-left: 3px solid #E9B44C; }
.rank-item.top2 { background: linear-gradient(90deg, #F5F1EA, #FFFDF8); border-left: 3px solid #AEB4BC; }
.rank-item.top3 { background: linear-gradient(90deg, #FBEDE4, #FFFDF8); border-left: 3px solid #C98B62; }
.rank-item.top1 .rank-pos { color: #C9922E; }
.rank-item.top2 .rank-pos { color: #7C828B; }
.rank-item.top3 .rank-pos { color: #A96A45; }
.rank-item.me {
  background: linear-gradient(90deg, #FFF3E7, #FFFBF5); border-left: 3px solid var(--brand);
  box-shadow: 0 2px 10px rgba(232,131,58,.18);
}
.rank-item.me .rank-name { color: var(--brand); }
.rank-me-mark {
  font-style: normal; font-size: 11px; font-weight: 700; color: #fff; background: var(--brand);
  padding: 1px 6px; border-radius: 8px; margin-left: 5px; vertical-align: 1px;
}

/* ================= R6 怪兽战斗战绩卡 ================= */
.battle-summary {
  display: flex; gap: 4px; margin-top: 8px; padding: 8px 6px;
  background: linear-gradient(135deg, #FFF8F1, #F2FAF7); border: 1px solid #F0E2D2;
  border-radius: var(--r-sm);
}
.battle-summary .bs-cell { flex: 1; display: flex; flex-direction: column; align-items: center; line-height: 1.2; }
.battle-summary .bs-v {
  font-size: 18px; font-weight: 800; color: var(--brand2);
  font-variant-numeric: tabular-nums;
}
.battle-summary .bs-v.win { color: var(--ok); }
.battle-summary .bs-v.lose { color: var(--warn); }
.battle-summary .bs-l { font-size: 11px; color: var(--ink3); margin-top: 1px; }
/* R6：难度可视化 */
.bdiff {
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
  padding: 6px 10px; border-radius: var(--r-sm); background: #F7F3EC;
  border: 1px solid transparent; font-size: 13px; color: var(--ink); margin-bottom: 4px;
}
.bdiff-cur b { font-size: 14px; }
.bdiff-tip { font-size: 12px; color: var(--ink3); }
.bdiff-reason { font-size: 12px; color: var(--ink3); padding: 0 4px; }
.bdiff-easy { color: #3F8F6A; }
.bdiff-hard { color: #C0762A; }
.bdiff-boss { color: #B03A4E; }
.bdiff-mini {
  font-style: normal; font-size: 10.5px; font-weight: 700; padding: 1px 5px;
  border-radius: 7px; background: #EFE7DE; margin-left: 4px; vertical-align: 1px;
}
.bdiff-mini.bdiff-boss { background: #F8DFE4; }
.bdiff-mini.bdiff-hard { background: #FBEAD4; }
.bdiff-mini.bdiff-easy { background: #E4F1E8; }
/* R6：战斗记录三栏（名称+难度 / 结果 / 相对时间） */
.battle-history-item { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; cursor: pointer; transition: filter .15s; }
.battle-history-item:hover { filter: brightness(.97); }
.battle-history-item:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.bh-name { flex-shrink: 0; font-weight: 600; max-width: 42%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bh-mid { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bh-time { flex-shrink: 0; font-size: 12px; color: var(--ink3); }
.bh-detail { flex-basis: 100%; font-size: 12px; color: var(--ink2); padding: 4px 0 2px; animation: fadeInUp .25s ease; }
.battle-history-item.open { filter: brightness(.96); }

/* ================= R7 创新舱空状态与提示 ================= */

/* R11: 统一空状态/加载态/错误态样式增强 */
.empty-state { text-align: center; padding: 32px 16px; color: var(--ink2); animation: fadeIn .4s ease; }
.empty-state .empty-icon { font-size: 64px; margin-bottom: 12px; opacity: .75; }
.empty-state p { font-size: 17px; margin-bottom: 8px; font-weight: 500; }
.empty-state .empty-hint { font-size: 14px; color: var(--ink3); }
.empty-state .empty-action { margin-top: 14px; }
.empty-state .empty-action button { padding: 10px 24px; font-size: 15px; border-radius: var(--r-md); }
/* R9：将 inno 系列空状态（成长树/建议等）与上方 .empty-state 视觉完全统一 */
.inno-empty { text-align: center; padding: 32px 16px; color: var(--ink2); animation: fadeIn .4s ease; }
.inno-empty .ie-icon { font-size: 64px; margin-bottom: 12px; opacity: .75; }
.inno-empty .ie-title { font-size: 17px; margin-bottom: 8px; font-weight: 500; color: var(--ink); }
.inno-empty .ie-hint { font-size: 14px; color: var(--ink3); line-height: 1.6; }
/* R9：空状态图标统一加柔光圆形底，增强插画感 */
.empty-state .empty-icon, .inno-empty .ie-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 104px; height: 104px; border-radius: 50%;
  background: radial-gradient(circle at 50% 40%, #FFF6E9 0%, #FBEFDC 60%, #F6E4CC 100%);
  box-shadow: inset 0 0 0 1px rgba(232,131,58,.15), 0 6px 18px rgba(232,131,58,.12);
}
/* R50 去重：此处原为第二处 @keyframes fadeIn（位移 8px），
   与 248 行定义（位移 12px）重复，后者会覆盖前者。
   两者视觉差异仅 4px，统一保留 248 行的 12px 版本，此处删除。 */

.error-state { text-align: center; padding: 24px 16px; color: var(--warn); background: #FDF0EF; border-radius: var(--r-md); border: 1px solid #F5D0CB; }
.error-state .error-icon { font-size: 42px; margin-bottom: 8px; }
.error-state p { font-size: 15px; margin-bottom: 12px; }
.error-state button { padding: 8px 20px; font-size: 14px; border-radius: var(--r-sm); background: var(--warn); color: #fff; border: none; cursor: pointer; }

.skeleton-pulse { background: linear-gradient(90deg, var(--line) 25%, #F0E8DE 50%, var(--line) 75%); background-size: 200% 100%; animation: shimmer 1.8s infinite; border-radius: var(--r-sm); }
.skeleton-circle { width: 48px; height: 48px; border-radius: 50%; }
.skeleton-rect { height: 14px; margin-bottom: 10px; border-radius: 4px; }
.skeleton-rect.w40 { width: 40%; }
.skeleton-rect.w60 { width: 60%; }
.skeleton-rect.w80 { width: 80%; }
.skeleton-row { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.skeleton-row:last-child { border-bottom: none; }

.inno-empty {
  text-align: center; padding: 22px 12px; color: var(--ink2);
  border: 1px dashed var(--line); border-radius: var(--r-sm); background: #FBF8F3;
}
.inno-empty .ie-icon { font-size: 34px; margin-bottom: 6px; opacity: .85; }
.inno-empty .ie-title { font-size: 15px; font-weight: 600; color: var(--ink); margin-bottom: 3px; }
.inno-empty .ie-hint { font-size: 12.5px; color: var(--ink3); }

/* R2：统一加载态（3 点跳动 + 文案） */
.inno-loading {
  display: flex; align-items: center; justify-content: center;
  gap: 6px; padding: 18px 12px; min-height: 60px;
  color: var(--ink3); font-size: 13px;
}
.inno-loading .il-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--brand); opacity: .35;
  animation: innoDot 1.1s infinite ease-in-out;
}
.inno-loading .il-dot:nth-child(2) { animation-delay: .18s; }
.inno-loading .il-dot:nth-child(3) { animation-delay: .36s; }
.inno-loading .il-text { margin-left: 4px; color: var(--ink2); }
@keyframes innoDot {
  0%, 80%, 100% { transform: translateY(0); opacity: .35; }
  40% { transform: translateY(-4px); opacity: 1; }
}

/* R2：统一错误态（含重试按钮） */
.inno-error {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 18px 12px; min-height: 60px;
  background: rgba(217,106,91,.06); border: 1px dashed rgba(217,106,91,.35);
  border-radius: var(--r-md); color: var(--ink2); font-size: 13px;
}
.inno-error .ie-icon { font-size: 30px; opacity: .85; margin-bottom: 4px; }
.inno-error .ie-title { font-size: 15px; font-weight: 600; color: var(--warn); margin-bottom: 3px; }
.inno-error .ie-hint { font-size: 12.5px; color: var(--ink3); max-width: 320px; }
/* R7：情绪站今日状态胶囊 */
.mood-today {
  display: flex; align-items: center; gap: 6px; padding: 7px 12px; margin-bottom: 8px;
  border-radius: 18px; font-size: 13.5px; font-weight: 600;
}
.mood-today.done { background: #EDF7EF; color: #2F6B42; border: 1px solid #C4E0C9; }
.mood-today.todo { background: #FFF6E6; color: #A9711C; border: 1px solid #F6DFB4; }
/* R7：呼吸「本次」时长 */
.breath-session {
  display: inline-flex; align-items: baseline; gap: 6px; margin-top: 8px;
  padding: 5px 12px; border-radius: 16px; background: #F2FAF7;
  border: 1px solid #D8EAE2; font-size: 13px; color: var(--ink2);
}
.breath-session b { font-size: 16px; color: var(--brand2); font-variant-numeric: tabular-nums; }

/* ================= R8: 个别谈话 / 工具 / 档案 ================= */
.talk-stage { display: flex; align-items: center; gap: 12px; padding: 6px 0 10px; flex-wrap: wrap; font-size: 13px; color: var(--ink2); }
.talk-stage .stage-pill { background: linear-gradient(135deg, #FFF0DE, #FBEAD9); border: 1.5px solid var(--brand); color: var(--brand); padding: 3px 12px; border-radius: 999px; font-weight: 600; }
.talk-tabs { display: flex; flex-wrap: wrap; gap: 4px; padding: 0 0 8px; }
.talk-tabs .topic-filter { padding: 4px 10px; border: 1px solid var(--line); border-radius: 999px; background: #FDF6EE; color: var(--ink2); font-size: 12px; cursor: pointer; transition: all .15s; }
.talk-tabs .topic-filter:hover { border-color: var(--brand); color: var(--brand); }
.talk-tabs .topic-filter.on { background: var(--brand); color: #fff; border-color: var(--brand); }
.talk-content { max-height: 480px; overflow-y: auto; padding: 4px 0; }
.talk-list { display: flex; flex-direction: column; gap: 8px; }
.talk-item { padding: 10px 12px; border: 1.5px solid var(--line); border-radius: var(--r-md); background: linear-gradient(180deg, #FFFBF5, #FFF); cursor: pointer; transition: all .2s; }
.talk-item:hover { border-color: var(--brand); transform: translateX(2px); box-shadow: 0 3px 8px rgba(232,131,58,.12); }
.talk-item .ti-title { font-weight: 600; font-size: 14px; color: var(--ink); margin-bottom: 4px; }
.talk-item .ti-meta { display: flex; gap: 6px; flex-wrap: wrap; font-size: 11px; color: var(--ink3); }
.talk-item .ti-tag { padding: 1px 6px; border-radius: 4px; background: rgba(232,131,58,.1); color: var(--brand); }
.talk-item .ti-homework { font-size: 12px; color: var(--ink3); margin-top: 4px; padding-top: 4px; border-top: 1px dashed #EDE3D8; }
.talk-convo { display: flex; flex-direction: column; gap: 10px; }
.talk-step { padding: 10px 12px; background: #FFF8EE; border-left: 3px solid var(--brand); border-radius: 0 var(--r-sm) var(--r-sm) 0; font-size: 14px; line-height: 1.7; color: var(--ink); }
.talk-step .step-no { font-size: 11px; color: var(--brand); font-weight: 700; letter-spacing: 1px; }
.talk-ans { padding: 8px 12px; background: #E8F4F1; border-left: 3px solid var(--brand2); border-radius: 0 var(--r-sm) var(--r-sm) 0; font-size: 13px; color: var(--ink2); white-space: pre-wrap; word-break: break-word; }
.talk-input-row { display: flex; gap: 6px; align-items: stretch; margin-top: 8px; }
.talk-input-row .field-in { flex: 1; min-height: 60px; padding: 8px 10px; border: 1.5px solid var(--line); border-radius: var(--r-sm); font-size: 13px; resize: vertical; font-family: inherit; }
.talk-input-row .field-in:focus { border-color: var(--brand); outline: none; }
.talk-finish { padding: 12px; background: linear-gradient(135deg, #E8F4F1, #D4ECE5); border-radius: var(--r-md); border: 1.5px solid var(--brand2); }
.talk-finish .ff-title { font-weight: 700; color: var(--brand2); margin-bottom: 6px; font-size: 14px; }
.talk-finish .ff-homework { color: var(--ink2); font-size: 13px; line-height: 1.7; }
.talk-back { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--brand); cursor: pointer; padding: 4px 8px; border: 1px solid var(--brand); border-radius: 999px; background: #FFF; margin-bottom: 8px; }
.talk-back:hover { background: var(--brand); color: #fff; }
.talk-progress { font-size: 11px; color: var(--ink3); }
.talk-progress .pb { display: inline-block; width: 28px; height: 4px; background: #EDE3D8; border-radius: 2px; margin-right: 2px; }
.talk-progress .pb.on { background: var(--brand); }

.tool-tabs { display: flex; flex-wrap: wrap; gap: 4px; padding: 0 0 10px; border-bottom: 1px solid var(--line); margin-bottom: 10px; }
.tool-tab { padding: 5px 12px; border: 1.5px solid var(--line); border-radius: 999px; background: #FDF6EE; color: var(--ink2); font-size: 12px; cursor: pointer; transition: all .15s; font-weight: 500; }
.tool-tab:hover { border-color: var(--brand); color: var(--brand); }
.tool-tab.on { background: linear-gradient(135deg, var(--brand), #d47632); color: #fff; border-color: transparent; box-shadow: 0 2px 6px rgba(232,131,58,.3); }
.tool-content { font-size: 13px; line-height: 1.7; }
.tool-section { margin-bottom: 14px; padding: 10px 12px; background: #FFF8EE; border-radius: var(--r-sm); }
.tool-section h5 { margin: 0 0 6px; color: var(--brand); font-size: 13px; font-weight: 700; }
.tool-section .desc { color: var(--ink3); font-size: 11px; margin-bottom: 6px; }
.tool-section .field-in, .tool-section textarea.field-in { width: 100%; border: 1px solid var(--line); border-radius: 6px; padding: 6px 8px; font-size: 13px; resize: vertical; font-family: inherit; }
.tool-section textarea.field-in { min-height: 60px; }
.tool-section .field-in:focus { border-color: var(--brand); outline: none; }
.tool-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.tool-section .hint { font-size: 11px; color: var(--ink3); margin-top: 4px; }
.tool-section .score-row { display: flex; align-items: center; gap: 10px; padding: 4px 0; }
.tool-section .score-row label { flex: 0 0 70px; font-size: 12px; color: var(--ink2); font-weight: 500; }
.tool-section .score-row input[type="range"] { flex: 1; }
.tool-section .score-row .v { flex: 0 0 24px; text-align: center; font-weight: 700; color: var(--brand); }
.tool-history { margin-top: 14px; padding-top: 10px; border-top: 1px dashed #EDE3D8; }
.tool-history h6 { margin: 0 0 8px; font-size: 12px; color: var(--ink3); }
.tool-history .th-item { padding: 6px 10px; background: #FAFAFA; border-radius: 6px; margin-bottom: 5px; font-size: 12px; }
.tool-history .th-item .th-t { font-weight: 600; color: var(--ink); }
.tool-history .th-item .th-d { color: var(--ink3); font-size: 11px; }
.tool-actions { display: flex; gap: 6px; align-items: center; margin-top: 8px; }

/* R482：宠物模块内的档案区（原独立 pane p-profile 已并入 pet-hub）
   限最大高度 320px，内容多时 pps-body 内部滚动，避免挤压上方三栏导致互动按钮被导航栏裁切 */
/* R507：pet-hub 底部子面板容器（打卡/勋章/战斗/成长树 从工具页迁入）
   各 pane 沿用 .pane/.pane.on 切换；容器纵向堆叠，整体可随 pet-hub 滚动 */
.pet-subpanes {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 2px;
  width: 100%;
}
.pet-subpanes .pane {
  border: 1.5px solid #F5D6A8;
  background: #FFF8EE;
}
/* view-pet 下 pet-hub 已可滚动，子面板自然跟随；确保 pane 在 pet 视图内正常显示 */
.main-area.view-pet .pet-subpanes { display: flex; }

/* R534：档案区展开/收起优化——展开态改自然高度（撑满到视口上限），
   外层统一滚动，去掉 pps-body 内部 260px 死区，避免内容多时裁切"显示异常" */
.pet-profile-section {
  flex: 0 0 auto;
  padding: 10px 14px;
  background: #FFF8EE;
  border: 1.5px solid #F5D6A8;
  border-radius: var(--r-md);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.6);
  display: flex;
  flex-direction: column;
  /* 展开态：自然高度，封顶 60vh 防止撑爆整页；超出时自身纵向滚动查看完整内容 */
  max-height: 60vh;
  overflow: hidden auto;
  transition: max-height .3s ease;
}
.pet-profile-section .pps-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
  flex: 0 0 auto;
}
.pet-profile-section .pps-header h3 {
  margin: 0;
  font-size: 15px;
  color: var(--brand);
  font-weight: 700;
  flex: 0 0 auto;
}
.pet-profile-section .pps-hint {
  flex: 1 1 auto;
  font-size: 12px;
  color: var(--ink3);
  line-height: 1.4;
}
.pet-profile-section .pps-toggle {
  flex: 0 0 auto;
  font-size: 12px;
  padding: 4px 10px;
  min-height: 26px;
}
.pet-profile-section .pps-body {
  flex: 1 1 auto;
  min-height: 0;
  /* R534：去掉内部 260px 死区，展开时随内容自然撑高，外层 60vh 封顶 + 滚动 */
  overflow: visible;
  padding: 2px 0;
  transition: max-height .3s ease;
}
.pet-profile-section.collapsed {
  /* R535：44px 裁切头部（header 27 + 上下 padding 20 = 47），实测按钮被切 → 放宽到 52px */
  max-height: 52px;
}
.pet-profile-section.collapsed .pps-body {
  max-height: 0;
  overflow: hidden;
  padding: 0;
}
/* 档案区内的 profile 组件适配紧凑空间 */
.pet-profile-section .profile-content { font-size: 13px; line-height: 1.7; }
.pet-profile-section .profile-hero { grid-template-columns: 1fr 1fr 1fr; gap: 8px; margin-bottom: 10px; }
.pet-profile-section .profile-stat { padding: 8px 10px; }
.pet-profile-section .profile-stat .v { font-size: 20px; }
.pet-profile-section .profile-block { margin-bottom: 8px; padding: 8px 10px; }

.profile-content { font-size: 13px; line-height: 1.7; }
.profile-hero { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; margin-bottom: 14px; }
.profile-stat { padding: 10px 12px; border-radius: var(--r-md); background: linear-gradient(135deg, #FFF8EE, #FFF); border: 1.5px solid #F5D6A8; text-align: center; }
.profile-stat .v { font-size: 22px; font-weight: 800; color: var(--brand); line-height: 1.2; }
.profile-stat .l { font-size: 11px; color: var(--ink3); margin-top: 2px; }
.profile-stat.s2 { border-color: #B5DDD2; background: linear-gradient(135deg, #E8F4F1, #FFF); }
.profile-stat.s2 .v { color: var(--brand2); }
.profile-stat.s3 { border-color: #BFD3E8; background: linear-gradient(135deg, #EAF2F9, #FFF); }
.profile-stat.s3 .v { color: var(--clean); }
.profile-block { margin-bottom: 12px; padding: 10px 12px; background: #FFF8EE; border-radius: var(--r-sm); }
.profile-block h5 { margin: 0 0 6px; font-size: 13px; color: var(--brand); font-weight: 700; }
.profile-tag { display: inline-block; padding: 2px 8px; background: rgba(232,131,58,.12); color: var(--brand); border-radius: 4px; font-size: 11px; margin: 2px; }
.profile-bar { display: flex; align-items: center; gap: 8px; padding: 3px 0; }
.profile-bar .lbl { flex: 0 0 80px; font-size: 12px; color: var(--ink2); }
.profile-bar .br { flex: 1; height: 8px; background: #EDE3D8; border-radius: 4px; overflow: hidden; }
.profile-bar .br > span { display: block; height: 100%; background: linear-gradient(90deg, var(--brand), var(--brand2)); border-radius: 4px; }
.profile-bar .cv { flex: 0 0 30px; text-align: right; font-size: 12px; color: var(--ink3); font-weight: 600; }
.profile-rec { padding: 10px 12px; background: linear-gradient(135deg, #E8F4F1, #FFF); border: 1.5px solid var(--brand2); border-radius: var(--r-md); }
.profile-rec h5 { margin: 0 0 6px; font-size: 13px; color: var(--brand2); font-weight: 700; }
.profile-rec-item { padding: 6px 0; font-size: 12px; cursor: pointer; color: var(--ink2); border-bottom: 1px dashed #D8EAE2; }
.profile-rec-item:last-child { border-bottom: 0; }
.profile-rec-item:hover { color: var(--brand2); }
.profile-rec-item .prti-t { font-weight: 600; color: var(--ink); }

/* R3(2026-09-29): 旧的 .msg-meta/.mm-tag 已废弃 —— R1 移除 talk.js 重复定义后，
   消息 meta 统一由 app.js 的 attachChatMeta 输出 .meta-tags/.meta-chip（见上方 R7 段），
   此处旧规则不再被任何代码生成，删除以免样式分叉。 */

/* R525: 单条消息删除按钮（悬浮显示，避免常驻干扰） */
.msg .msg-del {
  display: inline-block; margin-top: 4px; padding: 1px 7px;
  font-size: 11px; line-height: 1.5; color: var(--ink3);
  background: rgba(0,0,0,.04); border: 1px solid var(--line);
  border-radius: 6px; cursor: pointer; opacity: 0; transition: all .15s ease;
}
.msg:hover .msg-del { opacity: 1; }
.msg .msg-del:hover { color: #C0392B; background: #FDECEA; border-color: #F3C9C2; }


@media (max-width: 900px) {
  .profile-hero { grid-template-columns: 1fr 1fr; }
  .tool-grid-2 { grid-template-columns: 1fr; }
}

/* ================= 响应式断点 ================= */
@media (max-width: 1400px) {
  .qn-btn { font-size: 11px; }
  .qn-btn .ic { font-size: 16px; }
  .qn-btn .lb { font-size: 10px; }
}

@media (max-width: 1200px) {
  .qn-btn { padding: 4px 2px; min-height: 34px; }
  .qn-btn .ic { font-size: 15px; }
  .qn-btn .lb { font-size: 10px; }
}

@media (max-width: 1024px) {
  /* 平板横屏：2列布局（R512：pet-hub 横向通栏，宠物+子面板并排，充分利用宽度） */
  .grid-new { grid-template-columns: 1fr 1fr; }
  .pet-hub { grid-column: 1 / -1; }
  .func-panel { max-height: 50vh; overflow-y: auto; }
  .chat-full { min-height: 50vh; }
}

/* R512：平板竖屏（769-1024）补充——顶栏/登录卡/功能页单列，避免 768-1024 区间桌面级排版在窄竖屏溢出 */
@media (max-width: 1024px) {
  .topbar { padding: 6px 12px; gap: 5px; }
  .logo { font-size: 18px; }
  .pill { font-size: 13px; padding: 5px 11px; }
  .login-card { max-width: 420px; }
  .main-area.view-func .func-content { padding: 8px 12px; }
}

@media (max-width: 768px) {
  .layout-shell { flex-direction: column; }
  .main-area { padding: 4px; }
  .grid-new { grid-template-columns: 1fr; }
  .func-panel { max-height: none; overflow-y: visible; }
  .chat-full { min-height: 40vh; }
  .qn-btn-bar { padding: 6px 8px; gap: 4px; }
  .qn-btn { font-size: 12px; padding: 6px 3px; min-height: 42px; }
  .qn-btn .ic { font-size: 18px; }
  .qn-btn .lb { font-size: 11px; }
  /* R512：768 平板竖屏菜单保持单行可滚动，避免换行堆高 */
  .qn-btn-bar { flex-direction: row; flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .qn-btn-bar::-webkit-scrollbar { display: none; }
  .qn-btn { flex: 0 0 auto; }
}

@media (max-width: 700px) {
  .stats { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 480px) {
  body { font-size: 16px; }
  .topbar { padding: 6px 12px; gap: 6px; }
  .logo { font-size: 16px; }
  .pill { font-size: 13px; padding: 4px 10px; }
  .tabs { gap: 2px; }
  .tab { padding: 7px 12px; font-size: 13px; min-width: 64px; }
  .acts { grid-template-columns: repeat(4, 1fr); gap: 6px; }
  .act { padding: 10px 2px; font-size: 13px; min-height: 52px; }
  .act .ic { font-size: 18px; }
  .chatbox { height: 280px; }
  .login-card { padding: 30px 26px; }
  .login-card h1 { font-size: 22px; }
  .btn { padding: 12px; font-size: 15px; min-height: 52px; }
  .btn.sm { padding: 10px 16px; font-size: 14px; }
  .quick button { padding: 9px 16px; font-size: 14px; min-height: 40px; }
  .pet-type-btn { width: 58px; height: 58px; font-size: 30px; }
  /* 创新舱 */
  .inno-btn { padding: 6px 12px; font-size: 13px; }
  .mood-grid { grid-template-columns: repeat(5, 1fr); }
  .mood-b { min-width: 62px; font-size: 22px; }
  .breath-circle { width: 140px; height: 140px; font-size: 17px; }
  .sky-box { height: 260px; }
  /* 宠物乐园 */
  .dex-grid { grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); }
  .radar-svg { max-width: 260px; }
  .pp-combo-n { font-size: 27px; }
}


/* R12: 批量操作样式 */
.batch-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: var(--card);
  border-top: 1px solid var(--line);
  padding: 12px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  z-index: 1000;
  box-shadow: 0 -2px 10px rgba(0,0,0,.08);
  animation: slideUp .3s ease;
}
@keyframes slideUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
.batch-bar .count { font-size: 15px; color: var(--ink2); font-weight: 500; }
.batch-bar .actions { display: flex; gap: 10px; }
.batch-bar .actions button {
  padding: 8px 18px;
  border-radius: var(--r-sm);
  font-size: 14px;
  border: none;
  cursor: pointer;
  font-weight: 500;
}
.batch-bar .btn-batch-primary { background: var(--brand); color: #fff; }
.batch-bar .btn-batch-secondary { background: var(--line); color: var(--ink); }
.batch-item.selected { background: #FFF8F0; border-color: var(--brand); }
.batch-item input[type="checkbox"] { width: 18px; height: 18px; cursor: pointer; }
.batch-header { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.batch-header .select-all { display: flex; align-items: center; gap: 6px; cursor: pointer; font-size: 14px; }


/* R13: 键盘快捷键指示 */
.key-hint {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 18px;
  padding: 0 4px;
  font-size: 11px;
  font-family: monospace;
  background: var(--line);
  border-radius: 3px;
  color: var(--ink3);
  margin-left: 6px;
  vertical-align: middle;
}
kbd {
  display: inline-block;
  padding: 2px 6px;
  font-size: 12px;
  font-family: monospace;
  background: #f4f4f4;
  border: 1px solid #ccc;
  border-radius: 3px;
  box-shadow: 0 1px 0 #999;
}
.shortcut-hint {
  position: fixed;
  top: 60px;
  right: 20px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 12px 16px;
  font-size: 13px;
  color: var(--ink2);
  z-index: 1001;
  box-shadow: var(--sh);
  max-width: 240px;
}
.shortcut-hint h4 { margin: 0 0 8px 0; font-size: 14px; color: var(--ink); }
.shortcut-hint kbd { margin-right: 8px; }


/* R13: 焦点指示 */
*:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
button:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 2px;
}


/* R14: 宠物互动扩展样式 */
.pet-interact-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  padding: 12px 0;
}
.pet-interact-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 12px 8px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--card);
  cursor: pointer;
  transition: all .2s ease;
  font-size: 13px;
  color: var(--ink2);
}
.pet-interact-btn:hover {
  border-color: var(--brand);
  background: #FFF8F0;
  transform: translateY(-2px);
}
.pet-interact-btn:active {
  transform: translateY(0);
}
.pet-interact-btn .icon { font-size: 28px; }
.pet-interact-btn .label { font-size: 12px; font-weight: 500; }
.pet-interact-btn .cooldown {
  font-size: 10px;
  color: var(--ink3);
  margin-top: 2px;
}
.pet-interact-btn.disabled {
  opacity: .5;
  cursor: not-allowed;
}
.pet-interact-btn.disabled:hover {
  transform: none;
  border-color: var(--line);
  background: var(--card);
}
.interact-animation {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 80px;
  z-index: 2000;
  animation: interactPop .8s ease-out forwards;
  pointer-events: none;
}
@keyframes interactPop {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.5); }
  30% { opacity: 1; transform: translate(-50%, -50%) scale(1.2); }
  100% { opacity: 0; transform: translate(-50%, -60%) scale(1); }
}


/* R15: 战斗高级机制样式 */
.buff-indicator {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 600;
  animation: buffPop .3s ease;
}
@keyframes buffPop { from { transform: scale(0); } to { transform: scale(1); } }
.buff-positive { background: #E8F5E9; color: #2E7D32; }
.buff-negative { background: #FFEBEE; color: #C62828; }
.crit-flash {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(255, 68, 68, 0.1);
  pointer-events: none;
  z-index: 9999;
  animation: critFlash .3s ease-out forwards;
}
@keyframes critFlash { from { opacity: 1; } to { opacity: 0; } }
.combo-display {
  position: fixed;
  top: 80px;
  right: 20px;
  font-size: 24px;
  font-weight: 900;
  color: var(--brand);
  text-shadow: 0 2px 4px rgba(0,0,0,.2);
  z-index: 1000;
  animation: comboAppearFloat .5s ease;
}
/* R50 去重：comboAppear 原被定义两次且内容不同——3261 版为纯缩放，
   3389 版额外含 translateX(-50%) 居中定位；后者覆盖前者，
   使 .combo-float（3259 使用）丢失居中而错位。现拆分为两个独立命名，
   各自服务自己的使用场景。 */
@keyframes comboAppearFloat {
  0%{opacity:0;transform:scale(.5)} 100%{opacity:1;transform:scale(1)}
}
@keyframes comboAppearCentered {
  0%{opacity:0;transform:translateX(-50%) scale(.5)} 100%{opacity:1;transform:translateX(-50%) scale(1)}
}
.battle-stats-bar {
  display: flex;
  gap: 12px;
  padding: 8px 12px;
  background: var(--card);
  border-radius: var(--r-sm);
  margin-bottom: 12px;
  font-size: 13px;
}
.stat-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  background: var(--line);
  border-radius: 10px;
}


/* R16: 排行榜趋势可视化 */
.trend-chart {
  width: 100%;
  height: 200px;
  position: relative;
  margin: 16px 0;
}
.trend-line {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--brand) 0%, var(--brand2) 100%);
  border-radius: 2px;
}
.trend-point {
  position: absolute;
  width: 10px;
  height: 10px;
  background: var(--brand);
  border-radius: 50%;
  transform: translate(-50%, 50%);
  transition: all .3s ease;
}
.trend-point:hover {
  transform: translate(-50%, 50%) scale(1.5);
  box-shadow: 0 0 10px var(--brand);
}
.trend-label {
  position: absolute;
  bottom: -20px;
  font-size: 11px;
  color: var(--ink3);
  transform: translateX(-50%);
}
.trend-value {
  position: absolute;
  top: -25px;
  font-size: 11px;
  font-weight: 600;
  color: var(--ink);
  transform: translateX(-50%);
}


/* R18: 个性化设置中心 */
.settings-panel {
  background: var(--card);
  border-radius: var(--r-lg);
  padding: 20px;
  margin: 16px 0;
}
.setting-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}
.setting-item:last-child {
  border-bottom: none;
}
.setting-label {
  font-size: 15px;
  font-weight: 500;
}
.setting-control {
  display: flex;
  align-items: center;
  gap: 10px;
}
.toggle-switch {
  position: relative;
  width: 44px;
  height: 24px;
  background: var(--line);
  border-radius: 12px;
  cursor: pointer;
  transition: background .3s ease;
}
.toggle-switch.on {
  background: var(--brand);
}
.toggle-switch::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  background: white;
  border-radius: 50%;
  transition: transform .3s ease;
}
.toggle-switch.on::after {
  transform: translateX(20px);
}
.slider-control {
  width: 120px;
}



/* R26: 战斗视觉增强 */
.crit-flash { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(232,131,58,.15); pointer-events: none; z-index: 9999; animation: critFlash .3s ease-out forwards; }
.combo-display { position: fixed; top: 20%; left: 50%; transform: translateX(-50%); font-size: 32px; font-weight: 800; color: var(--brand); text-shadow: 0 2px 4px rgba(0,0,0,.2); z-index: 1000; animation: comboAppearCentered .5s ease; }
.buff-indicator { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 12px; font-weight: 600; margin: 2px; animation: buffPop .3s ease; }
.buff-positive { background: #E8F5E9; color: #2E7D32; }
.buff-negative { background: #FFEBEE; color: #C62828; }
.combat-log { max-height: 120px; overflow-y: auto; font-size: 12px; color: var(--ink2); padding: 8px; background: rgba(0,0,0,.03); border-radius: 6px; margin-top: 8px; }
.combat-log-entry { padding: 2px 0; border-bottom: 1px solid var(--line); }
.combat-log-entry:last-child { border-bottom: none; }

/* R20 / R478 修复：新手引导遮罩。
   遮罩本身可点击跳过，避免任何情况下永久挡住页面交互；提示卡 z-index 更高，
   按钮加主色高亮，进度条清晰可辨。 */
.tour-overlay {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(0,0,0,.32);
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;               /* 点击空白处即可跳过引导 */
  animation: fadeInPlain .25s ease;
}
.tour-tooltip {
  position: relative;
  z-index: 2001;
  cursor: default;
  background: var(--card);
  border-radius: var(--r-lg);
  padding: 24px;
  max-width: 420px;
  margin: 0 16px;
  box-shadow: 0 10px 40px rgba(0,0,0,.28);
  border: 1px solid rgba(255,255,255,.7);
  animation: popIn .28s cubic-bezier(.34,1.56,.64,1);
}
.tour-tooltip h3 {
  margin: 0 0 12px 0;
  font-size: 19px;
  color: var(--ink);
}
.tour-tooltip p {
  margin: 0 0 16px 0;
  font-size: 14px;
  color: var(--ink2);
  line-height: 1.7;
}
.tour-nav {
  display: flex;
  justify-content: space-between;
  gap: 10px;
}
.tour-nav button {
  padding: 8px 16px;
  font-size: 14px;
  border-radius: var(--r-sm);
  border: 1.5px solid var(--line);
  background: #fff;
  color: var(--ink2);
  cursor: pointer;
  transition: all .18s ease;
  font-family: inherit;
}
.tour-nav button:hover {
  border-color: var(--brand);
  color: var(--brand);
  transform: translateY(-1px);
  box-shadow: 0 3px 10px rgba(232,131,58,.18);
}
.tour-nav .tour-next {
  background: linear-gradient(135deg, var(--brand), var(--brand2));
  border-color: var(--brand);
  color: #fff;
  font-weight: 700;
  padding: 8px 24px;
}
.tour-nav .tour-next:hover {
  color: #fff;
  box-shadow: 0 4px 14px rgba(232,131,58,.35);
}
.tour-progress {
  margin-top: 14px;
  font-size: 12px;
  color: var(--ink3);
  text-align: center;
  font-variant-numeric: tabular-nums;
}
/* R50 去重：此处原为第三处 @keyframes fadeIn（纯淡入），
   会覆盖前面两处 fadeIn（淡入+上移），导致登录错误提示/告警框/空状态
   的上移效果全部失效。此处改名为 fadeInPlain，仅供引导遮罩（tour-mask）使用。 */
@keyframes fadeInPlain { from { opacity: 0; } to { opacity: 1; } }
@keyframes popIn { from { opacity: 0; transform: scale(.92) translateY(8px); } to { opacity: 1; transform: scale(1) translateY(0); } }

/* R56: 情感化设计 - 庆祝动画 */
.celebration {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 9999;
}
.confetti {
  position: absolute;
  width: 10px;
  height: 10px;
  animation: confettiFall 3s ease-out forwards;
}
@keyframes confettiFall {
  0% { transform: translateY(-100px) rotate(0deg); opacity: 1; }
  100% { transform: translateY(100vh) rotate(720deg); opacity: 0; }
}
.achievement-pop {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0);
  background: linear-gradient(135deg, #FFD700, #FFA500);
  color: #fff;
  padding: 24px 40px;
  border-radius: var(--r-xl);
  font-size: 20px;
  font-weight: 700;
  box-shadow: 0 10px 40px rgba(255,165,0,0.4);
  animation: achievementPop 2s ease-out forwards;
  z-index: 10000;
  text-align: center;
}
@keyframes achievementPop {
  0% { transform: translate(-50%, -50%) scale(0) rotate(-10deg); opacity: 0; }
  20% { transform: translate(-50%, -50%) scale(1.2) rotate(5deg); opacity: 1; }
  40% { transform: translate(-50%, -50%) scale(1) rotate(0deg); }
  80% { opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(0.8) rotate(0deg); opacity: 0; }
}
.pulse-anim {
  animation: pulse 0.6s ease-in-out;
}
/* R50 去重：此处原为重复的 pulse 定义（与 378 行完全相同），已删除 */

/* ================= R57: 响应式与触摸优化 ================= */
/* 禁止双击缩放，优化触摸体验 */
html, body {
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

/* R512：合并 pointer:coarse 触控目标规则（原 1954 与 2870 两处重复，统一收口在此）
   所有可点击控件 ≥44px，符合 W3C 触控可达性标准 */
@media (pointer: coarse) {
  .btn, .qn-btn, .act, .pet-type-btn, .theme-btn, .fc-btn {
    min-height: 44px;
    min-width: 44px;
  }
  .qn-btn {
    padding: 10px 6px;
  }
  .qn-btn .ic { font-size: 20px; }
  .qn-btn .lb { font-size: 12px; }
  .btn { padding: 18px; font-size: 18px; }
  * { -webkit-tap-highlight-color: transparent; }
  body { -webkit-touch-callout: none; }
}

/* 超小屏优化（360px及以下，适配2寸屏浏览器） */
@media (max-width: 360px) {
  body { font-size: 14px; }
  .topbar { padding: 4px 8px; gap: 4px; }
  .logo { font-size: 13px; }
  .pill { font-size: 11px; padding: 2px 6px; }
  .btn { padding: 10px 12px; font-size: 13px; min-height: 40px; }
  .qn-btn-bar { flex-direction: row; flex-wrap: wrap; padding: 4px; gap: 2px; }
  .qn-btn { font-size: 10px; padding: 4px 2px; min-height: 36px; }
  .qn-btn .ic { font-size: 14px; }
  .qn-btn .lb { font-size: 9px; }
  .func-content { padding: 4px; }
  .card { padding: 8px; }
  .pet-stage.mini canvas { height: 120px; }
  .acts.mini .act { padding: 6px 2px; font-size: 11px; min-height: 48px; }
  .chat-full { min-height: 40vh; }
  /* R512：超小屏横向单行底部菜单栏 + 功能页内容收窄 */
  .qn-btn-bar {
    flex-direction: row !important; flex-wrap: nowrap !important;
    overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none;
    padding: 4px 6px;
  }
  .qn-btn-bar::-webkit-scrollbar { display: none; }
  .qn-btn { flex: 0 0 auto; }
  .func-content { padding: 6px; }
}

/* 小屏优化（420px及以下） */
@media (max-width: 420px) {
  body { font-size: 15px; }
  .topbar { padding: 5px 10px; gap: 5px; }
  .btn { padding: 11px 16px; font-size: 14px; }
  .qn-btn { font-size: 11px; padding: 5px 3px; min-height: 38px; }
  .qn-btn .ic { font-size: 16px; }
  .qn-btn .lb { font-size: 10px; }
  .pet-stage.mini canvas { height: 150px; }
  .acts.mini .act { padding: 7px 3px; font-size: 12px; min-height: 52px; }
  .func-content { padding: 6px; }
  /* R512：420px 及以下功能页内容区 padding 收窄，最大化可用宽度 */
  .main-area.view-func .func-content { padding: 4px 8px; }
  .main-area.view-func .func-content > .pane { padding: 10px 12px; }
}

/* 中屏优化（540px及以下） */
@media (max-width: 540px) {
  .layout-shell { flex-direction: column; }
  .main-area { padding: 6px; }
  .grid-new { grid-template-columns: 1fr; }
  .pet-hub { order: 1; }
  .right-panel { order: 2; }
  .func-panel { order: 3; }
  .chat-full { min-height: 35vh; }
  /* R512：移动端菜单按钮改为横向单行可滚动底栏（iOS 风格），杜绝 33% 两行 30 个按钮溢出 */
  .qn-btn-bar {
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding: 6px 8px;
  }
  .qn-btn-bar::-webkit-scrollbar { display: none; }
  .qn-btn { flex: 0 0 auto; min-width: 56px; min-height: 44px; }
  /* 功能页单列 + 内容收窄 */
  .main-area.view-func .func-content { padding: 8px 10px; }
  .main-area.view-func .func-content > .pane { padding: 12px; }
}

/* 触摸反馈动画 */
.btn:active, .qn-btn:active, .act:active {
  transform: scale(0.96);
  opacity: 0.85;
}

/* 长按提示样式 */
.longpress-hint {
  position: fixed;
  background: rgba(0,0,0,0.75);
  color: #fff;
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 12px;
  pointer-events: none;
  z-index: 9999;
  opacity: 0;
  transition: opacity 0.2s;
}
.longpress-hint.show { opacity: 1; }

/* 滑动指示器 */
.swipe-indicator {
  position: fixed;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(232,131,58,0.9);
  color: #fff;
  padding: 12px 8px;
  border-radius: 8px;
  font-size: 20px;
  z-index: 999;
  opacity: 0;
  transition: opacity 0.3s;
  pointer-events: none;
}
.swipe-indicator.left { left: 10px; }
.swipe-indicator.right { right: 10px; }
.swipe-indicator.show { opacity: 1; }

/* ============ A1：心理测评 ============ */
.assess-disclaimer {
  background: #fff7ed; border: 1px solid #f5d9b0; color: #92591a;
  border-radius: 8px; padding: 9px 12px; font-size: 12.5px; line-height: 1.6; margin-bottom: 12px;
}
.assess-scale { border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; margin-bottom: 12px; background: #fff; }
.assess-scale h4 { margin: 0 0 8px; font-size: 14px; display: flex; align-items: center; gap: 8px; }
.assess-q { padding: 7px 0; border-top: 1px dashed #f0e9e0; }
.assess-q:first-of-type { border-top: none; }
.assess-q-t { font-size: 13.5px; color: var(--ink); margin-bottom: 6px; }
.assess-slider { display: flex; align-items: center; gap: 10px; }
.assess-slider input[type=range] { flex: 1; accent-color: var(--brand); }
.assess-val { min-width: 26px; text-align: center; font-weight: 700; color: var(--brand); background: #fbf3ec; border-radius: 6px; padding: 2px 0; }
.assess-opts { display: flex; flex-wrap: wrap; gap: 8px; }
.assess-opt { display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; background: #faf6f1; border: 1px solid var(--line); border-radius: 16px; padding: 4px 10px; cursor: pointer; }
.assess-opt input { margin: 0; }
.assess-result { margin-top: 12px; background: #fff; border: 1px solid var(--line); border-radius: 10px; padding: 14px; }
.assess-risk { display: inline-block; font-weight: 700; padding: 4px 12px; border-radius: 16px; font-size: 13px; margin-bottom: 10px; }
.assess-risk-low { background: #e6f5f0; color: #1f7a68; }
.assess-risk-medium { background: #fdf2dd; color: #9a6b00; }
.assess-risk-high { background: #fde8e8; color: #c0392b; }
.assess-bars { display: flex; flex-direction: column; gap: 7px; }
.assess-bar-row { display: flex; align-items: center; gap: 8px; font-size: 12.5px; }
.assess-bar-l { width: 56px; color: var(--ink2); flex-shrink: 0; }
.assess-bar-track { flex: 1; height: 10px; background: #f0eae2; border-radius: 6px; overflow: hidden; }
.assess-bar-fill { display: block; height: 100%; border-radius: 6px; transition: width .5s; }
.assess-bar-v { width: 28px; text-align: right; font-weight: 700; }
.assess-tips { margin-top: 12px; background: #f7fbfa; border: 1px solid #d6ece6; border-radius: 8px; padding: 10px 12px; font-size: 13px; }
.assess-tips ul { margin: 6px 0 0; padding-left: 18px; }
.assess-tips li { margin: 3px 0; line-height: 1.6; }
.assess-foot { margin: 10px 0 0; font-size: 11.5px; color: var(--ink3); }

/* ---------- 量表测评中心 ---------- */
.scale-disclaimer { background: #fff7ed; border: 1px solid #f5d9b0; color: #92591a; border-radius: 8px; padding: 9px 12px; font-size: 12.5px; line-height: 1.6; margin-bottom: 12px; }
.scale-disclaimer.sm { font-size: 11px; color: var(--ink3); background: #faf8f5; border-color: var(--line); margin-top: 10px; }
.scale-form-h { margin: 0 0 6px; font-size: 15px; color: var(--ink); }
.scale-desc { font-size: 12.5px; color: var(--ink3); margin: 0 0 10px; line-height: 1.6; }
.scale-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.scale-card { border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; background: #fff; display: flex; flex-direction: column; gap: 6px; transition: box-shadow .2s, transform .2s; }
.scale-card:hover { box-shadow: 0 4px 14px rgba(58,50,38,.08); transform: translateY(-2px); }
.scale-card-h { font-size: 14px; font-weight: 700; color: var(--ink); }
.scale-card-desc { font-size: 12px; color: var(--ink3); line-height: 1.5; min-height: 32px; }
.scale-card-meta { font-size: 11.5px; color: var(--ink2); }
.scale-card-actions { margin-top: auto; }
.scale-q { padding: 8px 0; border-top: 1px dashed #f0e9e0; }
.scale-q:first-of-type { border-top: none; }
.scale-q-t { font-size: 13.5px; color: var(--ink); margin-bottom: 6px; line-height: 1.5; }
.scale-opts { display: flex; flex-wrap: wrap; gap: 7px; }
.scale-opt { display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; background: #faf6f1; border: 1px solid var(--line); border-radius: 16px; padding: 4px 10px; cursor: pointer; }
.scale-opt:hover { border-color: var(--brand); }
.scale-opt input { margin: 0; accent-color: var(--brand); }
.scale-result { margin-top: 14px; background: #fff; border: 1px solid var(--line); border-radius: 10px; padding: 14px; }
.scale-result.normal { border-color: #bfe3d8; background: #f5fbf9; }
.scale-result.mild { border-color: #f3dca8; background: #fffbf2; }
.scale-result.moderate { border-color: #f0b48a; background: #fff6f0; }
.scale-result.severe { border-color: #e89a9a; background: #fdf0f0; }
.scale-result-h { font-size: 15px; color: var(--ink); margin-bottom: 6px; }
.scale-result-h b { color: var(--brand); }
.scale-result-sub { font-size: 13px; color: var(--ink2); margin-bottom: 8px; }
.scale-result-tip { font-size: 13px; line-height: 1.6; color: var(--ink); margin-bottom: 10px; }
.scale-alert { background: #fde8e8; color: #c0392b; border-radius: 8px; padding: 8px 10px; font-size: 12.5px; margin-bottom: 10px; line-height: 1.5; }
.scale-factors { display: flex; flex-direction: column; gap: 5px; margin-bottom: 10px; }
.scale-factor { display: flex; align-items: center; gap: 8px; font-size: 12.5px; padding: 5px 8px; background: #faf6f1; border-radius: 6px; }
.scale-factor-abn { background: #fdeaea; }
.scale-factor .sf-t { flex: 1; color: var(--ink); }
.scale-factor .sf-v { font-weight: 700; color: var(--ink2); }
.scale-factor .sf-l { color: var(--ink3); min-width: 48px; text-align: right; }
.scale-abn-h, .scale-sugg-h { font-size: 13px; font-weight: 700; color: var(--ink); margin: 8px 0 5px; }
.scale-abn { display: flex; flex-wrap: wrap; gap: 6px; }
.scale-abn-item { font-size: 12px; background: #fdeaea; color: #c0392b; border-radius: 12px; padding: 2px 9px; }
.scale-sugg { margin: 4px 0 0; padding-left: 18px; }
.scale-sugg li { font-size: 12.5px; color: var(--ink); line-height: 1.6; margin: 3px 0; }
.scale-detail-meta { font-size: 11.5px; color: var(--ink3); margin-bottom: 6px; }
.scale-hist { display: flex; flex-direction: column; gap: 6px; margin: 10px 0; }
.scale-hist-item { display: flex; align-items: center; gap: 10px; font-size: 13px; background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 8px 12px; cursor: pointer; transition: box-shadow .2s; }
.scale-hist-item:hover { box-shadow: 0 3px 10px rgba(58,50,38,.08); }
.scale-hist-d { color: var(--ink3); flex-shrink: 0; min-width: 64px; }
.scale-hist-title { font-weight: 600; color: var(--ink); flex: 1; }
.scale-hist-v { color: var(--ink2); flex-shrink: 0; }
.scale-hist-go { color: var(--brand); flex-shrink: 0; }
.scale-risk-pill { font-weight: 700; padding: 2px 9px; border-radius: 12px; font-size: 11.5px; flex-shrink: 0; }
.scale-risk-pill.normal { background: #e6f5f0; color: #1f7a68; }
.scale-risk-pill.mild { background: #fdf2dd; color: #9a6b00; }
.scale-risk-pill.moderate { background: #fde8d8; color: #b5640f; }
.scale-risk-pill.severe { background: #fde8e8; color: #c0392b; }

/* ---------- 量表测评中心（民警端） ---------- */
.scale-admin-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.scale-admin-toolbar select { font-size: 13px; padding: 6px 10px; border: 1px solid var(--line); border-radius: 8px; background: #fff; color: var(--ink); }
.scale-admin-chk { font-size: 13px; color: var(--ink2); display: inline-flex; align-items: center; gap: 4px; cursor: pointer; }
.scale-admin-sub { font-size: 14px; font-weight: 700; color: var(--ink); margin: 16px 0 8px; }
.scale-admin-tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; background: #fff; border-radius: 8px; overflow: hidden; box-shadow: 0 1px 4px rgba(58,50,38,.05); }
.scale-admin-tbl th, .scale-admin-tbl td { padding: 7px 10px; text-align: center; border-bottom: 1px solid var(--line); }
.scale-admin-tbl th { background: #faf6f1; color: var(--ink2); font-weight: 700; }
.scale-admin-tbl tbody tr:hover { background: #fff8f1; }
.scale-admin-tbl td.red { color: #c0392b; font-weight: 700; }
.scale-admin-tbl td.green { color: #1f7a68; }
.scale-abn-people { display: flex; flex-direction: column; gap: 10px; }
.scale-abn-person { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; background: #fff; }
.scale-abn-person.red { border-color: #e89a9a; background: #fdf0f0; }
.scale-abn-person.warn { border-color: #f3dca8; background: #fffbf2; }
.scale-abn-person-h { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13.5px; margin-bottom: 6px; }
.scale-abn-id { color: var(--ink3); font-size: 12px; }
.scale-abn-room { color: var(--ink2); font-size: 12px; }
.scale-abn-scales { display: flex; flex-direction: column; gap: 4px; }
.scale-abn-scale { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12.5px; }
.scale-abn-scale .sas-t { font-weight: 600; color: var(--ink); }
.scale-abn-scale .sas-v { color: var(--ink2); }
.scale-abn-scale .sas-f { color: #c0392b; font-size: 12px; }
.scale-abn-items { margin-top: 6px; font-size: 12px; color: #c0392b; line-height: 1.6; background: #fdeaea; border-radius: 6px; padding: 5px 8px; }

.assess-my-hdr, .assess-trend-hdr { font-weight: 700; font-size: 13.5px; margin: 14px 0 8px; color: var(--ink); }
.assess-hist { display: flex; flex-direction: column; gap: 6px; }
.assess-hist-item { display: flex; align-items: center; gap: 10px; font-size: 12.5px; background: #faf6f1; border-radius: 8px; padding: 6px 10px; }
.assess-hist-d { color: var(--ink3); }
.assess-hist-tag { font-size: 11px; padding: 1px 8px; border-radius: 10px; }
.assess-hist-v { color: var(--ink2); margin-left: auto; }
.assess-legend { display: flex; gap: 12px; justify-content: center; font-size: 11.5px; margin-top: 4px; color: var(--ink2); }
.assess-legend span { display: inline-flex; align-items: center; gap: 4px; }
.assess-legend i { width: 12px; height: 3px; border-radius: 2px; display: inline-block; }

/* 民警端心理测评看板 */
.assess-high-list { display: flex; flex-direction: column; gap: 6px; }
.assess-high-item { display: flex; align-items: center; gap: 10px; background: #fdeeee; border: 1px solid #f4cccc; border-radius: 8px; padding: 7px 10px; font-size: 13px; }
.assess-high-name { font-weight: 700; color: #c0392b; }
.assess-high-name small { font-weight: 400; color: var(--ink3); margin-left: 4px; }
.assess-high-v { color: var(--ink2); }
.assess-high-date { margin-left: auto; color: var(--ink3); font-size: 12px; }
.num.red { color: #d9534f; }
.num.warn { color: #e0a000; }

/* ===== B1 个性化干预推荐 ===== */
/* 学员端：建议卡片列表 */
.iv-list { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.iv-item { border: 1px solid var(--line); border-left: 4px solid var(--brand2); border-radius: var(--r-md); padding: 12px 14px; background: var(--card); box-shadow: var(--sh); }
.iv-item.iv-high { border-left-color: #d9534f; background: var(--bg-error); }
.iv-item.iv-medium { border-left-color: #e0a000; background: var(--bg-warn); }
.iv-item.iv-low { border-left-color: var(--ok); background: var(--bg-ok); }
.iv-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.iv-basis { font-weight: 700; color: var(--ink); font-size: 14px; }
.iv-risk { margin-left: auto; font-size: 11.5px; padding: 2px 9px; border-radius: 10px; font-weight: 700; }
.iv-body { color: var(--ink); line-height: 1.75; font-size: 14.5px; white-space: pre-wrap; }
.iv-foot { margin-top: 8px; }
.iv-date { color: var(--ink3); font-size: 12px; }

/* 民警端：生成 / 审核面板 */
.ivx-stats { display: flex; gap: 10px; flex-wrap: wrap; margin: 10px 0; }
.ivx-stat { flex: 1 1 120px; background: var(--bg-muted); border: 1px solid var(--line); border-radius: var(--r-md); padding: 10px 14px; }
.ivx-stat .ivx-n { display: block; font-size: 22px; font-weight: 800; color: var(--brand-deep); }
.ivx-stat .ivx-l { color: var(--ink3); font-size: 12.5px; }
.ivx-gen { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 10px 0 4px; }
.ivx-gen select { padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--card); color: var(--ink); font-size: 13.5px; }
.ivx-sec { margin-top: 18px; }
.ivx-sec-h { font-weight: 800; color: var(--ink); margin-bottom: 8px; display: flex; align-items: center; gap: 8px; }
.ivx-sec-h .ivx-cnt { font-size: 12px; font-weight: 700; color: var(--brand-deep); background: var(--bg-warn); padding: 1px 8px; border-radius: 10px; }
.ivx-list { display: flex; flex-direction: column; gap: 10px; }
.ivx-card { border: 1px solid var(--line); border-left: 4px solid var(--brand); border-radius: var(--r-md); padding: 12px 14px; background: var(--card); }
.ivx-card.ivx-high { border-left-color: #d9534f; }
.ivx-card.ivx-medium { border-left-color: #e0a000; }
.ivx-card.ivx-low { border-left-color: var(--ok); }
.ivx-card-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.ivx-name { font-weight: 800; color: var(--ink); }
.ivx-name small { font-weight: 400; color: var(--ink3); margin-left: 4px; }
.ivx-tag { font-size: 11.5px; padding: 2px 9px; border-radius: 10px; font-weight: 700; }
.ivx-tag.high { background: #fdeeee; color: #c0392b; }
.ivx-tag.medium { background: #fff6e0; color: #a97a00; }
.ivx-tag.low { background: #e8f5e9; color: #2e7d32; }
.ivx-tag.pending { background: #fff6e0; color: #a97a00; }
.ivx-tag.sent { background: #e8f5e9; color: #2e7d32; }
.ivx-tag.rejected { background: #f0f0f0; color: #888; }
.ivx-basis { color: var(--ink2); font-size: 13px; }
.ivx-date { margin-left: auto; color: var(--ink3); font-size: 12px; }
.ivx-sugg { color: var(--ink); line-height: 1.75; font-size: 14px; white-space: pre-wrap; }
.ivx-actions { margin-top: 10px; display: flex; gap: 8px; }
.ivx-btn { padding: 6px 14px; border: none; border-radius: var(--r-sm); cursor: pointer; font-size: 13.5px; font-weight: 700; transition: var(--transition); }
.ivx-btn.approve { background: var(--ok); color: #fff; }
.ivx-btn.reject { background: #fff; color: #c0392b; border: 1px solid #e6b0aa; }
.ivx-btn:hover { opacity: .88; }

/* ===== R11(HCI)：民警端预警筛选条 =====
   值班扫视场景：把「高危/待处置」做成可一键聚焦的入口，
   并在按钮上直接显示各档数量（信息前置，避免无效点击）。 */
.alert-filter-bar { display: flex; gap: 8px; flex-wrap: wrap; margin: 10px 0 12px; }
.alert-filter-bar .af-btn {
  min-height: 40px; padding: 8px 14px; border-radius: 999px;
  border: 1px solid var(--line, #e3e0da); background: var(--card2, #fff);
  color: var(--ink2, #555); font-size: 15px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  transition: background .15s, color .15s, border-color .15s;
}
.alert-filter-bar .af-btn:hover { border-color: var(--brand); color: var(--brand); }
.alert-filter-bar .af-btn.on {
  background: var(--brand); color: #fff; border-color: var(--brand); font-weight: 600;
}
.alert-filter-bar .af-btn span {
  font-size: 13px; opacity: .8; background: rgba(0,0,0,.07);
  border-radius: 999px; padding: 1px 7px; min-width: 20px; text-align: center;
}
.alert-filter-bar .af-btn.on span { background: rgba(255,255,255,.25); }
@media (max-width: 560px) {
  .alert-filter-bar .af-btn { flex: 1 1 auto; justify-content: center; font-size: 14px; padding: 8px 10px; }
}

/* ===== R12(HCI)：预警批量处置条 ===== */
.alert-batch-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; margin: 0 0 10px;
  border-radius: 10px; background: rgba(232,131,58,.10);
  border: 1px solid rgba(232,131,58,.35);
  position: sticky; top: 0; z-index: 5;
}
.alert-batch-bar .ab-txt { font-size: 15px; color: var(--ink2, #555); }
.alert-batch-bar .ab-txt b { color: var(--brand); font-size: 17px; }
.alert-batch-bar .btn.sm { min-height: 40px; }
@media (max-width: 560px) {
  .alert-batch-bar { gap: 8px; padding: 8px 10px; }
  .alert-batch-bar .btn.sm { flex: 1 1 auto; justify-content: center; }
}

/* ===== R13(HCI)：求助等待态状态条 ===== */
.help-wait-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px; margin: 0 0 10px;
  border-radius: 12px;
  background: linear-gradient(90deg, rgba(255,193,120,.22), rgba(255,224,178,.12));
  border: 1px solid rgba(232,131,58,.4);
}
.help-wait-bar .hw-ic { font-size: 22px; line-height: 1; }
.help-wait-bar .hw-txt { flex: 1 1 auto; display: flex; flex-direction: column; line-height: 1.35; }
.help-wait-bar .hw-txt b { font-size: 16px; color: var(--ink); }
.help-wait-bar .hw-sub { font-size: 13px; color: var(--ink2, #666); }
.help-wait-bar .hw-btn {
  flex: 0 0 auto; min-height: 40px; padding: 8px 14px;
  border-radius: 999px; border: 1px solid rgba(232,131,58,.55);
  background: #fff; color: var(--brand); font-size: 15px; cursor: pointer;
}
.help-wait-bar .hw-btn:hover { background: var(--brand); color: #fff; }
@media (max-width: 560px) {
  .help-wait-bar { flex-wrap: wrap; padding: 9px 12px; }
  .help-wait-bar .hw-btn { width: 100%; justify-content: center; }
}

/* ===== R14(HCI)：草稿恢复提示 ===== */
.draft-tip {
  align-self: center; max-width: 90%;
  margin: 6px auto; padding: 6px 12px;
  border-radius: 999px; background: rgba(120,160,255,.12);
  border: 1px dashed rgba(120,160,255,.45);
  font-size: 13px; color: var(--ink2, #666); text-align: center;
}

/* ===== R15(HCI)：连接状态条 ===== */
.net-pill {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 14px; margin: 0 0 10px;
  border-radius: 10px;
  background: rgba(120,130,145,.12);
  border: 1px solid rgba(120,130,145,.32);
  font-size: 14px; color: var(--ink2, #666);
}
.net-pill .np-ic { font-size: 17px; line-height: 1; }

/* ===== R26：学员端统一确认弹窗（替代原生 confirm）=====
   原生 confirm 无法定制样式、不响应主题、在内网旧浏览器上还会挡住整页渲染，
   且与民警端已建成的自定义弹窗观感不一致。此处提供同构替代。 */
.cf-overlay {
  position: fixed; top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(30,24,18,.5);
  display: flex; align-items: center; justify-content: center;
  z-index: 200; opacity: 0; pointer-events: none; transition: opacity .2s ease;
}
.cf-overlay.on { opacity: 1; pointer-events: auto; }
.cf-box {
  width: 92vw; max-width: 400px; background: var(--card);
  border-radius: var(--r-lg); box-shadow: 0 18px 50px rgba(0,0,0,.28);
  padding: 22px 22px 16px;
  transform: translateY(12px) scale(.98);
  transition: transform .2s cubic-bezier(.4,0,.2,1);
}
.cf-overlay.on .cf-box { transform: none; }
.cf-title { margin: 0 0 10px; font-size: 18px; font-weight: 700; color: var(--ink); }
.cf-text { margin: 0 0 18px; font-size: 15px; line-height: 1.75; color: var(--ink2); white-space: pre-wrap; word-break: break-word; }
.cf-actions { display: flex; gap: 10px; justify-content: flex-end; }
.cf-btn {
  min-height: 44px; padding: 0 20px; border-radius: var(--r-sm);
  font-size: 15px; cursor: pointer; border: 1px solid var(--line);
  background: #fff; color: var(--ink); font-family: inherit;
}
.cf-btn:focus-visible { outline: 2.5px solid var(--brand); outline-offset: 2px; }
.cf-btn.primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.cf-btn.danger { background: var(--warn); border-color: var(--warn); color: #fff; }
@media (prefers-reduced-motion: reduce) { .cf-overlay, .cf-box { transition: none; } }
@media (max-width: 420px) { .cf-actions { flex-direction: column-reverse; } .cf-btn { width: 100%; } }

/* ===== R28：高对比度模式 =====
   修复前：JS 会切换 html/body 的 .high-contrast 类，但 CSS 里没有任何对应规则，
   导致这个无障碍开关点了完全没反应（纯空壳）。此处补齐真实生效的样式：
   文字提至纯黑、分隔线加深、控件边框加粗，满足 WCAG 增强对比（AAA 方向）。 */
html.high-contrast, body.high-contrast {
  --bg: #FFFFFF;
  --card: #FFFFFF;
  --ink: #000000;
  --ink2: #141414;
  --ink3: #1F1F1F;
  --line: #6E6E6E;
  --brand: #8F3D00;
  --brand-deep: #6B2B00;
  --brand2: #0F5D55;
  --warn: #9C1B08;
  --ok: #0F4C26;
}
html.high-contrast .btn, body.high-contrast .btn,
html.high-contrast .btn.sm, body.high-contrast .btn.sm,
html.high-contrast .qn-btn, body.high-contrast .qn-btn,
html.high-contrast .inno-btn, body.high-contrast .inno-btn {
  border-width: 2px;
  border-color: currentColor;
}
html.high-contrast input, body.high-contrast input,
html.high-contrast textarea, body.high-contrast textarea,
html.high-contrast select, body.high-contrast select {
  border-width: 2px;
  border-color: #000000;
  color: #000000;
}
html.high-contrast a, body.high-contrast a { text-decoration: underline; }
html.high-contrast .toast, body.high-contrast .toast {
  background: #000000 !important; color: #FFFFFF !important;
}

/* ===== R28：阅读模式 =====
   修复前同样是空壳。此处按长文阅读的可读性研究给出实际排版：
   放大字号、放宽行距与行宽、停掉宠物装饰动画以降低干扰。 */
html.reading-mode .bub, body.reading-mode .bub {
  max-width: 46em;
  font-size: 17px;
  line-height: 2.0;
  letter-spacing: .01em;
}
html.reading-mode .pet-stage, body.reading-mode .pet-stage,
html.reading-mode #petImg, body.reading-mode #petImg {
  animation: none !important;
}
@media (prefers-reduced-motion: reduce) {
  html.reading-mode .bub, body.reading-mode .bub { transition: none; }
}

/* R10：四个功能面板的可达性增强（键盘焦点高亮 + 减少动效偏好） */
.ps-nav-btn:focus-visible,
.badge-card:focus-visible,
.battle-history-item:focus-visible,
.task .btn:focus-visible,
.act:focus-visible,
.battle-again-btn:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
/* 尊重系统「减少动效」偏好：关闭新增的入场/循环动画 */
@media (prefers-reduced-motion: reduce) {
  .badge-card.got, .badge-card.just-unlocked, .battle-again-btn,
  .bh-detail, .badge-detail, .tree-icon, .ts-node.current { animation: none !important; }
  .tree-icon { animation: none !important; }
}

/* ==========================================================
 * R11–R20 成长数据中心（.dc 系列）
 * ========================================================== */
.dc { display: flex; flex-direction: column; gap: 14px; padding: 4px 2px; }

/* 概览卡 */
.dc-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; }
.dc-card {
  background: linear-gradient(135deg, #FFF7EE, #F1F8F5);
  border: 1px solid var(--line, #E5DDD0); border-radius: 12px;
  padding: 14px 10px; text-align: center;
}
.dc-card .dc-ic { font-size: 22px; }
.dc-card .dc-num { font-size: 26px; font-weight: 800; color: var(--brand, #2E9E8F); line-height: 1.2; }
.dc-card .dc-lb { font-size: 12px; color: var(--muted, #8a8175); margin-top: 2px; }
.dc-card.dc-hot .dc-num { color: #E8833A; }

/* 两列网格（热力图 + 目标环） */
.dc-grid2 { display: grid; grid-template-columns: 1.6fr 1fr; gap: 14px; }
@media (max-width: 720px) { .dc-grid2 { grid-template-columns: 1fr; } }

.dc-sec { background: #fff; border: 1px solid var(--line, #E5DDD0); border-radius: 12px; padding: 12px 14px; }
.dc-sec h4 { margin: 0 0 10px; font-size: 15px; color: var(--ink, #4a4036); }

/* 热力图 */
.dc-heat { display: grid; grid-template-columns: repeat(10, 1fr); gap: 4px; }
.dc-cell {
  aspect-ratio: 1 / 1; border-radius: 4px; background: #F0EAE0;
  display: flex; align-items: center; justify-content: center;
  font-size: 10px; color: #fff; font-weight: 700;
}
.dc-cell.lvl1 { background: #CFE6DC; color: #5b8a7a; }
.dc-cell.lvl2 { background: #8FCBB8; color: #fff; }
.dc-cell.lvl3 { background: #2E9E8F; color: #fff; }
.dc-heat-legend { display: flex; align-items: center; gap: 4px; margin-top: 8px; font-size: 11px; color: var(--muted, #8a8175); }
.dc-heat-legend .dc-cell { width: 14px; aspect-ratio: 1/1; }

/* 目标环 */
.dc-ring { position: relative; width: 92px; height: 92px; margin: 0 auto; }
.dc-ring-num { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 26px; font-weight: 800; color: var(--brand, #2E9E8F); }
.dc-ring-tip { text-align: center; font-size: 12px; color: var(--muted, #8a8175); margin-top: 8px; }

/* 任务分布条 */
.dc-bars { display: flex; flex-direction: column; gap: 8px; }
.dc-bar-row { display: grid; grid-template-columns: 92px 1fr 34px; align-items: center; gap: 8px; }
.dc-bar-lb { font-size: 13px; color: var(--ink, #4a4036); text-align: right; }
.dc-bar-track { background: #F0EAE0; border-radius: 6px; height: 12px; overflow: hidden; }
.dc-bar-fill { display: block; height: 100%; background: linear-gradient(90deg, #E8833A, #2E9E8F); border-radius: 6px; transition: width .6s ease; }
.dc-bar-v { font-size: 12px; color: var(--muted, #8a8175); text-align: right; }

/* 战斗战绩 */
.dc-battle { display: grid; grid-template-columns: repeat(auto-fit, minmax(80px, 1fr)); gap: 10px; }
.dc-bc { background: #F7F2EA; border-radius: 10px; padding: 12px 6px; text-align: center; }
.dc-bc-v { display: block; font-size: 22px; font-weight: 800; color: var(--ink, #4a4036); }
.dc-bc.win .dc-bc-v { color: #2E9E8F; }
.dc-bc.lose .dc-bc-v { color: #C76B5A; }
.dc-bc.hot .dc-bc-v { color: #E8833A; }
.dc-bc-l { font-size: 11px; color: var(--muted, #8a8175); margin-top: 2px; }

/* 徽章收集 */
.dc-bs-bar { background: #F0EAE0; border-radius: 6px; height: 14px; position: relative; overflow: hidden; margin-bottom: 10px; }
.dc-bs-fill { display: block; height: 100%; background: linear-gradient(90deg, #E8833A, #2E9E8F); }
.dc-bs-pct { position: absolute; right: 6px; top: 0; line-height: 14px; font-size: 11px; color: #fff; font-weight: 700; }
.dc-badges { display: grid; grid-template-columns: repeat(auto-fill, minmax(78px, 1fr)); gap: 8px; }
.dc-badge { background: #F2ECE3; border: 1px solid #E5DDD0; border-radius: 10px; padding: 8px 4px; text-align: center; opacity: .55; }
.dc-badge.got { opacity: 1; background: linear-gradient(135deg, #FFF7EE, #F1F8F5); border-color: #E9C9A0; }
.dc-badge-ic { font-size: 20px; display: block; }
.dc-badge-nm { font-size: 11px; color: var(--ink, #4a4036); margin-top: 2px; display: block; }

/* 空状态 */
.dc-empty { font-size: 13px; color: var(--muted, #8a8175); padding: 12px; text-align: center; background: #FAF6EF; border-radius: 10px; }
.dc-empty-hero { padding: 18px; font-size: 14px; }

/* 减少动效：关闭进度条过渡 */
@media (prefers-reduced-motion: reduce) {
  .dc-bar-fill, .dc-bs-fill, .dc-ring circle { transition: none !important; }
}


/* ============================================================
 * UI 迭代 R1–R10 （20261003-opt14）统一追加区
 * 按迭代轮次分段，便于回溯与逐轮校验
 * ============================================================ */

/* ---------- R2(UI迭代)：触控目标尺寸统一 ≥44px ----------
   依据 WCAG 2.5.5 Target Size (Enhanced) 与移动端实测：
   顶部主导航、宠物左侧竖排子导航、分组子菜单、图标按钮
   原高度均<44px，手指误触率高。此处统一补min-height/min-width，
   并用 flex 居中保证图标+文字仍垂直居中（不因加高而错位）。
   仅在「粗指针/触屏」设备生效，避免影响桌面端紧凑布局。 */
@media (pointer: coarse) {
  .main-nav-btn { min-height: 48px; min-width: 64px; }
  .ps-nav-btn   { min-height: 60px; min-width: 56px; }
  .gm-btn       { min-height: 44px; min-width: 44px; padding: 9px 16px; }
  .qn-btn       { min-height: 44px; min-width: 44px; }
  .pet-settings-btn { width: 44px; height: 44px; }   /* 原 32px，远小于下限 */
  .pet-type-btn { width: 60px; height: 60px; }
  .theme-btn    { min-height: 44px; min-width: 44px; }
  .close-btn, .modal-close { min-width: 44px; min-height: 44px; }
  /* 选项卡类（答题/情景等） */
  .tab, .opt-btn, .opt { min-height: 48px; }
  /* 图标类小按钮 */
  .icon-btn, .mini-btn { min-width: 44px; min-height: 44px; }
}

/* ---------- R3(UI迭代)：补齐缺失的焦点环 ----------
   实测发现 .main-nav-btn / .gm-btn / .theme-btn / .help-btn /
   .pet-settings-btn / .pet-type-btn 这6 类可聚焦元素都没有自己的
   :focus-visible 规则。虽然全局 button:focus-visible 有兜底描边，
   但这些按钮自带 border/background，兜底描边与其配色对比不足，
   键盘操作时几乎看不出焦点在哪。统一补双层描边（内亮外深），
   在浅色/暗色主题下都能辨认，且不改变布局（用 outline 不占空间）。 */
.main-nav-btn:focus-visible,
.gm-btn:focus-visible,
.theme-btn:focus-visible,
.help-btn:focus-visible,
.pet-settings-btn:focus-visible,
.pet-type-btn:focus-visible,
.pet-style-btn:focus-visible,
.close-btn:focus-visible,
.modal-close:focus-visible {
  outline: 2.5px solid var(--brand-deep);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgba(232,131,58,.20);
  border-radius: var(--r-sm);
}
/* 已在选中态的导航按钮：焦点环改用内层浅色，避免与选中底色糊在一起 */
.main-nav-btn.on:focus-visible,
.gm-btn.on:focus-visible,
.theme-btn.on:focus-visible {
  box-shadow: 0 0 0 3px rgba(255,255,255,.85), 0 0 0 6px rgba(232,131,58,.45);
}
/* 跳转链接聚焦时不仅滑入，还要在暗底上可读 */
.skip-link:focus-visible {
  outline: 3px solid #fff;
  outline-offset: -3px;
  box-shadow: 0 4px 14px rgba(0,0,0,.28);
}
/* 落点容器聚焦时不显示描边（它只是跳转终点，不是控件） */
.main-area:focus { outline: none; }
.main-area:focus-visible { outline: none; }

/* ---------- R4(UI迭代)：骨架屏/空状态统一与防卡死 ----------
   1) 统一 4 个此前为空的容器（勋章/战斗记录/成长树/数据中心）预置骨架，消除闪屏
   2) 骨架容器加 min-height：即使JS 未渲染出内容，也保留合理高度，
      避免「元素高度为 0 → 面板塌陷 → 布局跳动」连带影响同栏其他面板
   3) 减少动效偏好下关闭流光（shimmer），改为静态浅色块——静态块仍可读，
      不会像动画那样持续闪烁干扰注意力障碍用户
   4) 尊重 forced-colors（Windows 高对比度）：骨架背景改为系统 Canvas，
      强制描边，保证高对比模式下依然看得出「这里有内容在加载」 */
.loading-skeleton { min-height: 92px; justify-content: center; }
#badgeList .loading-skeleton,
#battleHistoryList .loading-skeleton,
.tree-box .loading-skeleton { min-height: 120px; }
#growthBox .loading-skeleton { min-height: 220px; }

/* 骨架与真实内容切换时不留残影：容器本身给个最小高度 */
#badgeList, #battleHistoryList, #treeBox, #growthBox { min-height: 72px; }

@media (prefers-reduced-motion: reduce) {
  .skeleton, .loading-skeleton .skeleton {
    animation: none !important;
    background: #F1EAE1;
  }
  /* 无动画时给一点边框，保持「占位中」的视觉暗示 */
  .skeleton-line { outline: 1px dashed #DCD0C0; outline-offset: -1px; }
}
@media (forced-colors: active) {
  .skeleton, .loading-skeleton .skeleton {
    background: Canvas; border: 1px solid CanvasText; animation: none !important;
  }
}
/* 空状态与错误态也补最小高度，避免同一面板在「有内容/无内容」间切换时高度剧烈跳动 */
.empty-state, .error-state { min-height: 120px; }

/* ============================================================
 * R5(UI迭代)：暗色模式（独立开关，与 9 套彩色主题正交）
 * ============================================================
   设计要点（踩过的坑）：
   ① 绝不复用 data-theme 属性传 'dark'——该属性已被 9 套彩色主题占用，
      且 selectTheme() 的 VALID_THEMES 白名单里没有 dark，
      两者混用会导致主题校验失败被强制回退成 warm。
      故新增独立的 data-dark="1" 属性，与主题色完全正交：
      可任意组合「暗色 × 9 种主题色」。
   ② 主体走CSS 变量覆写（.card/.main-area/.pane 等已用令牌，天然适配）；
      对无法改动的历史硬编码浅色（渐变/徽章卡/聊天气泡等），
      追加定向覆写块兜底，避免暗色下出现「白底黑字」的刺眼割裂。
   ③ 颜色取自中性深色（#1B1814 系），文字用 #EDE6DA，对比度 ≥ 12:1，
      符合 WCAG AAA 正文要求。 */
[data-dark="1"] {
  color-scheme: dark;
  /* 背景层 */
  --bg:#17140F; --bg-muted:#1E1A15; --card:#221E18;
  /* 文字层：ink2/ink3 提到 AA 以上，弱层级但不牺牲可读性 */
  --ink:#EDE6DA; --ink2:#C3B9A9; --ink3:#A2968A;
  --line:#3A342B; --border:#3A342B;
  /* 品牌色在暗背景上需提亮，否则对比度不足 */
  --brand:#F0A05C; --brand-deep:#F5B77E; --brand2:#59C2B2;
  --sh: 0 1px 3px rgba(0,0,0,.42), 0 6px 20px rgba(0,0,0,.32);
  --bg-ok:#16301F; --bg-warn:#33280F; --bg-error:#3A1A17;
}

/* 定向覆写：把历史硬编码浅色在暗色下翻转 */
[data-dark="1"] body { background: var(--bg); color: var(--ink); }
/* 顶栏与主容器 */
[data-dark="1"] .topbar {
  background: linear-gradient(180deg, #201C16 0%, #1C1813 100%);
  border-bottom-color: #3A342B;
}
/* 导航按钮组 */
[data-dark="1"] .main-nav-btn,
[data-dark="1"] .gm-btn,
[data-dark="1"] .qn-btn,
[data-dark="1"] .ps-nav-btn {
  background: #241F19; border-color: #3A342B; color: var(--ink2);
}
[data-dark="1"] .main-nav-btn:hover,
[data-dark="1"] .gm-btn:hover,
[data-dark="1"] .qn-btn:hover,
[data-dark="1"] .ps-nav-btn:hover { background: #2C261E; border-color: #4A4237; }
[data-dark="1"] .qn-btn.on,
[data-dark="1"] .main-nav-btn.on,
[data-dark="1"] .ps-nav-btn.on {
  background: linear-gradient(135deg, #2E9E8F, #1F7A8C);
  border-color: #2E9E8F; color: #FFFFFF;
}
/* 卡片与面板 */
[data-dark="1"] .card,
[data-dark="1"] .badge-group,
[data-dark="1"] .inno-sec,
[data-dark="1"] .tool-section,
[data-dark="1"] .talk-step { background: var(--card); border-color: var(--line); }
[data-dark="1"] .card:hover { box-shadow: 0 4px 20px rgba(0,0,0,.42); }
[data-dark="1"] .pet-hub,
[data-dark="1"] .right-panel,
[data-dark="1"] .main-area { background: transparent; }
/* 输入框：暗色下必须显式给背景，否则浏览器自动渲染成白底黑字 */
[data-dark="1"] input,
[data-dark="1"] textarea,
[data-dark="1"] select {
  background: #1A1712; color: var(--ink); border-color: #3A342B;
  caret-color: var(--brand);
}
[data-dark="1"] input::placeholder,
[data-dark="1"] textarea::placeholder { color: #857A6E; }
[data-dark="1"] input:focus,
[data-dark="1"] textarea:focus,
[data-dark="1"] select:focus {
  background: #1F1B16; border-color: var(--brand);
  box-shadow: 0 0 0 4px rgba(240,160,92,.18);
}
/* 选项与列表项 */
[data-dark="1"] .opt,
[data-dark="1"] .mitem,
[data-dark="1"] .act,
[data-dark="1"] .rank-row { background: #221E18; border-color: #3A342B; color: var(--ink); }
[data-dark="1"] .opt:hover,
[data-dark="1"] .mitem:hover,
[data-dark="1"] .act:hover { background: #2C261E; border-color: #4A4237; }
/* 聊天气泡：本人/对方都要翻转，否则白气泡在暗底上极其刺眼 */
[data-dark="1"] .msg .bub { color: var(--ink); }
[data-dark="1"] .msg .bub.me { background: #3A2E22; color: #F5E9DA; }
[data-dark="1"] .msg .bub:not(.me) { background: #262119; }
/* 徽章卡：已得/未得两态都要有暗色版 */
[data-dark="1"] .badge-card.locked { background: #1F1B16; border-color: #332E27; }
[data-dark="1"] .badge-card.locked .badge-name { color: var(--ink2); }
[data-dark="1"] .badge-card.got {
  background: linear-gradient(135deg, #3D2F1E 0%, #4A3520 100%);
  border-color: #6B4E2C;
}
[data-dark="1"] .badge-card.got .badge-name { color: #F7D9AE; }
[data-dark="1"] .badge-group.complete { background: linear-gradient(135deg, #33281A, #2A2114); border-color: #5A4527; }
[data-dark="1"] .badge-summary { background: linear-gradient(135deg, #241F19, #1D2422); border-color: #3A342B; }
[data-dark="1"] .badge-group-hd { border-bottom-color: #3A342B; }
/* 弹窗与遮罩 */
[data-dark="1"] .modal { background: rgba(0,0,0,.66); }
[data-dark="1"] .modal-content,
[data-dark="1"] .login-card { background: var(--card); color: var(--ink); border-color: var(--line); }

/* R45 暗色补漏（聊天/宠物侧栏控件）：
   下列控件原为硬编码 background:#fff，暗色模式下是刺眼白块，
   与整体深色主题割裂。按暗色变量统一翻转。 */
[data-dark="1"] .fp-btn,
[data-dark="1"] .lh-btn,
[data-dark="1"] .chat-focus-btn,
[data-dark="1"] .pet-settings-btn,
[data-dark="1"] .pet-type-btn,
[data-dark="1"] .pet-mini-btn,
[data-dark="1"] .pet-action-btn {
  background: var(--card);
  border-color: var(--line);
  color: var(--ink2);
}
[data-dark="1"] .fp-btn:hover,
[data-dark="1"] .lh-btn:hover,
[data-dark="1"] .chat-focus-btn:hover,
[data-dark="1"] .pet-settings-btn:hover {
  background: #2C261E;
  color: var(--ink);
}
/* 选中态按钮原为白底反白，暗色下改为深底+亮描边，保持"已选中"可辨 */
[data-dark="1"] .fp-btn.on,
[data-dark="1"] .lh-btn.on,
[data-dark="1"] .chat-focus-btn.on {
  background: #2C261E;
  color: var(--brand);
  border-color: var(--brand);
}
/* 宠物语音气泡 */
[data-dark="1"] .speech {
  background: var(--card);
  border-color: var(--line);
  color: var(--ink);
}

/* R42 暗色补漏：登录页背景与宠物舞台原为硬编码亮色渐变，
   暗色模式下仍是刺眼亮块，与整体深色割裂（"半边亮半边暗"）。此处按暗色变量翻转。 */
[data-dark="1"] .login-wrap {
  background:
    radial-gradient(1100px 560px at 18% 8%, #2A2419 0%, transparent 60%),
    radial-gradient(1000px 560px at 92% 92%, #1C2A26 0%, transparent 55%),
    linear-gradient(135deg, #1A1712 0%, #201C16 50%, #18211E 100%);
}
[data-dark="1"] .pet-stage {
  background: radial-gradient(120% 90% at 50% 12%, #2A2419 0%, #241F18 55%, #1E1A14 100%);
  box-shadow: inset 0 0 0 1px rgba(240,160,92,.16);
}
/* 舞台高光层：亮色下是柔光，暗色下改为极淡暖光，避免出现灰白雾块 */
[data-dark="1"] .pet-stage::after {
  background: radial-gradient(60% 50% at 50% 38%, rgba(240,160,92,.10), transparent 70%);
}
/* 滚动条 */
[data-dark="1"] ::-webkit-scrollbar { width: 10px; height: 10px; }
[data-dark="1"] ::-webkit-scrollbar-track { background: #1A1712; }
[data-dark="1"] ::-webkit-scrollbar-thumb { background: #443C31; border-radius: 5px; }
[data-dark="1"] ::-webkit-scrollbar-thumb:hover { background: #564C3E; }
/* R47：暗色下同样在触摸设备加宽，保持与亮色一致 */
@media (pointer: coarse) {
  [data-dark="1"] ::-webkit-scrollbar { width: 14px; height: 14px; }
}
/* 图片类元素：暗色下统一轻微降亮，避免白底图片在深色背景上 stark 刺眼 */
[data-dark="1"] #petImg,
[data-dark="1"] #petCanvas,
[data-dark="1"] .pet-avatar { filter: brightness(.88) contrast(1.02); }
/* 骨架屏暗色版 */
[data-dark="1"] .skeleton {
  background: linear-gradient(90deg, #2A251E 25%, #353027 50%, #2A251E 75%);
  background-size: 200% 100%;
}
[data-dark="1"] .empty-state,
[data-dark="1"] .error-state,
[data-dark="1"] .dc-empty { background: #1F1B16; color: var(--ink2); }

/* ---------- R5(UI迭代)：暗色开关按钮 ----------
   开关复用了 .theme-btn 的类名，但 9 套主题的配色是靠
   .theme-btn[data-theme="xxx"] 选中的，开关没有 data-theme 属性，
   因此不会继承任何颜色，需显式定义，否则是透明无边框的裸文字。 */
[data-dark-toggle] {
  background: var(--bg-muted);
  border: 2px solid var(--line);
  color: var(--ink2);
  border-radius: var(--r-md);
  cursor: pointer;
  transition: all .2s cubic-bezier(.4,0,.2,1);
  font-family: inherit;
}
[data-dark-toggle]:hover { border-color: var(--brand); color: var(--ink); }
[data-dark-toggle].on {
  background: linear-gradient(135deg, #2E3A52, #3A3350);
  border-color: var(--brand);
  color: #E8EDF7;
  box-shadow: 0 2px 10px rgba(0,0,0,.28);
}
[data-dark-toggle]:focus-visible { outline: 2.5px solid var(--brand-deep); outline-offset: 2px; }
/* 首屏防白闪：内联脚本已置暗色时，body 先用深色打底，
   避免样式表加载完成前露出浅色底（仅影响首帧，不影响后续布局） */
html.preload-dark body { background: #17140F; color: #EDE6DA; }

/* ---------- R6(UI迭代)：滚动条统一美化 + 粘性分组头 ----------
   ① 滚动条：此前只有 .func-content / .pet-hub.mini 两处写了 4px 细滚动条，
      而真正长列表所在的 .pane.on（勋章 38 枚 / 战斗记录 / 数据中心）
      用的是浏览器默认宽度，Windows 下约 17px，视觉上与整体 UI 割裂。
      统一为 10px 细滚动条 + hover 加深，并补标准 scrollbar-color，
      让 Firefox 也保持一致。
   ② 粘性分组头：勋章页最多 8 个分组、38 张卡，滚动到第 5 组后
      前面分组已滚出视野，无法快速确认「当前在看哪一组」。
      给 .badge-group-hd 加 position:sticky，配不透明背景+底部描边，
      滚动时钉在顶部保留上下文。 */
.pane.on, .pet-hub.mini, .func-content, .right-panel, .main-area, .chat-list {
  scrollbar-width: thin;
  scrollbar-color: #D8CCBC transparent;
}
.pane.on::-webkit-scrollbar,
.pet-hub.mini::-webkit-scrollbar,
.func-content::-webkit-scrollbar,
.right-panel::-webkit-scrollbar,
.main-area::-webkit-scrollbar { width: 10px; height: 10px; }
.pane.on::-webkit-scrollbar-track,
.pet-hub.mini::-webkit-scrollbar-track,
.func-content::-webkit-scrollbar-track,
.right-panel::-webkit-scrollbar-track,
.main-area::-webkit-scrollbar-track { background: transparent; }
.pane.on::-webkit-scrollbar-thumb,
.pet-hub.mini::-webkit-scrollbar-thumb,
.func-content::-webkit-scrollbar-thumb,
.right-panel::-webkit-scrollbar-thumb,
.main-area::-webkit-scrollbar-thumb {
  background: #D8CCBC; border-radius: 6px; border: 2px solid transparent;
  background-clip: content-box;
}
.pane.on::-webkit-scrollbar-thumb:hover,
.pet-hub.mini::-webkit-scrollbar-thumb:hover,
.func-content::-webkit-scrollbar-thumb:hover,
.right-panel::-webkit-scrollbar-thumb:hover,
.main-area::-webkit-scrollbar-thumb:hover { background: #C2B4A1; background-clip: content-box; }

/* 粘性分组标题（勋章页）：滚动时钉在分组顶部 */
.badge-group-hd {
  position: sticky;
  top: 0;
  z-index: 2;
  background: #FBF6EF;
  /* 上下内边距补足，避免粘住时文字贴边 */
  box-shadow: 0 4px 8px -6px rgba(58,50,38,.22);
}
/* 集齐态的粘性头用对应的金色底，保持一致 */
.badge-group.complete .badge-group-hd { background: #FBF2E2; }
[data-dark="1"] .badge-group-hd { background: #221E18; }
[data-dark="1"] .badge-group.complete .badge-group-hd { background: #33281A; }
/* 粘性元素在打印时不要粘（打印会错位），且减少动效时不影响布局 */
@media print { .badge-group-hd { position: static; } }

/* ---------- R48 横屏适配（所内一体机/平板横放）----------
   此前全站只有 max-width 断点（竖屏宽度导向），完全没有 orientation 断点。
   横屏时可视高度被大幅压缩（一体机横放常见 1024×768 / 1280×800），
   聊天区与宠物舞台会被压扁甚至溢出，底部输入框够不到。
   此处按横屏且高度受限的特征做纵向空间再分配。 */
@media (orientation: landscape) and (max-height: 820px) {
  /* 聊天区在横屏下是主交互，压缩上下留白把空间让给消息列表 */
  .chatbox { padding-top: 10px; padding-bottom: 10px; }
  .chat-quick-wrap { max-height: 68px; }
  /* 宠物舞台：限制最大高度，避免占满纵向空间把下方操作挤出视口 */
  .pet-stage { max-height: 46vh; }
  .pet-stage::after { display: none; }
  /* 顶栏压缩，给内容让出高度 */
  .topbar { padding-top: 5px; padding-bottom: 5px; }
  /* 卡片内边距略收，横屏下纵向空间 precious */
  .card { padding: 14px 16px; }
  /* 触摸设备横屏：按钮保持触控下限，不因横屏而变小 */
  .btn, .btn.sm { min-height: 44px; }
}
/* 超宽横屏（如 1920×1080 一体机）：限制内容最大宽度，避免行宽过长难读 */
@media (orientation: landscape) and (min-width: 1600px) {
  .main-area, .right-panel { max-width: 1500px; margin-left: auto; margin-right: auto; }
}

/* ---------- R7(UI迭代)：卡片层级与间距令牌化 ----------
   实测：全站 138 处硬编码 box-shadow、约 100 种 padding 组合，
   同一视觉层级在不同模块用了不同数值，导致卡片「高矮胖瘦」不一致、
   阴影深浅不均（如 .card 用 var(--sh) 而 .btn 用 0 2px 8px）。
   本轮不追求全量替换（风险过高），而是**建立令牌 + 收敛主容器**：
   ① 定义 4 级阴影（--sh-1~4）与 5 级间距（--sp-1~5）令牌
   ② 把 .card / .pane / .modal-content / .btn / 徽章分组等
      高频主容器统一到令牌，使全站卡片高度、圆角、阴影节奏一致
   ③ 悬停态统一走 --sh-hover，卡片抬起感一致
   暗色模式已在上方覆写 --sh，天然跟随，无需重复处理。 */
:root {
  /* 阴影层级：1=贴地 2=卡片常态 3=悬停/浮起 4=弹窗 */
  --sh-1: 0 1px 2px rgba(58,50,38,.06);
  --sh-2: var(--sh);
  --sh-3: 0 4px 16px rgba(58,50,38,.10);
  --sh-4: 0 12px 36px rgba(58,50,38,.16);
  --sh-hover: 0 6px 22px rgba(58,50,38,.13);
  /* 间距刻度：4/8/12/16/24 */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px;  --sp-4: 16px;  --sp-5: 24px;
}
/* 主容器统一到令牌 */
.card {
  padding: var(--sp-3);
  box-shadow: var(--sh-2);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
.card:hover { box-shadow: var(--sh-hover); }
/* 卡片标题与正文的间距也用刻度，字号行距节奏统一 */
.card h3 { margin-bottom: var(--sp-3); }
.card h4 { margin: var(--sp-4) 0 var(--sp-2); }
/* 弹窗用最高层级阴影，突出「浮在内容之上」的语义 */
.modal-content {
  box-shadow: var(--sh-4);
  border-radius: var(--r-xl);
  padding: var(--sp-5);
}
/* 按钮阴影统一到 2 级，避免有的浮得过高 */
.btn { box-shadow: var(--sh-1); }
.btn:hover { box-shadow: var(--sh-3); }
/* 徽章分组与其它卡片对齐同一刻度 */
.badge-group { padding: var(--sp-3); border-radius: var(--r-md); margin-bottom: var(--sp-4); }
.badge-group:last-child { margin-bottom: 0; }
/* 暗色下阴影要更深才可见（黑底浅阴影等于没有） */
[data-dark="1"] {
  --sh-1: 0 1px 2px rgba(0,0,0,.44);
  --sh-3: 0 4px 16px rgba(0,0,0,.48);
  --sh-4: 0 12px 36px rgba(0,0,0,.58);
  --sh-hover: 0 6px 22px rgba(0,0,0,.52);
}

/* ---------- R8(UI迭代)：语义状态色与徽标组件 ----------
   现状问题：
   ① 危险语义色散落 13 处硬编码（#c0392b / #e74c3c / #fde8e8 / #fdeaea），
      暗色模式下「浅红底 + 深红字」会变成刺眼的粉底，且深红字在暗底上对比度不足。
   ② 量表风险徽标 .scale-risk-pill 四档（normal/mild/moderate/severe）
      各自硬编码一套底色与字色，没有语义令牌，无法统一调整与暗色适配。
   ③ 民警端工具栏 select 写死 background:#fff，暗色下直接变白底黑字。
   本轮：建立 --danger/--danger-soft/--info/--info-soft 语义令牌，
   统一 4 档风险徽标，补 .state-pill 通用徽标，并修掉暗色下的白底控件。 */
:root {
  --danger:#C0392B;  --danger-soft:#FDE8E8;  --danger-ink:#A32A1E;
  --info:#4A6FA5;    --info-soft:#E8EFF8;    --info-ink:#37527D;
  --ok-soft:#E8F5E9; --ok-ink:#2E6B41;
  --warn-soft:#FFF8E1; --warn-ink:#8A5B00;
}
[data-dark="1"] {
  /* 暗色：底色压暗，字色提亮，保证同样的语义但反转明度关系 */
  --danger:#F08A7C;  --danger-soft:#3A1A17;  --danger-ink:#F5B3A8;
  --info:#8FB3E0;    --info-soft:#182634;    --info-ink:#B9D0EC;
  --ok-soft:#16301F; --ok-ink:#8FCFA6;
  --warn-soft:#33280F; --warn-ink:#E5C167;
}

/* 4 档风险徽标统一走语义令牌 */
.scale-risk-pill.normal   { background: var(--ok-soft);   color: var(--ok-ink); }
.scale-risk-pill.mild     { background: var(--warn-soft); color: var(--warn-ink); }
.scale-risk-pill.moderate { background: #fde8d8; color: #b5640f; }
.scale-risk-pill.severe{ background: var(--danger-soft); color: var(--danger-ink); }
[data-dark="1"] .scale-risk-pill.moderate { background: #3A2413; color: #E8A87C; }

/* 风险提示条（学员端高危预警 / 量表异常）统一语义色 */
.assess-risk-high,
.scale-alert { background: var(--danger-soft); color: var(--danger-ink); }
.scale-abn-item { background: var(--danger-soft); color: var(--danger-ink); }

/* 通用状态徽标：供各模块复用，避免每个模块各写一套 */
.state-pill {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 700; line-height: 1.7;
  white-space: nowrap;
}
.state-pill.ok{ background: var(--ok-soft);   color: var(--ok-ink); }
.state-pill.warn      { background: var(--warn-soft); color: var(--warn-ink); }
.state-pill.danger    { background: var(--danger-soft); color: var(--danger-ink); }
.state-pill.info      { background: var(--info-soft); color: var(--info-ink); }
.state-pill.neutral   { background: var(--bg-muted); color: var(--ink2); border: 1px solid var(--line); }

/* 暗色下写死白底的控件统一改为令牌色（否则暗色模式出现白底黑字） */
[data-dark="1"] .scale-admin-toolbar select,
[data-dark="1"] .opt,
[data-dark="1"] .rank-row,
[data-dark="1"] .gm-btn { background: var(--card); color: var(--ink); }

/* ---------- R9(UI迭代)：表单可用性 + 键盘/触摸细节 ----------
   ① 触摸设备 hover 残留：全站 104 条 :hover 规则此前**无一条**被
      @media (hover:hover) 包裹。在触屏上点一下按钮，:hover 会「粘住」，
      直到用户点了别处才消失——表现为按钮/卡片长期保持高亮与抬起态，
      看起来像选中状态，对连续操作造成误导。
      这里不改写 104 条规则（风险过高），而是用「触屏上收紧 hover 效果」
      的方式消除粘滞观感：transform/box-shadow 归零，仅保留轻微底色。
   ② 表单：输入框补 hover 反馈与更大点击区；禁用态显式置灰且不可点，
      避免「按了没反应」的困惑；必填项视觉标记。
   ③ 键盘：输入框 Enter 提交已由 form onsubmit 保证；补 :focus-visible
      与 label 的点击热区扩大。 */
@media (hover: none) {
  /* 触屏：去掉位移与阴影，保留极浅底色变化，消除"粘住"的悬浮错觉 */
  .card:hover,
  .btn:hover,
  .btn.ghost:hover,
  .badge-card:hover:not(.locked),
  .opt:hover,
  .mitem:hover,
  .act:hover,
  .main-nav-btn:hover,
  .gm-btn:hover,
  .qn-btn:hover,
  .ps-nav-btn:hover,
  .stat:hover,
  .rank-row:hover {
    transform: none !important;
    box-shadow: var(--sh-1) !important;
  }
  .card:hover { box-shadow: var(--sh-2) !important; }
  /* 触摸时按下立刻给反馈，替代 hover 的「确认点到了」作用 */
  .btn:active, .card:active, .opt:active, .gm-btn:active { transform: scale(.985); }
}

/* 表单可用性 */
input, textarea, select {
  transition: border-color .18s, box-shadow .18s, background-color .18s;
}
/* 触摸设备上输入框行高更大，避免点错相邻输入框 */
@media (pointer: coarse) {
  input[type="text"], input[type="password"], input[type="number"],
  input[type="tel"], textarea, select { min-height: 48px; font-size: 17px; }
}
/* 禁用态：明确置灰 + 不可交互，避免「点了没反应」 */
input:disabled, textarea:disabled, select:disabled,
.btn:disabled, .btn[disabled] {
  opacity: .5; cursor: not-allowed; transform: none !important;
  box-shadow: none !important; filter: grayscale(.35);
}
/* 必填标记：仅用颜色会不便于色觉障碍者，补一个符号。
   注意定位：.field input 右侧已预留 46px 内边距给「👁 显示口令」按钮，
   必填星号若按常规放在 right:11px 会与眼睛按钮**重叠**，
   因此改为放在**左侧**（紧邻 leading 图标），此处padding-left 已达42px，
   星号落在 right:26px 处，与眼睛按钮（right:10px 起）互不干扰。 */
.field input[required] {
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 14 14'%3E%3Ccircle cx='7' cy='7' r='6' fill='none' stroke='%23C0392B' stroke-width='1.4'/%3E%3Ctext x='7' y='10.5' font-size='9' text-anchor='middle' fill='%23C0392B' font-family='sans-serif'%3E*%3C/text%3E%3C/svg%3E");
  background-repeat: no-repeat;
  /* 眼睛按钮在最右，星号右移 26px 避让；无眼睛按钮的输入框自然更靠右也无妨 */
  background-position: right 26px center;
}
/* 口令框已有「👁」按钮，星号再往左让一档，二者不会挤在一起 */
#loginPin[required] { background-position: right 40px center; }
/* 无 leading 图标的输入框（不套 .input-wrap 的场景）星号回到常规位置 */
.field input[required]:not([id]) { background-position: right 26px center; }
[data-dark="1"] .field input[required] {
  /* 暗色下把星号描线提亮，否则暗红在深底上几乎看不见 */
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 14 14'%3E%3Ccircle cx='7' cy='7' r='6' fill='none' stroke='%23F08A7C' stroke-width='1.4'/%3E%3Ctext x='7' y='10.5' font-size='9' text-anchor='middle' fill='%23F08A7C' font-family='sans-serif'%3E*%3C/text%3E%3C/svg%3E");
}
/* label 点击热区更大，触摸时更容易点到 */
@media (pointer: coarse) {
  .field label { display: block; min-height: 40px; line-height: 40px; margin-bottom: 2px; }
}
/* 焦点可见：输入框聚焦时外圈高亮，暗色下同样清晰 */
input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: 2px solid var(--brand-deep); outline-offset: 1px;
}
[data-dark="1"] input:focus-visible,
[data-dark="1"] textarea:focus-visible,
[data-dark="1"] select:focus-visible { outline-color: var(--brand); }
/* 搜索框等带清除按钮的输入框，焦点时别让文字压住按钮 */
.input-wrap:focus-within .in-ic { color: var(--brand); }

/* ============================================================
 * 【场景化 UI 迭代 N1–N10】戒毒人员 · 所内触摸一体机
 * ============================================================
   使用人群画像（决定一切取舍）：
   ① 年龄跨度大，普遍视力下降、老花——小字等于看不见；
   ② 文化程度偏低，理解「术语化文案」有门槛，要的是「大白话」；
   ③ 戒治场景下情绪敏感，失败/无响应的体验会放大焦虑；
   ④ 场所内光线复杂（强光/昏暗），淡雅配色对比度不足；
   ⑤ 触摸一体机多人共用，无物理键盘，误触与误操作风险高。
   本轮迭代据此设计：字号抬升 → 屏幕键盘 → 去术语 → 导航放大 →
   反馈强化 → 空状态引导 → 超大模式 → 高对比 → 防误触。 */

/* ---------- N1：全局字号基线抬升（可读性优先） ----------
   勘察实测：全站 font-size ≤12px 的规则多达 170+ 处，最低到 9px/10px。
   其中大量是**承载实际信息的文字**（按钮文字 .qn-btn .lb 11px、
   子导航文字 .ps-nav-btn .ps-lb 11px、成长树节点名、互助墙计数等），
   这些不是装饰，是用户必须读懂的内容，9-11px 在一体机距离下基本看不清。
   策略：**按「是否承载信息」分层**，而不是无脑整体放大——
     · 信息类（下类选择器）整体抬到 14px 起；
     · 纯装饰/计数类允许小字，但不低于 12px；
     · 图标 emoji 不受影响。
   这样既提升可读性，又不会把布局撑破（避免上一轮「放大导致错位」）。 */

/* N1-1：按钮与导航文字（最高频，承载功能名） */
.qn-btn .lb,
.main-nav-btn .lb,
.gm-btn .gm-lb,
.tab .lb,
.pane-switch .lb { font-size: 15px !important; line-height: 1.35; }

/* N1-2：宠物左侧竖向子导航：图标下方的功能名（用户靠它认功能） */
.ps-nav-btn .ps-lb { font-size: 13px !important; font-weight: 700; letter-spacing: .3px; }

/* N1-3：卡片/面板标题下的说明 tag（「每一枚都是你坚持的证明」这类引导语） */
.card h3 .tag { font-size: 13.5px !important; line-height: 1.5; }

/* N1-4：成长树节点名与解锁条件（真实信息，不能太小） */
.ts-node .ts-nm { font-size: 14px !important; }
.ts-node .ts-need { font-size: 12.5px !important; }

/* N1-5：互助墙 / 数据中心 / 档案统计类信息文本 */
.wall-cat, .wall-count, .wall-flag { font-size: 12.5px !important; }
.dc-lb, .dc-bc-l, .dc-badge-nm { font-size: 13px !important; }
.dc-empty { font-size: 14.5px !important; }
.dc-empty-hero { font-size: 15.5px !important; }

/* N1-6：徽章卡：名称是核心信息，描述也要能读 */
.badge-name { font-size: 15px !important; }
.badge-desc { font-size: 13px !important; }

/* N1-7：量表/评估结果类文本（心理测评结论，需要读懂） */
.scale-risk-pill { font-size: 13.5px !important; padding: 3px 11px; }
.scale-hist-v, .scale-hist-go { font-size: 13px !important; }
.scale-abn-item { font-size: 13px !important; }
.scale-alert { font-size: 13.5px !important; }

/* N1-8：答题/法律问答反馈区（学习反馈，是用户判断「我做对了吗」的唯一依据）
   注意：此处必须用**真实存在的类名**——先前写成 .law-result/.quiz-result-tip
   是我臆造的选择器，全站并不存在，属于死CSS（审计已剔除该写法）。
   实际结构：.explain（解析条）、.quiz-stats .qs-lbl（题头统计标签，11px 偏小）、
   #battleFeedback（战斗反馈，JS 动态设 className）。 */
.explain, .explain-actions button { font-size: 14.5px !important; }
.quiz-stats .qs-lbl { font-size: 13px !important; }
#battleFeedback { font-size: 17px !important; line-height: 1.55; padding: 8px 12px; }
#battleFeedback strong { font-size: 19px !important; }

/* N1-9：全局兜底：把所有残留的 9/10/10.5px 拉到 12px 下限
   （装饰性小圆点等纯图形不受影响，因为它们不带文字） */
.badge-check, .bg-done { font-size: 12px !important; }
.pill { font-size: 15px !important; }
.hint, .cm-hint { font-size: 13.5px !important; }

/* N1-10：行高配套放大——字号变大后行高必须跟上，否则会显得挤。
   中文正文行高 1.6~1.75 最易读，比英文更需要行距。 */
body { line-height: 1.65; }
.card p, .empty-hint, .badge-desc, .ts-need { line-height: 1.7; }

/* ---------- N2：触摸数字键盘样式 ----------
   触摸一体机无物理键盘，这块键盘是**登录能否完成的前提**，不是锦上添花。
   尺寸按Fitts 定律放大：键宽 ≥72px、键高 ≥64px，间距 10px——
   比常规键盘大得多，因为用户可能是手部不便或站立操作。
   清空/退格用低饱和色区分，避免误按；主色留给数字键。 */
.padk {
  margin-top: 16px; padding: 14px;
  background: linear-gradient(135deg, #FFFDFA, #FBF4EC);
  border: 2px solid var(--line); border-radius: var(--r-lg);
}
.padk-hint {
  text-align: center; font-size: 14.5px; color: var(--ink2);
  margin-bottom: 11px; font-weight: 600;
  padding: 7px 10px; border-radius: 10px; background: #FFF3E7;
  border: 1px dashed #E8C9A4;
}
.padk-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.padk-key {
  min-height: 64px; font-size: 26px; font-weight: 700;
  font-family: inherit; color: var(--ink);
  background: linear-gradient(180deg, #FFFFFF, #FBF3EA);
  border: 2px solid #E8DAC6; border-radius: var(--r-md);
  cursor: pointer; touch-action: manipulation;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 2px 0 #E4D5C0, var(--sh-1);
  transition: transform .08s ease, box-shadow .08s ease;
  user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent;
}
/* 明显的「按下」物理反馈：数字键是一体机上唯一可靠的点击确认 */
.padk-key:active {
  transform: translateY(3px);
  box-shadow: 0 0 0 var(--sh-1);
  background: #FFE8CC; border-color: var(--brand);
}
.padk-act {
  font-size: 18px; font-weight: 700;
  background: linear-gradient(180deg, #F3EAE0, #EDE2D6);
  border-color: #DCCBBA; color: var(--ink2);
}
.padk-del { font-size: 24px; }
/* 当前输入框高亮，让用户知道数字会进哪里——这是软键盘最易出错的地方 */
.field.focused-kbd input {
  border-color: var(--brand); background: #fff;
  box-shadow: 0 0 0 4px rgba(232,131,58,.20);
}
.field.focused-kbd label { color: var(--brand-deep); }
/* 暗色模式 */
[data-dark="1"] .padk { background: linear-gradient(135deg, #221E18, #1B1712); border-color: #3A342B; }
[data-dark="1"] .padk-hint { background: #2E2519; border-color: #5A4527; color: var(--ink2); }
[data-dark="1"] .padk-key {
  background: linear-gradient(180deg, #2A251E, #231F19);
  border-color: #3E382F; color: var(--ink);
  box-shadow: 0 2px 0 #17140F;
}
[data-dark="1"] .padk-key:active { background: #3A2E22; }
[data-dark="1"] .padk-act { background: linear-gradient(180deg, #332D25, #2A251E); border-color: #463F35; }
/* 超大模式（N7）下键盘同步放大 */
body.fz-xlarge .padk-key { min-height: 76px; font-size: 30px; }
@media (max-width: 420px) {
  .padk-key { min-height: 56px; font-size: 22px; }
  .padk-grid { gap: 8px; }
}

/* ---------- N4：主导航与子导航放大强化 ----------
   这两处是全站最高频入口（一日要按几十次），但现状是：
   顶部主导航 16px 文字 + 内边距 10px14px，5 个按钮挤在 flex:1 里；
   左侧子导航「我的成长」这类 4 字标签在 56px 宽的竖排按钮里很容易换行。
   本轮做三件事：
   ① 主导航加高到 64px、字号 17px，图标放大——站立操作时更好点；
   ② 子导航按钮加宽到 72px 并允许两行，杜绝「我的成长」被挤断；
   ③ 选中态从「浅底色」升级为「深底色 + 左侧色条 + 加粗」，
      在复杂界面里一眼看出当前在哪，且不只依赖颜色（色条是形状线索，
      色觉障碍用户也能分辨）。 */
.main-nav-btn {
  min-height: 64px; padding: 12px 16px; font-size: 17px;
  gap: 9px; flex-shrink: 0;
}
.main-nav-btn .ic { font-size: 26px; line-height: 1; }
.main-nav-btn .lb { font-weight: 700; white-space: nowrap; }
/* 选中态：深底 + 左侧竖条 + 加粗（形状线索，不只靠颜色） */
.main-nav-btn.on {
  background: linear-gradient(135deg, #2E9E8F, #1F7A8C);
  border-color: #2E9E8F; color: #FFF;
  box-shadow: 0 3px 12px rgba(31,122,140,.32);
  position: relative;
}
.main-nav-btn.on::before {
  content: ""; position: absolute; left: 0; top: 12%; bottom: 12%;
  width: 5px; border-radius: 0 4px 4px 0; background: #2E9E8F;
}
[data-dark="1"] .main-nav-btn.on {
  background: linear-gradient(135deg, #34B3A0, #1F8C9E); color: #FFFFFF;
}

/* 左侧子导航：加宽 + 文字可换行 + 选中态强化 */
.pet-subnav { gap: 10px; }
.ps-nav-btn {
  min-width: 72px; min-height: 74px; padding: 10px 6px;
  gap: 5px; flex-shrink: 0;
}
.ps-nav-btn .ps-ic { font-size: 28px; line-height: 1; }
.ps-nav-btn .ps-lb {
  font-size: 13.5px !important; line-height: 1.25; text-align: center;
  /* 「我的成长」「成绩单」等 4 字标签允许两行显示，绝不截断或省略 */
  white-space: normal; word-break: keep-all; min-height: 2.5em;
}
.ps-nav-btn.on {
  background: linear-gradient(180deg, #FFF0DE, #FBE0C4);
  border-color: var(--brand); border-width: 2.5px;
  box-shadow: 0 3px 10px rgba(232,131,58,.28);
  position: relative;
}
.ps-nav-btn.on::after {
  /* 右侧色条：与主导航的左侧条呼应，形成一致的「当前位置」语言 */
  content: ""; position: absolute; right: 0; top: 16%; bottom: 16%;
  width: 4px; border-radius: 4px 0 0 4px; background: var(--brand);
}
[data-dark="1"] .ps-nav-btn.on {
  background: linear-gradient(180deg, #3E3222, #2F2820); color: #FFF3E7;
}
/* 触摸反馈：点一下立刻有反应（一体机没有 hover 提示） */
@media (pointer: coarse) {
  .ps-nav-btn:active, .main-nav-btn:active { transform: scale(.94); }
}
/* 窄屏横屏一体机：5 个主导航要保证不换行地可点 */
@media (max-width: 900px) {
  .main-nav-btn { min-height: 56px; font-size: 15.5px; padding: 10px 12px; }
  .main-nav-btn .ic { font-size: 22px; }
  .main-nav-btn .lb { font-size: 14.5px !important; }
  .ps-nav-btn { min-width: 62px; min-height: 66px; }
  .ps-nav-btn .ps-lb { font-size: 12.5px !important; }
}

/* N4 补充防护：主导航原为 flex:1（等分宽度），本轮加 nowrap + 加高后，
   5 个按钮在中窄屏可能超出总宽被挤压或溢出。改为「等分但不小于最小宽」，
   空间不够时允许换行到第二行（宁可换行也不能挤到点不准）。 */
.main-nav { flex-wrap: wrap; }
.main-nav-btn { flex: 1 1 auto; min-width: 104px; }
/* 空间充裕时（横屏一体机常见 1280+）让主导航居中，视觉更稳 */
@media (min-width: 1100px) {
  .main-nav-btn { min-width: 128px; }
}
/* 左侧子导航竖排：允许换行，避免 6 个按钮在矮屏上超出可视区被截断 */
.pet-subnav { flex-wrap: wrap; }

/* ---------- N5：操作反馈强化（看得见「我做对了」）----------
   戒治场景下，用户按下按钮后如果得不到明确反馈，最容易产生的念头是
   「我是不是弄错了 / 是不是坏了」，进而反复点击甚至放弃。
   原 toast 的问题：字号 16px、位于底部 34px、停留 2.2 秒起——
   底部容易被键盘/手遮挡，且 2.2 秒对阅读较慢者根本不够。
   本轮：字号 21px、移到顶部（视线自然落点）、加粗大字、停留延长、
        成功时轻微弹跳以便余光捕捉、错误态加「请重试」类文案位。 */
.toast {
  top: 84px;                      /* 从底部移到顶部：阅读起点，天然先看到 */
  bottom: auto;
  font-size: 21px; font-weight: 700; line-height: 1.5;
  padding: 18px 34px; border-radius: 20px;
  max-width: min(86vw, 620px); text-align: center;
  letter-spacing: .3px;
  box-shadow: 0 8px 28px rgba(0,0,0,.26);
}
/* 顶部出现改为从上方滑入，与旧的底部上浮方向一致（避免视觉回退感） */
.toast {
  transform: translateX(-50%) translateY(-20px);
}
.toast.on { transform: translateX(-50%) translateY(0); }
/* 成功：轻微弹跳，余光也能确认 */
@keyframes toastPop {
  0% { transform: translateX(-50%) translateY(0) scale(.94); }
  55% { transform: translateX(-50%) translateY(0) scale(1.04); }
  100% { transform: translateX(-50%) translateY(0) scale(1); }
}
.toast.toast-pop { animation: toastPop .4s cubic-bezier(.34,1.56,.64,1); }
/* 四种类型强化：加左侧色块 + 更强的底色，色觉障碍下靠明度差也能区分 */
.toast { border-left: 7px solid rgba(255,255,255,.55); padding-left: 30px; }
.toast.success { background: rgba(30,142,90,.96); border-left-color: #BFF0D2; }
.toast.error   { background: rgba(178,44,32,.97);  border-left-color: #FFD2CB; }
.toast.warning { background: rgba(190,116,10,.97); border-left-color: #FFE9BF; }
.toast.info    { background: rgba(42,94,140,.96); border-left-color: #CFE4F5; }
/* 暗色模式：底色更沉、色块更亮，避免深底上出现过亮白块 */
[data-dark="1"] .toast { background: #1F1B16; color: var(--ink); border-left-width: 7px; }
[data-dark="1"] .toast.success { background: #16301F; border-left-color: #6FD79C; color: #D6F5E3; }
[data-dark="1"] .toast.error   { background: #3A1A17; border-left-color: #F08A7C; color: #FBD9D2; }
[data-dark="1"] .toast.warning { background: #33280F; border-left-color: #E5C167; color: #F7E7C4; }
[data-dark="1"] .toast.info    { background: #182634; border-left-color: #8FB3E0; color: #D6E6F7; }
/* 减少动效：关闭弹跳 */
@media (prefers-reduced-motion: reduce) {
  .toast.toast-pop { animation: none; }
}

/* ---------- N6：空状态放大强化+ 新手引导 ----------
   空状态对戒毒人员特别重要：面对一大片空白，多数人不会判断
   「这是没数据」还是「坏了」，继而放弃操作。
   N6-1 视觉：图标放大、标题与提示都放大加粗、加引导卡片，
         「下一步该做什么」用色块按钮明确给出。
   N6-2 错误态同步放大（与空态同规格，用户分不清时至少有反馈）。 */
.empty-state { padding: 34px 20px; }
.empty-state .empty-icon { font-size: 86px; margin-bottom: 14px; }
.empty-state .empty-title {
  font-size: 22px !important; font-weight: 700; color: var(--ink);
  margin-bottom: 12px; line-height: 1.45;
}
/* 提示语承载「怎么做」，必须比标题更大更清楚（此前只有 14px 灰字） */
.empty-state .empty-hint {
  font-size: 17px !important; color: var(--ink2);
  background: linear-gradient(135deg, #FFF6EA, #F2FAF7);
  border: 1.5px dashed #E4CDA8; border-radius: var(--r-md);
  padding: 14px 18px; line-height: 1.7; margin: 0 auto 16px;
  max-width: 460px;
}
/* 引导按钮做大做强：用户不该在空状态里犹豫「点哪里」 */
.empty-state .empty-action button {
  padding: 15px 40px !important; font-size: 19px !important;
  font-weight: 700; border-radius: var(--r-lg);
  box-shadow: 0 4px 14px rgba(232,131,58,.35);
  min-height: 56px;
}
.empty-state .empty-action button:active { transform: scale(.97); }

/* 错误态同步放大——用户分不清空/错时，清晰的反馈本身就是安慰 */
.error-state { padding: 32px 20px; }
.error-state .error-icon { font-size: 66px; }
.error-state p { font-size: 18px !important; color: var(--ink); line-height: 1.6; }
.error-state button {
  padding: 13px 34px; font-size: 17px; font-weight: 700;
  border-radius: var(--r-lg); background: var(--brand); color: #fff;
  border: none; cursor: pointer; min-height: 50px; margin-top: 8px;
}
/* 暗色下引导卡也要可读 */
[data-dark="1"] .empty-state .empty-hint {
  background: linear-gradient(135deg, #2A2419, #1D2422);
  border-color: #5A4527; color: var(--ink2);
}
[data-dark="1"] .error-state button { color: #241A10; }

/* ---------- N7：全局超大模式 ----------
   定位：给视力较弱者的一档「兜底」。与聊天字号档位（仅聊天）不同，
   本模式放大的是**整个界面**——导航、卡片标题、正文、按钮。
   实现要点（避免放大后布局崩）：
   ① 用 rem 无关的「关键元素定向放大」，不整体套transform:scale()
      （scale 会连同布局一起缩放，出现滚动条与点击偏移）；
   ② 只放大文字与内边距，不动容器宽高比例，避免卡片被挤破；
   ③ 与暗色模式正交，可任意组合。 */
body.fz-xlarge { font-size: 18px; }
/* 导航：主导航与子导航同步加高，容纳更大的字 */
body.fz-xlarge .main-nav-btn { min-height: 76px; font-size: 19px; }
body.fz-xlarge .main-nav-btn .ic { font-size: 30px; }
body.fz-xlarge .main-nav-btn .lb { font-size: 19px !important; }
body.fz-xlarge .ps-nav-btn { min-width: 84px; min-height: 86px; }
body.fz-xlarge .ps-nav-btn .ps-ic { font-size: 33px; }
body.fz-xlarge .ps-nav-btn .ps-lb { font-size: 16px !important; }
/* 卡片与面板标题 */
body.fz-xlarge .card h3 { font-size: 23px; }
body.fz-xlarge .card h3 .tag { font-size: 16px !important; }
/* 正文与列表 */
body.fz-xlarge .badge-name { font-size: 18px !important; }
body.fz-xlarge .badge-desc { font-size: 15.5px !important; }
body.fz-xlarge .badge-desc, body.fz-xlarge .ts-need { line-height: 1.8; }
body.fz-xlarge .explain { font-size: 17px !important; }
body.fz-xlarge .empty-state .empty-title { font-size: 26px !important; }
body.fz-xlarge .empty-state .empty-hint { font-size: 20px !important; }
body.fz-xlarge .toast { font-size: 24px; padding: 20px 38px; }
/* 按钮 */
body.fz-xlarge .btn { font-size: 21px; min-height: 52px; }
body.fz-xlarge .btn.sm { font-size: 19px; min-height: 52px; }
body.fz-xlarge .bf-btn { font-size: 16.5px; }
/* 徽章墙分组与信息文本 */
body.fz-xlarge .badge-group-cnt { font-size: 15.5px; }
body.fz-xlarge .dc-lb, body.fz-xlarge .dc-bc-l { font-size: 15px !important; }
body.fz-xlarge .dc-empty { font-size: 17px !important; }
/* 聊天与登录输入框字体（避免 iOS/Android 自动缩放页面） */
body.fz-xlarge input, body.fz-xlarge textarea, body.fz-xlarge select { font-size: 19px; }
body.fz-xlarge .padk-hint { font-size: 17px; }
/* 超大模式下的滚动条加粗，便于视力弱者看清可滚动区域 */
body.fz-xlarge .pane.on::-webkit-scrollbar { width: 14px; }
body.fz-xlarge .pane.on::-webkit-scrollbar-thumb { background: #B8A894; background-clip: content-box; }

/* 放大开关按钮样式 */
.xl-toggle {
  padding: 9px 18px; font-size: 15px; font-weight: 700;
  border-radius: var(--r-lg); cursor: pointer; font-family: inherit;
  background: linear-gradient(135deg, #FFF3E7, #FDE8D4);
  border: 2px solid var(--brand); color: var(--brand-deep);
  transition: all .2s; min-height: 44px;
}
.xl-toggle:hover { box-shadow: 0 3px 10px rgba(232,131,58,.3); }
.xl-toggle.on {
  background: linear-gradient(135deg, var(--brand), #D47632);
  color: #fff; box-shadow: 0 3px 12px rgba(232,131,58,.4);
}
.xl-toggle:focus-visible { outline: 2.5px solid var(--brand-deep); outline-offset: 2px; }
[data-dark="1"] .xl-toggle {
  background: linear-gradient(135deg, #3E3222, #2F2820); color: #F5D9AE;
  border-color: #6B4E2C;
}
[data-dark="1"] .xl-toggle.on {
  background: linear-gradient(135deg, #E8833A, #C06522); color: #241A10;
}

/* ---------- N8：高对比易读模式（场所光线适配）----------
   现实动因：戒治场所内光线复杂——走廊强光、活动室昏暗、且多为一整天的常亮屏幕。
   现有 R28 高对比只覆盖了按钮/输入框/链接/toast几个元素，
   卡片、徽章、导航、气泡、表单提示等**仍然是浅米色系**，在强光下几乎看不清。
   本轮：
   ① 把令牌层的浅色全部压到纯白/纯黑，并把次级文字也拉到纯黑（不靠灰度分层）；
   ② 补齐此前漏掉的容器（卡片/徽章两态/导航两态/聊天气泡/空态/输入框）；
   ③ 所有边框加粗到 2px——弱视用户常常先靠「框线」定位元素，而不是靠颜色；
   ④ 关键按钮加「下边框加粗」，形成明确的立体边界。
   ⑤ 与暗色模式互斥：暗色下不套用本模式（暗色本身就是另一种高对比方案）。 */
html.high-contrast, body.high-contrast {
  --bg: #FFFFFF;
  --card: #FFFFFF;
  --bg-muted: #FFFFFF;
  --ink: #000000;
  --ink2: #000000;          /* 次级文字也纯黑：灰度分层对本场景无意义 */
  --ink3: #1A1A1A;
  --line: #000000;
  --brand: #8F3D00;
  --brand-deep: #5A2200;
  --brand2: #0B4F48;
  --ok-soft: #E8F5E9; --ok-ink: #0A3D1E;
  --warn-soft: #FFF8E1; --warn-ink: #5E3F00;
  --danger-soft: #FDE8E8; --danger-ink: #7A1B10;
  --info-soft: #E8EFF8; --info-ink: #1F3B63;
}
/* 卡片与容器：加粗边框 + 去除淡雅底色 */
html.high-contrast .card, body.high-contrast .card,
html.high-contrast .badge-group, body.high-contrast .badge-group,
html.high-contrast .inno-sec, body.high-contrast .inno-sec,
html.high-contrast .empty-state, body.high-contrast .empty-state {
  background: #FFFFFF; border: 2px solid #000000; color: #000000;
}
/* 导航两态：靠「反色」而非「浅色」区分当前选中 */
html.high-contrast .main-nav-btn, body.high-contrast .main-nav-btn,
html.high-contrast .ps-nav-btn, body.high-contrast .ps-nav-btn,
html.high-contrast .qn-btn, body.high-contrast .qn-btn {
  background: #FFFFFF; border: 2px solid #000000; color: #000000;
}
html.high-contrast .main-nav-btn.on, body.high-contrast .main-nav-btn.on,
html.high-contrast .ps-nav-btn.on, body.high-contrast .ps-nav-btn.on,
html.high-contrast .qn-btn.on, body.high-contrast .qn-btn.on {
  background: #000000; color: #FFFFFF; border-color: #000000;
  font-weight: 700;
}
/* 徽章两态：已得=实心黑框，未得=虚线浅框（形状可辨，不只靠颜色） */
html.high-contrast .badge-card.got, body.high-contrast .badge-card.got {
  background: #FFFFFF; border: 3px solid #000000; color: #000000;
}
html.high-contrast .badge-card.locked, body.high-contrast .badge-card.locked {
  background: #FFFFFF; border: 2px dashed #666666; color: #1A1A1A;
  opacity: 1;
}
html.high-contrast .badge-card.locked .badge-ic,
body.high-contrast .badge-card.locked .badge-ic { filter: none; opacity: .75; }
/* 聊天气泡：本人纯黑底白字，对方白底黑框 */
html.high-contrast .msg .bub.me, body.high-contrast .msg .bub.me {
  background: #000000; color: #FFFFFF; border: 2px solid #000000;
}
html.high-contrast .msg .bub:not(.me), body.high-contrast .msg .bub:not(.me) {
  background: #FFFFFF; color: #000000; border: 2px solid #000000;
}
/* 输入框与提示条 */
html.high-contrast .field input, body.high-contrast .field input,
html.high-contrast textarea, body.high-contrast textarea,
html.high-contrast select, body.high-contrast select,
html.high-contrast .padk-key, body.high-contrast .padk-key {
  background: #FFFFFF; color: #000000; border: 3px solid #000000;
}
html.high-contrast .padk-key:active, body.high-contrast .padk-key:active {
  background: #000000; color: #FFFFFF;
}
/* R46 高对比补漏：R44/R45 新增与修复的控件（聊天侧栏按钮、宠物设置/类型按钮、
   语音气泡、加载 spinner）需在高对比模式下保持"白底黑字黑边"，
   否则高对比用户会看到低对比控件——恰与高对比模式的初衷相悖。 */
html.high-contrast .fp-btn, body.high-contrast .fp-btn,
html.high-contrast .lh-btn, body.high-contrast .lh-btn,
html.high-contrast .chat-focus-btn, body.high-contrast .chat-focus-btn,
html.high-contrast .pet-settings-btn, body.high-contrast .pet-settings-btn,
html.high-contrast .pet-type-btn, body.high-contrast .pet-type-btn,
html.high-contrast .pet-mini-btn, body.high-contrast .pet-mini-btn,
html.high-contrast .pet-action-btn, body.high-contrast .pet-action-btn {
  background: #FFFFFF; color: #000000; border: 2px solid #000000;
}
html.high-contrast .fp-btn.on, body.high-contrast .fp-btn.on,
html.high-contrast .lh-btn.on, body.high-contrast .lh-btn.on,
html.high-contrast .chat-focus-btn.on, body.high-contrast .chat-focus-btn.on {
  background: #000000; color: #FFFFFF; border-color: #000000;
}
html.high-contrast .speech, body.high-contrast .speech {
  background: #FFFFFF; color: #000000; border: 2px solid #000000;
}
/* 高对比下加载 spinner 必须是黑环（白环在白底上不可见） */
html.high-contrast .btn.loading::after, body.high-contrast .btn.loading::after,
html.high-contrast .btn.ghost.loading::after, body.high-contrast .btn.ghost.loading::after,
html.high-contrast .btn-outline.loading::after, body.high-contrast .btn-outline.loading::after {
  border-color: rgba(0,0,0,.3); border-top-color: #000000;
}
html.high-contrast .empty-state .empty-hint, body.high-contrast .empty-state .empty-hint {
  background: #FFFFFF; border: 2px solid #000000; color: #000000;
}
html.high-contrast .badge-summary, body.high-contrast .badge-summary {
  background: #FFFFFF; border: 2px solid #000000;
}
html.high-contrast .ts-node, body.high-contrast .ts-node {
  background: #FFFFFF; border: 2px solid #000000; color: #000000;
}
/* 数字键盘是登录命脉，高对比下必须最醒目 */
html.high-contrast .padk, body.high-contrast .padk {
  background: #FFFFFF; border: 3px solid #000000;
}
html.high-contrast .padk-hint, body.high-contrast .padk-hint {
  background: #FFFFFF; color: #000000; border: 2px solid #000000;
}
/* 提示气泡/统计条等浅色块 */
html.high-contrast .quiz-stats, body.high-contrast .quiz-stats,
html.high-contrast .stats, body.high-contrast .stats {
  background: #FFFFFF; border: 2px solid #000000;
}
/* 进度条在纯白底上要看得出进度 */
html.high-contrast .bs-fill, body.high-contrast .bs-fill,
html.high-contrast .badge-group-fill, body.high-contrast .badge-group-fill {
  background: #000000 !important;
}
html.high-contrast .bs-bar, body.high-contrast .bs-bar,
html.high-contrast .badge-group-bar, body.high-contrast .badge-group-bar {
  background: #FFFFFF; border: 2px solid #000000;
}
/* 暗色模式下不叠加高对比（两者语义冲突，会得到刺眼的白底黑字） */
[data-dark="1"].high-contrast .card,
body[data-dark="1"].high-contrast .card { background: var(--card); border-color: var(--line); }

/* ---------- N9：闲置锁定与防误触 ----------
   ① 闲置锁定：锁到登录页后给一层明显的遮罩与提示，
      避免用户以为「坏了」，能看懂发生了什么。
   ② 防误触：数字键盘/导航按钮在触摸时给按下态；
      用 touch-action 禁掉双击缩放与长按选择，减少滑动时的误触发。 */
body.idle-locked .login-card {
  box-shadow: 0 20px 60px rgba(0,0,0,.3);
  border: 3px solid var(--brand);
}
/* 锁定时登录页整体轻微提亮，明确「现在需要重新登录」 */
body.idle-locked .login-wrap { background: rgba(58,50,38,.16); }
/* 触摸目标：禁掉双击缩放与长按菜单，避免一体机上手势误判 */
.padk-key, .ps-nav-btn, .main-nav-btn, .qn-btn, .btn {
  touch-action: manipulation;
}
/* 触摸时立刻给出按下反馈（一体机没有 hover，这是唯一确认手段） */
@media (pointer: coarse) {
  .ps-nav-btn:active, .main-nav-btn:active, .qn-btn:active,
  .btn:active, .gm-btn:active, .opt:active, .task:active {
    transform: scale(.96);
    filter: brightness(1.06);
  }
  /* 触摸设备上 hover 态不再"粘住"，点击后立刻回落 */
  .card:hover, .badge-card:hover:not(.locked) { transform: none !important; }
}

/* ---------- N1 补充：清除残余超小字号（信息类，不可读） ----------
   审计发现仍有 13 处 9/10/10.5px，逐一确认后全部是**承载信息**的文字，
   不是装饰：按钮功能名(.qn-btn .lb / .qn-btn)、成长树解锁条件(.ts-node .ts-need)、
   子导航功能名(.ps-nav-btn .ps-lb)、题目区标题(.qn-sec-t)、图表轴标签(.chart .x)、
   呼吸目标文案(.breath-ring-label .br-tgt)、怪兽难度角标(.bdiff-mini)、
   互动冷却秒数(.pet-interact-btn .cooldown)、数据中心单元格(.dc-cell)。
   这些在一体机距离下都看不清，属于真实可读性缺陷，逐类抬到 13px 起。 */
.qn-btn .lb { font-size: 14px !important; }
.qn-sec-t{ font-size: 14px !important; }
.ps-nav-btn .ps-lb { font-size: 14px !important; }
.ts-node .ts-need { font-size: 13px !important; }
.breath-ring-label .br-tgt { font-size: 13.5px !important; }
.bdiff-mini { font-size: 12.5px !important; }
.pet-interact-btn .cooldown { font-size: 13px !important; }
.chart .x { font-size: 12.5px !important; }
.dc-cell { font-size: 13px !important; }
