/* ============================================================
 * 薯灵感 SparkNote —— 全站体验标准运行时（ux-core.css）
 * 2026-10-05
 * 覆盖：统一微交互时长 / 焦点可见(WCAG2.2 2.4.11) / 触控目标(2.5.8)
 *       骨架屏 / Toast 撤销窗口 / 空状态行动入口 / 离线降级
 * 约束：动效只用 transform 与 opacity；尊重 prefers-reduced-motion
 * ============================================================ */

:root {
  /* ---- 统一微交互时长（维度二 2.2）---- */
  --ux-t-press: 90ms;    /* 按压反馈 ≤100ms */
  --ux-t-hover: 170ms;   /* 悬停触发 150–200ms */
  --ux-t-drop: 220ms;    /* 下拉/提示 100–300ms */
  --ux-t-modal: 260ms;   /* 弹窗 200–300ms */
  --ux-t-page: 180ms;    /* 页面转场 150–200ms */
  --ux-ease: cubic-bezier(.2, .8, .3, 1);
  --ux-ease-out: cubic-bezier(.16, 1, .3, 1);

  --ux-red: #FF2442;
  --ux-focus: #FF2442;
  --ux-sk-1: #f2f3f5;
  --ux-sk-2: #e8eaee;
  /* 对话框专用层级。不要复用 --z-modal：design-tokens.css 里它已经被
     底部工具条占成 500，复用会让弹窗被顶栏和侧栏压住（实测踩过）。 */
  --z-dialog: 99985;
}

/* ============================================================
 * 1. 焦点可见性（WCAG 2.2 SC 2.4.11 / 2.4.7）
 *    站点里有 28 条 outline:none 规则，这里用 :focus-visible 统一补回焦点环，
 *    并给所有可聚焦元素 scroll-margin，避免被 sticky 顶栏遮挡。
 * ============================================================ */
:where(a[href], button, input, select, textarea,
       [tabindex]:not([tabindex="-1"]),
       [role="button"], [role="tab"], [role="menuitem"], [role="option"],
       summary, label[tabindex]) {
  scroll-margin-block: 96px;      /* 键盘聚焦时不被吸顶导航盖住 */
  scroll-margin-inline: 16px;
}

:where(a[href], button, input, select, textarea,
       [tabindex]:not([tabindex="-1"]),
       [role="button"], [role="tab"], [role="menuitem"], [role="option"]):focus-visible {
  outline: 3px solid var(--ux-focus);
  outline-offset: 2px;
  border-radius: 8px;
  box-shadow: 0 0 0 5px rgba(255, 36, 66, .16);
  position: relative;
  z-index: 5;
}

/* 深色/红底上的焦点环要反过来，保证 3:1 对比度 */
.btn-primary:focus-visible,
.ss-btn-primary:focus-visible,
[class*="primary"]:focus-visible {
  outline-color: #fff;
  box-shadow: 0 0 0 5px rgba(255, 255, 255, .35);
}

/* 跳转到主内容（WCAG 2.4.1 绕过区块） */
.ux-skip {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: var(--z-top-2, 99999);
  background: #fff;
  color: var(--xhs-red-text, #D81B37);
  border: 1px solid #FFD7DE;
  border-radius: 999px;
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  transition: transform var(--ux-t-drop) var(--ux-ease);
}
.ux-skip:focus {
  transform: translateY(72px);
}

/* ============================================================
 * 2. 触控目标尺寸（WCAG 2.2 SC 2.5.8，AA 底线 24×24）
 *    移动端按最佳实践放宽到 44px（仅对图标型/小按钮）
 * ============================================================ */
:where(button, [role="button"], a[href], select, input[type="checkbox"], input[type="radio"]) {
  min-height: 24px;
  min-width: 24px;
}
/* 明确点名：审计里实测仍小于 24px 的几类。
   注意这里必须 !important —— 这些元素自带 padding/line-height 规则，
   特异性更高，不加实测仍是 23px（SC 2.5.8 是 AA 底线，值得强制）。 */
.sopt, .ss-cb-btn, .ss-search-clear, .chip-mini, .tag-btn,
.ss-brief-more, .ss-cb-btn *, [data-ux-tap="small"] {
  min-height: 24px !important;
  min-width: 24px !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* 图标按钮：可点区域大于图标本身 */
button:has(> svg:only-child),
button:has(> i:only-child),
[role="button"]:has(> svg:only-child) {
  min-width: 32px;
  min-height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

@media (max-width: 768px) {
  /* 移动端：小按钮触控区放宽到 44px（用 padding 撑，不改视觉尺寸） */
  .sopt, .ss-cb-btn, .chip-mini, .tag-btn,
  button:has(> svg:only-child),
  button:has(> i:only-child) {
    min-height: 40px;
    min-width: 40px;
    padding-inline: 10px;
  }
  .ux-toast-undo { min-height: 44px; }
}

/* 需要保持紧凑的元素显式豁免 */
.ux-tap-none, .ux-tap-none * { min-height: 0 !important; min-width: 0 !important; }

/* ============================================================
 * 3. 骨架屏（维度二 2.7 / 维度四 4.2）
 *    形状贴近真实布局，避免加载完成时的 CLS
 * ============================================================ */
.ux-sk {
  background: var(--ux-sk-1);
  border-radius: 8px;
  position: relative;
  overflow: hidden;
}
.ux-sk::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
      rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, .65) 50%, rgba(255, 255, 255, 0) 100%);
  transform: translateX(-100%);
  animation: ux-sk-sweep 1.3s var(--ux-ease) infinite;
}
@keyframes ux-sk-sweep { to { transform: translateX(100%); } }

.ux-sk-line { height: 14px; margin: 8px 0; }
.ux-sk-line.w70 { width: 70%; }
.ux-sk-line.w50 { width: 50%; }
.ux-sk-title { height: 20px; width: 45%; margin: 4px 0 12px; }
.ux-sk-thumb { width: 100%; aspect-ratio: 1 / 1; border-radius: 12px; }
.ux-sk-avatar { width: 40px; height: 40px; border-radius: 50%; flex: 0 0 auto; }
.ux-sk-card { padding: 14px; border-radius: 14px; background: #fff; box-shadow: 0 2px 10px rgba(17, 24, 39, .06); }
.ux-sk-row { display: flex; gap: 10px; align-items: center; }
.ux-sk-grid { display: grid; gap: 12px; }

/* ============================================================
 * 4. Toast + 撤销窗口（维度二 2.1 / 2.5）
 * ============================================================ */
#ux-toast-host {
  position: fixed;
  left: 50%;
  bottom: 84px;
  transform: translateX(-50%);
  z-index: var(--z-top, 99990);
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  pointer-events: none;
}
.ux-toast {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: min(92vw, 460px);
  background: rgba(24, 24, 27, .94);
  color: #fff;
  font-size: 13px;
  line-height: 1.5;
  padding: 10px 14px;
  border-radius: 999px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .18);
  opacity: 0;
  transform: translateY(8px) scale(.96);
  transition: opacity var(--ux-t-drop) var(--ux-ease), transform var(--ux-t-drop) var(--ux-ease);
}
.ux-toast[data-show="1"] { opacity: 1; transform: translateY(0) scale(1); }
.ux-toast[data-kind="ok"] { background: rgba(16, 122, 87, .95); }
.ux-toast[data-kind="err"] { background: rgba(180, 35, 24, .95); }
.ux-toast[data-kind="warn"] { background: rgba(146, 84, 12, .95); }
.ux-toast-undo {
  pointer-events: auto;
  flex: 0 0 auto;
  border: 0;
  background: #fff;
  /* 2026-10-17：#FF2442 在白底胶囊上 3.76 不达标 → 文字档 #D81B37（5.08） */
  color: var(--xhs-red-text, #D81B37);
  font-size: 13px;
  font-weight: 800;
  padding: 5px 12px;
  border-radius: 999px;
  cursor: pointer;
  min-height: 32px;
  transition: transform var(--ux-t-press) var(--ux-ease);
}
.ux-toast-undo:active { transform: scale(.94); }
.ux-toast-timer {
  flex: 0 0 auto;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: conic-gradient(#fff var(--ux-p, 100%), rgba(255, 255, 255, .25) 0);
  -webkit-mask: radial-gradient(circle, transparent 5px, #000 6px);
  mask: radial-gradient(circle, transparent 5px, #000 6px);
}

/* ============================================================
 * 5. 空状态 = 行动入口（维度二 2.4）
 * ============================================================ */
.ux-empty {
  padding: 20px 16px;
  text-align: center;
  background: #fff;
  border: 1px dashed #E8EAEE;
  border-radius: 16px;
}
.ux-empty-ico {
  width: 44px; height: 44px;
  margin: 0 auto 10px;
  border-radius: 50%;
  background: #FFF1F3;
  color: var(--ux-red);
  display: flex; align-items: center; justify-content: center;
}
.ux-empty-ico svg { width: 22px; height: 22px; }
.ux-empty-t { font-size: 14px; font-weight: 800; color: #111827; margin-bottom: 4px; }
/* 2026-10-17：12.5px 半像素 → 13px；#6B7280 在浅底上 4.40 擦线 → --text-muted(5.9+) */
.ux-empty-d { font-size: 13px; color: var(--text-muted, #5B5457); line-height: 1.7; margin-bottom: 12px; }
.ux-empty-acts { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }
.ux-empty-btn {
  border: 0;
  /* 2026-10-17：白字压在 #FF2442 上只有 3.76（13px 正文需 4.5），
     改用 --xhs-red-solid(#E01230)：白字 4.89，观感仍是同一支品牌红。 */
  background: var(--xhs-red-solid, #E01230);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  padding: 9px 18px;
  min-height: 44px;
  border-radius: 999px;
  cursor: pointer;
  transition: transform var(--ux-t-press) var(--ux-ease), opacity var(--ux-t-hover) var(--ux-ease);
}
.ux-empty-btn:active { transform: scale(.96); }
.ux-empty-btn.ghost {
  background: #fff;
  color: #374151;
  border: 1px solid #E5E7EB;
  min-height: 44px;
}

/* ============================================================
 * 6. 统一错误状态（维度二 2.8 / 维度六 6.1）
 * ============================================================ */
.ux-err {
  padding: 16px;
  text-align: center;
  background: #FFF5F5;
  border: 1px solid #FECACA;
  border-radius: 16px;
}
.ux-err-t { font-size: 13.5px; font-weight: 800; color: #B91C1C; margin-bottom: 4px; }
.ux-err-d { font-size: 12.5px; color: #7F1D1D; line-height: 1.7; margin-bottom: 10px; }
.ux-err-acts { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }

/* ============================================================
 * 7. 行为触发式引导卡（维度一 1.1）
 * ============================================================ */
.ux-guide {
  position: fixed;
  right: 20px;
  bottom: 96px;
  /* 2026-10-05：99980 会把引导卡顶到所有弹窗（modal 9000~12000）之上，
     「层级异常」就是它——降层到弹窗之下、普通内容之上，弹窗打开时不再抢层。 */
  z-index: var(--z-guide, 8600);
  width: min(88vw, 330px);
  max-height: min(62vh, 480px);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: #fff;
  border: 1px solid #FFE0E6;
  border-radius: 18px;
  box-shadow: 0 12px 32px rgba(17, 24, 39, .14);
  padding: 14px;
  opacity: 0;
  transform: translateY(12px) scale(.97);
  /* 2026-10-10 夜致命修复：隐藏态原先只有 opacity:0 —— 透明但照样吃点击。
     卡片一经创建就常驻 DOM，右下角会留下一块「看不见的死区」，用户点上去毫无反应。
     隐藏时必须同时关掉命中，显示时再打开。 */
  pointer-events: none;
  transition: opacity var(--ux-t-modal) var(--ux-ease), transform var(--ux-t-modal) var(--ux-ease);
}
.ux-guide[data-show="1"] { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
/* 手机上 330px 宽的卡片几乎占满屏、正好糊住正文；同时要抬到 TabBar 之上 */
@media (max-width: 899px) {
  .ux-guide {
    width: min(92vw, 320px);
    /* ① 抬到 TabBar 之上；② 再抬一层让开 AI 任务卡（任务卡停在 TabBar+12 那一档），
       否则两样东西叠在同一条底部带里，卡片上的「知道了」会被任务卡压住点不了。 */
    bottom: calc(var(--tabbar-h, 56px) + 62px);
  }
}
.ux-guide-h { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.ux-guide-h b { font-size: 13.5px; color: #111827; }
.ux-guide-h .ux-guide-dot {
  width: 26px; height: 26px; border-radius: 50%;
  background: #FFF1F3; color: var(--ux-red);
  display: flex; align-items: center; justify-content: center; flex: 0 0 auto;
}
.ux-guide-b { font-size: 12.5px; line-height: 1.75; color: #4B5563; margin-bottom: 10px; }
.ux-guide-a { display: flex; gap: 8px; }

/* ============================================================
 * 8. 离线降级提示（维度四 4.4 / 维度六 6.2）
 * ============================================================ */
#ux-net {
  position: fixed;
  left: 0; right: 0; top: 0;
  z-index: var(--z-top-1, 99995);
  text-align: center;
  font-size: 12.5px;
  font-weight: 700;
  padding: 6px;
  color: #fff;
  background: #B42318;
  transform: translateY(-100%);
  transition: transform var(--ux-t-drop) var(--ux-ease);
}
#ux-net[data-on="1"] { transform: translateY(0); }
#ux-net[data-on="2"] { transform: translateY(0); background: #0F7A57; }

/* ============================================================
 * 9. 滚动进场只用于装饰元素（维度二 2.3）
 *    正文默认不动；只有显式标 data-ux-reveal="deco" 的装饰元素才进场
 * ============================================================ */
[data-ux-reveal="deco"] {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .42s var(--ux-ease-out), transform .42s var(--ux-ease-out);
}
[data-ux-reveal="deco"][data-shown="1"] { opacity: 1; transform: none; }

/* ============================================================
 * 10. reduced-motion：全部动效归零
 * ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .ux-toast, .ux-guide, .ux-skip, #ux-net,
  .ux-empty-btn, .ux-toast-undo, [data-ux-reveal="deco"] {
    transition: none !important;
    animation: none !important;
  }
  .ux-sk::after { animation: none !important; }
  [data-ux-reveal="deco"] { opacity: 1 !important; transform: none !important; }
  .ux-toast { opacity: 1 !important; transform: none !important; }
  .ux-guide { opacity: 1 !important; transform: none !important; }
}

/* ============================================================
 * 体验增强层（ux-extras.js）
 * 角色推荐卡 / 常用模块条 / 触控目标兜底 / 首次动画只播一次
 * 动效只用 transform + opacity，reduced-motion 下全部关闭
 * ============================================================ */

/* ---- 首次动画只播一次（维度一 1.2） ---- */
html[data-ux-intro="skip"] .hero-banner,
html[data-ux-intro="skip"] .ux-rec,
html[data-ux-intro="skip"] .ux-fav {
  animation: none !important;
  opacity: 1 !important;
  transform: none !important;
}
html[data-ux-intro="play"] .ux-rec,
html[data-ux-intro="play"] .ux-fav {
  animation: ux-rise .34s var(--ux-ease-out) both;
}
@keyframes ux-rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* 2026-10-18：#ux-today / #ux-role-rec 现由 index.html 预置（原先是 JS 运行时插入，
   造成首屏 CLS 0.11~0.22）。容器预置后仍有「空容器高度 0 → 内容填充把下方推走」
   的残留，所以这里按三态处理：
     ① 脚本没执行       → :empty → 隐藏，不留空盒子；
     ② 脚本已执行待填充 → ux-extras.js 打上 data-ux-loading → 预留高度 + 骨架底纹；
     ③ 内容已填充       → removeAttribute → 本组规则全部失效，回到正常样式。
   预留高度来自实测（69-measure.mjs，卡片数恒为 5、三种角色一致）：
     #ux-role-rec 桌面 144px（creator，brand/mcn 为 126px，差值只来自标题换行；
       且角色切换是用户点击，属 hadRecentInput，不计入 CLS）／窄屏 402px（单列）；
     #ux-today 两个视口均 156px。
   为什么可以预留而不算「猜高度」：68-clsn.mjs 实测移动端 CLS 6 次均为 0.1099
   （极差 0），是确定性移位，高度本身稳定，预留后可直接复测验证。
   内联 style.display 优先级高于本规则，renderTodayTask 的 display='none'/'' 照常生效。 */
#ux-today:empty,
#ux-role-rec:empty { display: none; }
#ux-today[data-ux-loading]:empty,
#ux-role-rec[data-ux-loading]:empty {
  display: block;
  min-height: 156px;
  border-radius: 16px;
  background-image: linear-gradient(180deg, #f5f6f8 0%, #eceef1 100%);
  opacity: .6;
}
#ux-role-rec[data-ux-loading]:empty { min-height: 144px; }
@media (max-width: 640px) {
  #ux-role-rec[data-ux-loading]:empty { min-height: 402px; }
}

/* ---- 角色差异化首屏（维度一 1.3） ---- */
.ux-rec {
  margin: 12px 0 14px;
  padding: 12px;
  background: #fff;
  border: 1px solid #f1f2f4;
  border-radius: 16px;
}
.ux-rec-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin-bottom: 10px; flex-wrap: wrap;
}
.ux-rec-k { font-size: 13px; color: #4b5563; }
.ux-rec-k b { color: var(--xhs-red-text, #D81B37); }
.ux-rec-switch {
  font-size: 12px; padding: 5px 10px; border-radius: 999px; cursor: pointer;
  border: 1px solid #ffe0e6; background: #fff1f3; color: var(--xhs-red-text, #D81B37);
  transition: transform var(--ux-t-press) var(--ux-ease);
}
.ux-rec-switch:active { transform: scale(.94); }
.ux-rec-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.ux-rec-card {
  text-align: left; cursor: pointer;
  padding: 10px; border-radius: 12px; border: 1px solid #f1f2f4; background: #fcfcfd;
  display: flex; flex-direction: column; gap: 3px; min-height: 44px;
  transition: transform var(--ux-t-press) var(--ux-ease), box-shadow var(--ux-t-hover) var(--ux-ease);
}
.ux-rec-card b { font-size: 13px; color: #111827; font-weight: 800; }
.ux-rec-card span { font-size: 12px; color: var(--text-muted, #5B5457); line-height: 1.5; }
.ux-rec-card:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(17, 24, 39, .07); }
.ux-rec-card:active { transform: scale(.97); }

/* ---- 常用模块置顶（维度二 2.6 / 五 5.1） ---- */
/* 高度固定：容器常驻、无数据时 visibility 隐藏而非移除，
   否则「常用条从无到有」会把整个侧边栏推下去 —— 实测 CLS 0.165。 */
.ux-fav {
  padding: 8px 10px 10px;
  border-bottom: 1px solid #f1f2f4;
  height: 68px;
  overflow: hidden;
  box-sizing: border-box;
}
.ux-fav[data-empty="1"] { visibility: hidden; }
.ux-fav-k { font-size: 12px; color: #6E6869; letter-spacing: .5px; margin-bottom: 6px; height: 15px; }
.ux-fav-row { display: flex; flex-wrap: nowrap; gap: 6px; overflow: hidden; }
.ux-fav-i {
  font-size: 12px; padding: 6px 10px; border-radius: 999px; cursor: pointer;
  border: 1px solid #f1f2f4; background: #fff; color: #374151;
  min-height: 28px;   /* >= 24×24（WCAG 2.2 SC 2.5.8） */
  transition: transform var(--ux-t-press) var(--ux-ease), background var(--ux-t-hover) var(--ux-ease);
}
.ux-fav-i:hover { background: #fff1f3; border-color: #ffe0e6; color: var(--xhs-red-text, #D81B37); }
.ux-fav-i:active { transform: scale(.94); }

/* ---- 触控目标兜底（维度七 7.2）：标出来的过小控件补最小尺寸 ---- */
[data-ux-tap="small"] { min-width: 24px; min-height: 24px; }
@media (max-width: 899px) {
  [data-ux-tap="small"] { min-width: 32px; min-height: 32px; }
  .ux-rec-card { min-height: 48px; }
}

/* ---- 健康度低时的温和提示（不打扰，只做视觉标记） ---- */
html[data-ux-health="low"] .ux-rec { border-color: #ffe0e6; background: #fffafa; }

@media (prefers-reduced-motion: reduce) {
  .ux-rec, .ux-fav, .ux-rec-card, .ux-fav-i, .ux-rec-switch {
    animation: none !important;
    transition-duration: .00001s !important;
  }
  .ux-rec-card:hover, .ux-fav-i:active, .ux-rec-switch:active { transform: none !important; }
}

/* ============================================================
 * 图标占位预留 —— 消除异步图标注入导致的布局跳动（CLS）
 * ============================================================
 * 实测：renderIcons() 异步执行，注入前 <i data-icon> 不带 .icon 类 → 盒子 0×0；
 *       注入后变 20×20（--icon-size-md），#topnav 从 35px 长到 68px，
 *       把 main / hero / logo 一起往下推 —— 单这一笔就贡献 CLS 0.1402。
 * 做法：给「还没有 class 的宿主」预留和 .icon 完全相同的盒子；
 *       渲染后 render() 会加上 .icon 类，尺寸不变 → 零位移。
 * 只匹配 :not([class])，避免覆盖 .icon-inline（1.05em）等自带尺寸类的宿主。
 */
i[data-icon]:not([class]) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--icon-size-md, 20px);
  height: var(--icon-size-md, 20px);
  line-height: 0;
}

/* ============================================================
 * 顶部栏高度预留 —— 消除 auth 异步完成后的整页下移（CLS）
 * ============================================================
 * 实测时序（navtrace）：t=509ms topbar 67px（0 图标、无用户徽章）
 *                    t=1332ms 登录态解析完成 → auth.js 注入 #spark-auth-badge、
 *                    图标重渲染 → topbar 90px，main / hero / logo 一起下移 22px，
 *                    单这一笔贡献 CLS ≈ 0.11。
 * 做法：给 .topbar 预留最终高度，重建前后高度一致 → 零位移。
 * 只作用于 >=900px（窄屏 .topnav 隐藏、走底部 TabBar，高度本就不同）。
 */
@media (min-width: 900px) {
  .topbar { min-height: 90px; }
  .topbar-inner { align-items: center; }
}

/* ===== 「今天发什么」任务卡（2026-10-12，产品优化提案 ③）=====
   首屏第一个问题不是「有哪些功能」，而是「我今天该发什么」。
   独立 ux-today 前缀，不复用 .ux-rec（那是功能导览，语义不同）。 */
.ux-today {
  margin: 0 0 14px; padding: 14px 16px; border-radius: 14px;
  border: 1px solid rgba(255,36,66,.16);
  background: linear-gradient(180deg, #FFF7F8 0%, #FFFDFD 100%);
}
.ux-today-k {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; font-weight: 700; letter-spacing: .2px;
  color: var(--xhs-red-text, #D81B37); background: rgba(255,36,66,.08);
  padding: 3px 9px; border-radius: 999px;
}
.ux-today-t {
  margin-top: 9px; font-size: 16px; font-weight: 800; line-height: 1.45;
  color: #111827; word-break: break-word;
}
.ux-today-s { margin-top: 5px; font-size: 12px; color: var(--text-muted, #5B5457); line-height: 1.6; }
.ux-today-ops { margin-top: 11px; display: flex; flex-wrap: wrap; gap: 8px; }
.ux-today-b {
  font-size: 12.5px; font-weight: 700; color: #374151;
  padding: 7px 13px; border-radius: 9px; cursor: pointer;
  border: 1px solid rgba(17,24,39,.12); background: #fff;
  transition: transform .16s cubic-bezier(.2,.7,.3,1), box-shadow .16s ease;
}
.ux-today-b:hover { box-shadow: 0 4px 12px rgba(17,24,39,.07); transform: translateY(-1px); }
.ux-today-b:active { transform: scale(.96); }
.ux-today-b.pri {
  color: #fff; background: var(--xhs-red-solid, #E01230); border-color: var(--xhs-red-text, #D81B37);
  box-shadow: 0 4px 12px rgba(255,36,66,.22);
}
.ux-today-b.pri:active { transform: scale(.96); }
.ux-today-done { }
.ux-today-done .ux-today-k { color: #137A52; background: rgba(29,158,117,.10); }
@media (max-width: 640px) {
  .ux-today { padding: 12px 13px; border-radius: 12px; }
  .ux-today-t { font-size: 15px; }
  .ux-today-b { flex: 1 1 auto; text-align: center; min-height: 38px; }
}
[data-theme="dark"] .ux-today {
  border-color: rgba(255,90,110,.22);
  background: linear-gradient(180deg, rgba(255,36,66,.10) 0%, rgba(255,255,255,.03) 100%);
}
[data-theme="dark"] .ux-today-t { color: rgba(255,255,255,.92); }
[data-theme="dark"] .ux-today-s { color: rgba(255,255,255,.56); }
[data-theme="dark"] .ux-today-b {
  color: rgba(255,255,255,.82); background: rgba(255,255,255,.06);
  border-color: rgba(255,255,255,.14);
}

/* ===== 48h 复盘提醒（2026-10-12，提案 ④ 轻量版）===== */
.ux-today-rev {
  margin-top: 12px; padding-top: 11px; border-top: 1px dashed rgba(17,24,39,.12);
  display: flex; align-items: flex-start; gap: 9px; flex-wrap: wrap;
}
.ux-rev-i { font-size: 15px; line-height: 1.4; }
.ux-rev-t { flex: 1 1 220px; min-width: 0; }
.ux-rev-t b { display: block; font-size: 13px; font-weight: 800; color: #92400E; }
.ux-rev-t span {
  display: block; margin-top: 3px; font-size: 12px; color: #8a6a3a; line-height: 1.6;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ux-rev-ops { display: flex; gap: 7px; flex: 0 0 auto; }
.ux-rev-b {
  font-size: 12px; font-weight: 700; color: #92400E; cursor: pointer;
  padding: 6px 11px; border-radius: 8px;
  border: 1px solid rgba(146,64,14,.24); background: rgba(255,255,255,.7);
  transition: transform .16s cubic-bezier(.2,.7,.3,1);
}
.ux-rev-b:active { transform: scale(.96); }
.ux-rev-b.pri { color: #fff; background: #D97706; border-color: #D97706; }
@media (max-width: 640px) {
  .ux-rev-ops { flex: 1 1 100%; }
  .ux-rev-b { flex: 1 1 auto; text-align: center; min-height: 36px; }
}
[data-theme="dark"] .ux-today-rev { border-top-color: rgba(255,255,255,.12); }
[data-theme="dark"] .ux-rev-t b { color: #FBBF24; }
[data-theme="dark"] .ux-rev-t span { color: rgba(251,191,36,.72); }
[data-theme="dark"] .ux-rev-b {
  color: rgba(251,191,36,.9); background: rgba(255,255,255,.06);
  border-color: rgba(251,191,36,.28);
}

/* ============================================================
 * 5b. 历史空态私壳的契约补位（P1-B，2026-10-17）
 * ------------------------------------------------------------
 * 全站唯一规范是上面的 .ux-empty。下面这些是历史遗留壳，
 * 各自有布局约束（侧栏 / 卡片内 / 表格 / 品牌页配色），
 * 本轮不换 DOM 结构（换结构需要逐模块视觉基线，风险 > 收益），
 * 只在 CSS 层补齐契约：触摸目标 ≥44px。
 * 注意：min-height 这些壳原本都没声明过，故不会被后面的同文件规则覆盖。
 * ============================================================ */
.lc-empty, .plog-empty, .ss-conv-empty, .sl-empty, .ss-ag-empty,
.ark-empty, .acct-empty, .sk-empty, .rs-empty, .sb-empty,
.ss-emp-empty, .cr-empty, .bf-pv-empty, .sh-empty, .bf-preview-empty,
.pp-empty, .ss-ava-empty {
  min-height: 44px;
}

/* ============================================================
 * 12. Modal / Confirm / Prompt（2026-10-20）
 *     替掉原生 alert/confirm/prompt 后的统一样式。
 *     约束沿用站内规范：只用 transform/opacity 做动效、尊重 reduced-motion、
 *     移动端触控目标 44px、桌面端不新造色值（走 --ux-red 与既有中性色）。
 * ============================================================ */
.ux-mask {
  position: fixed;
  inset: 0;
  z-index: var(--z-dialog, 99985);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(24, 20, 21, .42);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  opacity: 0;
  transition: opacity var(--ux-t-modal) var(--ux-ease);
  overscroll-behavior: contain;
}
.ux-mask.is-in { opacity: 1; }

.ux-dlg {
  width: min(440px, 100%);
  max-height: calc(100vh - 40px);
  max-height: calc(100dvh - 40px);
  overflow: auto;
  background: #fff;
  border-radius: 18px;
  box-shadow: 0 24px 60px rgba(24, 20, 21, .22), 0 2px 8px rgba(24, 20, 21, .06);
  padding: 22px 22px 16px;
  transform: translateY(8px) scale(.985);
  transition: transform var(--ux-t-modal) var(--ux-ease-out);
}
.ux-mask.is-in .ux-dlg { transform: none; }

.ux-dlg-t {
  margin: 0 0 8px;
  font-size: 15.5px;
  font-weight: 700;
  line-height: 1.5;
  color: var(--text-strong, #1F1B1C);
}
.ux-dlg-b {
  font-size: 14px;
  line-height: 1.72;
  color: var(--text-muted, #5B5457);
  word-break: break-word;
}

.ux-dlg-in {
  display: block;
  width: 100%;
  margin-top: 14px;
  padding: 11px 13px;
  font-size: 14px;
  line-height: 1.6;
  font-family: inherit;
  color: var(--text-strong, #1F1B1C);
  background: #FAF8F8;
  border: 1px solid var(--line, #EDE7E8);
  border-radius: 12px;
  /* ★ 全站 input/button 带 min-height，不归零会把 44px 顶下来 */
  min-height: 0;
  transition: border-color var(--ux-t-hover) var(--ux-ease),
              background var(--ux-t-hover) var(--ux-ease);
}
.ux-dlg-in::placeholder { color: #A9A2A4; }
.ux-dlg-in:focus {
  outline: none;
  border-color: var(--ux-red);
  background: #fff;
  box-shadow: 0 0 0 3px rgba(255, 36, 66, .12);
}
.ux-dlg-ta { resize: vertical; min-height: 84px; }

.ux-dlg-a {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  margin-top: 18px;
}
.ux-dlg-btn {
  /* ★ 站点级 button{min-height:44px} 会与这里的 36px 打架，必须显式归零 */
  min-height: 0;
  height: 36px;
  padding: 0 18px;
  font-size: 13.5px;
  font-weight: 600;
  font-family: inherit;
  border-radius: 10px;
  border: 1px solid var(--line, #EDE7E8);
  background: #fff;
  color: var(--text-strong, #1F1B1C);
  cursor: pointer;
  transition: transform var(--ux-t-press) var(--ux-ease),
              background var(--ux-t-hover) var(--ux-ease),
              filter var(--ux-t-hover) var(--ux-ease);
}
.ux-dlg-btn:hover { background: #FAF8F8; }
.ux-dlg-btn:active { transform: scale(.97); }
.ux-dlg-yes {
  background: var(--ux-red);
  border-color: transparent;
  color: #fff;
}
.ux-dlg-yes:hover { background: var(--ux-red); filter: brightness(.93); }
.ux-dlg-btn[disabled] { opacity: .5; cursor: not-allowed; }

/* 移动端：底部抽屉 + 44px 触控目标 */
@media (max-width: 560px) {
  .ux-mask-sheet { align-items: flex-end; padding: 0; }
  .ux-mask-sheet .ux-dlg {
    width: 100%;
    max-width: 100%;
    max-height: 86vh;
    max-height: 86dvh;
    border-radius: 18px 18px 0 0;
    padding: 20px 18px calc(16px + env(safe-area-inset-bottom, 0px));
    transform: translateY(16px);
  }
  .ux-dlg-btn { flex: 1 1 0; height: 44px; font-size: 14.5px; }
}

@media (prefers-reduced-motion: reduce) {
  .ux-mask, .ux-dlg { transition: none !important; }
  .ux-mask .ux-dlg { transform: none; }
}
