/* ============================================================
   Kezn Workbench 样式
   来源：design-system.html（Kezn Design System V1.0）token 与组件移植
   新增：暗色主题 / 弹窗 / 工作台业务组件
   资源版本：index.php 按 filemtime 自动生成 ?v=，改样式无需手动改版本号
   ============================================================ */

/* ===================== 自托管字体 =====================
   JetBrains Mono（latin 子集 woff2，约 21KB/字重）：
   等宽数字是本设计的灵魂，自托管保证 iOS/安卓/Windows 三端一致，
   不再各自落到 SF Mono / Droid Sans Mono 等系统差异字体。
   子集不含汉字，中文按栈自动回退到 sans 各代字体。 */
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url("fonts/jetbrains-mono-latin-400.woff2") format("woff2"); }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url("fonts/jetbrains-mono-latin-500.woff2") format("woff2"); }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 600; font-display: swap; src: url("fonts/jetbrains-mono-latin-600.woff2") format("woff2"); }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 700; font-display: swap; src: url("fonts/jetbrains-mono-latin-700.woff2") format("woff2"); }

/* KlogNum：同一批 woff2 的「数字专用」角色（unicode-range 只认领 0-9 : %）。
   置于 --font-sans 栈首 → 全站任何文本里的阿拉伯数字自动统一为 JetBrains Mono
   字形，中文/字母不受影响；新组件零成本继承，无需逐处点名 mono。 */
@font-face { font-family: "KlogNum"; font-style: normal; font-weight: 400; font-display: swap; src: url("fonts/jetbrains-mono-latin-400.woff2") format("woff2"); unicode-range: U+0030-0039, U+0025, U+003A; }
@font-face { font-family: "KlogNum"; font-style: normal; font-weight: 500; font-display: swap; src: url("fonts/jetbrains-mono-latin-500.woff2") format("woff2"); unicode-range: U+0030-0039, U+0025, U+003A; }
@font-face { font-family: "KlogNum"; font-style: normal; font-weight: 600; font-display: swap; src: url("fonts/jetbrains-mono-latin-600.woff2") format("woff2"); unicode-range: U+0030-0039, U+0025, U+003A; }
@font-face { font-family: "KlogNum"; font-style: normal; font-weight: 700; font-display: swap; src: url("fonts/jetbrains-mono-latin-700.woff2") format("woff2"); unicode-range: U+0030-0039, U+0025, U+003A; }

/* ===================== Design Tokens ===================== */
:root {
  /* ---- Color: Background ---- */
  --bg-page:              #F7F8FA;
  --bg-sidebar:          #F0F1F3;
  --bg-card:             #FFFFFF;
  --rm-well:             #EDEFF2; /* 小票机弹窗内衬（台面），让白纸与背景可区分 */
  --bg-soft:             #FAFBFC;
  --bg-header:           #F7F7F9;
  --bg-table-header:     #F7F8FA;
  --bg-hover:            #F3F4F6;
  --bg-selected:         #FFFFFF;
  --bg-disabled:         #FAFAFA;
  --bg-count:            #E5E7EB;
  --bg-count-active:     #D1D5DB;
  --bg-muted:            #F3F4F6;

  /* ---- Color: Border ---- */
  --border:              #E5E7EB;
  --border-strong:      #D1D5DB;

  /* ---- Color: Text ---- */
  --text-1:              #1A1A1A;
  --text-2:              #333333;
  --text-3:              #555555;
  --text-4:              #5B6472; /* 加深：在灰底（well/count）上仍满足 AA 4.5:1 */
  --text-disabled:       #D1D5DB;

  /* ---- Color: Status ---- */
  --status-good:         #279E49;
  --status-bad:          #E53E3E;
  --up:                  var(--status-good);
  --down:                var(--status-bad);
  --warning:             #F59E0B;
  --danger:              #E53E3E;

  /* ---- Color: Trend（红涨绿跌） ---- */
  --trend-up:            #EF4444;
  --trend-down:          #10B981;
  --delta-up:            var(--trend-up);
  --delta-down:          var(--trend-down);
  --delta-flat:          #6B7280;

  /* ---- Color: Brand / Action ---- */
  --primary:             #111111;
  --primary-hover:       #1F2937;
  --on-primary:          #FFFFFF;
  --white:               #FFFFFF;

  /* ---- Color: Badge Dots ---- */
  --badge-dot-1:          #FE2C55;
  --badge-dot-2:          #EF4444;
  --badge-dot-3:          #10B981;

  /* ---- Color: 扩展（组件原硬编码值 token 化，保证暗色可用） ---- */
  --mask:                rgba(17,17,17,.32);
  /* ---- Elevation（分层阴影：静态 / 悬浮 / 浮层 / 弹窗 / 轻提示） ---- */
  --shadow-sm:           0 1px 2px rgba(17,17,17,.03);
  --shadow-card:         0 1px 2px rgba(17,17,17,.04);
  --shadow-hover:        0 4px 12px rgba(17,17,17,.07);
  --shadow-float:        0 10px 28px rgba(17,17,17,.09);
  --shadow-modal:        0 18px 44px rgba(17,17,17,.13);
  --shadow-toast:        0 4px 14px rgba(17,17,17,.07);
  --btn-2-bg:            #FEFFFE;
  --btn-2-bg-hover:      #FFFFFF;
  --btn-2-bg-active:     #F3F4F6;
  --btn-danger-bg:       #FEFFFE;
  --focus-ring:          rgba(17,17,17,.16);
  --switch-track:        #D1D5DB;
  --tag-high-bg:         rgba(229,62,62,.08);
  --tag-high-fg:         #DC2626; /* 加深至 AA：原 #E53E3E 白底约 4.1:1 */
  --tag-good-bg:         rgba(16,185,129,.1);
  --tag-good-fg:         #047857; /* 原 #10B981 白底约 2.5:1 不达标 */
  --tag-warn-bg:         rgba(245,158,11,.1);
  --tag-warn-fg:         #B45309; /* 原 #F59E0B 白底约 2.2:1 不达标 */
  --tag-bad-bg:          rgba(229,62,62,.08);
  --tag-bad-fg:          #DC2626;

  /* ---- Color: 打卡热力（四档绿：空白 / 1 次 / 2 次 / 3 次以上） ---- */
  --hm-0:                #EEF0F2;
  --hm-1:                #CFE7D6;
  --hm-2:                #8CC79F;
  --hm-3:                #279E49;
  --hm-line:             rgba(17,17,17,.05);
  --hm-ink-0:            #C2C7CE;
  --hm-ink-1:            #2C6B41;
  --hm-ink-2:            #10401F;
  --hm-ink-3:            #FFFFFF;

  /* ---- Border Radius（分级：控件 4 / 标签 6 / 容器 8 / 浮层 12） ---- */
  --radius-sm:           3px;
  --radius-btn:          4px;
  --radius-md:           4px;
  --radius-badge:        6px;
  --radius-card:         8px;
  --radius-lg:           12px;

  /* ---- Spacing Tokens (4px 基准) ---- */
  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px; --sp-6: 24px;
  --sp-7: 28px; --sp-8: 32px; --sp-10: 40px; --sp-12: 48px;

  /* ---- Spacing: Layout ---- */
  --sidebar-w: 216px;
  --header-h: 72px;
  --content-px: var(--sp-8);
  --content-py: var(--sp-6);
  --module-gap: var(--sp-7);
  --filter-gap: var(--sp-6);
  --card-gap: var(--sp-4);
  --logo-gap: 10px;
  --meta-icon-gap: 8px;

  /* ---- Spacing: Component ---- */
  --card-pad: var(--sp-6);
  --control-h: 34px;
  --control-h-sm: 30px;
  --control-px: 16px;
  --select-px: 10px;

  /* ---- Typography ---- */
  --fs-display: 1.75rem;
  --fs-h1: 1.375rem;
  --fs-h2: 1.125rem;
  --fs-body: 0.875rem;
  --fs-caption: 0.8125rem;
  --fs-label: 0.75rem;
  --fs-micro: 0.6875rem;

  --lh-display: 1.2;
  --lh-h1: 1.3;
  --lh-h2: 1.4;
  --lh-body: 1.6;
  --lh-caption: 1.5;
  --lh-label: 1.4;
  --lh-micro: 1.4;

  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;

  /* ---- Animation ---- */
  --transition-fast: 0.15s;
  --d-fast: 0.15s;
  --d-modal: 0.22s;
  --d-enter: 0.35s;
  --ease-enter: cubic-bezier(.16, 1, .3, 1);
  --ease-float: cubic-bezier(.22, .61, .36, 1);

  /* ---- Font Family ---- */
  /* KlogNum 居首：0-9 一律 JetBrains Mono 字形（unicode-range 限定），其余字符落到后面字体；
     sans：iOS/mac → 安卓主流 OEM 中文字体（命中用户系统所选，观感最佳）→ Noto/雅黑 兜底 */
  --font-sans: "KlogNum", -apple-system, "PingFang SC", "HarmonyOS Sans SC", "MiSans", "OPPO Sans 4.0", "vivo Sans SC", "Noto Sans SC", "Noto Sans CJK SC", "Microsoft YaHei", Roboto, sans-serif;
  --font-mono: "JetBrains Mono", "SF Mono", ui-monospace, Consolas, monospace;
}

/* ===================== 暗色主题 ===================== */
[data-theme="dark"] {
  --bg-page:            #101114;
  --bg-sidebar:         #141519;
  --bg-card:            #191B1F;
  --rm-well:            #141519; /* 暗色下用更深的「井」衬出白纸 */
  --bg-soft:            #1D1F24;
  --bg-header:          #151619;
  --bg-table-header:    #151619;
  --bg-hover:           #202228;
  --bg-selected:        #1B1D21;
  --bg-disabled:        #1A1B1F;
  --bg-count:           #2B2E35;
  --bg-count-active:    #383C44;
  --bg-muted:           #202228;

  --border:              #272A31;
  --border-strong:      #363B44;

  --text-1:             #F0F1F3;
  --text-2:             #D3D6DB;
  --text-3:             #B0B4BC;
  --text-4:             #7E838D;
  --text-disabled:      #3E424A;

  --status-good:        #2FBF6B;
  --status-bad:         #F0655A;

  /* 打卡热力：暗底下绿由暗到亮，格内数字墨色随之反转 */
  --hm-0:                #22252B;
  --hm-1:                #1E4630;
  --hm-2:                #2F7A4A;
  --hm-3:                #57C070;
  --hm-line:             rgba(255,255,255,.07);
  --hm-ink-0:            #4A4F58;
  --hm-ink-1:            #A6DCBB;
  --hm-ink-2:            #E4F5E9;
  --hm-ink-3:            #08160D;
  --warning:            #F5A623;
  --danger:             #F0655A;
  --trend-up:           #F0655A;
  --trend-down:         #2FBF6B;
  --delta-flat:         #7E838D;

  --primary:            #E8E9EC;
  --primary-hover:      #FFFFFF;
  --on-primary:         #101114;

  --mask:               rgba(0,0,0,.62);
  --shadow-sm:          0 1px 2px rgba(0,0,0,.22);
  --shadow-card:        0 1px 2px rgba(0,0,0,.28);
  --shadow-hover:       0 4px 12px rgba(0,0,0,.38);
  --shadow-float:       0 10px 28px rgba(0,0,0,.46);
  --shadow-modal:       0 18px 44px rgba(0,0,0,.52);
  --shadow-toast:       0 4px 14px rgba(0,0,0,.38);
  --btn-2-bg:           #1D2025;
  --btn-2-bg-hover:     #24272D;
  --btn-2-bg-active:    #17191D;
  --btn-danger-bg:      #1D2025;
  --focus-ring:         rgba(232,233,236,.28);
  --switch-track:       #3A3E46;
  --tag-high-bg:        rgba(240,101,90,.14);
  --tag-high-fg:        #F0655A;
  --tag-good-bg:        rgba(47,191,107,.14);
  --tag-good-fg:        #2FBF6B;
  --tag-warn-bg:        rgba(245,166,35,.14);
  --tag-warn-fg:        #F5A623;
  --tag-bad-bg:         rgba(240,101,90,.14);
  --tag-bad-fg:         #F0655A;
}

/* ===================== 基础重置 ===================== */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html {
  -webkit-font-smoothing: antialiased;
  height: 100%;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* 关闭移动端默认点按高亮，改用自有按压反馈 */
  -webkit-tap-highlight-color: transparent;
}
body {
  font-family: var(--font-sans);
  background: var(--bg-page);
  color: var(--text-3);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  height: 100%;
}
h1 { font-size: var(--fs-h1); font-weight: var(--fw-bold); line-height: var(--lh-h1); }
h2 { font-size: var(--fs-h2); font-weight: var(--fw-semibold); line-height: var(--lh-h2); }
h3 { font-size: var(--fs-h2); font-weight: var(--fw-semibold); line-height: var(--lh-h2); }
code, pre { font-family: var(--font-mono); }
a { color: var(--primary); text-decoration: none; }
button { font-family: var(--font-sans); }
img, svg { display: block; }

/* ===================== 布局骨架 ===================== */
.app { display: flex; height: 100vh; overflow: hidden; }
.sidebar {
  width: var(--sidebar-w);
  background: var(--bg-sidebar);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column; flex-shrink: 0;
}
.sidebar .logo {
  display: flex; align-items: center; gap: var(--logo-gap);
  padding: var(--sp-4);
  border-bottom: 1px solid var(--border);
  min-height: var(--header-h); box-sizing: border-box;
}
/* 品牌 logo：内嵌 SVG 恒深底白 K（不随主题反转），容器仅做尺寸与居中 */
.logo-icon {
  width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.logo-icon svg { width: 100%; height: 100%; display: block; border-radius: 4px; }
.logo-cn { font-size: 15px; font-weight: var(--fw-semibold); color: var(--text-1); letter-spacing: .5px; }
.sidebar .menu { flex: 1; padding: 8px; overflow-y: auto; }
.menu-section-title {
  font-size: 11px; color: var(--text-4); font-weight: var(--fw-medium);
  padding: 8px 12px 6px; letter-spacing: .3px;
}
.menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  height: 40px; padding: 0 var(--sp-4);
  border: none; border-radius: 0; cursor: pointer; color: var(--text-2);
  font-size: var(--fs-body); letter-spacing: 1px; background: transparent;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.menu-item > span:first-of-type { flex: 1; text-align: left; }
.menu-item:hover { background: #E8E9EB; color: var(--text-1); }
[data-theme="dark"] .menu-item:hover { background: var(--bg-hover); }
.menu-item.active { background: var(--bg-selected); color: var(--text-1); font-weight: var(--fw-medium); }
.menu-item svg { width: 15px; height: 15px; flex-shrink: 0; color: var(--text-4); }
.menu-item.active svg, .menu-item:hover svg { color: var(--text-2); }
.menu-cnt {
  font-family: var(--font-mono); font-size: 10px;
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 9px; background: var(--primary); color: var(--on-primary);
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0; line-height: 1;
  animation: menuCntIn .22s var(--ease-enter);
  transition: opacity .22s var(--ease-enter), transform .22s var(--ease-enter), background-color .22s;
  transition: opacity .22s var(--ease-enter), transform .22s var(--ease-enter), background-color .22s, display .22s allow-discrete;
}
.menu-cnt[hidden] { display: none; opacity: 0; transform: scale(.5); }
@keyframes menuCntIn { from { opacity: 0; transform: scale(.5); } }
.menu-cnt.warn { background: var(--warning); color: var(--white); }
.menu-footer { padding: 10px 12px; border-top: 1px solid var(--border); }
/* 侧边栏用户栏：头像 + 用户名，点击进入个人中心 */
.user-bar {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 10px; border: none; border-radius: var(--radius-btn);
  background: transparent; cursor: pointer; text-align: left; font: inherit;
  transition: background var(--d-fast) ease;
}
.user-bar:hover { background: var(--bg-hover); }
.user-bar:active { transform: scale(.985); }
.user-avatar {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 34px; height: 34px; border-radius: var(--radius-btn);
  background: var(--primary); color: var(--on-primary);
  font-size: 14px; font-weight: 700; letter-spacing: .5px;
  user-select: none;
}
.user-meta { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.user-name { font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--text-1); }
.user-sub { font-size: var(--fs-micro); color: var(--text-4); }
.user-chev { width: 14px; height: 14px; color: var(--text-4); flex-shrink: 0; }

/* 顶栏头像入口（平板 / 移动端，侧边栏被收窄或隐藏时） */
.avatar-btn {
  display: none; align-items: center; justify-content: center; flex-shrink: 0;
  width: 32px; height: 32px; border-radius: var(--radius-btn); border: none; cursor: pointer;
  background: var(--primary); color: var(--on-primary);
  font-size: 13px; font-weight: 700; user-select: none;
}
.avatar-btn:active { transform: scale(.94); }

/* 个人中心弹窗 */
.profile-head {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 6px 0 14px;
}
.user-avatar-lg { width: 52px; height: 52px; font-size: 21px; }
/* 头像图片：容器内铺满 + 继承圆角裁剪（无图时容器仍显示首字母） */
.user-avatar img, .avatar-btn img, .user-row-avatar img {
  width: 100%; height: 100%; object-fit: cover; border-radius: inherit; display: block;
}

/* 个人中心：编辑资料入口（账户卡内铅笔小按钮） */
.pf-edit-btn { flex-shrink: 0; margin-left: 4px; color: var(--text-4); }
.pf-edit-btn svg { width: 16px; height: 16px; }

/* 编辑资料弹窗：头像预览 + 上传操作 */
.pf-edit-avatar { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.pf-edit-avatar-ops { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.pf-edit-avatar-ops .field-hint { margin: 0; }
.profile-name { font-size: 16px; font-weight: var(--fw-semibold); color: var(--text-1); }
.profile-sub { font-size: var(--fs-label); color: var(--text-4); }

/* ===================== 移动端底部导航 ===================== */
.tabbar {
  display: none; flex-shrink: 0;
  background: var(--bg-card); border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom, 0px); z-index: 60;
}
.tabbar .menu-item {
  position: relative;
  flex: 1; flex-direction: column; justify-content: center; gap: 3px;
  height: auto; padding: 7px 0 6px; border-radius: 0;
  color: var(--text-4); font-size: var(--fs-micro); letter-spacing: .5px;
}
.tabbar .menu-item > span:first-of-type { flex: 0; text-align: center; }
.tabbar .menu-item svg { width: 20px; height: 20px; color: inherit; }
.tabbar .menu-item svg { transition: transform .12s ease; }
.tabbar .menu-item:hover { background: none; }
.tabbar .menu-item.active { background: none; color: var(--text-1); }
.tabbar .menu-item.active svg { color: inherit; }
.tabbar .menu-item:active svg { transform: scale(.88); }
.tabbar .menu-cnt {
  position: absolute; top: 4px; left: calc(50% + 11px);
  height: 15px; min-width: 15px; padding: 0 4px;
  border-radius: 8px; font-size: 9px;
}

.main { flex: 1; display: flex; flex-direction: column; min-width: 0; height: 100%; overflow-x: hidden; overflow-y: auto; overscroll-behavior-y: contain; }
.header {
  position: sticky; top: 0; height: var(--header-h); flex-shrink: 0;
  background: color-mix(in srgb, var(--bg-card) 82%, transparent);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
  border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  overflow: hidden; display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4); padding: 0 var(--content-px); z-index: 50;
}
.header-left { display: flex; align-items: center; gap: 12px; min-width: 0; }
.header-txt { min-width: 0; }
.header-left h1 { font-size: var(--fs-h1); font-weight: var(--fw-bold); color: var(--text-1); line-height: var(--lh-h1); }
.header-left p { font-size: var(--fs-caption); color: var(--text-4); margin-top: 6px; line-height: var(--lh-caption); }
/* 顶栏 logo = 回概览：替代原「房子」按钮。
   只在侧栏隐藏的 ≤768 出现——桌面与 ≤1024 的窄侧栏里，侧栏顶部本来就有同一枚 K 标，
   再放一次就是同屏两个黑方块。手机端它是除「双击 tab」外唯一的回家入口。 */
.head-logo {
  display: none;
  flex-shrink: 0; width: 38px; height: 38px; padding: 0; border: none; background: transparent;
  cursor: pointer; align-items: center; justify-content: center;
  -webkit-tap-highlight-color: transparent;
  transition: transform .16s var(--ease-float);
}
.head-logo img { width: 26px; height: 26px; display: block; border-radius: var(--radius-badge); }
@media (hover: hover) and (pointer: fine) {
  .head-logo:hover { transform: translateY(-1px); }
}
.head-logo:active { transform: scale(.9); }
.head-logo:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }
@media (max-width: 768px) {
  .head-logo { display: inline-flex; margin-left: -6px; }  /* 图形左缘与下方卡片对齐，热区仍 ≥38 */
}
.header-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.content { flex: 1; padding: var(--content-py) var(--content-px); }

/* ===================== Typography Utilities ===================== */
.t-display { font-size: var(--fs-display); font-weight: var(--fw-bold); line-height: var(--lh-display); }
.t-h1 { font-size: var(--fs-h1); font-weight: var(--fw-bold); line-height: var(--lh-h1); }
.t-h2 { font-size: var(--fs-h2); font-weight: var(--fw-semibold); line-height: var(--lh-h2); }
.t-body { font-size: var(--fs-body); font-weight: var(--fw-regular); line-height: var(--lh-body); }
.t-caption { font-size: var(--fs-caption); font-weight: var(--fw-regular); line-height: var(--lh-caption); }
.t-label { font-size: var(--fs-label); font-weight: var(--fw-regular); line-height: var(--lh-label); }
.t-micro { font-size: var(--fs-micro); font-weight: var(--fw-regular); line-height: var(--lh-micro); }
.fw-regular { font-weight: var(--fw-regular); }
.fw-medium { font-weight: var(--fw-medium); }
.fw-semibold { font-weight: var(--fw-semibold); }
.fw-bold { font-weight: var(--fw-bold); }
.font-mono { font-family: var(--font-mono); }
.num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.muted { color: var(--text-4); }
.text-danger { color: var(--status-bad); }

/* ===================== Buttons ===================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--meta-icon-gap);
  height: var(--control-h); line-height: 1; padding: 0 var(--control-px);
  border-radius: var(--radius-btn); font-size: var(--fs-caption); font-weight: var(--fw-regular);
  cursor: pointer; border: none; white-space: nowrap;
  transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}
.btn svg { width: 14px; height: 14px; }
.btn-primary { background: var(--primary); color: var(--on-primary); }
.btn-primary:hover { background: var(--primary-hover); }
.btn-primary:active { transform: scale(0.97); background: var(--primary-hover); }
.btn-default { background: var(--btn-2-bg); color: var(--text-2); border: 1px solid var(--border); }
.btn-default:hover { border-color: var(--border-strong); background: var(--btn-2-bg-hover); color: var(--text-1); }
.btn-default:active { transform: scale(0.97); background: var(--btn-2-bg-active); }
.btn-danger { background: var(--btn-danger-bg); color: var(--status-bad); border: 1px solid var(--status-bad); }
.btn-danger:hover { background: var(--status-bad); color: var(--white); }
.btn-danger:active { transform: scale(0.97); background: var(--danger); border-color: var(--danger); }
.btn:disabled { opacity: .5; cursor: not-allowed; pointer-events: none; transform: none; }
.btn-sm { height: var(--control-h-sm); padding: 0 12px; }
.btn-link {
  border: none; background: transparent; padding: 0; cursor: pointer;
  color: var(--primary); font-size: var(--fs-caption);
  transition: color var(--transition-fast);
}
.btn-link:hover { text-decoration: underline; }
.link-danger { color: var(--status-bad); }

/* 图标按钮（主题切换等） */
.icon-btn {
  width: 34px; height: 34px; border: 1px solid var(--border); border-radius: var(--radius-btn);
  background: var(--btn-2-bg); color: var(--text-3); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: border-color var(--transition-fast), color var(--transition-fast), background var(--transition-fast);
}
.icon-btn:hover { border-color: var(--border-strong); color: var(--text-1); }
.icon-btn:active { transform: scale(0.97); }
.icon-btn svg { width: 15px; height: 15px; }
[data-theme="dark"] .theme-icon-moon { display: none; }
[data-theme="light"] .theme-icon-sun,
:root:not([data-theme="dark"]) .theme-icon-sun { display: none; }
.theme-icon-sun, .theme-icon-moon { display: block; }

/* ===================== Form / Input ===================== */
.form-input, .search-field-input {
  width: 100%; height: 36px; padding: 0 12px; font-size: 13px; color: var(--text-1);
  background: var(--bg-page); border: 1px solid var(--border); border-radius: var(--radius-btn);
  outline: none; box-sizing: border-box; font-family: var(--font-sans); text-align: left;
}
.form-input::placeholder, .search-field-input::placeholder { color: var(--text-4); }
.form-input:hover, .search-field-input:hover { border-color: var(--border-strong); }
.form-input:focus, .search-field-input:focus { border-color: var(--primary); box-shadow: 0 0 0 2px var(--focus-ring); }
.form-input[readonly] { color: var(--text-3); background: var(--bg-disabled); cursor: default; }
select.form-input { padding: 0 10px; cursor: pointer; }
textarea.form-input {
  height: auto; min-height: 72px; padding: 8px 12px; line-height: 1.6; resize: vertical;
}
.form-input.date { width: 140px; }

.search-field { display: inline-flex; align-items: center; position: relative; width: min(320px, 100%); max-width: 100%; }
.search-field-icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 14px; height: 14px; color: var(--text-4); pointer-events: none; z-index: 1; }
.search-field-input { padding-left: 34px; padding-right: 30px; }
.search-field-input::-webkit-search-cancel-button { display: none; }
.search-clear {
  position: absolute; right: 5px; top: 50%; transform: translateY(-50%);
  width: 22px; height: 22px; border: none; border-radius: var(--radius-btn);
  background: transparent; color: var(--text-4); cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.search-clear[hidden] { display: none; }
.search-clear svg { width: 10px; height: 10px; }
.search-clear:hover { background: var(--bg-hover); color: var(--text-1); }

/* 下拉选择（原生 select 美化） */
.select-wrap { position: relative; display: block; }
.select-wrap::after {
  content: ""; position: absolute; right: 10px; top: 50%; transform: translateY(-35%);
  width: 0; height: 0; pointer-events: none;
  border-left: 3px solid transparent; border-right: 3px solid transparent;
  border-top: 4px solid var(--text-4);
}
.select-wrap select {
  appearance: none; -webkit-appearance: none;
  width: 100%; height: 36px; line-height: 1; padding: 0 30px 0 12px;
  border: 1px solid var(--border); border-radius: var(--radius-btn);
  background: var(--bg-page); font-size: 13px; color: var(--text-1);
  cursor: pointer; font-family: var(--font-sans);
  transition: border-color var(--transition-fast);
}
.select-wrap select:hover { border-color: var(--border-strong); }
.select-wrap select:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 2px var(--focus-ring); }

/* 原生下拉展开后的列表：与站点设计系统对齐
   注：Chrome / Edge / Firefox 生效；Safari(macOS) 会忽略 option 自定义样式，
   此时依赖 html 上的 color-scheme 让浏览器自行适配深浅色 */
.select-wrap select option {
  background: var(--bg-card);
  color: var(--text-1);
  font-family: var(--font-sans);
  font-size: 13px;
  padding: 7px 10px;
}
.select-wrap select option:hover,
.select-wrap select option:focus {
  background: var(--bg-hover);
  color: var(--text-1);
}
.select-wrap select option:checked {
  background: var(--bg-muted);
  color: var(--text-1);
}
/* 占位选项（月 / 日 / 空值）弱化处理 */
.select-wrap select option[value=""] { color: var(--text-4); }

/* ---- Switch ---- */
.status-switch { position: relative; display: inline-block; width: 30px; height: 16px; cursor: pointer; flex-shrink: 0; }
.status-switch input { opacity: 0; width: 0; height: 0; }
.status-switch .switch-slider { position: absolute; inset: 0; background: var(--switch-track); border-radius: 9999px; transition: background var(--transition-fast); }
.status-switch .switch-slider::before { content: ''; position: absolute; width: 12px; height: 12px; left: 2px; top: 2px; background: #fff; border-radius: 50%; transition: transform var(--transition-fast); }
.status-switch input:checked + .switch-slider { background: var(--primary); }
.status-switch input:checked + .switch-slider::before { transform: translateX(14px); }

/* ===================== 徽章 / 标签 ===================== */
.badge {
  display: inline-flex; align-items: center; gap: 8px; height: 25px; padding: 0 8px;
  border-radius: 6px; font-size: var(--fs-caption); font-weight: var(--fw-medium);
  line-height: 1.4; color: var(--text-1); background: var(--bg-muted); border: 1px solid var(--border);
}
.badge::before { content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; background: var(--bdot, var(--text-disabled)); }
.badge.badge-dot-1 { --bdot: var(--badge-dot-1); }
.badge.badge-dot-2 { --bdot: var(--badge-dot-2); }
.badge.badge-dot-3 { --bdot: var(--badge-dot-3); }
.badge-sm { height: 20px; padding: 0 6px; font-size: var(--fs-micro); gap: 6px; border-radius: 4px; }

/* 轻量标签（优先级 / 分类 / 状态） */
.tag {
  display: inline-flex; align-items: center; height: 20px; padding: 0 8px;
  border-radius: var(--radius-badge); font-size: var(--fs-micro);
  line-height: 1; background: var(--bg-muted); color: var(--text-3); white-space: nowrap;
}
.tag-high { background: var(--tag-high-bg); color: var(--tag-high-fg); }
.tag-good { background: var(--tag-good-bg); color: var(--tag-good-fg); }
.tag-warn { background: var(--tag-warn-bg); color: var(--tag-warn-fg); }
.tag-bad  { background: var(--tag-bad-bg); color: var(--tag-bad-fg); }

/* 优先级：4 角闪烁星（1 / 2 / 3 颗） */
.prio { display: inline-flex; align-items: center; gap: 2px; line-height: 1; color: var(--text-4); }
.prio svg { width: 15px; height: 15px; flex-shrink: 0; }

/* ===================== Toast ===================== */
.toast-container { position: fixed; top: calc(20px + env(safe-area-inset-top, 0px)); left: 50%; transform: translateX(-50%); z-index: 9999; display: flex; flex-direction: column; align-items: center; gap: 8px; pointer-events: none; }
.toast {
  display: inline-flex; align-items: center; gap: 6px; padding: 8px 16px;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-card);
  font-size: 14px; color: var(--text-1); box-shadow: var(--shadow-toast);
  animation: toastIn var(--d-fast) var(--ease-float);
}
.toast-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--status-good); flex-shrink: 0; box-shadow: 0 0 0 3px color-mix(in srgb, var(--status-good) 18%, transparent); }
.toast-warn .toast-dot { background: var(--warning); box-shadow: 0 0 0 3px color-mix(in srgb, var(--warning) 18%, transparent); }
.toast-error .toast-dot { background: var(--status-bad); box-shadow: 0 0 0 3px color-mix(in srgb, var(--status-bad) 18%, transparent); }
.toast-out { opacity: 0; transform: translateY(-6px); transition: opacity .2s ease, transform .2s ease; }
@keyframes toastIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }

/* ===================== Card / Panel ===================== */
.summary-card {
  background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-card);
  padding: 14px 16px 12px; box-shadow: var(--shadow-card);
  transition: border-color var(--transition-fast), background var(--transition-fast),
              transform .18s var(--ease-float), box-shadow .18s var(--ease-float);
}
.summary-card:hover {
  border-color: var(--border-strong); transform: translateY(-2px); box-shadow: var(--shadow-hover);
}
.summary-label { font-size: var(--fs-caption); color: var(--text-4); line-height: var(--lh-caption); }
.summary-value { font-size: 22px; font-weight: var(--fw-semibold); color: var(--text-1); line-height: var(--lh-display); margin-top: 8px; font-family: var(--font-mono); }
.summary-value .unit { font-size: var(--fs-micro); font-weight: var(--fw-regular); color: var(--text-3); }
.summary-sub { font-size: 11px; color: var(--text-4); margin-top: 4px; line-height: 1.3; }
.summary-value.is-warn { color: var(--tag-warn-fg); }
.summary-value.is-danger { color: var(--status-bad); }

.panel {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-card); overflow: hidden; box-shadow: var(--shadow-card);
}
.panel-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 16px; border-bottom: 1px solid var(--border);
  font-size: var(--fs-label); font-weight: var(--fw-medium); color: var(--text-2);
}

/* ===================== Table ===================== */
.table-wrap { overflow-x: auto; }
.data-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.data-table thead { background: var(--bg-header); }
.data-table th {
  padding: 10px 14px; text-align: left; font-weight: 500; font-size: 12px; color: var(--text-3);
  white-space: nowrap; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
}
.data-table td { padding: 11px 14px; color: var(--text-2); border-bottom: 1px solid var(--border); vertical-align: middle; }
/* 空态单元格：允许换行、不受 nowrap 影响 */
.data-table td[colspan] { white-space: normal; }
.data-table tbody tr:hover { background: var(--bg-hover); }
.data-table tbody tr[data-id] { cursor: pointer; }
.memo-card, .date-card { cursor: pointer; }
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table td.code { font-family: var(--font-mono); font-size: 13.5px; font-variant-numeric: tabular-nums; color: var(--text-1); }
.col-check { width: 44px; }
.col-priority { width: 72px; }
.col-due { width: 170px; }
.col-created { width: 118px; }

/* 待办行 */
.todo-check { display: inline-flex; align-items: center; cursor: pointer; }
.todo-check input { position: absolute; opacity: 0; width: 0; height: 0; }
.todo-check-box {
  width: 16px; height: 16px; border: 1px solid var(--border-strong); border-radius: 3px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-card); transition: background var(--transition-fast), border-color var(--transition-fast);
}
.todo-check-box svg { width: 10px; height: 10px; color: var(--on-primary); opacity: 0; }
.todo-check:hover .todo-check-box { border-color: var(--text-4); }
.todo-check input:checked + .todo-check-box { background: var(--primary); border-color: var(--primary); }
.todo-check input:checked + .todo-check-box svg { opacity: 1; }
.todo-check input:focus-visible + .todo-check-box { outline: 2px solid var(--primary); outline-offset: 2px; }
.todo-title {
  color: var(--text-1); font-weight: var(--fw-medium); max-width: 460px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.todo-title.is-done { color: var(--text-4); text-decoration: line-through; font-weight: var(--fw-regular); }
.todo-desc {
  color: var(--text-4); font-size: var(--fs-caption); margin-top: 2px; max-width: 460px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ===================== Segmented ===================== */
.seg { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius-btn); background: var(--bg-card); overflow: hidden; }
.seg button {
  height: var(--control-h); padding: 0 16px; border: none; background: transparent;
  font-size: var(--fs-caption); color: var(--text-3); cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.seg button + button { border-left: 1px solid var(--border); }
.seg button:hover { color: var(--text-1); background: var(--bg-hover); }
.seg button.active { background: var(--primary); color: var(--on-primary); }
.seg button.active:hover { background: var(--primary-hover); color: var(--on-primary); }
.seg-cnt {
  display: inline-flex; min-width: 16px; height: 16px; padding: 0 4px; margin-left: 5px;
  border-radius: 8px; background: color-mix(in srgb, var(--text-1) 12%, transparent);
  color: var(--text-2); font-size: 10px; font-family: var(--font-mono); line-height: 1;
  align-items: center; justify-content: center; vertical-align: middle;
}
.seg button.active .seg-cnt { background: color-mix(in srgb, var(--on-primary) 22%, transparent); color: var(--on-primary); }

/* ===================== Toolbar / 空态 ===================== */
.toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-3); margin-bottom: var(--sp-4); }
.toolbar .spacer { flex: 1; }
.toolbar .search-field-input, .toolbar .form-input, .toolbar select { background: var(--white); }
[data-theme="dark"] .toolbar .search-field-input,
[data-theme="dark"] .toolbar .form-input { background: var(--bg-soft); }
.toolbar[hidden] { display: none; }

.empty {
  padding: 48px 16px; text-align: center; color: var(--text-4); font-size: var(--fs-caption);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.empty[hidden] { display: none; }
.empty-block {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-card); box-shadow: var(--shadow-card);
}
.empty-ico { width: 36px; height: 36px; color: var(--text-disabled); margin-bottom: 10px; }
.empty-clear { margin-top: 12px; }

/* ===================== 概览 ===================== */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: var(--card-gap); }
.ov-empty { padding: 24px 16px; text-align: center; color: var(--text-4); font-size: var(--fs-caption); }

/* ===================== 备忘卡片 ===================== */
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--card-gap); }
.memo-card {
  background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-card);
  padding: 14px 16px; display: flex; flex-direction: column; gap: 10px;
  box-shadow: var(--shadow-card);
  transition: border-color var(--transition-fast), transform .18s var(--ease-float), box-shadow .18s var(--ease-float);
}
.memo-card:hover { border-color: var(--border-strong); transform: translateY(-2px); box-shadow: var(--shadow-hover); }
.memo-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.memo-title {
  font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--text-1); line-height: 1.5;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.memo-ops { display: flex; gap: 10px; flex-shrink: 0; }
.memo-content {
  color: var(--text-3); font-size: var(--fs-caption); line-height: 1.6;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden; white-space: pre-wrap; word-break: break-word; min-height: 20px;
}
.memo-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.memo-foot { color: var(--text-4); font-size: var(--fs-micro); line-height: 1.5; margin-top: auto; }

/* 标签筛选条 */
.chip-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.chip {
  display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 12px;
  border: 1px solid var(--border); border-radius: var(--radius-btn); background: var(--bg-card);
  color: var(--text-3); font-size: var(--fs-caption); cursor: pointer;
  transition: border-color var(--transition-fast), color var(--transition-fast), background var(--transition-fast);
}
.chip:hover { border-color: var(--border-strong); color: var(--text-1); }
.chip:active { transform: scale(0.97); }
.chip.active { border-color: var(--primary); color: var(--text-1); font-weight: var(--fw-medium); }
.chip .chip-cnt { font-family: var(--font-mono); font-size: 11px; color: var(--text-4); }
.chip.active .chip-cnt { color: var(--text-2); }

/* ===================== 纪念日卡片 ===================== */
.date-list { display: flex; flex-direction: column; gap: 10px; }
.date-card {
  display: flex; align-items: center; gap: var(--sp-4);
  background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-card);
  padding: 14px 16px; box-shadow: var(--shadow-card);
  transition: border-color var(--transition-fast), transform .18s var(--ease-float), box-shadow .18s var(--ease-float);
}
.date-card:hover { border-color: var(--border-strong); transform: translateY(-2px); box-shadow: var(--shadow-hover); }
.date-card.is-soon { border-left: 3px solid var(--warning); }
.date-card.is-past { opacity: .72; }
.date-info { flex: 1; min-width: 0; }
.date-title { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.date-name { font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--text-1); }
.date-sub { color: var(--text-4); font-size: var(--fs-micro); margin-top: 4px; }
.date-note { color: var(--text-3); font-size: var(--fs-caption); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.date-count { text-align: right; flex-shrink: 0; min-width: 92px; }
.count-num { font-family: var(--font-mono); font-size: 22px; font-weight: var(--fw-semibold); color: var(--text-1); line-height: 1; }
.count-unit { font-size: var(--fs-micro); color: var(--text-4); margin-left: 3px; }
.count-label { color: var(--text-4); font-size: var(--fs-micro); margin-top: 4px; }
/* 纪念卡「至今 N 天」附加行：等宽数字，视觉弱于主倒计时一档 */
.count-since { color: var(--text-3); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 11px; margin-top: 7px; }
.date-card.is-soon .count-num, .date-card.is-soon .count-label { color: var(--tag-warn-fg); }
.date-card.is-today .count-num { color: var(--status-bad); }

/* ===================== 弹窗 ===================== */
.modal-mask {
  position: fixed; inset: 0; z-index: 100; background: var(--mask);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 72px 16px 32px; overflow-y: auto; overscroll-behavior: contain;
  animation: maskIn var(--d-fast) ease-out;
}
.modal-mask[hidden] { display: none; }
.modal-card {
  position: relative; /* 标题栏 absolute 悬浮的定位锚 */
  background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg);
  width: 100%; max-width: 480px; max-height: 82vh; display: flex; flex-direction: column;
  box-shadow: var(--shadow-modal); transform-origin: top center;
  animation: wrFormIn var(--d-modal) var(--ease-enter);
}
.modal-card.closing { animation: modalOut var(--d-fast) ease-in forwards; }
@keyframes modalOut { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(.97); } }
@keyframes maskIn { from { opacity: 0; } to { opacity: 1; } }
.modal-head {
  /* 悬浮于内容之上：body 内容从标题栏底下滚过，毛玻璃才有可见的模糊对象；
     上圆角与卡片一致，避免半透明背景在卡片圆角外露出方角（三角瑕疵） */
  position: absolute; top: 0; left: 0; right: 0; z-index: 5;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 20px; border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent); flex-shrink: 0;
  /* 与顶栏 .header 同款半透明毛玻璃质感 */
  background: color-mix(in srgb, var(--bg-card) 82%, transparent);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
}
.modal-head h2 { font-size: var(--fs-h2); color: var(--text-1); }
/* 返回式关闭按钮：桌面隐藏，≤768px 显示并替代右上角 X（切换规则见移动端弹窗区块） */
.modal-back {
  display: none; align-items: center; justify-content: center; flex-shrink: 0;
  border: none; background: transparent; color: var(--text-2); cursor: pointer;
  width: 28px; height: 28px; margin-left: -6px; border-radius: var(--radius-btn);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.modal-back:hover { background: var(--bg-hover); color: var(--text-1); }
.modal-back svg { display: block; }
.modal-x {
  border: none; background: transparent; color: var(--text-4); font-size: 18px; line-height: 1;
  width: 28px; height: 28px; border-radius: var(--radius-btn); cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.modal-x:hover { background: var(--bg-hover); color: var(--text-1); }
.modal-body { padding: 76px 20px 20px; overflow-y: auto; } /* 顶部 76px = 悬浮标题栏高度(56) + 原留白(20) */
.modal-foot {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 14px 20px; border-top: 1px solid var(--border);
  background: var(--bg-soft); flex-shrink: 0; border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}
.modal-foot-group { display: flex; align-items: center; gap: 8px; }
.modal-foot-left { margin-right: auto; }
/* .modal-text 已废弃：确认类弹窗正文统一走文件末尾的 .cf-msg 外壳 */
.modal-tip { font-size: var(--fs-caption); color: var(--text-4); margin-bottom: 14px; }

/* 弹窗表单 */
/* 表单节奏（全站统一）：label 紧贴所属控件 5px，组间距 16px；
   报错/提示紧贴所属控件 6px */
.field { margin-bottom: 16px; }
.field:last-child { margin-bottom: 0; }
.field > label { display: block; font-size: var(--fs-label); color: var(--text-3); margin-bottom: 5px; }
.field .req { color: var(--status-bad); margin-left: 2px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 16px; }
.field-row-3 { display: grid; grid-template-columns: 1.3fr .9fr 1fr; gap: 16px 16px; }
.form-error { color: var(--status-bad); font-size: var(--fs-label); margin-top: 6px; display: none; }
.form-error.show { display: block; }
.switch-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 9px 12px; background: var(--bg-page); border: 1px solid var(--border);
  border-radius: var(--radius-btn); cursor: pointer;
}
/* 修复：上面第 837 行 .field > label { display: block }（特异性 0,1,1）一直压着
   .switch-row / .check-line（0,1,0），凡是写成 <div class="field"><label class="switch-row">
   的开关行都会退化为块级——开关掉到文字下方并跟着左对齐。补一条 class 级选择器抬回来 */
.field > .switch-row, .field > .check-line { display: flex; }
.switch-row .switch-label { font-size: var(--fs-caption); color: var(--text-2); }
.switch-row .switch-desc { font-size: var(--fs-micro); color: var(--text-4); margin-top: 2px; }

/* ===================== 自定义下拉 ===================== */
/* 原生 select 保留在数据层（承载 value 与 change 事件），仅隐藏视觉 */
.sel-native { display: none !important; }
.sel-btn,
.dp-display {
  display: block; width: 100%; height: 36px; padding: 0 30px 0 12px;
  border: 1px solid var(--border); border-radius: var(--radius-btn);
  background: var(--bg-page); color: var(--text-1);
  font-family: var(--font-sans); font-size: 13px; line-height: 1;
  text-align: left; cursor: pointer; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.sel-btn:hover,
.dp-display:hover { border-color: var(--border-strong); }
.sel-btn.is-open,
.sel-btn:focus-visible,
.dp-display.is-open,
.dp-display:focus-visible {
  outline: none; border-color: var(--primary); box-shadow: 0 0 0 2px var(--focus-ring);
}
.sel-btn.is-placeholder,
.dp-display.is-placeholder { color: var(--text-4); }

.sel-panel {
  /* fixed 定位：脱离弹窗内容区 overflow 裁切，坐标由 JS 按触发按钮计算 */
  position: fixed; left: 0; top: 0;
  z-index: 200; max-height: 240px; overflow-y: auto; overscroll-behavior: contain;
  padding: 4px; background: var(--bg-card);
  border: 1px solid var(--border); border-radius: var(--radius-card);
  box-shadow: var(--shadow-hover);
  animation: selIn var(--d-modal) var(--ease-enter);
}
.sel-panel[hidden] { display: none; }
.sel-opt {
  padding: 7px 10px; border-radius: var(--radius-btn);
  font-size: 13px; color: var(--text-2); cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.sel-opt:hover, .sel-opt:focus { background: var(--bg-hover); color: var(--text-1); outline: none; }
.sel-opt.is-active { background: var(--bg-muted); color: var(--text-1); font-weight: var(--fw-medium); }
.sel-panel.is-up { animation-name: selInUp; }
@keyframes selIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }
@keyframes selInUp { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }

/* ============ 日期选择 + 自定义日历 ============ */
/* 原生 input[type=date] 隐藏（仅承载数据/事件），
   可见层为 .dp-display 按钮 + .dp-panel 日历浮层。
   移动端点按日期框会唤起系统日历（浏览器内置行为，事件无法拦截），
   故必须替换可见层，系统选择器才不会出现 */
.dp-native { display: none !important; }

.date-wrap { position: relative; display: block; }
.date-wrap .dp-display { padding-right: 32px; }
.date-ico {
  position: absolute; right: 9px; top: 50%; transform: translateY(-50%);
  width: 20px; height: 20px; padding: 0; border: none; border-radius: var(--radius-btn);
  background: transparent; color: var(--text-4); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: color var(--transition-fast), background var(--transition-fast);
}
.date-ico svg { width: 15px; height: 15px; pointer-events: none; }
.date-ico:hover { color: var(--text-1); background: var(--bg-hover); }
.date-ico.is-open { color: var(--text-1); }

/* 月历浮层（单例，挂 body，fixed 定位脱离弹窗裁切，坐标由 JS 计算） */
.dp-panel {
  position: fixed; left: 0; top: 0; z-index: 200;
  padding: 10px; background: var(--bg-card);
  border: 1px solid var(--border); border-radius: var(--radius-card);
  box-shadow: var(--shadow-hover);
  animation: selIn var(--d-modal) var(--ease-enter);
}
.dp-panel[hidden] { display: none; }
.dp-panel.is-up { animation-name: selInUp; }
.dp-head { display: flex; align-items: center; gap: 3px; margin-bottom: 6px; }
.dp-title { flex: 1; display: flex; align-items: center; justify-content: center; gap: 2px; min-width: 0; font-size: var(--fs-caption); font-weight: var(--fw-semibold); color: var(--text-1); }
.dp-tl {
  border: none; background: transparent; color: var(--text-1);
  font-size: var(--fs-caption); font-weight: var(--fw-semibold);
  padding: 3px 4px; border-radius: var(--radius-btn); cursor: pointer; line-height: 1.4;
  white-space: nowrap; flex-shrink: 0;
  transition: background var(--transition-fast);
}
.dp-tl:hover { background: var(--bg-hover); }
.dp-caret { width: 12px; height: 12px; margin-left: 4px; color: var(--text-3); flex-shrink: 0; }
.dp-nav {
  width: 26px; height: 26px; border: 1px solid var(--border); border-radius: var(--radius-btn);
  background: var(--bg-card); color: var(--text-3); cursor: pointer;
  font-size: 14px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  transition: border-color var(--transition-fast), color var(--transition-fast), background var(--transition-fast);
}
.dp-nav:hover { border-color: var(--border-strong); color: var(--text-1); background: var(--bg-hover); }
.dp-week { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; margin-bottom: 4px; }
.dp-week span { text-align: center; font-size: var(--fs-micro); color: var(--text-4); line-height: 22px; }
.dp-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
/* 年 / 月选择视图（点头部「2026 年」「9 月」进入） */
.dp-years {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px;
  max-height: 216px; overflow-y: auto; overscroll-behavior: contain;
}
.dp-year {
  height: 32px; border: none; border-radius: var(--radius-btn);
  background: transparent; color: var(--text-2); font-size: var(--fs-caption);
  font-family: var(--font-mono); font-variant-numeric: tabular-nums; cursor: pointer;
  white-space: nowrap;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.dp-year:hover { background: var(--bg-hover); color: var(--text-1); }
.dp-year.is-sel { background: var(--primary); color: var(--on-primary); font-weight: var(--fw-medium); }
.dp-months { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; }
.dp-month {
  height: 42px; border: none; border-radius: var(--radius-btn);
  background: transparent; color: var(--text-2); font-size: var(--fs-caption);
  cursor: pointer; white-space: nowrap;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.dp-month:hover { background: var(--bg-hover); color: var(--text-1); }
.dp-month.is-sel { background: var(--primary); color: var(--on-primary); font-weight: var(--fw-medium); }
.dp-day {
  height: 30px; border: none; border-radius: var(--radius-btn);
  background: transparent; color: var(--text-2); font-size: var(--fs-caption);
  font-family: var(--font-sans); cursor: pointer; line-height: 1;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.dp-day:hover { background: var(--bg-hover); color: var(--text-1); }
.dp-day.is-out { color: var(--text-disabled); }
.dp-day.is-today { box-shadow: inset 0 0 0 1px var(--border-strong); }
.dp-day.is-sel { background: var(--primary); color: var(--on-primary); font-weight: var(--fw-medium); }
.dp-day.is-sel:hover { background: var(--primary); color: var(--on-primary); }
.dp-foot {
  display: flex; justify-content: space-between; gap: 8px;
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border);
}
.dp-quick {
  border: none; background: transparent; color: var(--primary); cursor: pointer;
  font-size: var(--fs-caption); padding: 2px 4px; border-radius: var(--radius-btn);
  transition: color var(--transition-fast);
}
.dp-quick:hover { text-decoration: underline; }

/* ===================== 数据中心 ===================== */
.dc-block + .dc-block { margin-top: 18px; }
.dc-title {
  font-size: var(--fs-label); font-weight: var(--fw-medium); color: var(--text-4);
  margin-bottom: 10px; letter-spacing: .3px;
}
.dc-rows { border: 1px solid var(--border); border-radius: var(--radius-card); overflow: hidden; }
.dc-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 9px 14px; border-bottom: 1px solid var(--border);
  font-size: var(--fs-caption); color: var(--text-2);
}
.dc-row:last-child { border-bottom: none; }
.dc-row .dc-k { color: var(--text-4); }
.dc-row .dc-v { font-family: var(--font-mono); color: var(--text-1); font-variant-numeric: tabular-nums; }
.dc-row .dc-v.is-danger { color: var(--status-bad); }
.dc-row .dc-v.is-warn { color: var(--warning); }
.dc-tip { margin-top: 14px; font-size: var(--fs-label); color: var(--text-4); line-height: 1.7; }
.dc-tip b { color: var(--text-2); }
/* 数据中心弹窗在桌面端略宽，容纳双列 KPI；移动端保持全屏（不受影响） */
@media (min-width: 769px) { .modal-card.dc-card { max-width: 520px; } }
@media (min-width: 769px) { .modal-card.hm-modal { max-width: 560px; } } /* 热力面板（年视图连续日期网格）需要更宽的画幅 */

/* ===================== 视图切换 ===================== */
.view { display: block; animation: pageSlideIn var(--d-enter) var(--ease-enter); }
.view[hidden] { display: none; }
.view-enter-list { animation: listSlideIn var(--d-enter) var(--ease-enter); }
.tbody-enter tr { animation: rowIn .22s var(--ease-float) backwards; }
.tbody-enter tr:nth-child(2) { animation-delay: 18ms; }
.tbody-enter tr:nth-child(3) { animation-delay: 36ms; }
.tbody-enter tr:nth-child(4) { animation-delay: 54ms; }
.tbody-enter tr:nth-child(5) { animation-delay: 72ms; }
.tbody-enter tr:nth-child(6) { animation-delay: 90ms; }
.tbody-enter tr:nth-child(7) { animation-delay: 108ms; }
.tbody-enter tr:nth-child(8) { animation-delay: 126ms; }

/* ===================== 动效 Keyframes ===================== */
@keyframes pageSlideIn { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: translateX(0); } }
@keyframes listSlideIn { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: translateX(0); } }
@keyframes wrFormIn { from { opacity: 0; transform: scale(1.04); } to { opacity: 1; transform: scale(1); } }
@keyframes rowIn { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  55% { transform: translateX(4px); }
  80% { transform: translateX(-2px); }
}
/* .shake 类已废弃：弹窗抖动改用 WAAPI（element.animate），
   避免切换 animation 属性导致入场动画（wrFormIn）重放。
   @keyframes shake 仍被登录页错误提示使用 */

/* ===================== 登录页 ===================== */
.login-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: var(--bg-page); padding: 16px; }
.login-card {
  width: 100%; max-width: 380px; background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-card); padding: 32px 28px; box-shadow: var(--shadow-float);
  animation: wrFormIn var(--d-modal) var(--ease-enter); transform-origin: top center;
}
.login-logo { display: flex; align-items: center; gap: 10px; margin-bottom: var(--sp-6); }
.login-error {
  color: var(--status-bad); font-size: var(--fs-label);
  padding: 8px 12px; margin-top: 10px;
  background: rgba(229, 62, 62, .06); border: 1px solid rgba(229, 62, 62, .2);
  border-radius: var(--radius-badge);
  animation: shake 0.3s ease-out;
}
.login-error:empty { display: none; }

/* 密码可见切换（登录页） */
.pwd-field { position: relative; }
.pwd-field .form-input { padding-right: 36px; }
.pwd-toggle {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  width: 28px; height: 28px; border: none; border-radius: var(--radius-btn);
  background: transparent; color: var(--text-4); cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.pwd-toggle svg { width: 15px; height: 15px; }
.pwd-toggle:hover { background: var(--bg-hover); color: var(--text-1); }
.pwd-toggle.on { color: var(--text-1); }

/* 全宽按钮 */
.btn-block { width: 100%; }
.login-card .btn-block { margin-top: 4px; }

/* ===================== 无障碍基线 ===================== */
html { color-scheme: light; }
[data-theme="dark"] { color-scheme: dark; }
h1, h2, h3 { text-wrap: balance; }

/* ===================== 登录弹卡（本地模式的可选登录入口） ===================== */
.login-mask {
  position: fixed; inset: 0; z-index: 400;
  display: flex; align-items: center; justify-content: center;
  background: var(--mask); padding: 16px;
  animation: maskIn var(--d-modal) ease-out;
}
.login-pop {
  position: relative; width: 100%; max-width: 380px;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-card); padding: 28px 24px;
  box-shadow: var(--shadow-float);
  /* 出场自下而上（桌面为浮起卡片；≤768 底部抽屉版见文件末尾同名块） */
  animation: loginRiseIn .32s var(--ease-enter);
}
/* 内容错峰：logo → 表单 → 按钮 依次微升，跟随母卡节奏 */
.login-pop .login-logo { animation: rowIn .34s var(--ease-enter) backwards .06s; }
.login-pop .field { animation: rowIn .34s var(--ease-enter) backwards .12s; }
.login-pop .btn-block { animation: rowIn .34s var(--ease-enter) backwards .18s; }
@keyframes loginRiseIn { from { opacity: 0; transform: translateY(32px); } to { opacity: 1; transform: none; } }
@keyframes loginPopDown { to { opacity: 0; transform: translateY(20px); } }
@keyframes maskOut { to { opacity: 0; } }
/* 退场自上而下：JS 加 .is-closing，动画结束后再置 hidden */
.login-mask.is-closing { animation: maskOut .26s ease forwards; }
.login-pop.is-closing { animation: loginPopDown .26s ease-in forwards; }
.login-pop .btn-block + .btn-block { margin-top: 8px; }
.login-pop-sub { font-size: var(--fs-label); color: var(--text-4); margin-top: 2px; }
.login-pop-x {
  position: absolute; right: 10px; top: 10px;
  width: 30px; height: 30px; border: none; border-radius: 50%;
  background: transparent; color: var(--text-4); font-size: 18px; line-height: 1;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.login-pop-x:hover { background: var(--bg-hover); color: var(--text-1); }

/* ===================== 首次访问引导（欢迎页 + 昵称设置） =====================
   与详情/编辑同一套语言：遮罩 → 灰底画布卡（.bg-page）→ 白圆角分组卡
   （直接复用 .dd-hero / .dd-group / .dd-row 的发丝线与 48px 缩进），
   等宽数字做步数计数与文件名预览，虚线「撕纸线」呼应小票机。
   手机端（≤768）收进底部抽屉，参数与 .login-pop 抽屉一致，见文件末尾同名块。
   ============================================================ */
.ob-mask {
  position: fixed; inset: 0; z-index: 500;
  display: flex; align-items: center; justify-content: center;
  background: var(--mask);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  padding: 16px;
  animation: obMaskIn var(--d-modal) ease-out;
}
.ob-mask[hidden] { display: none; } /* 探针/兜底会直接置 hidden，压过上面的 display:flex */
.ob-mask.is-out { animation: obMaskOut .26s ease forwards; pointer-events: none; }
@keyframes obMaskIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes obMaskOut { to { opacity: 0; } }
.ob-card {
  position: relative; width: 100%; max-width: 404px;
  max-height: calc(100vh - 32px); overflow-y: auto;
  background: var(--bg-page); border: 1px solid var(--border);
  border-radius: 22px; padding: 16px;
  box-shadow: var(--shadow-modal); text-align: left;
  animation: obCardIn .34s var(--ease-enter);
  overscroll-behavior: contain;
}
.ob-card.is-out { animation: obCardOut .26s ease-in forwards; }
@keyframes obCardIn { from { opacity: 0; transform: translateY(18px) scale(.985); } to { opacity: 1; transform: none; } }
@keyframes obCardOut { to { opacity: 0; transform: translateY(14px); } }

/* ---- 页眉：真 logo + 品牌名 + 等宽步数 ---- */
.ob-head { display: flex; align-items: center; gap: 10px; padding: 2px 2px 14px; }
.ob-mark { flex-shrink: 0; }
.ob-mark.ob-mark-fb {
  width: 32px; height: 32px; border-radius: 5px; background: var(--primary); color: var(--on-primary);
  font-family: var(--font-mono); font-size: 17px; font-weight: var(--fw-bold);
  display: flex; align-items: center; justify-content: center;
}
[data-theme="dark"] .ob-mark.logo-icon svg { box-shadow: 0 0 0 1px var(--border); }
.ob-head-txt { flex: 1; min-width: 0; }
.ob-tag {
  display: block; margin-top: 2px; font-family: var(--font-mono);
  font-size: 12px; line-height: 1.4; color: var(--text-4); letter-spacing: .2px;
}
.ob-count {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: 12px; letter-spacing: .5px; color: var(--text-disabled); flex-shrink: 0;
}
.ob-count b { font-weight: var(--fw-medium); color: var(--text-disabled); transition: color var(--transition-fast); }
.ob-count b.on { color: var(--text-1); }
.ob-count i { font-style: normal; margin: 0 2px; }
.ob-back {
  width: 32px; height: 32px; margin-left: -6px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; border-radius: 50%; background: transparent; color: var(--text-3); cursor: pointer; padding: 0;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.ob-back svg { width: 18px; height: 18px; }
.ob-back:hover { background: var(--bg-hover); color: var(--text-1); }
.ob-back[hidden] { display: none; } /* 第 1 步没有上一步：inline-flex 会压掉 UA 的 hidden，必须点名 */

/* ---- 步骤：切步时整步自顶部推入，步内三张卡错峰跟随（同 .login-pop 节奏） ---- */
.ob-step { animation: obStepIn .3s var(--ease-enter) backwards; }
.ob-step > *:nth-child(1) { animation: rowIn .34s var(--ease-enter) backwards .05s; }
.ob-step > *:nth-child(2) { animation: rowIn .34s var(--ease-enter) backwards .11s; }
.ob-step > *:nth-child(3) { animation: rowIn .34s var(--ease-enter) backwards .17s; }
@keyframes obStepIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.ob-title { font-size: 20px; font-weight: var(--fw-bold); color: var(--text-1); line-height: 1.35; margin: 0 0 8px; }
.ob-desc { font-size: 15px; color: var(--text-3); line-height: 1.7; margin: 0; }
.ob-desc b { color: var(--text-1); font-weight: var(--fw-semibold); }
.ob-hero { }
.ob-feats { list-style: none; }
.ob-feat { align-items: flex-start; }
.ob-feat .dd-ico { margin-top: 2px; }
.ob-feat-k { font-weight: var(--fw-medium); line-height: 1.45; }
.ob-feat-k i { display: block; font-style: normal; font-size: 12px; line-height: 1.6; color: var(--text-4); font-weight: var(--fw-regular); margin-top: 4px; }

/* ---- 昵称表单：卡内「上标签 + 下井」，井与编辑表单同一衬底参数 ---- */
.ob-nfield { padding: 14px 16px 16px; }
.ob-nlab { display: block; font-size: 12px; color: var(--text-4); letter-spacing: .3px; margin-bottom: 8px; }
.ob-form .ob-ninput {
  height: 54px; padding: 0 14px; font-size: 18px; text-align: center;
  background: var(--bg-muted); border: 1px solid transparent; border-radius: 12px;
  color: var(--text-1); font-family: var(--font-sans);
}
.ob-form .ob-ninput::placeholder { font-size: 15px; color: var(--text-4); }
.ob-form .ob-ninput:hover { border-color: var(--border-strong); }
.ob-form .ob-ninput:focus {
  background: var(--bg-card); border-color: var(--primary); box-shadow: 0 0 0 3px var(--focus-ring);
}
.ob-form .form-error { font-size: 12px; margin-top: 8px; text-align: center; }
.ob-form.bad { animation: shake .3s ease-out; } /* 复用登录报错抖动，不另起第二套参数 */
.ob-nfile {
  display: flex; align-items: center; gap: 12px; position: relative;
  padding: 12px 16px; border-top: 1px solid var(--border);
}
.ob-nfile-k { flex: 1; min-width: 0; font-size: 12px; color: var(--text-4); }
.ob-nfile-v {
  font-family: var(--font-mono); font-size: 12px; color: var(--text-1);
  background: var(--bg-muted); border-radius: 4px; padding: 3px 6px;
  max-width: 58%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---- 收尾：撕纸虚线 + 通栏黑胶囊主操作 ---- */
.ob-foot { margin-top: 16px; }
.ob-tear { border-top: 1px dashed var(--border-strong); margin: 0 2px 16px; opacity: .8; }
.btn.ob-go {
  width: 100%; height: 48px; font-size: 15px; font-weight: var(--fw-medium);
  border-radius: 12px; letter-spacing: .5px;
}
.btn.ob-go svg { width: 16px; height: 16px; }
.ob-note { font-size: 12px; line-height: 1.6; color: var(--text-4); text-align: center; margin-top: 10px; }

/* 本地模式徽章（个人中心） */
.role-badge.role-local { background: color-mix(in srgb, #D97706 14%, transparent); color: #B45309; }
[data-theme="dark"] .role-badge.role-local { color: #F59E0B; }

@media (max-width: 600px) {
  /* .ob-card 不再在此改 padding：引导画布内距一律吃 --content-px（手机端间距规范 v1.0） */
  .login-pop { padding: 24px 18px 20px; }
}
@media (prefers-reduced-motion: reduce) {
  .login-mask, .login-pop, .ob-card { animation: none; }
  .login-mask.is-closing, .login-pop.is-closing,
  .login-pop .login-logo, .login-pop .field, .login-pop .btn-block { animation: none; }
  .ob-mask, .ob-mask.is-out, .ob-card.is-out, .ob-step, .ob-step > *, .ob-form.bad { animation: none; }
}
button, a, [role="button"], input, select, textarea { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
input:focus-visible, textarea:focus-visible, select:focus-visible { outline: none; }
.btn:focus-visible, .menu-item:focus-visible, .icon-btn:focus-visible,
.seg button:focus-visible, .chip:focus-visible, .btn-link:focus-visible, .modal-x:focus-visible, .modal-back:focus-visible,
.todo-check input:focus-visible + .todo-check-box { outline-offset: -2px; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}

/* ===================== 滚动条（细 / 贴合主题） ===================== */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-4); }
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }

/* 移动端（窄屏或触屏）：隐藏滚动条 */
@media (max-width: 768px), (hover: none) and (pointer: coarse) {
  ::-webkit-scrollbar { width: 0; height: 0; }
  * { scrollbar-width: none; }
}

/* ===================== 响应式 ===================== */
/* ≤1024px：侧边栏收窄为图标、双栏面板单列 */
@media (max-width: 1024px) {
  .sidebar { width: 64px; }
  .sidebar .logo { justify-content: center; padding: var(--sp-4) 0; }
  .logo-text { display: none; }
  .menu-section-title { visibility: hidden; height: 6px; padding: 0; }
  .sidebar .menu-item { justify-content: center; padding: 0; }
  .sidebar .menu-item > span, .sidebar .menu-cnt { display: none; }
  .menu-footer { display: none; }
  .avatar-btn { display: inline-flex; } /* 侧边栏收窄：个人中心入口移至顶栏头像 */
  .header-left p { display: none; }
  .content { padding: var(--sp-4); }
}
/* ≤768px：移动端布局 —— 隐藏侧栏、底部导航、全屏弹窗 */
@media (max-width: 768px) {
  :root { --content-px: var(--sp-4); --content-py: var(--sp-4); --header-h: 56px; --control-h: 40px; }
  .app { flex-direction: column; height: 100dvh; }
  .sidebar { display: none; }
  .tabbar { display: flex; }
  .main { height: auto; min-height: 0; overscroll-behavior-y: contain; }
  /* 触控目标：移动端控件加高，降低误触（--control-h 影响 .btn / .seg） */
  .form-input, .search-field-input, .select-wrap select, .sel-btn, .dp-display { height: 40px; }
  /* iOS 防聚焦自动放大：输入类字号必须 ≥16px（<16px 触发整页 zoom 且不可逆） */
  .form-input, .search-field-input, textarea.form-input { font-size: 16px; }
  /* 悬浮导航栏脱离文档流：内容区预留底部空间（含安全区），避免列表末项被遮挡 */
  .content { padding-bottom: calc(92px + env(safe-area-inset-bottom, 0px)); }
  /* 搜索清空按钮：隐形扩展点击区到约 46px（视觉尺寸不变） */
  .search-clear::after { content: ""; position: absolute; inset: -8px; }
  /* 日历日格加高，接近正方形触控目标 */
  .dp-day { height: 36px; }
  /* 触屏无 hover：补 :active 按压反馈 */
  .seg button:active, .chip:active { background: var(--bg-hover); color: var(--text-1); }

  .header-actions .btn-text { display: none; }
  .header-actions .btn { padding: 0 12px; }
  .header-left h1 { font-size: var(--fs-h2); }

  /* 紧凑分段（编辑/预览）移动端提高触控高度 */
  .md-seg button { height: 36px; }
  .icon-btn { width: 38px; height: 38px; }
  .chip { height: 34px; }
  .cat-filter .chip { height: 36px; }
  /* 文字链接触控区扩展：position:relative 锚定伪元素，视觉零变化 */
  .btn-link { position: relative; }
  .btn-link::after { content: ""; position: absolute; inset: -8px -6px; }

  .toolbar .search-field { width: 100%; }

  /* 工具栏新增按钮收起（避免与筛选器挤在同一行折行），新增动作移至导航栏右侧 */
  .toolbar > .btn-primary { display: none; }

  /* 底部导航：悬浮白色胶囊 dock + 右侧独立圆形新增按钮。
     dock 宽度恒定（100%-70px）：概览页平移 35px 居中，
     其他视图滑回左侧、按钮 0.5→1 弹性放大出现 */
  .tabbar {
    position: fixed; left: 12px; right: 12px;
    bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    z-index: 60;
    display: flex; align-items: center; justify-content: center;
    background: transparent; border-top: none; padding: 0;
  }
  .tabbar-dock {
    position: relative;
    flex: 0 0 auto; width: calc(100% - 70px);
    display: flex; align-items: center;
    background: var(--bg-card);
    border-radius: 9999px;
    box-shadow: 0 0 0 1px var(--border), 0 8px 24px rgba(17,17,17,.12);
    padding: 6px;
    transition: transform .28s var(--ease-enter);
  }
  /* 概览页无新增按钮：dock 平移 35px 居中。
     延迟 .08s：按钮缩到约一半时 dock 即开始回中（重叠 80ms，避免等待感），
     340ms 内完成；向左让位方向仍走基础规则的即时过渡 */
  .tabbar:not(.has-add) .tabbar-dock {
    transform: translateX(35px);
    transition: transform .26s var(--ease-enter) .08s;
  }
  /* 选中指示器：灰色胶囊（非黑底填充），JS 定位到选中项，切换时滑动 */
  .tabbar-ind {
    position: absolute; top: 6px; bottom: 6px; left: 0;
    width: 0; background: var(--bg-count); border-radius: 9999px;
    transition: transform .28s var(--ease-enter), width .28s var(--ease-enter);
  }
  [data-theme="dark"] .tabbar-dock {
    box-shadow: 0 0 0 1px var(--border), 0 8px 24px rgba(0,0,0,.5);
  }
  .tabbar .menu-item { flex: 1; margin: 0; border-radius: 9999px; position: relative; z-index: 1; }
  .tabbar .menu-item.active { color: var(--text-1); }

  /* dock 右侧独立圆形新增按钮：出现 0.5→1 弹性放大（back 曲线带过冲，明显）；
     消失 0.16s ease-in 快速缩没 */
  .tabbar-add {
    flex: 0 0 auto; align-self: center;
    width: 60px; height: 60px; margin-left: 10px;
    border: none; border-radius: 9999px;
    background: var(--primary); color: var(--on-primary); cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    box-shadow: var(--shadow-hover);
    transition: transform .3s cubic-bezier(.34,1.56,.64,1), opacity .22s ease, visibility 0s;
  }
  .tabbar-add svg { width: 22px; height: 22px; }
  .tabbar-add:active { transform: scale(0.92); }
  .tabbar-add[hidden] {
    /* !important 对冲全局 [hidden]{display:none!important} 兜底——FAB 动画依赖 hidden 时保持 flex 占位 */
    display: flex !important; opacity: 0; transform: scale(0.5); pointer-events: none;
    visibility: hidden;
    transition: transform .16s ease-in, opacity .12s ease-in, visibility 0s .16s;
  }

  .field-row, .field-row-3 { grid-template-columns: 1fr; gap: 16px; }
  .date-card { flex-wrap: wrap; }
  .date-count { text-align: left; min-width: 0; }
  /* 待办：表格 → 卡片列表（手机上多列表格过窄，改多行卡片布局）
     结构仍为 table，仅重排 display，JS 与事件委托（tr[data-id]）保持不变 */
  #view-todo .table-wrap { overflow-x: visible; }
  #view-todo .data-table { display: block; }
  #view-todo .data-table thead { display: none; }
  #todoBody { display: block; }
  #todoBody tr {
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
      "check title priority"
      "check due   created";
    align-items: start;
    column-gap: 10px; row-gap: 5px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
  }
  #todoBody tr:last-child { border-bottom: none; }
  #todoBody td { display: block; padding: 0; border-bottom: none; }
  #todoBody td.col-check { grid-area: check; width: auto; padding-top: 2px; }
  #todoBody td:nth-child(2) { grid-area: title; }          /* 内含标题 + 描述，纵向堆叠 */
  #todoBody td.col-priority { grid-area: priority; width: auto; }
  #todoBody td.col-due { grid-area: due; width: auto; font-size: var(--fs-micro); color: var(--text-4); }
  #todoBody td.code {
    grid-area: created; width: auto; text-align: right;
    font-family: var(--font-sans); font-size: var(--fs-micro); color: var(--text-4);
  }
  #todoBody .todo-title, #todoBody .todo-desc { max-width: none; }
  #todoBody .todo-desc { margin-top: 3px; }

  /* 复选框：放大到 20px 并用伪元素扩展隐形点击区至约 34px */
  .todo-check { position: relative; }
  .todo-check::after { content: ""; position: absolute; inset: -7px; }
  .todo-check-box { width: 20px; height: 20px; }
  .todo-check-box svg { width: 12px; height: 12px; }

  /* 弹窗全屏化 + 底部抽屉式入场（移动端原生手感）；遮罩灰层移除 */
  .modal-mask { padding: 0; background: transparent; }
  .modal-card {
    max-width: none; max-height: none; height: 100%;
    border: none; border-radius: 0;
    animation: none;
  }
  .modal-card.closing { animation: sheetDown var(--d-fast) ease-in forwards; }
  .modal-card .modal-body { flex: 1; } /* 顶部留白=头高48+模块间距20，见「手机端间距规范」块 */
  /* 全面屏：底栏按钮避开 home 指示条（桌面 env=0，无副作用） */
  .modal-card .modal-foot { padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px)); }

  /* 返回式关闭：左箭头替代右上角 X（原生 App 导航栏手感，标题保持在左侧） */
  .modal-back { display: inline-flex; }
  .modal-x { display: none; }
  /* 返回箭头靠左，标题绝对居中（不随箭头宽度偏移）；超长省略且不挡箭头点击 */
  .modal-head {
    /* 注意：不可写 position —— 基础规则的 absolute 悬浮必须保持；
       此处曾写 relative 把悬浮打回文档流，导致 头高48+body顶距56=104px 双倍空白且毛玻璃失效 */
    justify-content: flex-start;
    /* 全屏弹窗无圆角：头部同步去圆角，避免上角露出底页 */
    border-radius: 0;
    /* 头部变薄（48px）压缩打开时的顶部空白；玻璃基底改用页面灰，与白色内容形成可感知的毛玻璃层次 */
    padding-top: 10px; padding-bottom: 10px;
    background: color-mix(in srgb, var(--bg-page) 82%, transparent);
    /* 毛玻璃移动端降级：与顶栏同参数，减少滚动掉帧 */
    -webkit-backdrop-filter: blur(12px) saturate(140%); backdrop-filter: blur(12px) saturate(140%);
  }
  .modal-head h2 {
    position: absolute; left: 50%; transform: translateX(-50%);
    max-width: calc(100% - 96px); margin: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    pointer-events: none;
  }

  /* 移动端不展示「取消/关闭」按钮：退出统一走左上返回箭头；确认/提示类弹窗（keepCancel）保留 */
  .modal-foot [data-cancel] { display: none; }
  /* 左组不再推左：单独的「退出登录」等左组按钮随 flex-end 落到右侧（桌面不受影响） */
  .modal-foot-left { margin-right: 0; }

  /* 危险操作「重置」按钮：移动端只显示简约图标（rotate-ccw），无边框无底色，点击即执行重置。
     加 .pfg-row.is-danger 前缀抬高特异性——桌面隐藏图标的基础规则在文件更后位置，等特异性会被其反杀 */
  .pfg-row.is-danger .dc-reset-btn {
    width: 40px; height: 40px; padding: 0; flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    border: none; background: transparent; color: var(--tag-bad-fg);
  }
  .pfg-row.is-danger .dc-reset-btn .dc-reset-txt { display: none; }
  .pfg-row.is-danger .dc-reset-btn .dc-reset-ico { display: block; width: 20px; height: 20px; }

  /* ============ 移动端动效系统：轻量 / 原生 / 尊重 reduced-motion ============ */

  /* 视图切换：自下而上淡入，替代桌面横滑（更贴近手机手感，避免横向溢出） */
  .view { animation: pageUpIn var(--d-enter) var(--ease-enter); }

  /* 底部导航：按压反馈 + 激活态微弹跳 + 48px 触控高度（满足 WCAG 44px 最小目标） */
  .tabbar { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
  .tabbar .menu-item {
    min-height: 48px;
    transition: color var(--transition-fast), background-color var(--transition-fast), transform var(--transition-fast);
  }
  /* 按压不叠加圆形底（项宽仅约 57px，:active 胶囊会呈小圆圈）；反馈交给滑动指示器 */
  .tabbar .menu-item.active svg { animation: tabPop 0.3s var(--ease-enter); }

  /* 列表 / 卡片：触摸按下轻微回弹，提供即时物理反馈 */
  .memo-card:active, .date-card:active { transform: scale(0.985); }
  .data-table tbody tr:active { background: var(--bg-hover); }

  /* 顶栏毛玻璃降级：移动端降低模糊半径，减少滚动掉帧 */
  .header {
    -webkit-backdrop-filter: blur(12px) saturate(140%);
    backdrop-filter: blur(12px) saturate(140%);
  }

  /* 移动端专属关键帧 */
  @keyframes pageUpIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
  @keyframes sheetDown { from { transform: translateY(0); } to { transform: translateY(100%); } }
  @keyframes tabPop { 0% { transform: scale(0.82); } 60% { transform: scale(1.08); } 100% { transform: scale(1); } }
}

/* ============================================================
   阶段一增强：今日一言 / 快捷操作 / 数据洞察 / 分类
   （.ov-hero / .ov-quote* / .ov-quick 基线已随「概览 · 今日时间线 v1.0」
     迁移到文件末尾，此处只保留仍被空态使用的 .empty .btn）
   ============================================================ */
.empty .btn { display: inline-flex; align-items: center; gap: 6px; }
.empty .btn svg { width: 14px; height: 14px; }
.empty .btn span { margin: 0; }

.insight-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(218px, 1fr)); gap: var(--card-gap); margin-top: var(--sp-4); }
.insight-card {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-card); box-shadow: var(--shadow-card);
  padding: 14px 16px; min-width: 0;
}
.insight-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; }
.insight-head > span { font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--text-1); }
.insight-head .btn-link { font-size: var(--fs-label); padding: 0; }
.insight-body { min-height: 132px; display: flex; flex-direction: column; }
.insight-empty {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; color: var(--text-4); font-size: var(--fs-caption); gap: 6px; line-height: 1.6;
}
.insight-empty .empty-ico { width: 30px; height: 30px; margin: 0; }
.insight-empty-sub { color: var(--text-disabled); font-size: var(--fs-micro); }

.ov-bars { flex: 1; display: flex; align-items: flex-end; justify-content: space-between; gap: 6px; padding-top: 4px; }
.ov-bar-col { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 4px; min-width: 0; }
.ov-bar-n { font-size: var(--fs-micro); color: var(--text-4); height: 15px; line-height: 15px; font-variant-numeric: tabular-nums; }
.ov-bar { width: 58%; max-width: 22px; min-height: 3px; border-radius: 3px 3px 2px 2px; background: color-mix(in srgb, var(--primary) 34%, transparent); }
.ov-bar-col.is-today .ov-bar { background: var(--primary); }
.ov-bar-l { font-size: var(--fs-micro); color: var(--text-4); }
.ov-bar-col.is-today .ov-bar-l { color: var(--primary); font-weight: var(--fw-medium); }

.ov-dist-row { display: flex; align-items: center; gap: 10px; padding: 5px 0; font-size: var(--fs-caption); color: var(--text-3); }
.ov-dist-name { display: flex; align-items: center; gap: 6px; width: 104px; flex-shrink: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ov-dist-track { flex: 1; height: 6px; border-radius: 3px; background: var(--bg-soft); overflow: hidden; }
.ov-dist-fill { display: block; height: 100%; border-radius: 3px; background: color-mix(in srgb, var(--primary) 55%, transparent); }
.ov-dist-n { width: 26px; text-align: right; font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--text-4); flex-shrink: 0; font-variant-numeric: tabular-nums; }

.cat-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; vertical-align: -1px; }

.cat-filter { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 0 0 var(--sp-4); }
.cat-filter .chip { height: 30px; }
.cat-filter > * { flex-shrink: 0; } /* 移动端横向滚动布局下禁止 chips 被压缩折行 */
.cat-filter .chip .cat-dot { margin-left: 2px; }
.chip { white-space: nowrap; }
.chip-manage { color: var(--text-4); }
.chip-manage svg { width: 12px; height: 12px; }

.todo-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 3px; }
.todo-cat { display: inline-flex; align-items: center; gap: 5px; height: 19px; padding: 0 7px; border: 1px solid var(--border); border-radius: 999px; font-size: var(--fs-micro); color: var(--text-3); background: var(--bg-card); }
.todo-cat .cat-dot { width: 7px; height: 7px; }
.todo-desc { font-size: var(--fs-micro); color: var(--text-4); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; min-width: 0; }

.field-hint { margin-top: 6px; font-size: var(--fs-micro); color: var(--text-4); line-height: 1.6; }

/* 空态（友好文案 + 引导按钮） */
.empty .empty-ico { margin-bottom: 0; }
.empty-text { font-size: var(--fs-body); color: var(--text-3); margin: 12px 0 14px; line-height: 1.6; }

/* 分类管理弹窗 */
.cat-palette { display: flex; flex-wrap: wrap; gap: 8px; position: relative; }
.cat-swatch { width: 24px; height: 24px; border-radius: 7px; border: none; cursor: pointer; transition: transform .15s var(--ease-float); }
.cat-swatch:hover { transform: scale(1.12); }
.cat-swatch.is-sel { box-shadow: 0 0 0 2px var(--bg-card), 0 0 0 4px var(--primary); }
/* 自定义颜色入口：虚线圈 + 加号（与「新增」同语言）；取到颜色后填色并显示勾 */
.cat-swatch-custom {
  display: flex; align-items: center; justify-content: center;
  background: transparent; color: var(--text-4);
  border: 1.5px dashed var(--border-strong);
  transition: transform .15s var(--ease-float), border-color var(--transition-fast), color var(--transition-fast), background .18s linear;
}
.cat-swatch-custom svg { width: 13px; height: 13px; display: block; }
.cat-swatch-custom:hover { color: var(--text-1); border-color: var(--text-4); }
.cat-swatch-custom.is-filled { border-color: transparent; }
.cat-swatch-custom.is-filled .habit-check { width: 14px; height: 14px; }
.cat-custom-hex {
  align-self: center; margin-left: 2px;
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fs-micro); color: var(--text-4); letter-spacing: .02em;
}
@media (max-width: 768px) {
  .cat-swatch-custom svg { width: 15px; height: 15px; }
  .cat-custom-hex { flex: 1 1 100%; margin-left: 0; }
}

/* ---- 自建取色抽屉（.wp-mask / .wp-sheet 外壳，黑白语言里只让颜色有彩色） ---- */
.cp-stage {
  display: flex; align-items: center; gap: 12px;
  padding: 12px; margin-bottom: 16px;
  background: var(--bg-soft); border: 1px solid var(--border); border-radius: 14px;
}
.cp-chip {
  flex: none; width: 46px; height: 46px; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  background: #5DCAA5; color: #fff;
  box-shadow: inset 0 0 0 1px rgba(17, 17, 17, .08);
  transition: background .16s linear, color .16s linear;
}
.cp-chip .habit-check { width: 20px; height: 20px; }
.cp-stage-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.cp-stage-txt b { font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--text-1); }
.cp-stage-txt em { font-style: normal; font-size: var(--fs-micro); color: var(--text-4); line-height: 1.5; }
.cp-ramp { flex: none; display: flex; gap: 4px; }
.cp-ramp i {
  width: 26px; height: 26px; border-radius: 7px;
  display: flex; align-items: center; justify-content: center;
  font-style: normal; font-family: var(--font-mono); font-size: 10px; line-height: 1;
  transition: background .16s linear, color .16s linear;
}
.cp-sv {
  position: relative; height: 150px; border-radius: 14px;
  background:
    linear-gradient(to top, #000000, rgba(0, 0, 0, 0)),
    linear-gradient(to right, #ffffff, rgba(255, 255, 255, 0)),
    hsl(calc(var(--cp-h, 210) * 1deg), 100%, 50%);
  box-shadow: inset 0 0 0 1px var(--border);
  touch-action: none; cursor: crosshair;
}
.cp-hue {
  position: relative; height: 26px; margin-top: 12px; border-radius: 9999px;
  background: linear-gradient(90deg, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00);
  box-shadow: inset 0 0 0 1px var(--border);
  touch-action: none; cursor: ew-resize;
}
.cp-thumb {
  position: absolute; width: 22px; height: 22px; border-radius: 50%;
  border: 2px solid #fff; background: transparent; pointer-events: none;
  box-shadow: 0 0 0 1px rgba(17, 17, 17, .3), 0 2px 6px rgba(17, 17, 17, .3);
  transform: translate(-50%, -50%);
  transition: transform .14s var(--ease-float);
}
.cp-sv .cp-thumb {
  left: calc(var(--cp-s, 0) * 100%);
  top: calc((1 - var(--cp-v, 1)) * 100%);
  background: hsl(calc(var(--cp-h, 210) * 1deg), calc(var(--cp-s, 0) * 100%), calc(var(--cp-v, 1) * 50%));
}
.cp-hue .cp-thumb { top: 50%; left: calc(var(--cp-h, 0) * 100% / 360); background: hsl(calc(var(--cp-h, 0) * 1deg), 100%, 50%); }
.cp-sv.is-drag .cp-thumb, .cp-hue.is-drag .cp-thumb { transform: translate(-50%, -50%) scale(1.16); }
.cp-sv:focus-visible, .cp-hue:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }
.cp-hex-row { display: flex; align-items: center; gap: 10px; margin-top: 16px; }
.cp-hex-k { flex: none; font-size: var(--fs-caption); color: var(--text-4); }
.cp-hex {
  flex: 1; min-width: 0; height: 44px; padding: 0 12px;
  font-family: var(--font-mono); font-size: 15px; letter-spacing: .06em; text-transform: uppercase;
}
.cp-sheet .wp-foot { margin-top: 22px; }
/* 桌面端「居中对话框」形态见文件末尾的 .wp-mask.cp-mask 块：
   必须排在 .wp-sheet 基础规则之后并带上 .wp-mask 前缀，否则会被同特异性的 width:100% / 24px 顶圆角反压 */
.cat-form-actions { display: flex; gap: 8px; margin-top: 6px; }
.cat-form-err { min-height: 18px; margin-top: 6px; font-size: var(--fs-caption); color: var(--status-bad); line-height: 1.5; }
.cat-rows { display: flex; flex-direction: column; }
.cat-row { display: flex; align-items: center; gap: 10px; padding: 8px 2px; border-bottom: 1px solid var(--border); }
.cat-row:last-child { border-bottom: none; }
.cat-row-name { flex: 1; min-width: 0; font-size: var(--fs-caption); color: var(--text-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cat-row-cnt { font-size: var(--fs-micro); color: var(--text-4); font-family: var(--font-mono); flex-shrink: 0; }
.cat-row-actions { display: flex; gap: 2px; flex-shrink: 0; }
.cat-act { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: none; border-radius: var(--radius-btn); background: transparent; color: var(--text-3); cursor: pointer; }
.cat-act svg { width: 14px; height: 14px; }
.cat-act:hover { background: var(--bg-hover); color: var(--text-1); }
.cat-act-del:hover { color: var(--status-bad); }
.cat-row-empty { padding: 14px 2px; text-align: center; font-size: var(--fs-caption); color: var(--text-4); }

@media (max-width: 768px) {
  .insight-grid { grid-template-columns: 1fr; }
  .cat-filter { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 2px; }
}

/* ============================================================
   阶段二：子任务 / 重复 / Markdown / 置顶 / 习惯打卡
   ============================================================ */
label .opt { color: var(--text-4); font-size: var(--fs-micro); font-weight: 400; }

/* 子任务编辑器 */
.sub-editor { display: flex; flex-direction: column; gap: 4px; margin-bottom: 6px; }
.sub-row {
  display: flex; align-items: center; gap: 8px; padding: 6px 8px;
  border: 1px solid var(--border); border-radius: var(--radius-btn); background: var(--bg-card);
}
.sub-row.is-done .sub-title { color: var(--text-4); text-decoration: line-through; }
.sub-check { flex-shrink: 0; }
.sub-title { flex: 1; min-width: 0; font-size: var(--fs-caption); color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sub-del { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border: none; border-radius: var(--radius-btn); background: transparent; color: var(--text-4); cursor: pointer; }
.sub-del svg { width: 13px; height: 13px; }
.sub-del:hover { background: var(--bg-hover); color: var(--status-bad); }
.sub-add { display: flex; gap: 8px; }
.sub-add .form-input { flex: 1; }
.sub-add .btn { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; width: 40px; padding: 0; }
.sub-add .btn svg { width: 15px; height: 15px; }

/* 待办行徽标：子任务进度 / 重复 */
.todo-flag {
  display: inline-flex; align-items: center; gap: 4px; height: 19px; padding: 0 7px;
  border-radius: 999px; background: var(--bg-soft); color: var(--text-3);
  font-size: var(--fs-micro); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.todo-flag svg { width: 11px; height: 11px; }
.todo-flag-rep { color: var(--text-3); }

/* 重复规则：每周几 / 每月几号 */
.wd-row { display: flex; gap: 6px; margin-top: 6px; }
.wd-btn {
  flex: 1; height: 30px; border: 1px solid var(--border); border-radius: var(--radius-btn);
  background: var(--bg-card); color: var(--text-3); font-size: var(--fs-caption); cursor: pointer;
  transition: border-color var(--transition-fast), color var(--transition-fast), background var(--transition-fast);
}
.wd-btn:hover { border-color: var(--border-strong); color: var(--text-1); }
.wd-btn.active { border-color: var(--primary); color: var(--text-1); font-weight: var(--fw-medium); background: color-mix(in srgb, var(--primary) 8%, transparent); }
.dom-row { display: flex; align-items: center; gap: 8px; margin-top: 6px; font-size: var(--fs-caption); color: var(--text-3); }
.dom-row .form-input { width: 84px; }

/* Markdown 编辑 / 预览 */
.md-field-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 5px; }
/* 备忘表单的紧凑分段（复用 .seg 组件，选中态 = 主色填充） */
.md-seg button { height: 28px; padding: 0 12px; font-size: var(--fs-micro); }
.md-body {
  border: 1px solid var(--border); border-radius: var(--radius-btn);
  background: var(--bg-card); padding: 10px 12px;
  font-size: var(--fs-caption); color: var(--text-2); line-height: 1.7; overflow: auto;
  min-height: 140px; max-height: 320px;
}
.md-body h1, .md-body h2, .md-body h3, .md-body h4 { color: var(--text-1); margin: 10px 0 6px; line-height: 1.4; }
.md-body h1 { font-size: 17px; } .md-body h2 { font-size: 15px; } .md-body h3 { font-size: 14px; } .md-body h4 { font-size: 13px; }
.md-body p { margin: 6px 0; }
.md-body ul, .md-body ol { margin: 6px 0; padding-left: 1.4em; }
.md-body li { margin: 2px 0; }
.md-body code { font-family: var(--font-mono); font-size: var(--fs-micro); background: var(--bg-soft); border-radius: 4px; padding: 1px 5px; }
.md-body pre { background: var(--bg-soft); border-radius: var(--radius-btn); padding: 10px 12px; overflow: auto; margin: 8px 0; }
.md-body pre code { background: transparent; padding: 0; }
.md-body blockquote { margin: 8px 0; padding: 4px 12px; border-left: 3px solid var(--border-strong); color: var(--text-3); }
.md-body a { color: var(--primary); }
.md-body img { max-width: 100%; border-radius: var(--radius-btn); }
.md-body hr { border: none; border-top: 1px solid var(--border); margin: 10px 0; }
.md-body table { border-collapse: collapse; margin: 8px 0; }
.md-body th, .md-body td { border: 1px solid var(--border); padding: 4px 10px; font-size: var(--fs-caption); }
.md-empty-hint { color: var(--text-disabled); font-size: var(--fs-caption); }
.check-line { display: flex; align-items: center; gap: 8px; font-size: var(--fs-caption); color: var(--text-2); cursor: pointer; margin: 4px 0 2px; }
.check-line input { accent-color: var(--primary); }

/* 备忘置顶 */
.memo-card.is-pinned { border-color: color-mix(in srgb, var(--primary) 45%, var(--border)); }
.memo-pin {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 26px; height: 26px; border: none; border-radius: var(--radius-btn);
  background: transparent; color: var(--text-4); cursor: pointer;
  transition: color var(--transition-fast), background var(--transition-fast), transform .15s var(--ease-float);
}
.memo-pin svg { width: 14px; height: 14px; }
.memo-pin:hover { background: var(--bg-hover); color: var(--text-1); transform: rotate(-12deg); }
.memo-pin.on { color: var(--primary); }
.memo-pin.on svg { fill: color-mix(in srgb, var(--primary) 18%, transparent); }
.pin-mark { color: var(--primary); font-weight: var(--fw-medium); }

/* 标签管理 */
.tag-merge-row { display: flex; align-items: center; gap: 8px; }
.tag-merge-row .select-wrap { flex-shrink: 0; min-width: 140px; }
.tag-merge-row .form-input { min-width: 0; }
.tag-merge-arrow { width: 16px; height: 16px; color: var(--text-4); flex-shrink: 0; }

/* 习惯打卡 */
.habit-today-panel { margin-bottom: var(--sp-4); }
.habit-today-panel .panel-head .t-micro { font-size: var(--fs-micro); color: var(--text-4); }
/* 完成度提示：跟在「今日打卡」标题右边的一枚灰胶囊（原先是工具栏里那颗黑色 .seg） */
.panel-head .ph-title { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.hb-count {
  font-style: normal; white-space: nowrap;
  padding: 2px 8px; border-radius: 9999px;
  background: var(--bg-muted); color: var(--text-4);
  font-size: var(--fs-micro); font-weight: var(--fw-regular); line-height: 1.5;
  font-variant-numeric: tabular-nums;
}
.habit-today-row {
  display: flex; align-items: center; gap: 10px; padding: 10px 16px;
  border-bottom: 1px solid var(--border); font-size: var(--fs-caption); color: var(--text-2);
}
.habit-today-row:last-child { border-bottom: none; }
.habit-today-row .row-title { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.streak-mark { font-size: var(--fs-micro); color: var(--text-4); flex-shrink: 0; }
.habit-toggle-btn {
  flex-shrink: 0; height: 30px; padding: 0 14px; border-radius: 999px;
  border: 1px solid var(--border-strong); background: var(--bg-card); color: var(--text-2);
  font-size: var(--fs-caption); cursor: pointer;
  transition: all var(--transition-fast);
}
.habit-toggle-btn:hover { border-color: var(--primary); color: var(--text-1); }
/* 已打卡：与未打卡同款描边，仅以勾图标区分 */
.habit-toggle-btn.on { background: var(--bg-card); border-color: var(--border-strong); color: var(--primary); }
.habit-toggle-btn.on:hover { background: var(--bg-hover); }
.habit-check { width: 14px; height: 14px; display: block; }
.habit-toggle-btn:active { transform: scale(.96); }

.habit-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--card-gap); }
.habit-card {
  background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-card);
  padding: 14px 16px; box-shadow: var(--shadow-card); min-width: 0;
  transition: border-color var(--transition-fast), transform .18s var(--ease-float), box-shadow .18s var(--ease-float);
}
.habit-card:hover { border-color: var(--border-strong); transform: translateY(-2px); box-shadow: var(--shadow-hover); }
.habit-head { display: flex; align-items: center; gap: 9px; }
.habit-name { flex: 1; min-width: 0; font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--text-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.habit-ops { display: flex; gap: 2px; flex-shrink: 0; }
.habit-meta { display: flex; gap: 14px; margin: 8px 0 10px; font-size: var(--fs-caption); color: var(--text-4); }
.habit-meta b { color: var(--text-1); font-variant-numeric: tabular-nums; }

/* ---- 打卡热力（本周 7 格 + 详情弹窗周/月/年） ---- */
.hm-cell {
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 4px; background: var(--hm-0); color: var(--hm-ink-0);
  box-shadow: inset 0 0 0 1px var(--hm-line);
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: 11px; line-height: 1; font-weight: var(--fw-medium);
}
.hm-l0 { background: var(--hm-0); color: var(--hm-ink-0); }
/* 1~3 档由「习惯自己的颜色」派生：JS 把亮/暗两套档位与墨色写在 .hb-heat / .hm-panel 的 style 上，
   取不到变量时回落品牌绿 token（如站外预览、旧数据） */
.hm-l1 { background: var(--hm-a, var(--hm-1)); color: var(--hm-ka, var(--hm-ink-1)); box-shadow: none; }
.hm-l2 { background: var(--hm-b, var(--hm-2)); color: var(--hm-kb, var(--hm-ink-2)); box-shadow: none; }
.hm-l3 { background: var(--hm-c, var(--hm-3)); color: var(--hm-kc, var(--hm-ink-3)); box-shadow: none; }
[data-theme="dark"] .hm-l1 { background: var(--hm-ad, var(--hm-1)); color: var(--hm-kad, var(--hm-ink-1)); }
[data-theme="dark"] .hm-l2 { background: var(--hm-bd, var(--hm-2)); color: var(--hm-kbd, var(--hm-ink-2)); }
[data-theme="dark"] .hm-l3 { background: var(--hm-cd, var(--hm-3)); color: var(--hm-kcd, var(--hm-ink-3)); }
.hm-cell.is-today { box-shadow: 0 0 0 1.5px var(--primary); }
.hm-cell.is-future { background: transparent; box-shadow: inset 0 0 0 1px var(--border); color: var(--text-disabled); }
.hm-cell.is-pad { background: transparent; box-shadow: none; }
.hm-dot { width: 3px; height: 3px; border-radius: 50%; background: var(--text-disabled); display: block; }
/* 周视图格子里的次数：包一层 .hm-v 便于原位改写，外观完全继承格子 */
.hm-v { font: inherit; line-height: 1; display: inline-block; }

/* 卡片内：只给本周 7 格 */
.hb-heat { margin-top: 10px; }
.hb-heat-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.hb-heat-title { font-size: var(--fs-micro); letter-spacing: .08em; color: var(--text-4); }
.hb-heat-sum { font-size: var(--fs-micro); color: var(--text-4); font-variant-numeric: tabular-nums; white-space: nowrap; }
.hb-heat-sum b { color: var(--text-1); font-weight: var(--fw-semibold); }
.hm-week { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.hm-col { display: flex; flex-direction: column; align-items: center; gap: 5px; min-width: 0; }
.hm-col em { font-style: normal; font-size: 10px; line-height: 1; color: var(--text-4); }
.hm-col:has(.is-future) em { color: var(--text-disabled); }
.hm-sq { width: 100%; max-width: 34px; aspect-ratio: 1 / 1; }
.hm-sq-lg { max-width: 46px; font-size: 13px; }
.hm-sq-lg .hm-dot { width: 4px; height: 4px; }

/* 详情弹窗里的热力面板 */
.hm-panel {
  margin-top: 14px; padding: 14px;
  background: var(--bg-soft); border: 1px solid var(--border); border-radius: var(--radius-lg);
}
.hm-seg { width: 100%; }
.hm-seg .hm-tab { flex: 1; font-family: var(--font-mono); }
.hm-nav { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.hm-range {
  flex: 1; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 6px;
  font-size: var(--fs-caption); font-weight: var(--fw-semibold); color: var(--text-1);
  font-variant-numeric: tabular-nums;
}
.hm-cur {
  font-style: normal; padding: 2px 7px; border-radius: 999px;
  background: var(--tag-good-bg); color: var(--tag-good-fg);
  font-size: var(--fs-micro); font-weight: var(--fw-medium); letter-spacing: .02em;
}
.hm-back {
  border: none; background: transparent; color: var(--text-4); cursor: pointer;
  font-size: var(--fs-micro); padding: 4px 7px; border-radius: var(--radius-btn);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.hm-back:hover { background: var(--bg-hover); color: var(--text-1); }
.dp-nav[disabled] { opacity: .35; cursor: default; pointer-events: none; }
.hm-summ { margin: 8px 0; text-align: center; font-size: var(--fs-micro); color: var(--text-4); font-variant-numeric: tabular-nums; }
.hm-summ b { color: var(--text-2); font-weight: var(--fw-medium); }
/* 月视图：桌面把 7 列收到 336px 居中（格约 44px），一屏看完整月，不必滚动弹窗 */
.hm-wkrow { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; max-width: 336px; margin: 0 auto 5px; }
.hm-wkrow span { text-align: center; font-size: 10px; line-height: 1; color: var(--text-4); }
.hm-grid7 { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; max-width: 336px; margin: 0 auto; }
.hm-day { width: 100%; aspect-ratio: 1 / 1; font-size: 12px; }
.hm-year { display: flex; align-items: flex-start; gap: 6px; margin-top: 2px; }
.hm-ylab { display: grid; grid-template-rows: repeat(7, 12px); gap: 3px; padding-top: 15px; flex: none; }
.hm-ylab span { font-size: 9px; line-height: 12px; color: var(--text-4); }
.hm-year-scroll {
  flex: 1; min-width: 0; overflow-x: auto; overscroll-behavior: contain;
  padding-bottom: 4px; -webkit-overflow-scrolling: touch; scrollbar-width: thin;
}
.hm-year-inner { display: inline-block; min-width: max-content; }
.hm-year-scroll::-webkit-scrollbar { height: 6px; }
.hm-year-scroll::-webkit-scrollbar-button { display: none; }
.hm-year-scroll::-webkit-scrollbar-track { background: transparent; }
.hm-year-scroll::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
.hm-year-scroll:hover::-webkit-scrollbar-thumb { background: var(--text-disabled); }
.hm-mlab { display: flex; gap: 3px; height: 15px; }
.hm-mlab i {
  flex: none; width: 12px; font-style: normal; font-size: 9px; line-height: 15px;
  color: var(--text-4); font-family: var(--font-mono); text-align: left;
}
.hm-ygrid { display: grid; grid-template-rows: repeat(7, 12px); grid-auto-flow: column; grid-auto-columns: 12px; gap: 3px; }
.hm-dot-c { width: 12px; height: 12px; border-radius: 3px; }
.hm-legend {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px;
  margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border);
  font-size: var(--fs-micro); color: var(--text-4);
}
.hm-lg-item { display: inline-flex; align-items: center; gap: 5px; }
.hm-legend .hm-cell { width: 12px; height: 12px; }

/* 面板过渡：切视图上移淡入、翻页按方向滑入（方向可感知），打卡只做今日格脉冲 */
@keyframes hmInUp   { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes hmInLeft { from { opacity: 0; transform: translateX(18px); } to { opacity: 1; transform: none; } }
@keyframes hmInRight{ from { opacity: 0; transform: translateX(-18px); } to { opacity: 1; transform: none; } }
@keyframes hmPulse  { 0% { transform: scale(1); } 40% { transform: scale(1.14); } 100% { transform: scale(1); } }
.hm-in-up    { animation: hmInUp   .26s var(--ease-enter); }
.hm-in-left  { animation: hmInLeft .26s var(--ease-enter); }
.hm-in-right { animation: hmInRight .26s var(--ease-enter); }
.hm-body.hm-in-left .hm-week > .hm-col,
.hm-body.hm-in-right .hm-week > .hm-col,
.hm-body.hm-in-up .hm-week > .hm-col { animation: hmInUp .3s var(--ease-enter) backwards; }
.hm-body .hm-week > .hm-col:nth-child(2) { animation-delay: .022s; }
.hm-body .hm-week > .hm-col:nth-child(3) { animation-delay: .044s; }
.hm-body .hm-week > .hm-col:nth-child(4) { animation-delay: .066s; }
.hm-body .hm-week > .hm-col:nth-child(5) { animation-delay: .088s; }
.hm-body .hm-week > .hm-col:nth-child(6) { animation-delay: .11s; }
.hm-body .hm-week > .hm-col:nth-child(7) { animation-delay: .132s; }
.hm-cell.hm-pulse { animation: hmPulse .34s var(--ease-float); }
/* 区间标题与统计行只做透明度：它们和网格是相邻块级元素，
   带 translateY 的入场会在动画起点压住今日格顶部那圈 1.5px 黑环（看着像被裁掉一下） */
@keyframes hmFade { from { opacity: 0; } to { opacity: 1; } }
.hm-swap.hm-in-up, .hm-swap.hm-in-left, .hm-swap.hm-in-right { animation-name: hmFade; animation-duration: .22s; }
@media (prefers-reduced-motion: reduce) {
  .hm-in-up, .hm-in-left, .hm-in-right, .hm-cell.hm-pulse,
  .hm-body .hm-week > .hm-col { animation: none; }
}

/* 多次打卡控件：勾选钮带当日次数，前面挂「减一次」小钮 */
.hb-ctl { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0; }
.habit-toggle-btn.on { display: inline-flex; align-items: center; gap: 5px; }
.hb-times { min-width: 7px; font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--fs-micro); color: var(--text-1); }
.hb-minus {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 26px; height: 26px; padding: 0; border-radius: 999px;
  border: 1px solid var(--border); background: var(--bg-card); color: var(--text-4); cursor: pointer;
  transition: all var(--transition-fast);
}
.hb-minus svg { width: 12px; height: 12px; display: block; }
.hb-minus:hover { border-color: var(--border-strong); background: var(--bg-hover); color: var(--text-1); }
.hb-minus:active { transform: scale(.92); }

/* 长按主钮 = 取消今天：按住过程中缓慢压下一档并转危险色，
   过渡 380ms 略短于 500ms 触发点，松手前就能看出「再按下去要取消了」 */
.habit-toggle-btn, .hb-minus {
  -webkit-touch-callout: none; -webkit-user-select: none; user-select: none;
  touch-action: manipulation;
}
.habit-toggle-btn.on.is-holding {
  border-color: var(--danger); color: var(--danger); background: var(--tag-bad-bg);
  transform: scale(.93);
  transition: transform .38s var(--ease-float), color .25s ease, background .25s ease, border-color .25s ease;
}

@media (max-width: 768px) {
  .habit-grid { grid-template-columns: 1fr; }
  .tag-merge-row { flex-wrap: wrap; }
}

/* ============================================================
   阶段三：日记 / 回收站 / 数据与提醒
   ============================================================ */
.mood-chip {
  display: inline-flex; align-items: center; gap: 5px; height: 22px; padding: 0 9px;
  border-radius: 999px; background: var(--bg-soft);
  font-size: var(--fs-micro); color: var(--text-2);
}
.mood-row { display: flex; flex-wrap: wrap; gap: 6px; }
.mood-btn {
  display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 10px;
  border: 1px solid var(--border); border-radius: var(--radius-btn);
  background: var(--bg-card); color: var(--text-3); font-size: var(--fs-caption); cursor: pointer;
  transition: border-color var(--transition-fast), color var(--transition-fast);
}
.mood-btn:hover { border-color: var(--border-strong); color: var(--text-1); }
.mood-btn.active { border-color: var(--primary); color: var(--text-1); font-weight: var(--fw-medium); background: color-mix(in srgb, var(--primary) 8%, transparent); }
.field-diary-head { align-items: flex-end; }
.field-diary-head .field-grow { flex: 1; min-width: 0; }
.ov-diary-cta { margin-top: 6px; display: flex; align-items: center; gap: 8px; }
.ov-diary-row .ov-diary-k { flex-shrink: 0; color: var(--text-4); width: 72px; }
.ov-diary-mood { padding: 4px 16px 0; }
.diary-bring .btn-link { font-size: var(--fs-caption); }

.diary-list { display: flex; flex-direction: column; gap: var(--card-gap); }
.diary-card {
  background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-card);
  box-shadow: var(--shadow-card); padding: 14px 16px; cursor: pointer;
  transition: border-color var(--transition-fast), transform .18s var(--ease-float), box-shadow .18s var(--ease-float);
}
.diary-card:hover { border-color: var(--border-strong); transform: translateY(-2px); box-shadow: var(--shadow-hover); }
.diary-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.diary-date { display: flex; align-items: baseline; gap: 8px; }
.diary-date b { font-size: var(--fs-body); color: var(--text-1); }
.diary-date span { font-size: var(--fs-micro); color: var(--text-4); }
.diary-body { display: flex; flex-direction: column; gap: 6px; }
.diary-sec { display: flex; gap: 10px; font-size: var(--fs-caption); line-height: 1.7; }
.diary-k { flex-shrink: 0; color: var(--text-4); width: 76px; }
.diary-v { color: var(--text-2); min-width: 0; word-break: break-word; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; white-space: pre-wrap; }
.diary-v.muted { color: var(--text-disabled); }

/* 回收站 */
.trash-rows { display: flex; flex-direction: column; max-height: 320px; overflow: auto; }
.trash-row { display: flex; align-items: center; gap: 10px; padding: 8px 2px; border-bottom: 1px solid var(--border); }
.trash-row:last-child { border-bottom: none; }
.trash-title { flex: 1; min-width: 0; font-size: var(--fs-caption); color: var(--text-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trash-time { font-size: var(--fs-micro); color: var(--text-4); font-family: var(--font-mono); flex-shrink: 0; }

/* 个人中心：数据与提醒 */
.prof-ops { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
.prof-ops .btn .chip-cnt { margin-left: 6px; }

/* ============================================================
   可点击 KPI 卡（现服务于「个人中心 → 数据概览」弹窗）
   ============================================================ */
.summary-card[data-goto] { cursor: pointer; transition: border-color var(--transition-fast), transform .18s var(--ease-float), box-shadow .18s var(--ease-float); }
.summary-card[data-goto]:hover { border-color: var(--border-strong); transform: translateY(-2px); box-shadow: var(--shadow-hover); }
.summary-card[data-goto]:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

@media (max-width: 768px) {
  .kpi-grid { grid-template-columns: repeat(2, 1fr); }
  .ov-diary-cta { justify-content: center; }
}
.md-warn { margin: 0 0 8px; padding: 6px 10px; border-radius: var(--radius-btn); background: color-mix(in srgb, var(--warning) 14%, transparent); color: var(--text-2); font-size: var(--fs-micro); }

/* ============================================================
   日历头部改版：左「年 月 ▾」下拉 + 右 ‹ › 切月
   ============================================================ */
.dp-head { justify-content: space-between; }
.dp-head-navs { display: flex; align-items: center; gap: 3px; }
.dp-ym { font-size: var(--fs-caption); font-weight: var(--fw-semibold); color: var(--text-1); }

/* ============================================================
   日历下钻动画（Win11 式）：下钻放大入场 / 返回收拢入场
   ============================================================ */
.dp-years, .dp-months, .dp-grid { transform-origin: 50% 40%; }
.dp-zoom-in  { animation: dpZoomIn  .22s cubic-bezier(.2, .7, .3, 1); }
.dp-zoom-out { animation: dpZoomOut .22s cubic-bezier(.2, .7, .3, 1); }
@keyframes dpZoomIn  { from { opacity: 0; transform: scale(.72); } to { opacity: 1; transform: scale(1); } }
@keyframes dpZoomOut { from { opacity: 0; transform: scale(1.12); } to { opacity: 1; transform: scale(1); } }
@media (prefers-reduced-motion: reduce) {
  .dp-zoom-in, .dp-zoom-out { animation: none; }
}
/* 修复：全局 svg display:block 导致 dp-tl 内箭头折行 */
.dp-tl { display: inline-flex; align-items: center; }

/* 修复：field-row 双列内的 label（优先级/截止时间等）与全局 label 标尺一致 */
.field-row > div > label { display: block; font-size: var(--fs-label); color: var(--text-3); margin-bottom: 5px; }
/* 无子任务时列表容器不占位，避免 label 到输入行间距偏大 */
.sub-editor:empty { display: none; }

/* ============================================================
   打卡状态切换过渡：勾/文字弹性入场 + 连续天数淡入
   ============================================================ */
@keyframes btnPop {
  0% { transform: scale(.88); opacity: .4; }
  70% { transform: scale(1.03); }
  100% { transform: scale(1); opacity: 1; }
}
.btn-pop { animation: btnPop .24s cubic-bezier(.25, .8, .3, 1); }
@keyframes fadeSoft { from { opacity: 0; } to { opacity: 1; } }
.fade-in { animation: fadeSoft .3s ease-out; }
@media (prefers-reduced-motion: reduce) {
  .btn-pop, .fade-in { animation: none; }
}

/* ============================================================
   详情弹窗（点击卡片/行 = 查看，编辑走表单）
   ============================================================ */
.detail-hero { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.detail-hero .todo-check { flex-shrink: 0; }
.detail-title { flex: 1; min-width: 0; font-size: var(--fs-h3, 16px); font-weight: var(--fw-semibold); color: var(--text-1); line-height: 1.45; word-break: break-word; }
.detail-title.is-done { color: var(--text-4); text-decoration: line-through; }
.detail-kv { display: flex; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--border); font-size: var(--fs-caption); line-height: 1.6; }
.detail-kv:last-of-type { border-bottom: none; }
.detail-kv .diary-k { flex-shrink: 0; color: var(--text-4); width: 82px; }
.detail-v { color: var(--text-2); min-width: 0; word-break: break-word; }
.detail-desc { margin-top: 12px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-btn); background: var(--bg-soft); color: var(--text-2); font-size: var(--fs-caption); line-height: 1.7; white-space: pre-wrap; word-break: break-word; }
.detail-meta-line { margin-top: 14px; font-size: var(--fs-micro); color: var(--text-disabled); }
.detail-count { display: flex; align-items: baseline; gap: 8px; margin: 4px 0 10px; }
.detail-count .count-num { font-size: 26px; font-weight: var(--fw-bold); color: var(--text-1); font-variant-numeric: tabular-nums; }
.detail-count .count-unit { font-size: var(--fs-caption); color: var(--text-4); }
.detail-count .tag { align-self: center; }
#dt-subs .sub-row { cursor: pointer; }
#dt-subs .sub-row .dt-sub-check { accent-color: var(--primary); width: 15px; height: 15px; flex-shrink: 0; margin: 0; }

/* 弹窗链切换（详情→编辑/删除确认）：移动端新弹窗从顶部滑下
   —— 实现在文件末尾「手机端全局 UI/UX 优化 v1.0 · 6」，
   须排在 cascade 等 ≤768 规则之后才能覆盖它们 */

/* ============================================================
   移动端动效优化：退出柔和化 + 弹窗内容级联 + 列表 stagger
   ============================================================ */
@media (max-width: 768px) {
  /* 退出：向下滑出的同时淡出并轻微收拢，不再生硬 */
  @keyframes sheetDown { from { opacity: 1; transform: translateY(0) scale(1); } to { opacity: 0; transform: translateY(60%) scale(.98); } }

  /* 弹窗内容级联入场：字段依次上浮淡入（≤8 档，整体 320ms 内完成） */
  .modal-card.cascade .modal-body > * { animation: cascadeIn .26s var(--ease-enter) backwards; }
  .modal-card.cascade .modal-body > *:nth-child(2) { animation-delay: .04s; }
  .modal-card.cascade .modal-body > *:nth-child(3) { animation-delay: .08s; }
  .modal-card.cascade .modal-body > *:nth-child(4) { animation-delay: .12s; }
  .modal-card.cascade .modal-body > *:nth-child(5) { animation-delay: .16s; }
  .modal-card.cascade .modal-body > *:nth-child(6) { animation-delay: .2s; }
  .modal-card.cascade .modal-body > *:nth-child(7) { animation-delay: .24s; }
  .modal-card.cascade .modal-body > *:nth-child(8) { animation-delay: .28s; }
  @keyframes cascadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }

  /* 列表卡片 stagger：仅视图切换时播（staggerList 控制），筛选重渲染不重放 */
  .list-cascade > * { animation: cascadeIn .3s var(--ease-enter) backwards; }
  .list-cascade > *:nth-child(2) { animation-delay: .035s; }
  .list-cascade > *:nth-child(3) { animation-delay: .07s; }
  .list-cascade > *:nth-child(4) { animation-delay: .105s; }
  .list-cascade > *:nth-child(5) { animation-delay: .14s; }
  .list-cascade > *:nth-child(6) { animation-delay: .175s; }
  .list-cascade > *:nth-child(7) { animation-delay: .21s; }
  .list-cascade > *:nth-child(8) { animation-delay: .245s; }
  .list-cascade > *:nth-child(n + 9) { animation-delay: .25s; }
}
/* 待办表格行递进（沿用 tbody-enter 触发，全端生效） */
.tbody-enter tr:nth-child(2) { animation-delay: .03s; }
.tbody-enter tr:nth-child(3) { animation-delay: .06s; }
.tbody-enter tr:nth-child(4) { animation-delay: .09s; }
.tbody-enter tr:nth-child(5) { animation-delay: .12s; }
.tbody-enter tr:nth-child(6) { animation-delay: .15s; }
.tbody-enter tr:nth-child(7) { animation-delay: .18s; }
.tbody-enter tr:nth-child(n + 8) { animation-delay: .2s; }

@media (prefers-reduced-motion: reduce) {
  .modal-card.cascade .modal-body > *,
  .list-cascade > *,
  .tbody-enter tr { animation: none !important; }
}

/* ============================================================
   移动端弹窗链：离场内容淡出（卡片背景常驻，无空白帧）
   ============================================================ */
@media (max-width: 768px) {
  .modal-card .modal-body, .modal-card .modal-foot { transition: opacity .12s ease, transform .12s ease; }
  .modal-card.leaving .modal-body, .modal-card.leaving .modal-foot { opacity: 0; transform: translateY(10px); }
}
@media (prefers-reduced-motion: reduce) {
  .modal-card .modal-body, .modal-card .modal-foot { transition: none; }
  .modal-card.leaving .modal-body, .modal-card.leaving .modal-foot { opacity: 0; }
}



/* ============================================================
   用户管理页 + 角色徽章（Max / Pro / Free，仅标识）
   ============================================================ */
.role-badge {
  display: inline-flex; align-items: center; height: 16px; padding: 0 6px;
  border-radius: 4px; font-size: 10px; font-weight: var(--fw-semibold);
  letter-spacing: .02em; vertical-align: middle; margin-left: 5px;
}
.role-badge.role-max { background: color-mix(in srgb, #8B5CF6 16%, transparent); color: #7C3AED; }
.role-badge.role-pro { background: color-mix(in srgb, #378ADD 16%, transparent); color: #2B6CB0; }
.role-badge.role-free { background: var(--bg-soft); color: var(--text-4); }

.users-rows { display: flex; flex-direction: column; gap: var(--card-gap); }
.user-row {
  display: flex; align-items: center; gap: 12px;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-card);
  box-shadow: var(--shadow-card); padding: 12px 16px;
}
.user-row-avatar {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 36px; height: 36px; border-radius: var(--radius-btn);
  background: color-mix(in srgb, var(--primary) 12%, transparent); color: var(--primary);
  font-size: var(--fs-body); font-weight: var(--fw-semibold);
}
.user-row-info { flex: 1; min-width: 0; }
.user-row-name { display: flex; align-items: center; font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--text-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-row-name .tag { margin-left: 8px; }
.user-row-name .role-badge { margin-left: 6px; }
.user-row-sub { margin-top: 2px; font-size: var(--fs-micro); color: var(--text-4); }
.user-role-wrap { width: 96px; flex-shrink: 0; }
.user-role-wrap .form-input { width: 100%; }
.users-denied {
  padding: 32px 16px; text-align: center; border: 1px dashed var(--border);
  border-radius: var(--radius-card); color: var(--text-4); font-size: var(--fs-caption);
}
@media (max-width: 768px) {
  .user-row { flex-wrap: wrap; }
  .user-row-info { flex-basis: calc(100% - 48px); }
  .user-role-wrap { width: 100%; }
}

/* 侧栏用户名行：徽章跟随名字右侧（flex 对齐 + 溢出保护） */
.user-name { display: flex; align-items: center; gap: 6px; min-width: 0; }
.user-name .role-badge { margin-left: 0; flex-shrink: 0; }
.user-name { overflow: hidden; }
.user-name > :first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ============================================================
   自定义下拉（用户管理角色选择）：展开列表主题化
   ============================================================ */
.dd { position: relative; width: 96px; flex-shrink: 0; }
.dd-toggle {
  width: 100%; display: flex; align-items: center; justify-content: space-between;
  gap: 6px; cursor: pointer; text-align: left;
}
.dd-toggle svg { width: 12px; height: 12px; color: var(--text-4); flex-shrink: 0; transition: transform .16s var(--ease-float); }
.dd.open .dd-toggle svg { transform: rotate(180deg); }
.dd-menu {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 40;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-btn);
  box-shadow: var(--shadow-hover); padding: 4px; display: flex; flex-direction: column; gap: 2px;
  animation: ddIn .14s var(--ease-enter);
}
@keyframes ddIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }
.dd-item {
  display: flex; align-items: center; justify-content: space-between;
  border: none; background: transparent; border-radius: calc(var(--radius-btn) - 2px);
  padding: 6px 10px; font-size: var(--fs-caption); color: var(--text-2); cursor: pointer; text-align: left;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.dd-item:hover { background: var(--bg-hover); color: var(--text-1); }
.dd-item.is-sel { color: var(--primary); font-weight: var(--fw-medium); }
@media (max-width: 768px) {
  .dd { width: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .dd-menu { animation: none; }
}

/* hidden 属性全局兜底：任何自定义 display 的元素，hidden 时必须真正隐藏
   （.dd-menu 的 display:flex 覆盖过 hidden 默认样式 → 菜单常开） */
[hidden] { display: none !important; }

/* Ultra（创始人）：金色系徽章 */
.role-badge.role-ultra {
  background: linear-gradient(135deg, color-mix(in srgb, #F0C75E 22%, transparent), color-mix(in srgb, #D4A017 18%, transparent));
  color: #A67C00;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #D4A017 35%, transparent);
}


/* ============================================================
   移动端 tabbar 布局（显式 margin 版）：dock 滑动动画可过渡
   有 FAB：dock 左贴（margin-left:0），FAB 绝对定位右侧
   无 FAB：dock margin-left 35px 居中——margin-left 数值可过渡，
   切换视图时 dock 平滑滑动 35px（动效保留）
   ============================================================ */
@media (max-width: 768px) {
  .tabbar { display: block; }
  .tabbar-dock { transition: margin-left .28s var(--ease-enter); }
  .tabbar .tabbar-add {
    position: absolute; right: 0; bottom: 6px;
    width: 60px; height: 60px; margin: 0;
  }
  .tabbar.has-add .tabbar-dock {
    width: calc(100% - 70px);
    margin-left: 0; margin-right: 0;
    transform: none;
  }
  .tabbar:not(.has-add) .tabbar-dock {
    width: calc(100% - 70px);
    margin-left: 35px; margin-right: 0;
    transform: none;
    /* 同选择器覆盖旧 translateX 段的 transition:transform（否则 margin 变化无过渡） */
    transition: margin-left .28s var(--ease-enter);
  }
}

/* 周岁 / 周年徽章：主色淡底，区别于普通 tag */
.years-tag {
  /* 中性浅底 + 描边：告别半透明黑压出来的「发灰」脏底，改成一枚干净的浅色描边小片 */
  background: var(--bg-soft);
  border: 1px solid var(--border);
  color: var(--text-1);
  font-weight: var(--fw-medium);
}

/* 类型 / 分类筛选浮层共用的 tf-row 列表（复用 .wp-mask/.wp-sheet 抽屉骨架） */
.tf-list {
  display: flex; flex-direction: column; gap: 8px;
  max-height: 52vh; overflow-y: auto; margin-bottom: 16px;
}
.tf-row {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 14px 16px; border: 1px solid var(--border); border-radius: 14px;
  background: var(--bg-card); color: var(--text-1); font-size: 15px; text-align: left;
  cursor: pointer; transition: background .15s, border-color .15s;
}
.tf-row:hover { background: var(--bg-hover); }
.tf-row.is-sel { border-color: var(--primary); background: var(--bg-hover); }
.tf-dot { width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0; }
.tf-dot-all { background: transparent; box-shadow: inset 0 0 0 1.5px var(--text-4); }
.tf-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tf-cnt { font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--text-4); font-size: 13px; }
.tf-check { color: var(--primary); display: inline-flex; }
.tf-check svg { width: 18px; height: 18px; }

/* 类型管理：内置类型（生日 / 纪念日）只读行 + 内置小标 */
.mg-row-builtin { cursor: default; }
.mg-row-builtin:hover { background: transparent; }
.mg-builtin-tag { margin-left: auto; }

@media (max-width: 768px) {
  .tf-row { padding: 13px 14px; }
}

/* ============================================================
   小票机：机身（深色）+ 纸（吐纸动画）+ 小票盒
   ============================================================ */
.rm-tabs { margin-bottom: 12px; } /* 视觉由 .seg 分段组件承担 */

.rm-machine {
  background: #2b2b2e; border-radius: 18px; padding: 18px 18px 0;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.06), 0 14px 30px rgba(17,17,17,.25);
  position: relative; overflow: hidden;
}
.rm-brand { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.rm-logo { color: #f3f3f3; font-weight: var(--fw-bold); font-size: var(--fs-body); letter-spacing: .04em; }
.rm-screen {
  background: #1c1c1f; border-radius: 12px; padding: 14px 16px; min-height: 96px;
  display: flex; flex-direction: column; justify-content: center; gap: 8px;
}
.rm-date-line { display: flex; align-items: baseline; gap: 10px; }
.rm-date-line b { color: #f3f3f3; font-size: var(--fs-h3, 17px); font-weight: var(--fw-bold); }
.rm-date-line span { color: #8b8b90; font-size: var(--fs-caption); }
.rm-state { display: flex; align-items: center; gap: 8px; color: #c9c9ce; font-size: var(--fs-caption); }
.rm-dot { width: 8px; height: 8px; border-radius: 50%; background: #6d6d72; flex-shrink: 0; }
.rm-dot-busy { background: #EF9F27; animation: rmPulse 1s ease-in-out infinite; }
.rm-dot-done { background: #639922; }
@keyframes rmPulse { 50% { opacity: .3; } }

.rm-actions { padding: 12px 0; display: flex; justify-content: flex-end; }
.rm-actions .btn { background: #e9e9ec; border-color: transparent; color: #1c1c1f; }
.rm-actions .btn:hover { background: #fff; }
.rm-slot { height: 10px; background: #141416; border-radius: 8px 8px 0 0; margin: 0 -18px; }



.rm-paper-ops { display: flex; justify-content: center; padding: 10px 0 0; }

.rm-box-list { display: flex; flex-direction: column; gap: 10px; max-height: 420px; overflow: auto; }
.rm-box-row {
  display: flex; align-items: center; gap: 10px;
  border: 1px solid var(--border); border-radius: var(--radius-btn);
  padding: 10px 12px; background: var(--bg-card);
}
.rm-box-info { flex: 1; min-width: 0; }
.rm-box-date { font-size: var(--fs-caption); font-weight: var(--fw-medium); color: var(--text-1); }
.rm-box-sub { font-size: var(--fs-micro); color: var(--text-4); margin-top: 2px; }
.rm-box-ops { display: flex; gap: 6px; flex-shrink: 0; }
.rm-box-empty { text-align: center; padding: 30px 0; color: var(--text-4); font-size: var(--fs-caption); }


/* ============================================================
   出纸机制：overflow 裁剪窗（静止、透明）——整卷纸藏于出纸口内，
   打印时整张纸（含投影）分段下移 translateY(-100% → 0)，从出纸口滑出。
   窗口自身不做任何动画，纸的外观全部跟纸走，避免"纸先出现、内容再动"的割裂感
   ============================================================ */
/* 高度：移动端随 ≤768 的 .modal-card 规则全屏；桌面在下方媒体块定高 82vh */
.rm-modal .modal-body { flex: 1; overflow-y: auto; background: var(--rm-well); }
.rm-machine {
  max-width: 340px; margin: 0 auto;
  background: #2b2b2e; border-radius: 18px 18px 0 0; padding: 16px 16px 0;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.06), 0 10px 26px rgba(17,17,17,.22);
  position: relative; z-index: 2;
}
.rm-brand { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.rm-screen { background: #1c1c1f; border-radius: 12px; padding: 14px 16px; }
.rm-screen .rm-actions { padding: 12px 0 0; }
.rm-slot {
  height: 12px; background: #141416; border-radius: 0 0 4px 4px;
  margin: 0 -16px; box-shadow: inset 0 3px 6px rgba(0,0,0,.55);
}
/* 机身「打印 ID 昵称」开关行：深色机身上浅白小字，左标题右开关（复用 .status-switch 结构，配色按机身定制） */
.rm-nick-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 2px 12px; font-size: 13px; color: rgba(255,255,255,.72);
  cursor: pointer; user-select: none; -webkit-user-select: none;
}
.rm-nick-row .status-switch .switch-slider { background: rgba(255,255,255,.22); }
.rm-nick-row .status-switch input:checked + .switch-slider { background: #fff; }
.rm-nick-row .status-switch input:checked + .switch-slider::before { background: #111; }
/* 裁剪窗口（静止、透明）：只负责把纸裁在出纸口以下，自身不参与动画。
   左右 + 底部留内边距为画布 box-shadow 腾出扩散空间（否则 overflow:hidden 会切掉两侧阴影）；
   顶部不留内边距，保证纸与出纸口平齐滑出。border-box 下 max-width 356 = 300 内容 + 2×28 内距。 */
.rm-paper-win { max-width: 356px; margin: 0 auto; overflow: hidden; padding: 0 28px 34px; }
.rm-paper { margin: 0; }
/* 纸的外观（白底、圆角、投影）全部挂在纸上，滑动时跟着纸一起走 */
.rm-paper canvas {
  display: block; width: 100%; background: #fff;
  border-radius: 0 0 8px 8px;
  box-shadow: 0 2px 6px rgba(17,17,17,.10), 0 14px 28px rgba(17,17,17,.2);
}

/* 小票盒「查看」：全屏纯小票查看器（body 级独立浮层，叠在小票机之上、关闭回到小票盒，不顶掉弹窗） */
.rm-view-mask {
  position: fixed; inset: 0; z-index: 9000;
  background: rgba(12,12,14,.74);
  opacity: 0; transition: opacity .24s ease;
}
.rm-view-mask.is-open { opacity: 1; }
.rm-view { position: absolute; inset: 0; display: flex; flex-direction: column; }
.rm-view-bar {
  flex: 0 0 auto; display: flex; align-items: center; gap: 8px;
  padding: calc(10px + env(safe-area-inset-top, 0px)) 12px 10px;
}
.rm-view-title {
  flex: 1; text-align: center; font-size: 15px; font-weight: 600;
  letter-spacing: .01em; color: rgba(255,255,255,.92);
}
.rm-view-x, .rm-view-save {
  width: 38px; height: 38px; flex: 0 0 auto; border: none; border-radius: 50%;
  background: rgba(255,255,255,.14); color: #fff; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .18s ease;
}
.rm-view-x:hover, .rm-view-save:hover { background: rgba(255,255,255,.26); }
.rm-view-x:active, .rm-view-save:active { background: rgba(255,255,255,.34); }
.rm-view-x svg, .rm-view-save svg { width: 20px; height: 20px; }
.rm-view-scroll {
  flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch;
  display: flex; justify-content: center; align-items: flex-start;
  padding: 6px 22px calc(30px + env(safe-area-inset-bottom, 0px));
}
.rm-view-paper {
  width: 100%; max-width: 320px; background: #fff; border-radius: 8px; overflow: hidden;
  box-shadow: 0 2px 6px rgba(0,0,0,.14), 0 18px 44px rgba(0,0,0,.4);
}
.rm-view-paper canvas { display: block; width: 100%; }

/* 小票机日期控件：极简日历图标（深色融合；选中日期由机身屏展示，点按开日历）。
   enhanceDates 注入的 dp-display 承载点击与可达性（文字 font-size:0 隐藏、保留朗读），
   date-ico 提供图标并铺满整个按钮 */
.rm-cal {
  position: relative; width: 36px; height: 36px; padding: 0;
  border-radius: 10px; background: rgba(255,255,255,.1);
  display: inline-flex; align-items: center; justify-content: center;
  transition: background var(--transition-fast);
}
.rm-cal:hover { background: rgba(255,255,255,.18); }
.rm-cal .date-wrap { position: absolute; inset: 0; } /* 流内无内容会塌缩，强制铺满按钮作为定位参照 */
.rm-cal .dp-display {
  position: absolute; inset: 0; width: 100%; height: 100%; padding: 0;
  border: none; background: transparent; font-size: 0; line-height: 0;
}
.rm-cal .date-ico {
  inset: 0; width: 100%; height: 100%; right: auto; top: auto; transform: none;
  color: #f3f3f3; border-radius: 10px;
}
.rm-cal .date-ico:hover { background: transparent; color: #fff; }
/* 保存按钮：简约圆形下载图标，紧跟纸底 */
.rm-save-btn {
  width: 42px; height: 42px; border-radius: 50%;
  border: 1px solid var(--border); background: var(--bg-card); color: var(--text-2);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  transition: color var(--transition-fast), border-color var(--transition-fast), transform .15s var(--ease-float);
}
.rm-save-btn svg { width: 18px; height: 18px; }
.rm-save-btn:hover { color: var(--primary); border-color: var(--primary); transform: translateY(-2px); }
.rm-save-btn:active { transform: scale(.92); }

/* 小票机弹窗：桌面宽一点 + 定高 82vh；移动端随全局弹窗全屏 */
@media (min-width: 769px) { .modal-card.rm-modal { max-width: 560px; height: 82vh; } }

/* ============================================================
   键盘跳转链接：视觉隐藏，获得焦点时从顶部滑入
   ============================================================ */
.skip-link {
  position: fixed; top: -48px; left: 16px; z-index: 300;
  padding: 10px 16px; border-radius: 0 0 10px 10px;
  background: var(--primary); color: var(--on-primary);
  font-size: var(--fs-caption); text-decoration: none;
  transition: top var(--transition-fast);
}
.skip-link:focus-visible { top: 0; }

/* 长列表渲染优化：屏外卡片跳过渲染（滚动到即恢复，auto 记住上次高度）
   覆盖 备忘/纪念/习惯/回顾 四类卡片列表（备忘实际类名是 .card-grid，
   此前写成 .memo-grid 一直是死选择器） */
.date-list > *, .habit-grid > *, .diary-list > *, .card-grid > * {
  content-visibility: auto;
  contain-intrinsic-size: auto 120px;
}

/* 个人中心内嵌管理区块：导出 / 导入按钮横排 */
.prof-btn-row { display: flex; flex-wrap: wrap; gap: 10px; }
.prof-btn-row .btn { flex: 0 0 auto; }

/* ===================== 个人中心 pf-* 区块体系 =====================
   布局：账户卡 → 我的概览 KPI → 数据统计 → 数据管理 → 偏好设置 → 账户安全 → 危险操作
   颜色 / 圆角 / 字号 / 动效全部走全站设计令牌，暗色主题自动适配 */
.dc-block.pf-sec { margin-top: 22px; }
.dc-title { display: flex; align-items: center; gap: 6px; }
.dc-title svg { width: 14px; height: 14px; flex: none; }
.pf-sec-danger .dc-title, .pf-sec-danger .dc-title svg { color: var(--tag-bad-fg); }

/* 账户卡 */
.pf-account {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px;
  background: var(--bg-soft); border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
/* 登录态账户卡整卡可点击进入编辑资料（右箭头为视觉引导） */
.pf-account-click { cursor: pointer; }
/* 账户卡 + 云端同步状态行：单容器连体（一卡两段，内部分隔线），消除拼接割裂感 */
.pf-idcard {
  background: var(--bg-soft); border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  transition: border-color var(--transition-fast);
}
.pf-idcard:has(.pf-account-click:hover) { border-color: var(--border-strong); }
.pf-idcard .pf-account { background: transparent; border: 0; border-radius: 0; }
/* 云端同步状态行：容器内第二段，上边框即内部分隔线 */
.pf-sync-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 11px 16px;
  border-top: 1px solid var(--border);
  font-size: var(--fs-body); color: var(--text-2);
}
.pf-sync-ok { display: inline-flex; align-items: center; gap: 5px; color: var(--tag-good-fg); flex: none; }
.pf-sync-ok svg { width: 14px; height: 14px; }
.pf-account-main { flex: 1; min-width: 0; }
.pf-name { display: flex; align-items: center; font-size: var(--fs-h2); font-weight: 600; color: var(--text-1); line-height: 1.3; }
.pf-name .role-badge { flex: none; }
.pf-sub {
  margin-top: 3px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  font-size: var(--fs-caption); color: var(--text-4);
}

/* 图标片 */
.pf-ico {
  width: 34px; height: 34px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-muted); border-radius: var(--radius-card);
  color: var(--text-3);
}
.pf-ico svg { width: 18px; height: 18px; }
.pf-ico-sm { width: 28px; height: 28px; border-radius: var(--radius-badge); }
.pf-ico-sm svg { width: 15px; height: 15px; }

/* 我的概览：KPI 卡（图标 + 数值，点击跳转对应视图） */
.dc-card .kpi-grid { grid-template-columns: repeat(2, 1fr); gap: 10px; }
.pf-kpi-card { display: flex; gap: 10px; align-items: flex-start; cursor: pointer; }
.pf-kpi-card:hover { border-color: var(--border-strong); }
.pf-kpi-card:focus-visible { outline: 2px solid var(--border-strong); outline-offset: 2px; }
.pf-kpi-card .pf-ico { margin-top: 1px; }
.pf-kpi-main { flex: 1; min-width: 0; }
.pf-kpi-main .summary-label { margin-bottom: 0; }
.pf-kpi-main .summary-value { margin-top: 2px; }
.pf-kpi-main .summary-sub { margin-top: 1px; }

/* 数据统计 / 数据管理 / 偏好设置：行式列表 */
.pf-list { border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; background: var(--bg-card); }
.pf-row, .pf-act, .pf-set { display: flex; align-items: center; gap: 10px; padding: 10px 12px; }
.pf-row + .pf-row, .pf-act + .pf-act, .pf-set + .pf-set,
.pf-row + .pf-act, .pf-act + .pf-row, .pf-row + .pf-set, .pf-set + .pf-row, .pf-act + .pf-set, .pf-set + .pf-act {
  border-top: 1px solid var(--border);
}
.pf-k { flex: 1; min-width: 0; font-size: var(--fs-caption); color: var(--text-2); }
.pf-v { flex: none; font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--fs-caption); color: var(--text-1); }
.pf-row.is-danger .pf-v { color: var(--tag-bad-fg); }

/* 操作行（回收站 / 导出 / 导入） */
.pf-act {
  width: 100%; text-align: left; font: inherit; color: inherit;
  background: none; border: 0; cursor: pointer;
  transition: background var(--transition-fast);
}
.pf-act:hover { background: var(--bg-hover); }
.pf-act:focus-visible { outline: 2px solid var(--border-strong); outline-offset: -2px; }
.pf-act-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.pf-act-title { font-size: var(--fs-caption); font-weight: 500; color: var(--text-1); }
.pf-act-desc { font-size: var(--fs-micro); color: var(--text-4); }
.pf-act-chev { flex: none; width: 16px; height: 16px; color: var(--text-disabled); transition: color var(--transition-fast); }
.pf-act-chev svg { width: 16px; height: 16px; }
.pf-act:hover .pf-act-chev { color: var(--text-2); }

/* 回收站数量角标 */
.pf-chip {
  flex: none; min-width: 20px; padding: 1px 7px;
  border-radius: 999px; background: var(--bg-muted);
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fs-micro); color: var(--text-2); text-align: center;
}

.pf-list .field-hint { padding: 8px 12px 10px; }

/* 偏好开关（行内 switch） */
.pf-set { cursor: default; }
.pf-switch { position: relative; flex: none; width: 38px; height: 22px; display: inline-block; }
.pf-switch input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: pointer; z-index: 1;
}
.pf-track {
  position: absolute; inset: 0; pointer-events: none;
  background: var(--switch-track); border-radius: 999px;
  transition: background var(--transition-fast);
}
.pf-track::after {
  content: ''; position: absolute; top: 2px; left: 2px;
  width: 18px; height: 18px; border-radius: 50%; background: #fff;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .15);
  transition: transform var(--transition-fast);
}
.pf-switch input:checked + .pf-track { background: var(--primary); }
.pf-switch input:checked + .pf-track::after { transform: translateX(16px); }
.pf-switch input:focus-visible + .pf-track { outline: 2px solid var(--border-strong); outline-offset: 2px; }

/* 危险操作（红色淡底卡） */
.pf-danger-card {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  background: color-mix(in srgb, var(--danger) 5%, transparent);
  border: 1px solid color-mix(in srgb, var(--danger) 26%, transparent);
  border-radius: var(--radius-lg);
}
.pf-danger-card .pf-act-main { flex: 1; }
.pf-danger-card .pf-act-title { color: var(--tag-bad-fg); }
.pf-danger-card .pf-act-desc { color: var(--text-4); }
.pf-danger-card .btn { flex: none; }

/* ============================================================
   个人中心「灰标题 + 白卡 + 单行」分组（参考图新样式）
   样板：数据管理。桌面/移动共用，靠 token 随断点自适应。
   结构：卡片外灰色小标题（无图标）→ 白卡 → 单行「图标+名称+箭头/角标」，无描述。
   ============================================================ */
.pfg { margin-top: 22px; }
.pfg:first-child { margin-top: 0; }
.pfg-label {
  margin: 0 0 8px 6px;
  font-size: var(--fs-label);
  font-weight: 500;
  color: var(--text-4);
  letter-spacing: .01em;
}
.pfg-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.pfg-row {
  display: flex; align-items: center; gap: 12px;
  width: 100%; text-align: left; font: inherit; color: inherit;
  background: none; border: 0; cursor: pointer;
  padding: 0 var(--card-pad);
  min-height: 52px;
  transition: background var(--transition-fast);
}
.pfg-row + .pfg-row { border-top: 1px solid var(--border); }
.pfg-row:hover { background: var(--bg-hover); }
.pfg-row:active { background: var(--bg-hover); }
.pfg-ico {
  flex: none; width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--text-1);
}
.pfg-ico svg { width: 22px; height: 22px; }
.pfg-t { flex: 1; min-width: 0; font-size: var(--fs-body); color: var(--text-1); }
.pfg-chev { flex: none; width: 18px; height: 18px; color: var(--text-disabled); }
.pfg-chev svg { width: 18px; height: 18px; }
/* 控制行（开关 / 分段）：整行不可点，取消悬停/按压高亮与指针 */
.pfg-ctl { cursor: default; }
.pfg-ctl:hover, .pfg-ctl:active { background: transparent; }
/* 卡内辅助说明行（如桌面提醒权限提示） */
.pfg-note {
  padding: 8px var(--card-pad) 12px;
  border-top: 1px solid var(--border);
  font-size: var(--fs-label); color: var(--text-4); line-height: 1.6;
}
/* 危险分组：分组标题与行文字/图标转红 */
.pfg.is-danger .pfg-label { color: var(--tag-bad-fg); }
.pfg-row.is-danger .pfg-t, .pfg-row.is-danger .pfg-ico { color: var(--tag-bad-fg); }
/* 个人中心灰底画布：账户卡改白底，与分组卡一致浮起。
   登录态账户卡是 .pf-idcard 容器（内含 border-radius:0 的透明 .pf-account），只给容器刷白即可；
   本地态是挂在 body 下的独立 .pf-account，才需要单独刷白。
   切勿写成裸 `.pf-account` 类——那会盖掉登录态嵌套账户的透明基线、把它刷成方块而吃掉容器上圆角。 */
.dc-card.dd-modal .pf-idcard { background: var(--bg-card); }
.dc-card.dd-modal .modal-body > .pf-account { background: var(--bg-card); }
/* 移动端：头部是半透明「页面灰」，与账户卡顶部几乎无间隙会让圆角被误看成直角；
   给个人中心顶部多留一段灰色沟槽，账户卡上圆角才浮得出来 */
@media (max-width: 768px) {
  .dc-card.dd-modal .modal-body { padding-top: calc(48px + var(--module-gap) * 2); }
}
/* 重置按钮：桌面只显示文字（图标隐藏），移动端媒体查询内切换为仅图标 */
.dc-reset-btn .dc-reset-ico { display: none; }

/* ===================== ≤380px 超窄屏（iPhone SE / 小屏安卓 / 系统大字体） ===================== */
/* 触控目标、dock 尺寸与字号地板的超窄屏收缩已迁至文件末尾
   「手机端全局 UI/UX 优化 v1.0」——那些规则必须晚于 ≤768 基线才会生效；
   此处只保留与后续基线不冲突的两条收缩。 */
@media (max-width: 380px) {
  .toolbar { gap: var(--sp-2); }
  .seg button { padding: 0 10px; }
}

/* ============================================================
   手机端可读性强化（≤768px）
   原则：正文 15~16px、辅助文字不低于 12px、触控目标 ≥44px；
   保持桌面端建立的字阶层级，只抬手机端基线与地板。
   ============================================================ */
@media (max-width: 768px) {
  :root {
    --fs-display: 1.85rem;
    --fs-h1: 1.45rem;    /* ≈23px 页面主标题 */
    --fs-h2: 1.25rem;    /* ≈20px 弹窗/分区标题 */
    --fs-body: 0.95rem;  /* ≈15.2px 正文 */
    --fs-caption: 0.9rem;/* ≈14.4px 次级文字 */
    --fs-label: 0.82rem; /* ≈13px 表单标签 */
    --fs-micro: 0.75rem; /* 12px 微标签地板 */
    --lh-body: 1.65;
    --control-h: 44px;   /* iOS HIG 触控基准 */
    --control-h-sm: 34px;
  }

  /* 表单/搜索/自定义下拉：高度与字号对齐 44px 触控行 */
  .form-input, .search-field-input, .select-wrap select, .sel-btn, .dp-display { height: 44px; }
  .sel-btn, .dp-display, .sel-opt { font-size: 15px; }
  .select-wrap::after { top: calc(50% + 1px); }
  textarea.form-input { min-height: 88px; font-size: 16px; }
  .md-seg button { height: 40px; }
  .icon-btn { width: 42px; height: 42px; }
  .icon-btn svg { width: 19px; height: 19px; }
  .chip { height: 38px; font-size: var(--fs-caption); }
  .cat-filter .chip { height: 38px; }
  .search-field-icon { width: 16px; height: 16px; }
  .search-field-input { padding-left: 38px; padding-right: 36px; }
  .search-clear { width: 26px; height: 26px; right: 6px; }
  .search-clear svg { width: 12px; height: 12px; }

  /* 待办：表格字号与行高（移动端已转卡片布局） */
  .data-table { font-size: 15px; }
  .data-table th { font-size: 13px; }
  #todoBody tr { padding: 13px 14px; row-gap: 6px; }
  .todo-check-box { width: 22px; height: 22px; }
  .todo-check-box svg { width: 14px; height: 14px; }
  .todo-desc { margin-top: 4px; }

  /* 大数字区：等宽数字是这套设计的灵魂，手机端给足存在感 */
  .count-num { font-size: 27px; }
  .count-unit { font-size: var(--fs-micro); }
  .count-since { font-size: 12px; margin-top: 8px; }
  .summary-value { font-size: 24px; }
  .summary-sub { font-size: 12px; }
  .detail-count .count-num { font-size: 30px; }

  /* 徽章/计数：全部抬到 ≥11px 地板，计数泡加大 */
  .seg-cnt { font-size: 12px; min-width: 18px; height: 18px; }
  .chip .chip-cnt { font-size: 12px; }
  .menu-cnt { font-size: 11px; min-width: 20px; height: 20px; line-height: 20px; }
  .tabbar .menu-cnt { font-size: 10px; top: 2px; left: calc(50% + 13px); }
  .role-badge { font-size: 11px; height: 18px; padding: 0 7px; }
  .badge { font-size: var(--fs-micro); }

  /* 底部 dock：图标与标签同步放大 */
  .tabbar .menu-item { padding: 8px 0 7px; }
  .tabbar .menu-item svg { width: 22px; height: 22px; }
  .tabbar-add svg { width: 24px; height: 24px; }

  /* Markdown 渲染（备忘详情） */
  .md-body h1 { font-size: 19px; } .md-body h2 { font-size: 17px; }
  .md-body h3 { font-size: 15px; } .md-body h4 { font-size: 14px; }

  /* Toast 与空态 */
  .toast { font-size: 15px; padding: 10px 18px; }
}

/* 超窄屏回补：在 768 新基线上做温和收缩，不再压回小字号
   （dock 标签字号地板已迁至文件末尾的 ≤380 块） */
@media (max-width: 380px) {
  .summary-value { font-size: 22px; }
  .count-num { font-size: 24px; }
}

/* ============================================================
   父子级联瀑布动效（详情弹窗）
   勾选父待办：子任务自上而下依次弹入勾选；取消：同序依次熄灭。
   ============================================================ */
@keyframes subPop {
  0%   { transform: scale(1); }
  38%  { transform: scale(1.32); }
  70%  { transform: scale(.94); }
  100% { transform: scale(1); }
}
@keyframes subFlash {
  0%   { background: var(--bg-hover); border-color: var(--border-strong); }
  100% { background: var(--bg-card);  border-color: var(--border); }
}
.dt-sub-check.sub-pop { animation: subPop .32s var(--ease-float); }
.sub-row.sub-flash    { animation: subFlash .55s ease-out; }

/* ============================================================
   底部导航 · 果冻指示块（双层结构）
   外层 .tabbar-ind：只负责位移，弹性曲线过冲回弹；
   内芯 .tabbar-ind-core：半透明圆角胶囊，WAAPI 沿运动方向拉伸形变。
   ============================================================ */
@media (max-width: 768px) {
  .tabbar-dock { overflow: hidden; } /* 裁剪形变，拉伸不越出 dock 圆角卡片 */
  .tabbar-ind {
    width: 0; background: transparent;
    transition: transform .46s cubic-bezier(.34, 1.28, .64, 1),
                width .28s var(--ease-enter);
    will-change: transform;
  }
  .tabbar-ind-core {
    position: absolute; inset: 0; display: block;
    border-radius: 9999px;
    background: color-mix(in srgb, var(--text-1) 10%, transparent);
    will-change: transform;
  }
  [data-theme="dark"] .tabbar-ind-core { background: color-mix(in srgb, var(--text-1) 16%, transparent); }
}

/* ============================================================
   底部导航 · 毛玻璃透明 dock
   与顶栏/弹窗头部同一玻璃语言：半透明底 + backdrop 模糊饱和；
   指示块同步调透一档，保证内容穿透时层级仍清晰。
   ============================================================ */
@media (max-width: 768px) {
  .tabbar-dock {
    background: color-mix(in srgb, var(--bg-card) 55%, transparent);
    -webkit-backdrop-filter: blur(26px) saturate(170%);
    backdrop-filter: blur(26px) saturate(170%);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--border) 55%, transparent),
                0 10px 28px rgba(17, 17, 17, .10);
  }
  [data-theme="dark"] .tabbar-dock {
    background: color-mix(in srgb, var(--bg-card) 57%, transparent);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--border) 45%, transparent),
                0 10px 28px rgba(0, 0, 0, .45);
  }
  .tabbar-ind-core { background: color-mix(in srgb, var(--text-1) 15%, transparent); }
  [data-theme="dark"] .tabbar-ind-core { background: color-mix(in srgb, var(--text-1) 22%, transparent); }
}

/* ============================================================
   事件详情 · 分组卡片式（灰底画布 + 白色圆角卡 + 巨型倒计时）
   参考 iOS 设置式信息分组，融入 Klog 黑白 + 等宽数字语言。
   ============================================================ */
.dd-modal { background: var(--bg-page); }
.dd-modal .modal-body { padding-bottom: 24px; }

.dd-hero {
  background: var(--bg-card); border-radius: 20px;
  padding: 20px 20px 18px; box-shadow: var(--shadow-card);
}
.dd-hero-head { display: flex; align-items: center; gap: 8px; }
.dd-hero-name { font-size: 20px; font-weight: var(--fw-bold); color: var(--text-1); margin-top: 10px; line-height: 1.35; }
.dd-cap { display: block; font-size: var(--fs-micro); color: var(--text-4); margin-top: 14px; letter-spacing: .5px; }
.dd-big { display: flex; align-items: baseline; gap: 6px; margin-top: 2px; }
.dd-num {
  font-family: var(--font-mono); font-size: 56px; font-weight: var(--fw-bold);
  color: var(--text-1); line-height: 1.05; letter-spacing: -2px; font-variant-numeric: tabular-nums;
}
.dd-num-today { font-size: 40px; letter-spacing: 0; color: var(--status-bad); }
.dd-unit { font-size: 14px; color: var(--text-4); }
.dd-hero-date { font-size: 14px; color: var(--text-4); margin-top: 10px; }
.dd-hero-since { font-size: var(--fs-caption); color: var(--text-3); margin-top: 8px; }
.dd-hero-since b { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-weight: var(--fw-semibold); color: var(--text-1); }

.dd-group {
  background: var(--bg-card); border-radius: 16px; margin-top: 12px;
  box-shadow: var(--shadow-card); overflow: hidden;
}
.dd-row { display: flex; align-items: center; gap: 12px; padding: 14px 16px; position: relative; }
/* iOS 式缩进发丝线：从文字起笔，不顶到图标 */
.dd-row + .dd-row::before {
  content: ""; position: absolute; top: 0; left: 48px; right: 0;
  border-top: 1px solid var(--border);
}
.dd-ico { width: 20px; flex-shrink: 0; color: var(--text-4); display: inline-flex; justify-content: center; }
.dd-ico svg { width: 17px; height: 17px; }
.dd-k { flex: 1; min-width: 0; font-size: 15px; color: var(--text-1); }
.dd-v { color: var(--text-4); font-size: 14px; text-align: right; max-width: 62%; word-break: break-word; }

/* 底部主操作：通栏黑胶囊（参考图），删除保持幽灵态 */
.dd-modal .modal-foot .btn-primary { flex: 1; height: 46px; font-size: 15px; border-radius: 12px; }
.dd-modal .modal-foot .btn-danger { height: 46px; border-radius: 12px; }
@media (max-width: 768px) {
  .dd-modal .modal-foot { padding-left: 16px; padding-right: 16px; }
  .dd-hero { border-radius: 18px; }
}

/* ============================================================
   待办详情 · dd-modal 迁移 v1.0（2026-09-16）
   把待办详情从旧的扁平 detail-hero/detail-kv 提升到与备忘/事件/回顾
   一致的「灰底画布 + 白色圆角卡 + iOS 图标行」语言。dd-hero/dd-group/
   dd-row 复用既有 token（shadow-card、16 内距、8 组距、发丝线缩进 48px），
   这里只补站内没有覆盖的两块：完成勾选英雄区 + 卡内子任务行。
   ============================================================ */
/* 英雄卡：完成勾选 + 标题；整块可点 = 一键完成（勾选框走原生，JS 里跳过避免二次取反） */
.td-hero { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.td-hero .td-title { transition: opacity var(--transition-fast); }
.td-hero:active .td-title { opacity: .55; }
.td-hero-row { display: flex; align-items: flex-start; gap: 12px; }
.td-hero-row .todo-check { flex-shrink: 0; margin-top: 3px; }
.td-title { flex: 1; min-width: 0; font-size: 20px; font-weight: var(--fw-bold); color: var(--text-1); line-height: 1.35; word-break: break-word; }
.td-title.is-done { color: var(--text-4); text-decoration: line-through; }

/* 分类值：色点与文字上下居中 + 拉开间距（dd-v 里内联成一条，不再贴边） */
.td-cat { display: inline-flex; align-items: center; gap: 7px; }
.td-cat .cat-dot { width: 9px; height: 9px; flex-shrink: 0; }

/* 描述卡：单独一张白卡内的正文块，长文换行、保留手打换行 */
.td-desc-group { padding: 16px; }
.td-desc { font-size: 15px; line-height: 1.7; color: var(--text-2); white-space: pre-wrap; word-break: break-word; }

/* 信息组计数徽标：等宽数字，与 dd-v 灰字同档 */
.td-sub-head .chip-cnt { font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--text-4); }
/* 子任务表头行与本组列表之间补一道发丝线（dd-row 相邻规则只连 dd-row，此处手动收尾） */
.td-sub-head { padding-bottom: 13px; }
.td-sub-head::after { content: ""; position: absolute; left: 48px; right: 0; bottom: 0; border-bottom: 1px solid var(--border); }

/* 卡内子任务行：拍平掉旧 .sub-row 的独立外框，降为无边框 hairline 行，与 dd-row 同缩进节奏 */
.td-sub-editor { display: flex; flex-direction: column; gap: 0; margin: 0; padding: 0; }
.td-sub-editor .sub-row {
  display: flex; align-items: center; gap: 12px; position: relative;
  min-height: 46px; padding: 12px 16px;
  border: none; border-radius: 0; background: transparent;
  cursor: pointer;
}
.td-sub-editor .sub-row + .sub-row::before {
  content: ""; position: absolute; top: 0; left: 43px; right: 0; border-top: 1px solid var(--border);
}
.td-sub-editor .dt-sub-check { accent-color: var(--primary); width: 17px; height: 17px; flex-shrink: 0; margin: 0; }
.td-sub-editor .sub-title { font-size: 15px; color: var(--text-1); white-space: normal; overflow: visible; text-overflow: clip; }
.td-sub-editor .sub-row.is-done .sub-title { color: var(--text-4); text-decoration: line-through; }
.td-sub-editor .sub-row:active { background: var(--bg-hover); }

/* ============================================================
   习惯详情 · dd-modal 迁移 v1.0（2026-09-16）
   与待办/备忘详情统一：灰底画布 + 白色圆角卡。习惯特有的热力面板
   保留 hm-modal 的宽度（年视图网格需要），但外壳从 bg-soft 描边框
   升级为白卡（与 .dd-group 同壳）。仅作用于 .dd-modal 内的习惯详情，
   习惯列表卡片的 .habit-meta 完全不受影响。
   ============================================================ */
.hb-hero-row { display: flex; align-items: center; gap: 12px; }
.hb-hero-dot { width: 12px; height: 12px; flex-shrink: 0; }
.hb-hero-name { flex: 1; min-width: 0; font-size: 20px; font-weight: var(--fw-bold); color: var(--text-1); line-height: 1.35; word-break: break-word; }
.hb-hero .hb-ctl { flex-shrink: 0; }

/* 统计组数值：等宽大数字，呼应站内「黑白 + 等宽数字」语言 */
.hb-stats .hb-num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-weight: var(--fw-bold); font-size: 16px; color: var(--text-1); }

/* 热力面板：在灰底画布上升级为白卡，与 dd-group 同壳同距 */
.dd-modal .hm-panel {
  margin-top: 12px; padding: 16px;
  background: var(--bg-card); border: none; border-radius: 16px;
  box-shadow: var(--shadow-card);
}

/* ============================================================
   回收站 / 已归档 · dd-modal 收口 v1.0（2026-09-16）
   原来「浮动灰标题 + 每条一张独立白卡」→ 收进一张 dd-group：
   表头 dd-row（图标 + 说明 + 计数）+ 条目 hairline 行 + 可选说明行，
   与待办详情子任务卡、习惯统计组同一节奏。全部 scope 到 .tb-card，
   列表页/个人中心的 .trash-row、.dc-* 独立样式不受影响。
   ============================================================ */
.tb-card:first-child { margin-top: 0; }
.tb-head { padding-bottom: 13px; }
.tb-head::after { content: ""; position: absolute; left: 48px; right: 0; bottom: 0; border-bottom: 1px solid var(--border); }
.tb-head .chip-cnt { font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--text-4); }

.tb-card .trash-rows { display: flex; flex-direction: column; gap: 0; margin: 0; padding: 0; max-height: none; overflow: visible; }
.tb-card .trash-row {
  display: flex; align-items: center; gap: 12px; position: relative;
  min-height: 60px; padding: 14px 16px;
  background: transparent; border: none; border-radius: 0; box-shadow: none;
}
.tb-card .trash-row + .trash-row::before { content: ""; position: absolute; top: 0; left: 16px; right: 0; border-top: 1px solid var(--border); }
.tb-card .trash-row:active { background: var(--bg-hover); transform: none; }
.tb-card .trash-rows .cat-row-empty { background: transparent; border: none; box-shadow: none; border-radius: 0; padding: 26px 16px; }
.tb-tip { position: relative; padding: 12px 16px; font-size: 13px; line-height: 1.6; color: var(--text-4); }
.tb-tip::before { content: ""; position: absolute; top: 0; left: 16px; right: 0; border-top: 1px solid var(--border); }

/* ============================================================
   滚轮日期选择器（移动端 · 底部抽屉 + 三列滚轮 + 公历/农历）
   ============================================================ */
.wp-mask {
  position: fixed; inset: 0; z-index: 9000;
  background: var(--mask);
  display: flex; align-items: flex-end;
  opacity: 0; transition: opacity .22s ease, padding-bottom .24s var(--ease-enter, ease);
}
.wp-mask.is-open { opacity: 1; }
.wp-sheet {
  width: 100%; background: var(--bg-card);
  border-radius: 24px 24px 0 0;
  padding: 18px 16px calc(16px + env(safe-area-inset-bottom, 0px));
  box-shadow: var(--shadow-modal);
  transform: translateY(100%); transition: transform .32s var(--ease-enter);
}
.wp-mask.is-open .wp-sheet { transform: translateY(0); }
.wp-title { text-align: center; font-size: 17px; font-weight: var(--fw-bold); color: var(--text-1); margin-bottom: 14px; }

.wp-seg {
  display: flex; justify-content: center; gap: 4px; margin: 0 auto 10px;
  padding: 4px; width: max-content; max-width: 100%;
  background: var(--bg-muted); border-radius: 9999px;
}
.wp-seg-btn {
  border: none; background: transparent; height: 36px; padding: 0 26px;
  border-radius: 9999px; font-size: 15px; color: var(--text-3); cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.wp-seg-btn.is-on { background: var(--primary); color: var(--on-primary); font-weight: var(--fw-medium); }

.wp-wheels { display: flex; height: 220px; margin: 6px 0 16px; }
.wp-col {
  flex: 1; position: relative; overflow: hidden;
  touch-action: none; user-select: none; -webkit-user-select: none; cursor: grab;
  -webkit-mask-image: linear-gradient(transparent 0%, #000 24%, #000 76%, transparent 100%);
  mask-image: linear-gradient(transparent 0%, #000 24%, #000 76%, transparent 100%);
}
.wp-col:active { cursor: grabbing; }
/* 中心选中带：浅灰圆角横带（各列独立，贴合参考图） */
.wp-col::before {
  content: ""; position: absolute; left: 6px; right: 6px; top: 50%;
  height: 40px; margin-top: -20px;
  background: var(--bg-hover); border-radius: 10px; z-index: 0;
}
.wp-list { position: absolute; left: 0; right: 0; top: 0; will-change: transform; z-index: 1; }
.wp-item {
  height: 44px; line-height: 44px; text-align: center;
  font-size: 15px; color: var(--text-4);
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.wp-item.is-on { color: var(--text-1); font-weight: var(--fw-semibold); font-size: 17px; }

.wp-foot { display: flex; gap: 12px; }
.wp-btn { border: none; height: 50px; border-radius: 9999px; font-size: 16px; cursor: pointer; }
.wp-btn-cancel { flex: 1; background: var(--bg-muted); color: var(--text-2); }
.wp-btn-cancel:active { background: var(--bg-count); }
.wp-btn-ok { flex: 1.5; background: var(--primary); color: var(--on-primary); font-weight: var(--fw-medium); }
.wp-btn-ok:active { background: var(--primary-hover); transform: scale(.985); }
/* 危险确认：同一枚胶囊，只换成语义红（与左滑删除展开的胶囊同款红） */
.wp-btn-ok.wp-btn-danger { background: var(--danger); color: #fff; }
.wp-btn-ok.wp-btn-danger:active { background: var(--danger); filter: brightness(.9); transform: scale(.985); }

@media (prefers-reduced-motion: reduce) {
  .wp-mask, .wp-sheet, .wp-list { transition: none !important; }
}

/* ============================================================
   移动端选项选择卡片（复用 .wp-mask/.wp-sheet 抽屉骨架）
   灰色胶囊选项 + 选中黑底，与参考图「订阅周期」弹层同款
   ============================================================ */
.op-list {
  display: flex; flex-direction: column; gap: 12px;
  max-height: 46vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
  margin-bottom: 16px;
}
.op-item {
  flex-shrink: 0; width: 100%; text-align: left;
  border: none; height: 52px; padding: 0 18px;
  border-radius: 14px; background: var(--bg-muted); color: var(--text-1);
  font-size: 16px; cursor: pointer;
  transition: background var(--transition-fast), transform .12s ease;
}
.op-item:active { transform: scale(.985); }
.op-item.is-on { background: var(--primary); color: var(--on-primary); font-weight: var(--fw-medium); }

/* ============================================================
   事件详情 · 内联操作区（移动端）：无固定底栏，
   内容末尾通栏黑色「编辑」胶囊 + 居中「删除事件」文字按钮
   ============================================================ */
.dd-foot-inline {
  margin-top: 18px;
  padding-bottom: env(safe-area-inset-bottom, 0px);
  display: flex; flex-direction: column; gap: 8px;
}
.dd-edit-pill {
  width: 100%; height: 52px; border: none; border-radius: 9999px;
  background: var(--primary); color: var(--on-primary);
  font-size: 16px; font-weight: var(--fw-medium); cursor: pointer;
  transition: transform .12s ease, background var(--transition-fast);
}
.dd-edit-pill:active { transform: scale(.985); background: var(--primary-hover); }
.dd-del-text {
  width: 100%; height: 40px; border: none; background: transparent;
  color: var(--tag-bad-fg); font-size: 14px; cursor: pointer;
}
.dd-del-text:active { opacity: .55; }

/* ============================================================
   表单分组卡（编辑页 · 参考 iOS 设置式）
   桌面端 .fg-card 完全透明（display:contents，布局照旧）；
   移动端：灰底画布 + 白色分组卡 + 左标签右控件行 + 头部保存胶囊。
   ============================================================ */
.fg-card { display: contents; }

.modal-head-act {
  margin-left: auto; flex-shrink: 0;
  border: none; height: 32px; padding: 0 16px;
  border-radius: 9999px; background: var(--primary); color: var(--on-primary);
  font-size: 14px; font-weight: var(--fw-medium); cursor: pointer;
  transition: transform .12s ease, background var(--transition-fast);
}
.modal-head-act:active { transform: scale(.94); background: var(--primary-hover); }

@media (max-width: 768px) {
  .wbf-modal { background: var(--bg-page); }
  .wbf-modal .modal-body { padding-bottom: 24px; }

  .fg-card {
    display: block; background: var(--bg-card);
    border-radius: 16px; box-shadow: var(--shadow-card);
    overflow: hidden; margin-bottom: 12px;
  }
  .fg-card .field { margin: 0; padding: 0 16px; position: relative; }
  .fg-card .field + .field::before {
    content: ""; position: absolute; top: 0; left: 16px; right: 16px;
    border-top: 1px solid var(--border);
  }

  /* 行式：左标签 + 右控件（无边框、右对齐） */
  .fg-card .fg-row { display: flex; align-items: center; gap: 12px; min-height: 54px; }
  .fg-card .fg-row > label { flex: 0 0 auto; min-width: 64px; font-size: 15px; color: var(--text-1); }
  .fg-card .fg-row > label .req { margin-left: 2px; }
  .fg-card .fg-row .form-input,
  .fg-card .fg-row .select-wrap,
  .fg-card .fg-row .date-wrap { flex: 1; min-width: 0; }
  .fg-card .fg-row .form-input {
    border: none; background: transparent; box-shadow: none;
    height: 54px; text-align: right; padding: 0; font-size: 16px;
  }
  .fg-card .fg-row .form-input:focus { border: none; box-shadow: none; }
  .fg-card .fg-row .sel-btn,
  .fg-card .fg-row .dp-display {
    width: 100%; border: none; background: transparent; box-shadow: none;
    height: 54px; text-align: right; font-size: 16px; color: var(--text-1);
    padding-right: 0;
  }
  /* 行式下拉：右对齐的值必须给小三角让位，否则「纪念日」这类长字会压在箭头上 */
  .fg-card .fg-row .sel-btn { padding-right: 20px; }
  .fg-card .fg-row .select-wrap::after,
  .fg-card .fg-row .date-wrap .dp-caret { right: 6px; }
  .fg-card .fg-row .date-ico { display: none; }
  .fg-card .fg-row .form-input::placeholder { text-align: right; }

  /* 农历换算：标签在上、三个描边小下拉 */
  .fg-card .fg-stack { padding: 13px 16px 15px; }
  .fg-card .fg-stack > label { display: block; font-size: var(--fs-label); color: var(--text-4); margin-bottom: 9px; }
  .fg-card .fg-stack .field-row-3 { gap: 8px; }
  .fg-card .fg-stack .sel-btn {
    height: 40px; border: 1px solid var(--border); background: var(--bg-page);
    border-radius: var(--radius-btn); font-size: 14px; text-align: center; padding: 0 4px;
  }

  /* 开关行：沿用 switch-row 结构，只给卡片节奏 */
  .fg-card .fg-switch { padding: 4px 16px; }
  .fg-card .fg-switch .switch-row { padding: 10px 0; }
}

/* 分组卡内开关联动拍平：switch-row 自带的小内衬与卡片叠层冲突 */
@media (max-width: 768px) {
  .fg-card .fg-row > label { margin: 0; }
  .fg-card .fg-switch .switch-row { padding: 12px 0; border: none; background: transparent; }
  .fg-card .fg-switch + .fg-switch .switch-row::before { content: none; }
  .fg-card .fg-switch .switch-desc { font-size: var(--fs-label); margin-top: 3px; }
  /* 编辑页开关放大为 iOS 比例（46×27），统一靠右 */
  .fg-card .status-switch { width: 46px; height: 27px; }
  .fg-card .status-switch .switch-slider::before { width: 23px; height: 23px; left: 2px; top: 2px; }
  .fg-card .status-switch input:checked + .switch-slider::before { transform: translateX(19px); }
  /* check-line 搬家后的开关行：去掉复选框时代的左边距节奏 */
  .fg-card .check-line.switch-row { gap: 12px; align-items: center; justify-content: space-between; }
}

/* 头部对勾保存（移动端表单通用） */
.modal-head-act.is-icon {
  width: 34px; height: 34px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
.modal-head-act.is-icon svg { width: 19px; height: 19px; }

@media (max-width: 768px) {
  /* 分组卡内组件节奏 */
  .fg-card .fg-stack { padding: 13px 16px 15px; }
  .fg-card .fg-stack .check-line {
    display: flex; align-items: center; justify-content: space-between;
    padding: 13px 0; margin: 0; font-size: 15px; color: var(--text-1);
  }
  .fg-card .fg-stack .mood-row { flex-wrap: wrap; gap: 8px; }
  .fg-card .fg-stack .md-field-head { flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
  .fg-card .fg-stack .md-seg button { height: 32px; }
  .fg-card .fg-stack .field-hint { margin-top: 8px; }
  .fg-card .fg-stack .sub-add .form-input { height: 40px; }
  /* 回顾：日期+心情组合行在卡内转纵向 */
  .fg-card .fg-stack.field-row { display: block; }
  .fg-card .fg-stack.field-row > .field { padding: 0; }
  .fg-card .fg-stack.field-row > .field + .field { margin-top: 14px; }
  .fg-card .fg-stack.field-row > .field > label { margin-bottom: 8px; font-size: var(--fs-label); color: var(--text-4); display: block; }
}

/* mobDetailify 搬家后的按钮重塑形：主操作通栏胶囊、删除降红字行 */
.dd-foot-inline .btn { width: 100%; height: 52px; border-radius: 9999px; font-size: 16px; font-weight: var(--fw-medium); }
.dd-foot-inline .btn-primary { border: none; }
.dd-foot-inline .btn-primary:active { transform: scale(.985); }
.dd-foot-inline .btn-danger {
  width: 100%; height: 40px; border: none; border-radius: 0;
  background: transparent; color: var(--tag-bad-fg);
  font-size: 14px; font-weight: var(--fw-regular);
}
.dd-foot-inline .btn-danger:hover { background: transparent; color: var(--tag-bad-fg); }
.dd-foot-inline .btn-danger:active { transform: none; opacity: .55; background: transparent; color: var(--tag-bad-fg); }

/* ============================================================
   纪念日列表卡 · 信息层级重排
   名称行（类型圆点+名字）/ 属性文字行 / 时间语境行；右侧数字去重
   ============================================================ */
.date-card .date-title { gap: 8px; flex-wrap: nowrap; }
.date-name { font-size: 16px; }
.dd-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.dd-dot-b { background: var(--badge-dot-1); }
.dd-dot-a { background: var(--badge-dot-3); }
.date-attrs { color: var(--text-4); font-size: var(--fs-micro); margin-top: 5px; letter-spacing: .2px; }
.date-when {
  color: var(--text-3); font-size: var(--fs-caption); margin-top: 6px;
  font-variant-numeric: tabular-nums; font-family: var(--font-mono);
}
.date-when { font-size: 13px; }

/* ============================================================
   手机端提示 · 底部深色胶囊 Snackbar
   反馈落在拇指操作区上方（dock 之上），深色半透明 + 毛玻璃；
   状态点换 iOS 暗色系统色保证深底可读；桌面端保持顶部白卡。
   ============================================================ */
.toast { pointer-events: auto; cursor: pointer; }
@media (max-width: 768px) {
  .toast-container {
    top: auto;
    bottom: calc(96px + env(safe-area-inset-bottom, 0px));
    gap: 8px;
  }
  .toast {
    background: rgba(26, 26, 28, .92); color: #FCFCFC;
    border: none; border-radius: 9999px;
    padding: 11px 18px; font-size: 14.5px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .25);
    max-width: 86vw;
    animation: toastUp .26s var(--ease-float);
    -webkit-backdrop-filter: blur(12px) saturate(140%);
    backdrop-filter: blur(12px) saturate(140%);
  }
  [data-theme="dark"] .toast {
    background: rgba(60, 62, 68, .94);
    border: 1px solid var(--border);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .5);
  }
  .toast .toast-dot { background: #30D158; box-shadow: 0 0 0 3px rgba(48, 209, 88, .22); }
  .toast-warn .toast-dot { background: #FF9F0A; box-shadow: 0 0 0 3px rgba(255, 159, 10, .22); }
  .toast-error .toast-dot { background: #FF453A; box-shadow: 0 0 0 3px rgba(255, 69, 58, .22); }
  .toast-out { opacity: 0; transform: translateY(10px); }
}
@keyframes toastUp {
  from { opacity: 0; transform: translateY(14px) scale(.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* ============================================================
   设置整合：顶栏单头像入口 + 外观三分段
   ============================================================ */
/* 头像按钮全端可见（顶栏唯一入口） */
.avatar-btn { display: inline-flex; }
@media (min-width: 1025px) {
  .avatar-btn { width: 34px; height: 34px; }
}
/* 设置行内三分段（iOS 设置式：灰轨白胶囊） */
.pf-seg {
  display: inline-flex; flex-shrink: 0; gap: 2px;
  background: var(--bg-muted); border-radius: 9999px; padding: 3px;
}
.pf-seg button {
  border: none; background: transparent; cursor: pointer;
  height: 28px; padding: 0 12px; border-radius: 9999px;
  font-size: 12.5px; color: var(--text-3);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.pf-seg button.active {
  background: var(--bg-card); color: var(--text-1);
  font-weight: var(--fw-medium); box-shadow: var(--shadow-sm);
}

/* 本地模式名片右侧「登录账号」文字入口 */
.pf-login-act {
  margin-left: auto; flex-shrink: 0;
  display: inline-flex; align-items: center; gap: 2px;
  border: none; background: transparent; cursor: pointer;
  color: var(--primary); font-size: 14px; font-weight: var(--fw-medium);
  padding: 8px 0 8px 12px;
}
.pf-login-act svg { width: 15px; height: 15px; }
.pf-login-act:active { opacity: .55; }

/* ============================================================
   编辑资料页：退出登录长胶囊（参考详情编辑按钮形态，danger 语义色）
   ============================================================ */
.pf-logout-pill {
  width: 100%; height: 52px; border-radius: 9999px; cursor: pointer;
  background: var(--bg-card);
  border: 1px solid color-mix(in srgb, var(--danger) 42%, transparent);
  color: var(--tag-bad-fg);
  font-size: 16px; font-weight: var(--fw-medium);
  transition: transform .12s ease, background var(--transition-fast);
}
.pf-logout-pill:active { transform: scale(.985); background: var(--tag-bad-bg); }
@media (max-width: 768px) {
  .fg-card .pf-edit-avatar { padding: 16px 16px 0; margin-bottom: 0; }
  .fg-card .pf-edit-avatar .field-hint { margin-top: 6px; }
}

/* ============================================================
   头像圆形化（手机端）+ 编辑资料页居中放大点头像
   ============================================================ */
@media (max-width: 768px) {
  .user-avatar, .avatar-btn, .user-row-avatar { border-radius: 50%; }
}

/* 编辑资料：头像独立浮于灰底画布居中，昵称卡在其下方 */
.pf-edit-avatar { flex-direction: column; align-items: center; gap: 0; margin-bottom: 0; padding: 26px 16px 16px; }
.user-avatar-xl { width: 92px; height: 92px; font-size: 36px; border-radius: 50%; }
.ep-avatar-btn {
  position: relative; display: block; padding: 0; border: none; background: transparent;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: transform .14s ease;
}
.ep-avatar-btn:active { transform: scale(.955); }
.ep-avatar-cam {
  position: absolute; right: -2px; bottom: -2px;
  width: 30px; height: 30px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-card); border: 1px solid var(--border);
  color: var(--text-3); box-shadow: var(--shadow-sm);
}
.ep-avatar-cam svg { width: 15px; height: 15px; }

/* ============================================================
   Klog 手机端间距规范 v1.0（2026-09-14 定稿，仅 ≤768px 生效）
   ------------------------------------------------------------
   4pt 基准网格，对齐 iOS HIG。后续所有手机端改动必须遵循：

     页面边距        16px   --content-px   页面内容左右
     卡片内距      16px横 / 14px纵  --card-pad（纵向为光学修正）
     组内间距        8px   同组元素：label↔控件、图标↔文字、标题↔内容
     卡片间距       12px   --card-gap    卡片列表、全部网格 gap
     模块间距       20px   --module-gap  工具栏↔列表、分区↔分区、hero↔卡区
     触控目标      ≥44px   --control-h；表单行 54、列表行 ≥44
     浮层规则       dock=底12+安全区 · toast=dock 上 96 · 弹窗底栏=横16+安全区

   桌面端维持自身 24/16 节奏，本规范只在手机端媒体查询内覆盖。
   ============================================================ */
@media (max-width: 768px) {
  :root {
    --sp-5: 20px;
    --content-px: var(--sp-4);      /* 16 页面边距 */
    --content-py: var(--sp-4);      /* 16 */
    --card-pad:   var(--sp-4);      /* 16 卡片内距（横） */
    --card-gap:   var(--sp-3);      /* 12 卡片/网格间距 */
    --module-gap: var(--sp-5);      /* 20 模块/分区间距 */
    --filter-gap: var(--sp-4);      /* 16 */
  }
  /* 消费方重映射 */
  .toolbar { margin-bottom: var(--module-gap); }
  .insight-grid { margin-top: var(--module-gap); }
  .dc-block + .dc-block { margin-top: var(--module-gap); }
  .dc-block.pf-sec { margin-top: var(--module-gap); }
  .pfg { margin-top: var(--module-gap); }
  .modal-card .modal-body { padding: calc(48px + var(--module-gap)) var(--card-pad) var(--card-pad); }
  .modal-foot { padding-left: var(--card-pad); padding-right: var(--card-pad); }
  .login-pop { padding-left: var(--card-pad); padding-right: var(--card-pad); }
}

/* ============================================================
   待办左滑快捷操作层（移动端）：归档 / 删除
   参考 HarmonyOS 短信两段式：动作层从行右外随内容同步滑入；
   圆形图标按钮 → 完全展开时主操作（删除）膨胀为大胶囊，
   次操作（归档）保持小圆；内容平移同时渐隐。
   ============================================================ */
.swipe-acts { display: none; }
@media (max-width: 768px) {
  #todoBody tr { position: relative; overflow: hidden; }
  #todoBody td:not(.swipe-acts) {
    transition: transform .38s cubic-bezier(.32, 1.18, .48, 1), opacity .3s ease;
  }
  /* 注意：动作层是 td，会被 #todoBody td{display:block}（表格转卡片）压掉，
     必须用更高特异性的 #todoBody td.swipe-acts 恢复横向 flex */
  #todoBody td.swipe-acts {
    position: absolute;
    top: 0; bottom: 0; left: 100%;
    width: 188px;
    display: flex; align-items: center; gap: 10px;
    padding-right: 14px; box-sizing: border-box; z-index: 2;
    transition: transform .38s cubic-bezier(.32, 1.18, .48, 1);
  }
  .swipe-act {
    flex-shrink: 0; width: 44px; height: 44px;
    border: none; border-radius: 9999px; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    transition: width .28s var(--ease-enter), filter var(--transition-fast), transform .12s ease;
  }
  .swipe-act svg { width: 20px; height: 20px; flex-shrink: 0; }
  .swipe-act:active { filter: brightness(.88); transform: scale(.93); }
  .swipe-arch { background: var(--bg-count); color: var(--text-1); }
  .swipe-del { background: var(--danger); color: #fff; }
}

/* ============================================================
   手机端全局 UI/UX 优化 v1.0（2026-09-15）
   ------------------------------------------------------------
   本块统一收口手机端的手感、层级、安全区与字号缺陷，
   只在 ≤768px / 触屏生效，桌面端零影响；视觉风格不动。
   遵循「手机端间距规范 v1.0」：4pt 网格、主操作 ≥44、
   icon 类 ≥38、表单行 54、列表行 ≥44、正文 ≥15、辅助 ≥12。
   ============================================================ */

/* ---- 1. 触摸目标：视觉尺寸克制，热区用 ::after 隐形扩张 ---- */
@media (max-width: 768px) {
  /* 头部「保存」是全页第一主操作：视觉 34px 胶囊，热区约 50×54 */
  .modal-head-act { position: relative; height: 34px; }
  .modal-head-act::after { content: ""; position: absolute; inset: -10px -10px; }
  .modal-head-act.is-icon { width: 36px; height: 36px; }

  .cat-swatch { position: relative; width: 30px; height: 30px; border-radius: 9px; }
  .cat-swatch::after { content: ""; position: absolute; inset: -5px; } /* 40px 热区，相邻色块仅轻微重叠 */
  .cat-act { width: 40px; height: 40px; }
  .cat-act svg { width: 16px; height: 16px; }
  .sub-del { position: relative; width: 36px; height: 36px; }
  .sub-del::after { content: ""; position: absolute; inset: -4px; }
  .sub-del svg { width: 15px; height: 15px; }
  .memo-pin { width: 38px; height: 38px; }
  .mood-btn { height: 44px; padding: 0 14px; font-size: 15px; }
  .wd-btn { height: 40px; font-size: 15px; }
  .habit-toggle-btn { height: 40px; padding: 0 16px; font-size: 15px; }
  .pf-seg { padding: 3px; }
  .pf-seg button { height: 38px; padding: 0 14px; font-size: 13px; }
  .dc-reset-btn { width: 40px; height: 40px; }
  .login-pop-x { top: 4px; right: 4px; width: 40px; height: 40px; }
  /* 小眼睛：保持叠加在输入框内侧右缘（基线 absolute 不动），只放大触控目标；
     旧覆写 position: relative 会让按钮换行掉到输入框下方 */
  .pwd-toggle { width: 34px; height: 34px; right: 5px; }
  .pwd-field .form-input { padding-right: 46px; }
  .pwd-toggle::after { content: ""; position: absolute; inset: -5px; }
  .ep-avatar-cam { width: 34px; height: 34px; }
  .ep-avatar-cam svg { width: 16px; height: 16px; }
  .dp-day { height: 40px; }
  .rm-cal { width: 44px; height: 44px; }
  .rm-save-btn { width: 46px; height: 46px; }
  .dd-item { padding: 12px 14px; font-size: 15px; }
  .cat-row, .trash-row { min-height: 48px; padding: 8px 2px; }
  .habit-today-row { min-height: 52px; }
  .search-clear { width: 30px; height: 30px; }
}

/* ---- 2. 层级：用户管理角色菜单曾被底部 dock（z60）压住 ---- */
@media (max-width: 768px) {
  .dd-menu { z-index: 70; max-height: 264px; overflow-y: auto; -webkit-overflow-scrolling: touch; }
}

/* ---- 3. 触屏反馈：取消「点一次就粘住」的 hover 悬浮态，改由 :active 承担 ----
   只把确有 hover 规则的控件重置回基线值（不碰没有 hover 态的元素），
   并给带选中类的元素补同特异性的 :hover 保护，避免重置反杀选中态。 */
@media (hover: none) {
  /* 卡片/色块类：去掉抬升与旋转 */
  .cat-swatch:hover, .memo-pin:hover, .rm-save-btn:hover, .memo-card:hover, .date-card:hover,
  .habit-card:hover, .diary-card:hover, .summary-card[data-goto]:hover { transform: none; }
  .memo-card:hover, .date-card:hover,
  .habit-card:hover, .diary-card:hover, .summary-card[data-goto]:hover {
    border-color: var(--border); box-shadow: var(--shadow-card);
  }
  /* 状态描边必须继续胜出：置顶卡的主色描边、临近事件的警示左条 */
  .memo-card.is-pinned:hover { border-color: color-mix(in srgb, var(--primary) 45%, var(--border)); }
  .date-card.is-soon:hover { border-left-color: var(--warning); }

  /* 图标按钮类：hover 底色与变色全部退回基线 */
  .cat-act:hover, .sub-del:hover, .dd-item:hover, .pwd-toggle:hover,
  .login-pop-x:hover, .memo-pin:hover, .pfg-row:hover { background: transparent; }
  .cat-act:hover { color: var(--text-3); }
  .cat-act.cat-act-del:hover { color: var(--status-bad); }
  .sub-del:hover { color: var(--text-4); }
  .dd-item:hover { color: var(--text-2); }
  .dd-item:hover.is-sel { color: var(--primary); }
  .pwd-toggle:hover { color: var(--text-4); }
  .pwd-toggle.on:hover { color: var(--text-1); }
  .login-pop-x:hover { color: var(--text-4); }
  .memo-pin:hover { color: var(--text-4); }
  .memo-pin.on:hover { color: var(--primary); }

  /* 选择型小按钮：选中态必须继续胜出 */
  .wd-btn:hover, .mood-btn:hover { border-color: var(--border); color: var(--text-3); }
  .wd-btn.active:hover, .mood-btn.active:hover { border-color: var(--primary); color: var(--text-1); }
  .habit-toggle-btn:hover { border-color: var(--border-strong); color: var(--text-2); background: var(--bg-card); }
  .habit-toggle-btn.on:hover { border-color: var(--border-strong); color: var(--primary); background: var(--bg-card); }

  /* 小票机：深色底上的悬浮态退回各自基线 */
  .rm-cal:hover { background: rgba(255, 255, 255, .1); }
  .rm-cal .date-ico:hover { color: #f3f3f3; }
  .rm-actions .btn:hover { background: #e9e9ec; color: #1c1c1f; }
  .rm-save-btn:hover { color: var(--text-2); border-color: var(--border); }

  /* 即时按压反馈 */
  .cat-act:active, .sub-del:active, .dd-item:active, .pwd-toggle:active,
  .login-pop-x:active, .dc-reset-btn:active, .pf-seg button:active,
  .memo-pin:active, .rm-cal:active, .habit-today-row:active,
  .cat-row:active, .trash-row:active { background: var(--bg-hover); }
  .cat-swatch:active { transform: scale(.88); }
  .mood-btn:active, .wd-btn:active, .habit-toggle-btn:active { transform: scale(.97); }
  .habit-card:active, .diary-card:active, .summary-card[data-goto]:active,
  .user-row:active { transform: scale(.985); }
  .rm-save-btn:active { transform: scale(.92); }
  .dd-item:active { color: var(--text-1); }
}

/* ---- 4. 视口与安全区：登录页 / 引导页贴 home 条、固定 px 高在横屏溢出 ---- */
@media (max-width: 768px) {
  .login-wrap {
    min-height: 100dvh;
    padding:
      calc(var(--content-px) + env(safe-area-inset-top, 0px))
      calc(var(--content-px) + env(safe-area-inset-right, 0px))
      calc(var(--content-px) + env(safe-area-inset-bottom, 0px))
      calc(var(--content-px) + env(safe-area-inset-left, 0px));
  }
  .login-mask {
    padding:
      calc(var(--content-px) + env(safe-area-inset-top, 0px))
      calc(var(--content-px) + env(safe-area-inset-right, 0px))
      calc(var(--content-px) + env(safe-area-inset-bottom, 0px))
      calc(var(--content-px) + env(safe-area-inset-left, 0px));
  }
  /* 引导层（.ob-mask / .ob-card）手机端见文件末尾「首次访问引导 → 底部抽屉」块，单一权威源 */
  /* 内部滚动容器一律改用 dvh：固定 px 高在小屏会顶掉底部按钮 */
  .trash-rows { max-height: min(52dvh, 340px); }
  .md-body { max-height: min(48dvh, 360px); }
  .rm-box-list { max-height: min(56dvh, 420px); }
  .op-list { max-height: 46dvh; }
  .modal-body, .rm-modal .modal-body { overscroll-behavior: contain; }
}

/* ---- 5. 字号地板与 4pt 网格回归 ---- */
@media (max-width: 768px) {
  .md-body h4 { font-size: 15px; }
  .fg-card .fg-stack .sel-btn { font-size: 15px; }
  .toast { font-size: 15px; }
  .role-badge { height: 20px; padding: 0 7px; font-size: 12px; }
  .menu-cnt { font-size: 12px; }
  .tabbar .menu-cnt { font-size: 11px; } /* 数字气泡非正文，11px 为可读下限 */
  .todo-title { font-size: 16px; }
  .sub-title, .cat-row-name, .trash-title { font-size: 15px; }
  #todoBody tr { padding: 14px var(--card-pad); column-gap: var(--sp-2); row-gap: 4px; }

  /* 开关行对齐参考图：左「标题 + 说明」纵向成组、右开关垂直居中靠右 */
  .fg-card .fg-switch .switch-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
  .fg-card .fg-switch .switch-row > span:first-child { min-width: 0; }
  .fg-card .fg-switch .switch-label { font-size: 16px; color: var(--text-1); font-weight: var(--fw-medium); }
  .fg-card .fg-switch .switch-desc { font-size: 12px; line-height: 1.5; margin-top: 4px; }
}

/* ---- 6. 弹窗链切换：详情→编辑/删除确认时新内容自顶部推入 ----
   （原「1802 行」声明为空块，此处补齐；与返回时的下移离场成对） */
@media (max-width: 768px) {
  .modal-card.chain-in .modal-body > * { animation: chainPushIn .24s var(--ease-enter) backwards; }
  .modal-card.chain-in .modal-body > *:nth-child(2) { animation-delay: .03s; }
  .modal-card.chain-in .modal-body > *:nth-child(3) { animation-delay: .06s; }
  .modal-card.chain-in .modal-body > *:nth-child(4) { animation-delay: .09s; }
  .modal-card.chain-in .modal-body > *:nth-child(5) { animation-delay: .12s; }
  .modal-card.chain-in .modal-body > *:nth-child(n + 6) { animation-delay: .14s; }
  @keyframes chainPushIn { from { opacity: 0; transform: translateY(-12px); } to { opacity: 1; transform: translateY(0); } }
  /* 详情页入场方向统一（2026-09-17）：点卡片进详情一律自下而上浮入，
     不受「380ms 链窗口」或强制 chain 影响（复用 cascadeIn 的上浮轨迹，只改方向不改节奏）；
     自上而下推入仅保留给「详情→编辑 / 删除确认」这类链内推进（非 dd-modal 表单壳）。
     特异性须压过上方 .modal-card.chain-in 基础规则，故带 .dd-modal 且排在其后 */
  .modal-card.dd-modal.chain-in .modal-body > * { animation-name: cascadeIn; }
}
@media (prefers-reduced-motion: reduce) {
  .modal-card.chain-in .modal-body > * { animation: none !important; }
}

/* ============================================================
   ≤380px 超窄屏收缩（必须排在所有 ≤768 规则之后才生效）
   规范：只收缩字号与 dock 宽度，间距与触控目标不回退。
   ============================================================ */
@media (max-width: 380px) {
  :root { --header-h: 52px; }
  .icon-btn { width: 38px; height: 38px; }
  .icon-btn svg { width: 18px; height: 18px; }
  .header-actions { gap: 6px; }
  /* FAB 与 dock 宽度的收缩必须带上 .tabbar 前缀：
     基础规则 .tabbar .tabbar-add / .tabbar.has-add .tabbar-dock 特异性更高，
     裸类名的 ≤380 规则历史上一直是死代码（实测 FAB 仍 60px） */
  .tabbar .tabbar-add { width: 54px; height: 54px; }
  .tabbar .tabbar-add svg { width: 20px; height: 20px; }
  .tabbar.has-add .tabbar-dock { width: calc(100% - 62px); }
  /* 概览页（无加号）：与 has-add 同宽，居中量取空余 62px 的一半 */
  .tabbar:not(.has-add) .tabbar-dock { width: calc(100% - 62px); margin-left: 31px; }
  .tabbar .menu-item { font-size: 12px; }
  .mood-btn { padding: 0 12px; font-size: 14.5px; }
  .pf-seg button { padding: 0 10px; }
  .habit-toggle-btn { padding: 0 12px; }
}

/* ============================================================
   【样板 · 待确认】待办列表卡片化（仅手机端）
   ------------------------------------------------------------
   把「表格行 + 分隔线」升级为独立信息卡：
   · 卡片各自呼吸（--card-gap），去掉行分隔线的表感
   · 截止时间降为第二行等宽数字，创建日期让位（详情页仍完整可见）
   · 优先级星标补语义色：高=警示红 / 中=正文灰 / 低=禁用灰
   · 完成态整卡降权重，与未完成拉开层次
   不满意可整块删除，不影响上面的规范收口。
   ============================================================ */
@media (max-width: 768px) {
  /* 外层 .panel 拍平：行本身已是卡片，再套一层白底描边壳会露出第二张卡
     （卡间缝隙与末行下方都会透出面板白底）——让行卡直接落在页面灰底上 */
  #view-todo .panel {
    background: transparent; border: none; border-radius: 0;
    box-shadow: none; overflow: visible;
  }
  #view-todo .table-wrap { overflow: visible; }
  #todoBody { display: flex; flex-direction: column; gap: var(--card-gap); padding-top: 2px; }
  #todoBody tr, #todoBody tr:last-child {
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
      "check title  priority"
      "check due    due";
    align-items: start; column-gap: var(--sp-2); row-gap: 4px;
    padding: 14px var(--card-pad);
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    transition: transform .14s var(--ease-float), opacity .2s ease,
                border-color var(--transition-fast), box-shadow var(--transition-fast);
  }
  #todoBody td.code { display: none; } /* 创建日期：手机端让位 */
  #todoBody td.col-check, #todoBody td.col-priority { padding-top: 1px; }
  #todoBody .todo-title { font-size: 16px; line-height: 1.4; }
  #todoBody .todo-meta { margin-top: 6px; gap: var(--sp-2); }

  /* 截止时间：等宽数字，作为第二行的轻量锚点 */
  #todoBody td.col-due {
    width: auto; text-align: left; padding-top: 1px;
    font-family: var(--font-mono); font-size: var(--fs-micro);
    color: var(--text-4); letter-spacing: .01em;
  }

  /* 优先级语义色（形状已表意，颜色只做辅助强化，不单靠色觉） */
  #todoBody .prio-3 { color: var(--tag-high-fg); }
  #todoBody .prio-2 { color: var(--text-3); }
  #todoBody .prio-1 { color: var(--text-disabled); }

  /* 完成态：整卡降权重（:has 不支持时自然退回原样，不影响功能） */
  #todoBody tr:has(.todo-check input:checked) {
    background: var(--bg-soft); box-shadow: none; opacity: .72;
  }
  #todoBody tr:has(.todo-check input:checked) .prio { opacity: .5; }

  /* 按压反馈与其余卡片列表同幅度 */
  #todoBody tr:active { transform: scale(.985); }
}

/* ============================================================
   【推广】卡片列表语言统一：备忘 / 事件 / 习惯 / 日记
   ------------------------------------------------------------
   四张列表的卡壳（白底 + 1px 描边 + radius-card + 14/16 内距 +
   shadow-card）本就与待办样板一致，此处补齐的是文字层级与节奏：
   · 主标题一律 16px（与待办标题同档），事件名此前已是 16px
   · 次级信息一律 12px 地板，数字统一 tabular-nums
   · 列表间距回归 --card-gap（事件列表原本 10px 脱离 4pt 网格）
   · 按压缩放全部统一 .985
   ============================================================ */
@media (max-width: 768px) {
  .date-list { gap: var(--card-gap); }
  .memo-card, .date-card, .habit-card, .diary-card { padding: 14px var(--card-pad); }

  /* 主标题层 */
  .memo-title, .habit-name, .diary-date b { font-size: 16px; }
  .memo-title { line-height: 1.4; }

  /* 次级层：辅助文字与数字 */
  .memo-content, .habit-meta, .diary-sec, .diary-date span { font-size: 12px; }
  .date-when { font-size: 12px; }        /* 与待办截止行同档 */
  .date-attrs { letter-spacing: 0; }
  .habit-meta b, .diary-date b, .memo-time { font-variant-numeric: tabular-nums; }

  /* 卡内首层间距与待办对齐（标题↔次级 = 6px，次级之间 8px） */
  .memo-card { gap: var(--sp-2); }
  .habit-meta { margin: 8px 0 10px; }
  .diary-head { margin-bottom: var(--sp-2); }

  /* 按压缩放统一 */
  .memo-card:active, .date-card:active, .habit-card:active, .diary-card:active { transform: scale(.985); }
}

/* ============================================================
   确认类弹窗外壳（删除 / 清空 / 重置 / 退出 / 容量 / 数据异常）
   ------------------------------------------------------------
   线性描边图标圆底 → 对象名 → 说明，三段纵向居中；
   桌面沿用窄卡，手机端在全屏页里垂直居中、底栏转通栏胶囊。
   危险色只取站点已有的 --tag-bad-* / --danger（左滑删除胶囊同款红）。
   ============================================================ */
.cf-body {
  display: flex; flex-direction: column; align-items: center;
  gap: var(--sp-2); text-align: center;
}
.cf-mark {
  width: 52px; height: 52px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-muted); color: var(--text-3);
}
.cf-mark svg { width: 24px; height: 24px; }
.cf-mark.is-danger { background: var(--tag-bad-bg); color: var(--tag-bad-fg); }
.cf-headline {
  font-size: 17px; font-weight: var(--fw-semibold); color: var(--text-1);
  line-height: 1.45; word-break: break-word; max-width: 24em;
}
.cf-headline b { font-weight: var(--fw-bold); }
.cf-msg {
  font-size: var(--fs-caption); color: var(--text-3); line-height: 1.7;
  max-width: 30em; word-break: break-word;
}
.cf-msg b { color: var(--text-1); font-weight: var(--fw-medium); }

/* 手机端：确认弹窗改为与滚轮日期选择器 / 选项卡片同款的底部抽屉
   （.wp-mask / .wp-sheet 一套参数：24 圆角、18/16 内距、自下而上 .32s、
   标题居中 17px 粗、底栏 50px 双胶囊 flex 1 / 1.5） */

/* 手机端确认抽屉排版 v1.1（cfSheet 独立抽屉）
   ------------------------------------------------------------
   历史上四级内容挤在 gap:10 里、说明与按钮间距实测为 0，读起来一坨。
   现在按 4pt 网格拉开节奏，并让「对象名」成为唯一主标题：
   带 headline 时把 .wp-title 降为 13px 眉标（:has 判定，退出 / 重置等
   没有对象名的确认仍保持 17px 粗标题）。数值与下方 .cf-modal 成对维护。
   选择器一律带 .cf-sheet：.wp-title / .wp-foot 与滚轮选择器、选项卡片共用。 */
@media (max-width: 768px) {
  .cf-sheet { padding-top: 20px; }
  .cf-sheet .wp-title { margin-bottom: 16px; }
  .cf-sheet:has(.cf-headline) .wp-title {
    font-size: 13px; font-weight: var(--fw-medium); color: var(--text-3);
    letter-spacing: .04em; margin-bottom: 18px;
  }
  .cf-sheet .cf-body { gap: 14px; }
  .cf-sheet .cf-mark { width: 56px; height: 56px; animation: cfMarkIn .34s var(--ease-float) backwards .1s; }
  .cf-sheet .cf-mark svg { width: 26px; height: 26px; }
  .cf-sheet .cf-headline {
    font-size: 19px; font-weight: var(--fw-bold); line-height: 1.4;
    max-width: 16em; margin: 0 auto; text-wrap: balance;
  }
  .cf-sheet .cf-msg { font-size: 14px; line-height: 1.75; max-width: 21em; margin: 2px auto 0; text-wrap: balance; }
  .cf-sheet .wp-foot { margin-top: 26px; }
}
@media (max-width: 768px) {
  /* 遮罩：抽屉必须压暗背景（全屏弹窗的遮罩是透明的），并对齐底边 */
  .modal-mask:has(.cf-modal) {
    background: var(--mask);
    align-items: flex-end;
    padding: 0; overflow: hidden;
    animation: maskIn .22s ease; /* 与 .wp-mask 淡入同参数（基础规则是 .15s） */
  }
  .cf-modal {
    height: auto; max-height: 86dvh;
    background: var(--bg-card);
    border-radius: 24px 24px 0 0;
    box-shadow: var(--shadow-modal);
    animation: cfSheetUp .32s var(--ease-enter);
  }
  .cf-modal.closing { animation: cfSheetDown var(--d-fast) ease-in forwards; } /* 收在 Modal 170ms 清理预算内 */
  /* 抽屉只播「自下而上」一段，叠加内容级联 / 自上推入会打架 */
  .cf-modal.cascade .modal-body > *, .cf-modal.chain-in .modal-body > * { animation: none; }

  /* 头部退化为抽屉标题（不再是悬浮玻璃条） */
  .cf-modal .modal-head {
    position: static; justify-content: center;
    padding: 18px var(--content-px) 12px;
    background: none; border-radius: 0;
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
  .cf-modal .modal-head h2 {
    position: static; transform: none; max-width: 100%;
    font-size: 17px; font-weight: var(--fw-bold); color: var(--text-1);
    text-align: center; pointer-events: auto;
  }
  /* 与 .cf-sheet 同一处理：有对象名成行时标题降为眉标，全卡只留一个主标题 */
  .cf-modal:has(.cf-headline) .modal-head h2 {
    font-size: 13px; font-weight: var(--fw-medium); color: var(--text-3); letter-spacing: .04em;
  }
  .cf-modal .modal-back, .cf-modal .modal-x { display: none; } /* 关闭交给遮罩点击与底栏按钮，与选择器一致 */

  .cf-modal .modal-body { display: block; padding: 0 var(--content-px) 16px; }
  .cf-modal .cf-body { gap: 14px; }
  .cf-modal .cf-mark { width: 56px; height: 56px; animation: cfMarkIn .34s var(--ease-float) backwards .1s; }
  .cf-modal .cf-mark svg { width: 26px; height: 26px; }
  .cf-modal .cf-headline {
    font-size: 19px; font-weight: var(--fw-bold); line-height: 1.4;
    max-width: 16em; margin: 0 auto; text-wrap: balance;
  }
  .cf-modal .cf-msg { font-size: 14px; line-height: 1.75; max-width: 21em; margin: 2px auto 0; text-wrap: balance; }

  /* 底栏：与 .wp-foot 同参数（取消 flex:1 灰 / 主操作 flex:1.5） */
  .cf-modal .modal-foot {
    background: transparent; border-top: none;
    padding: 12px var(--content-px) calc(16px + env(safe-area-inset-bottom, 0px));
  }
  .cf-modal .modal-foot-group { display: flex; gap: 12px; width: 100%; }
  .cf-modal .modal-foot .btn {
    height: 50px; border: none; border-radius: 9999px;
    font-size: 16px; cursor: pointer;
    transition: transform .12s ease, background var(--transition-fast), filter var(--transition-fast);
  }
  .cf-modal .modal-foot .btn-default { flex: 1; background: var(--bg-muted); color: var(--text-2); }
  .cf-modal .modal-foot .btn-default:active { background: var(--bg-count); }
  .cf-modal .modal-foot .btn-danger, .cf-modal .modal-foot .btn-primary {
    flex: 1.5; font-weight: var(--fw-medium);
  }
  .cf-modal .modal-foot .btn-danger { background: var(--danger); color: #fff; }
  .cf-modal .modal-foot .btn-danger:active { transform: scale(.985); filter: brightness(.9); }
  .cf-modal .modal-foot .btn-primary { background: var(--primary); color: var(--on-primary); }
  .cf-modal .modal-foot .btn-primary:active { transform: scale(.985); background: var(--primary-hover); }

  @keyframes cfSheetUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
  @keyframes cfSheetDown { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(100%); } }
  @keyframes cfMarkIn { from { opacity: 0; transform: scale(.82); } to { opacity: 1; transform: scale(1); } }
}

@media (prefers-reduced-motion: reduce) {
  .cf-modal .cf-mark, .cf-sheet .cf-mark { animation: none; }
  .cf-modal, .cf-modal.closing { animation: none; }
}

/* ============================================================
   dock 瘦身：概览退出底部导航（4 tab + 加号）
   回归路径：双击任意 tab（JS）或点顶栏标题左侧的 logo（.head-logo）
   ============================================================ */
@media (max-width: 768px) {
  /* 概览页（无加号）的居中已由 ≤768 段的 margin-left:35px 负责
     （dock 宽 calc(100% - 70px)，空余 70px 的一半）。
     这里绝不能再叠 transform：本块历史上写过 translateX(31px)，
     与 margin 相加后 dock 右移 66px、贴死屏幕右边（实测 gapLeft 66 / gapRight 4）。 */
}

/* ============================================================
   四页排版优化 v1.0（备忘详情 / 备忘编辑 / 已归档 / 回收站）
   ------------------------------------------------------------
   全部收口到站内已定稿的两套语言：详情＝iOS 分组卡片（灰底画布 + 白色
   圆角卡 + 图标行组，同 .dd-modal），表单＝.wbf-modal + .fg-card。
   只补三类硬伤：
   ① 触控目标：弹窗返回键 28px、恢复按钮 34px、置顶开关行 37px；
   ② 可读性：详情时间戳原为 --text-disabled 12px 灰字（对比度≈1.5:1），
      改走图标行组；正文 14.4px → 15px 地板；
   ③ 分组与描边：归档/回收站条目浮在灰底上没有卡片、Markdown 分段控件
      白底贴白卡完全看不见、搬家后的开关行带着 .switch-row 的小内衬灰底。
   选择器坑（与历史教训同类）：mobFormify 把 .check-line 原节点升级成
   .fg-switch.switch-row 时，两个类挂在同一元素上，
   「.fg-card .fg-switch .switch-row」是后代选择器，永远匹配不到 → 必须写复合。
   ============================================================ */

/* ---- 弹窗返回键：视觉不变，触屏热区提到 40px（规范 icon 类 ≥38） ---- */
@media (max-width: 768px) {
  .modal-head .modal-back { width: 40px; height: 40px; margin-left: -10px; }
}

/* ---- 备忘详情：hero 内的标题与置顶钮同轴 ---- */
.md-hero-top { display: flex; align-items: flex-start; gap: 12px; }
.md-hero-top .dd-hero-name { flex: 1; min-width: 0; }
.md-hero-tags { margin-top: 12px; }
/* 置顶：裸图标升级为圆形幽灵钮（44px 触控，选中态实心黑） */
#dt-pin.memo-pin {
  width: 44px; height: 44px; flex: 0 0 44px; border-radius: 9999px;
  background: var(--bg-muted); color: var(--text-3);
}
#dt-pin.memo-pin svg { width: 18px; height: 18px; }
#dt-pin.memo-pin.on { background: var(--primary); color: var(--on-primary); }
#dt-pin.memo-pin.on svg { fill: none; }
/* 正文卡：白卡自带描边会再套一层框，这里拍平成卡片本身的内容 */
.md-doc { padding: 2px 0; }
.md-doc .md-body {
  background: transparent; border: none; border-radius: 0;
  padding: 16px; min-height: 0; max-height: none; overflow: visible;
  font-size: 15px; line-height: 1.8; color: var(--text-2);
}
.md-doc .md-body h1 { font-size: 18px; }
.md-doc .md-body h2 { font-size: 16px; }
.md-doc .md-body code { font-size: 13px; }
.md-doc .md-empty-hint { color: var(--text-4); }

/* ---- 备忘编辑：分段控件、开关行、正文输入 ---- */
@media (max-width: 768px) {
  /* 编辑/预览：白底描边贴白卡看不见 → 站内灰底胶囊（与 .wp-seg 同语言） */
  .fg-card .md-seg,
  .fg-card .fg-stack .md-seg {
    background: var(--bg-muted); border: none; border-radius: 9999px; padding: 4px;
  }
  .fg-card .md-seg button,
  .fg-card .fg-stack .md-seg button {
    border-left: none; height: 36px; padding: 0 20px; border-radius: 9999px;
    font-size: 14px; color: var(--text-3); background: transparent;
  }
  .fg-card .md-seg button.active { background: var(--primary); color: var(--on-primary); font-weight: var(--fw-medium); }
  /* 开关行：复合选择器（同一元素两个类），拍平内衬灰底并补足 54px 表单行 */
  .fg-card .fg-switch.switch-row {
    background: transparent; border: none; border-radius: 0;
    padding: 0 16px; min-height: 54px;
  }
  .fg-card .fg-switch.switch-row .switch-label { font-size: 16px; color: var(--text-1); font-weight: var(--fw-medium); }
  /* 正文输入与预览：4px 直角 → 12px 内衬井，与卡片 16px 圆角成层级 */
  .fg-card textarea.form-input,
  .fg-card .md-body {
    border: none; border-radius: 12px; background: var(--bg-soft);
    padding: 12px 14px; font-size: 15px; line-height: 1.75;
  }
  .fg-card .md-body { min-height: 180px; max-height: none; }
  .fg-card .md-field-head { margin-bottom: 10px; }
}

/* ---- 已归档 / 回收站：条目卡片化（两端一致，画布已是灰底） ---- */
.trash-rows { gap: 10px; }
.trash-row {
  display: flex; align-items: center; gap: 12px;
  background: var(--bg-card); border: none; border-radius: 14px;
  padding: 12px 14px; box-shadow: var(--shadow-card);
}
.trash-row:last-child { border-bottom: none; }
.tr-main { flex: 1; min-width: 0; }
.trash-row .trash-title {
  flex: none; font-size: 15px; font-weight: var(--fw-medium); color: var(--text-1);
  line-height: 1.45; white-space: normal;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.tr-meta { display: flex; align-items: center; gap: 8px; margin-top: 5px; }
.tr-acts { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.trash-rows .cat-row-empty {
  background: var(--bg-card); border: none; border-radius: 14px;
  padding: 22px 16px; text-align: center;
  font-size: 14px; color: var(--text-4); box-shadow: var(--shadow-card);
}
@media (max-width: 768px) {
  .trash-rows { gap: var(--card-gap); max-height: none; overflow: visible; }
  .trash-row { border-radius: 16px; padding: 14px 16px; min-height: 66px; }
  .trash-row .trash-title { font-size: 16px; }
  .trash-row .btn-sm {
    height: 38px; padding: 0 16px; border-radius: 9999px;
    border: 1px solid var(--border-strong); background: transparent;
    color: var(--text-1); font-size: 14px;
  }
  .trash-row .btn-sm:active { background: var(--bg-hover); }
  .trash-row .cat-act { width: 40px; height: 40px; border-radius: 9999px; }
  /* 彻底删除：与左滑删除胶囊同一系危险色，避免「灰色垃圾桶看不出是删除」 */
  .trash-row .cat-act.cat-act-del { background: var(--tag-bad-bg); color: var(--tag-bad-fg); }
  .trash-row:active { transform: scale(.985); background: var(--bg-card); }
  .trash-row, .trash-rows .cat-row-empty { transition: transform .12s ease, background var(--transition-fast); }
}
@media (prefers-reduced-motion: reduce) {
  .trash-row:active { transform: none; }
}

/* ============================================================
   回顾详情 · 编辑排版 v2（2026-09-16）
   外壳走站内既有 .dd-modal（灰底画布），内容拆成白色圆角卡，
   与灰色背景形成图底分离；仅作用于 .diary-detail，待办/习惯
   详情共用类（detail-hero / detail-kv / detail-meta-line）不受影响。
   基调：黑白杂志——封面大日期 + 编号时间轴卡片 + 版权页脚
   ============================================================ */
.diary-detail { position: relative; color: var(--text-1); }

/* 封面卡：心情胶囊 + 眉标 + 大日期 */
.diary-detail .dd-cover {
  background: var(--bg-card); border-radius: 20px;
  padding: 18px 20px 22px; box-shadow: var(--shadow-card);
}
.diary-detail .dd-mood {
  display: inline-flex; align-items: center; gap: 6px;
  height: 24px; padding: 0 10px 0 8px; margin-bottom: 16px;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--bg-card);
  font-size: var(--fs-micro); color: var(--text-3); letter-spacing: .02em;
}
.diary-detail .dd-mood-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--mood, var(--text-4));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--mood, transparent) 18%, transparent);
}
.diary-detail .dd-mast { position: relative; }
.diary-detail .dd-eyebrow {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .28em; text-transform: uppercase;
  color: var(--text-4); margin-bottom: 12px;
}
.diary-detail .dd-dateline { display: flex; align-items: baseline; gap: 14px; }
.diary-detail .dd-day {
  font-family: var(--font-mono); font-weight: var(--fw-bold);
  font-size: 68px; line-height: .86; letter-spacing: -.04em;
  color: var(--text-1); font-variant-numeric: tabular-nums;
}
.diary-detail .dd-my {
  display: inline-flex; align-items: baseline; gap: 10px;
  font-size: var(--fs-body); color: var(--text-3); letter-spacing: .02em;
}
.diary-detail .dd-week {
  font-style: normal; padding-left: 10px; position: relative;
  color: var(--text-4); font-size: var(--fs-caption);
}
.diary-detail .dd-week::before {
  content: ''; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 1px; height: 12px; background: var(--border-strong);
}

/* 三问：每条一张白色卡，编号 + 短横刻度作时间轴导轨 */
.diary-detail .dd-entries { display: flex; flex-direction: column; gap: 12px; margin-top: 12px; }
.diary-detail .dd-entry {
  position: relative; display: grid;
  grid-template-columns: 40px 1fr; gap: 14px;
  background: var(--bg-card); border-radius: 16px; box-shadow: var(--shadow-card);
  padding: 16px 18px 16px 16px;
}
.diary-detail .dd-no {
  font-family: var(--font-mono); font-weight: var(--fw-semibold);
  font-size: 13px; letter-spacing: .04em;
  color: var(--text-4); padding-top: 2px;
  font-variant-numeric: tabular-nums;
}
.diary-detail .dd-no::after {
  content: ''; display: block; width: 14px; height: 1px;
  background: var(--border-strong); margin-top: 6px;
}
.diary-detail .dd-label {
  margin: 0 0 8px;
  font-family: var(--font-mono); font-size: 11px; font-weight: var(--fw-medium);
  letter-spacing: .22em; text-transform: uppercase; color: var(--text-4);
}
.diary-detail .dd-text {
  font-size: 15px; line-height: 1.8; color: var(--text-1);
  white-space: pre-wrap; word-break: break-word; letter-spacing: .01em;
}
.diary-detail .dd-text .dd-empty { color: var(--text-disabled); font-style: italic; }
.diary-detail .dd-entry.is-empty .dd-text { color: var(--text-disabled); }
.diary-detail .dd-entry.is-empty .dd-no { color: var(--text-disabled); }
.diary-detail .dd-entry.is-empty { background: color-mix(in srgb, var(--bg-card) 55%, var(--bg-page)); box-shadow: none; }

/* 版权页脚：细字直接落在灰底上 */
.diary-detail .dd-colophon {
  display: flex; align-items: center; gap: 10px; margin-top: 18px; padding-left: 4px;
  font-family: var(--font-mono); font-size: 11px;
  letter-spacing: .1em; color: var(--text-4);
}
.diary-detail .dd-rule { flex: 0 0 24px; height: 1px; background: var(--text-4); opacity: .5; }

/* 载入 stagger：封面 → 三问 → 页脚自上而下轻入，幅度克制 */
@media (prefers-reduced-motion: no-preference) {
  .diary-detail .dd-cover    { animation: dd-in .34s var(--ease-enter) both; }
  .diary-detail .dd-entry    { animation: dd-in .34s var(--ease-enter) both; }
  .diary-detail .dd-entry:nth-of-type(1) { animation-delay: .10s; }
  .diary-detail .dd-entry:nth-of-type(2) { animation-delay: .16s; }
  .diary-detail .dd-entry:nth-of-type(3) { animation-delay: .22s; }
  .diary-detail .dd-colophon { animation: dd-in .34s var(--ease-enter) .28s both; }
}
@keyframes dd-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* 手机端 ≤768：遵循手机端间距规范 v1.0（卡片内距/正文地板/触控目标） */
@media (max-width: 768px) {
  .diary-detail .dd-cover { border-radius: 18px; padding: 16px var(--card-pad) 18px; }
  .diary-detail .dd-day { font-size: 56px; letter-spacing: -.03em; }
  .diary-detail .dd-eyebrow { font-size: 10px; letter-spacing: .24em; margin-bottom: 10px; }
  .diary-detail .dd-my { font-size: 14px; gap: 8px; }
  .diary-detail .dd-week { font-size: 13px; padding-left: 8px; }
  .diary-detail .dd-entries { gap: var(--card-gap); margin-top: var(--card-gap); }
  .diary-detail .dd-entry {
    grid-template-columns: 34px 1fr; gap: 12px;
    border-radius: 16px; padding: var(--card-pad);
  }
  .diary-detail .dd-no { font-size: 12px; padding-top: 3px; }
  .diary-detail .dd-label { font-size: 10px; letter-spacing: .2em; margin-bottom: 6px; }
  .diary-detail .dd-text { font-size: 15px; line-height: 1.75; }
  .diary-detail .dd-colophon { margin-top: 16px; font-size: 10px; }
}

/* ============================================================
   回顾编辑 · 桌面端与详情同一套「灰底画布 + 白色圆角卡」语言
   （≤768 仍走 mobFormify 的 .wbf-modal + .fg-card，本块不介入）
   ============================================================ */
@media (min-width: 769px) {
  .diary-form { background: var(--bg-page); }
  .diary-form .modal-body { padding-bottom: 24px; }

  /* 顶层字段组各成一张白卡（嵌套在 head 行内的 .field 不重复套壳） */
  .diary-form .modal-body > .field,
  .diary-form .modal-body > .field-row {
    background: var(--bg-card); border-radius: 16px; box-shadow: var(--shadow-card);
    padding: 16px 18px; margin-bottom: 12px;
  }
  .diary-form .modal-body > .form-error { margin: 0; padding: 0 4px; }
  .diary-form .field-row .field { margin-bottom: 0; }

  /* 眉标式标签：等宽 + 字距，呼应详情三问导轨 */
  .diary-form .field > label,
  .diary-form .field-row > div > label {
    display: block; margin: 0 0 10px;
    font-family: var(--font-mono); font-size: 11px; font-weight: var(--fw-medium);
    letter-spacing: .18em; text-transform: uppercase; color: var(--text-4);
  }

  /* 输入：软底内衬，聚焦回白并描黑边 */
  .diary-form .form-input {
    background: var(--bg-soft); border-color: transparent; border-radius: 10px;
    transition: background var(--transition-fast), border-color var(--transition-fast), box-shadow var(--transition-fast);
  }
  .diary-form textarea.form-input { padding: 12px 14px; min-height: 68px; line-height: 1.7; font-size: 15px; resize: vertical; }
  .diary-form .form-input:hover { background: var(--bg-hover); }
  .diary-form .form-input:focus { background: var(--bg-card); border-color: var(--primary); }

  /* 头部：日期定宽 + 心情自适应 */
  .diary-form .field-diary-head { display: grid; grid-template-columns: 176px 1fr; gap: 20px; align-items: start; }
  .diary-form .mood-row { gap: 8px; }
  .diary-form .mood-btn { height: 36px; padding: 0 12px; }
  .diary-form .diary-bring { margin-top: 12px; gap: 14px; }
  .diary-form .diary-bring .btn-link {
    font-size: var(--fs-caption); color: var(--text-3);
    padding: 4px 10px; border: 1px solid var(--border); border-radius: 999px;
    transition: border-color var(--transition-fast), color var(--transition-fast);
  }
  .diary-form .diary-bring .btn-link:hover { border-color: var(--border-strong); color: var(--text-1); }
  .diary-form .field-hint { margin-top: 0; }
}

/* ============================================================
   手机端编辑表单统一规范 v1.0（2026-09-16，仅 ≤768px）
   ------------------------------------------------------------
   五个编辑弹窗（待办 / 事件 / 回顾 / 备忘 / 习惯）收口到同一套语言，
   基准取自已定稿的事件页：灰底画布 + 语义分组白卡。卡内只允许两种行：

     行式 .fg-row    单值控件（文本 / 下拉 / 日期 / 开关）
                     54px 行高、左标签右值、无边框、行间发丝线
     堆叠 .fg-stack  多行或复合控件（正文 / 子任务 / 心情 / 农历 / 色板）
                     上标签（13px --text-4）下「井」

   本块修掉的三类不统一（改前实测）：
     ① 分组：待办一张 895px 巨卡、回顾一张 726px 巨卡 vs 事件 4 张语义卡
        → mobFormify 按字段 data-fg 分组，桌面端 .fg-card 仍是 display:contents 零影响；
     ② 同类控件三种长相：日期在事件＝右对齐行、在回顾＝描边盒 44px 左对齐、
        在待办＝描边盒 40px 居中；下拉同理 → 行式一律无边框右对齐；
     ③ 「井」不存在：正文井用 --bg-soft(#FAFBFC) 落在白卡上几乎看不见，
        下拉 / 日期 / 子任务 / 添加步骤用 --bg-page + 1px 描边 + 4px 直角
        → 统一 --bg-muted 衬底 + 12px 圆角 + 无边框（与卡片 16px 圆角成层级）。

   选择器纪律：本块排在全部 ≤768 基线块之后，且与旧规则同特异性或更高
   （如 .fg-card .fg-stack .sub-add .form-input 必须写满四级，否则被 2719 行压死）。
   ============================================================ */
@media (max-width: 768px) {
  /* ---- ① 分组卡外壳 ---- */
  .wbf-modal .fg-card { border-radius: 16px; box-shadow: var(--shadow-card); margin-bottom: var(--card-gap); }

  /* ---- ② 行式：提示语与附加控件换到第二行，整行仍是左标签右值 ---- */
  .fg-card .fg-row { flex-wrap: wrap; }
  .fg-card .fg-row .field-hint,
  .fg-card .fg-row .field-extra { flex: 0 0 100%; }
  .fg-card .fg-row .field-hint { margin: -4px 0 14px; font-size: var(--fs-micro); line-height: 1.5; }
  .fg-card .fg-row .field-extra { margin: 2px 0 14px; }
  .fg-card .fg-row .field-extra:empty { display: none; margin: 0; }
  .fg-card .fg-row .wd-row { margin-top: 0; }
  .fg-card .fg-row .dom-row { margin-top: 0; }
  /* 开关行补足 54px 表单行（无描述项不再塌成 51px） */
  .fg-card .fg-switch .switch-row { min-height: 54px; }

  /* ---- ③ 井：卡内多行 / 复合控件的统一衬底 ---- */
  .fg-card .fg-stack .form-input,
  .fg-card .fg-stack textarea.form-input,
  .fg-card .fg-stack .md-body,
  .fg-card .fg-stack .sel-btn,
  .fg-card .fg-stack .dp-display {
    background: var(--bg-muted); border: 1px solid transparent; border-radius: 12px;
    box-shadow: none; color: var(--text-1); font-size: 15px;
  }
  /* 可输入的井一律 16px：iOS 聚焦小于 16px 的输入框会整页放大，且与行式输入框同字号
     （必须带上 textarea 限定：上面分组选择器里的 textarea 形式是 (0,3,1)，
       只写 .fg-stack .form-input 是 (0,3,0)，会被压回 15px —— 实测备忘/回顾正文井踩过） */
  .fg-card .fg-stack textarea.form-input,
  .fg-card .fg-stack .form-input { font-size: 16px; }
  .fg-card .fg-stack textarea.form-input { padding: 12px 14px; min-height: 96px; line-height: 1.75; resize: none; }
  .fg-card .fg-stack .sel-btn,
  .fg-card .fg-stack .dp-display { height: 46px; line-height: 44px; padding: 0 14px; text-align: left; }
  /* 箭头要落在 padding 之外：井里的下拉右内距 32px，否则长值会盖住小三角 */
  .fg-card .fg-stack .sel-btn { padding-right: 32px; }
  .fg-card .fg-stack .date-wrap .dp-display { padding-right: 40px; }
  .fg-card .fg-stack .select-wrap::after { right: 12px; }
  .fg-card .fg-stack .date-wrap .date-ico { right: 12px; }
  .fg-card .fg-stack .sel-btn.is-placeholder,
  .fg-card .fg-stack .dp-display.is-placeholder { color: var(--text-4); }
  .fg-card .fg-stack .form-input:focus,
  .fg-card .fg-stack .sel-btn:focus-visible,
  .fg-card .fg-stack .dp-display:focus-visible {
    background: var(--bg-card); border-color: var(--primary); box-shadow: 0 0 0 3px var(--focus-ring);
  }
  /* 农历三列：井同色；左右对称内距让短值真居中，箭头收在 right:10px */
  .fg-card .fg-stack .field-row-3 .sel-btn { height: 46px; padding: 0 26px; text-align: center; }
  .fg-card .fg-stack .field-row-3 .select-wrap::after { right: 10px; }

  /* ---- ④ 子任务：卡内无框行 + 发丝线；按住拖动排序，标题常可行内编辑 ---- */
  .fg-card .sub-editor { gap: 0; margin-bottom: 0; }
  .fg-card .sub-editor .sub-row {
    display: flex; align-items: center; gap: 10px; min-height: 52px;
    background: transparent; border: none; border-bottom: 1px solid var(--border);
    border-radius: 0; padding: 8px 0; transition: transform .18s var(--ease-enter);
  }
  .fg-card .sub-editor .sub-row:last-child { border-bottom: none; }
  .fg-card .sub-editor .sub-name { font-size: 16px; }
  .fg-card .sub-editor .sub-handle { width: 24px; height: 44px; flex: 0 0 24px; }
  .fg-card .sub-editor .sub-del { flex: 0 0 38px; width: 38px; height: 38px; }
  /* 拖起的那一行：浮起来跟手（transform 由 JS 实时写，别在这里写死会被覆盖） */
  .fg-card .sub-editor .sub-row.is-dragging {
    transition: none; padding: 8px 12px; margin: 0 -12px;
    background: var(--bg-card); border-bottom-color: transparent;
    border-radius: 12px; box-shadow: var(--shadow-float);
  }
  .fg-card .sub-editor.is-dragging-mode { user-select: none; -webkit-user-select: none; }
  .fg-card .fg-stack .sub-add { margin-top: 12px; gap: 8px; }
  .fg-card .fg-stack .sub-add .form-input,
  .fg-card .fg-stack .sub-add .btn {
    height: 46px; background: var(--bg-muted); border: 1px solid transparent;
    border-radius: 12px; color: var(--text-1); font-size: 15px;
  }
  .fg-card .fg-stack .sub-add .form-input { padding: 0 14px; font-size: 16px; }
  .fg-card .fg-stack .sub-add .btn { flex: 0 0 46px; width: 46px; padding: 0; }
  .fg-card .fg-stack .sub-add .form-input:focus { background: var(--bg-card); border-color: var(--primary); box-shadow: 0 0 0 3px var(--focus-ring); }
  .fg-card .fg-stack .sub-add .btn:active { transform: scale(.96); background: var(--bg-count); }

  /* ---- ⑤ 带入：纯文字链接 → 幽灵胶囊（与心情 chip 同语言） ---- */
  .fg-card .diary-bring { margin-top: 10px; align-items: center; flex-wrap: wrap; gap: 8px; }
  .fg-card .diary-bring .btn-link {
    display: inline-flex; align-items: center; height: 38px; padding: 0 14px;
    border: 1px solid var(--border-strong); border-radius: 9999px;
    background: transparent; color: var(--text-2); font-size: 13px; text-decoration: none;
    transition: border-color var(--transition-fast), color var(--transition-fast), transform .12s ease;
  }
  .fg-card .diary-bring .btn-link:hover { text-decoration: none; color: var(--text-2); border-color: var(--border-strong); }
  .fg-card .diary-bring .btn-link:active { transform: scale(.97); border-color: var(--primary); color: var(--text-1); }
  .fg-card .diary-bring .field-hint { flex: 1 1 auto; min-width: 0; margin: 0; }
}

/* 描述收起态（手机端）：整行按行式呈现，右侧「＋ 填写描述」是无框幽灵入口 */
@media (max-width: 768px) {
  .fg-card .desc-field.is-collapsed { min-height: 54px; }
  .fg-card .desc-field.is-collapsed .desc-toggle {
    border: none; background: transparent; border-radius: 0; padding: 8px 0;
    margin-left: auto; font-size: 15px; color: var(--text-4);
  }
  .fg-card .desc-field.is-collapsed .desc-toggle:active { color: var(--text-1); }
}

/* 子任务手柄 / 行内编辑 / 描述入口：两端共用（拖动排序在桌面端同样可用） */
.sub-handle {
  flex: 0 0 22px; width: 22px; height: 32px; padding: 0; border: none; background: transparent;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--text-4); opacity: .55; cursor: grab;
  touch-action: none; -webkit-user-select: none; user-select: none;
}
.sub-handle svg { width: 14px; height: 14px; }
.sub-handle:hover { opacity: .85; }
.sub-handle:active, .sub-row.is-dragging .sub-handle { cursor: grabbing; opacity: 1; }
.sub-row.is-dragging { position: relative; z-index: 3; }
/* 行内标题：无边框输入框，看起来就是这行文字本身，随时可改（含已完成的步骤） */
.sub-name {
  flex: 1; min-width: 0; border: none; background: transparent; box-shadow: none; outline: none;
  padding: 0; font-family: var(--font-sans); font-size: var(--fs-caption); color: var(--text-1);
  text-align: left; height: auto; min-height: 24px;
}
.sub-row.is-done .sub-name { color: var(--text-4); text-decoration: line-through; }
.desc-field .desc-toggle { display: none; }
.desc-field.is-collapsed > .form-input { display: none; }
.desc-field.is-collapsed .desc-toggle {
  display: inline-flex; align-items: center; gap: 4px; cursor: pointer;
  border: 1px dashed var(--border-strong); border-radius: var(--radius-btn);
  background: transparent; color: var(--text-3); font-size: var(--fs-caption); padding: 7px 12px;
  transition: border-color var(--transition-fast), color var(--transition-fast);
}
.desc-field.is-collapsed .desc-toggle:hover { border-color: var(--text-4); color: var(--text-1); }

/* 超窄屏（≤380）：只收缩字号与井内距，分组与行高不回退（间距规范 v1.0） */
@media (max-width: 380px) {
  .fg-card .fg-stack .sub-add .btn { flex: 0 0 44px; width: 44px; }
  .fg-card .diary-bring .btn-link { padding: 0 12px; font-size: 12.5px; }
  .fg-card .fg-stack .field-row-3 .sel-btn { padding: 0 18px; }
}

/* ============================================================
   打卡热力 · 手机端适配（遵循「手机端间距规范 v1.0」：
   4pt 网格、字号地板、icon 类触控目标 ≥38、主操作 ≥44）
   ============================================================ */
@media (max-width: 768px) {
  /* 卡片内本周格：铺满 7 等分，格间走 8pt 节奏 */
  .hb-heat { margin-top: var(--sp-3); }
  .hb-heat-head { margin-bottom: var(--sp-2); }
  .hb-heat-title, .hb-heat-sum { font-size: 12px; }
  .hm-week { gap: var(--sp-2); }
  .hm-col em { font-size: var(--fs-micro); }
  .hm-cell { font-size: 13px; }
  .hm-sq { max-width: none; }
  .hm-sq-lg { max-width: 44px; font-size: 15px; }

  /* 详情弹窗内的热力面板：整块按卡片内距收进「井」 */
  .hm-panel { margin-top: var(--module-gap); padding: var(--card-pad); border-radius: 14px; }
  .hm-nav { gap: 4px; margin-top: var(--sp-3); }
  .hm-nav .dp-nav { width: 38px; height: 38px; font-size: 18px; }
  .hm-range { font-size: 15px; }
  .hm-back { height: 34px; padding: 0 10px; font-size: 13px; }
  .hm-summ { margin: var(--sp-2) 0; font-size: 13px; }
  .hm-wkrow { gap: var(--sp-2); margin-bottom: var(--sp-2); max-width: 420px; }
  .hm-wkrow span { font-size: var(--fs-micro); }
  .hm-grid7 { gap: var(--sp-2); max-width: 420px; }
  .hm-day { font-size: 13px; border-radius: 6px; }

  /* 年视图：连续日期网格横向滚动，格子给到可点尺寸 */
  .hm-ygrid { grid-template-rows: repeat(7, 14px); grid-auto-columns: 14px; gap: 4px; }
  .hm-dot-c { width: 14px; height: 14px; }
  .hm-mlab { gap: 4px; }
  .hm-mlab i { width: 14px; font-size: 10px; }
  .hm-ylab { grid-template-rows: repeat(7, 14px); gap: 4px; padding-top: 18px; }
  .hm-ylab span { font-size: 10px; line-height: 14px; }

  /* 四档图例：与正文同地板，色块给到 14px */
  .hm-legend { margin-top: var(--sp-3); padding-top: var(--sp-3); gap: var(--sp-2) var(--sp-3); font-size: 12px; }
  .hm-legend .hm-cell { width: 14px; height: 14px; }

  /* 多次打卡控件：减一次为 icon 类目标 38，主钮沿用 40 高 */
  .hb-ctl { gap: var(--sp-2); }
  .hb-minus { width: 38px; height: 38px; }
  .hb-minus svg { width: 14px; height: 14px; }
  .hb-times { font-size: 13px; }
  .habit-meta { flex-wrap: wrap; gap: 10px; }
}

/* 触屏无 hover：热力面板控件按压反馈补齐 */
@media (hover: none) {
  .hm-back:hover { background: transparent; color: var(--text-4); }
  .hb-minus:hover { border-color: var(--border); background: var(--bg-card); color: var(--text-4); }
  .hb-minus:active { transform: scale(.94); }
}

/* 超窄屏（≤380）：只收缩年视图格宽，间距与字号地板不回退 */
@media (max-width: 380px) {
  .hm-ygrid { grid-template-rows: repeat(7, 13px); grid-auto-columns: 13px; }
  .hm-dot-c { width: 13px; height: 13px; }
  .hm-mlab i { width: 13px; }
}

/* ============================================================
   登录弹窗 → 底部抽屉（≤768，2026-09-16）
   与 wp-sheet / cf-sheet 抽屉同一骨架参数：贴底、顶圆角 24、
   .32s ease-enter 自下而上滑入，关闭 .28s 下滑退场，
   内距吃 --card-pad、底部垫安全区；
   必须排在文件末尾：压过基线 .login-mask/.login-pop 与
   前文 ≤768 的安全区 padding、≤600 padding 覆写。
   ============================================================ */
@media (max-width: 768px) {
  .login-mask {
    align-items: flex-end;
    padding: 0;
  }
  .login-pop {
    width: 100%; max-width: none;
    border: none;
    border-radius: 24px 24px 0 0;
    padding: 26px var(--card-pad) calc(22px + env(safe-area-inset-bottom, 0px));
    box-shadow: var(--shadow-modal);
    animation: loginSheetUp .32s var(--ease-enter);
  }
  .login-pop.is-closing { animation: loginSheetDown .28s ease-in forwards; }
  /* 通用抽屉「返回箭头替代 ×」把 .modal-x 整体隐藏，登录抽屉没有返回钮，× 必须回来 */
  .login-pop-x { display: flex; }
}
@keyframes loginSheetUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
@keyframes loginSheetDown { from { transform: translateY(0); } to { transform: translateY(100%); } }

/* 减动效：排在末尾的手机端规则必须在同位置归零，
   否则会反压文件前部的 prefers-reduced-motion 块 */
@media (max-width: 768px) and (prefers-reduced-motion: reduce) {
  .login-mask, .login-pop, .login-mask.is-closing, .login-pop.is-closing { animation: none; }
}

/* ============================================================
   自建取色抽屉 · 手机端（间距规范 v1.0：主操作 ≥44、iOS 输入字号 ≥16px）
   ============================================================ */
@media (max-width: 768px) {
  .cp-sheet { padding-top: 20px; }
  .cp-stage { margin-bottom: var(--sp-4); }
  .cp-sv { height: 172px; }
  .cp-hue { height: 30px; margin-top: var(--sp-3); }
  .cp-thumb { width: 24px; height: 24px; }
  .cp-hex-row { margin-top: var(--sp-4); gap: var(--sp-2); }
  .cp-hex-k { font-size: 15px; }
  .cp-hex { height: 46px; font-size: 16px; } /* 小于 16px 会触发 iOS 聚焦整页放大 */
  .cp-sheet .wp-foot { margin-top: var(--module-gap); }
  .cat-swatch-custom.is-filled .habit-check { width: 16px; height: 16px; }
}
/* 排在末尾的手机端规则必须在同位置归零，否则会反压前部 prefers-reduced-motion 块 */
@media (max-width: 768px) and (prefers-reduced-motion: reduce) {
  .cp-chip, .cp-ramp i, .cp-thumb { transition: none; }
}

/* ============================================================
   首次访问引导 → 底部抽屉（≤768，2026-09-16）
   与 .login-pop / .wp-sheet 同一抽屉骨架：贴底、顶圆角 24、
   .32s ease-enter 自下而上、关闭 .26s 下滑淡出，
   内距吃 --content-px（画布 16）＋底部安全区，卡内仍是
   「灰底画布 + 白圆角分组卡 + dd-row 图标行」语言。
   主操作 48（≥44）、昵称井 54（表单行）、输入 18px（iOS ≥16）。
   必须排在文件末尾：压过基线 .ob-mask/.ob-card 与前置 ≤768 覆写。
   ============================================================ */
@media (max-width: 768px) {
  .ob-mask { align-items: flex-end; padding: 0; }
  .ob-card {
    width: 100%; max-width: none; border: none;
    max-height: calc(100dvh - 2 * var(--content-px));
    border-radius: 24px 24px 0 0;
    padding: 20px var(--content-px) calc(18px + env(safe-area-inset-bottom, 0px));
    animation: obSheetUp .32s var(--ease-enter);
  }
  .ob-card.is-out { animation: obSheetDown .26s ease-in forwards; }
  .ob-head { padding: 0 0 var(--sp-3); }
  .ob-back { width: 38px; height: 38px; margin-left: -9px; } /* icon 类触控 ≥38 */
  .ob-title { font-size: 20px; }
  .ob-foot { margin-top: var(--module-gap); }
  .btn.ob-go { height: 50px; }
  .ob-form .ob-ninput { height: 54px; font-size: 18px; }
  @keyframes obSheetUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
  @keyframes obSheetDown { from { transform: translateY(0); } to { transform: translateY(100%); } }
}
/* 触屏无 hover：引导层控件按压即反馈，悬停态一律退回基线 */
@media (hover: none) {
  .ob-back:hover { background: transparent; color: var(--text-3); }
  .ob-back:active { background: var(--bg-hover); }
  .ob-feat:active { background: var(--bg-hover); }
  .btn.ob-go:active { transform: scale(.985); }
}
/* 超窄屏（≤380）：只收字号与页眉副标，画布 16 / 卡内 16·14 间距不回退 */
@media (max-width: 380px) {
  .ob-card { max-height: calc(100dvh - var(--content-px)); }
  .ob-tag { font-size: 12px; }
  .ob-title { font-size: 19px; }
  .ob-desc { font-size: 15px; }
}
/* 排在末尾的手机端规则必须在同位置归零，否则会反压前部 prefers-reduced-motion 块 */
@media (max-width: 768px) and (prefers-reduced-motion: reduce) {
  .ob-mask, .ob-card, .ob-card.is-out, .ob-mask.is-out,
  .ob-step, .ob-step > *, .ob-form.bad { animation: none; }
}

/* ============================================================
   备忘标签条 / 待办分类条 · 单行横滑 + 「全部…」浮层（2026-09-16）
   标签/分类只增不减，换行会无限占高：收成一横行滑区，溢出靠
   左右渐隐提示，全量收进浮层（手机 wp-sheet 抽屉 / 桌面 dd-modal）。
   scope 到 .memo-tagbar / .todo-catbar / .date-typebar 与 .tag-pick* / .cat-list。
   ============================================================ */
.memo-tagbar, .todo-catbar, .date-typebar { flex-wrap: nowrap; min-width: 0; }
.memo-tagbar .chip-scroll, .todo-catbar .chip-scroll, .date-typebar .chip-scroll {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; gap: 8px;
  overflow-x: auto; overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none; -ms-overflow-style: none;
  scroll-padding: 0 12px;
}
.memo-tagbar .chip-scroll::-webkit-scrollbar, .todo-catbar .chip-scroll::-webkit-scrollbar, .date-typebar .chip-scroll::-webkit-scrollbar { display: none; }
.memo-tagbar .chip-scroll .chip, .todo-catbar .chip-scroll .chip, .date-typebar .chip-scroll .chip { flex: 0 0 auto; }
/* 边缘渐隐：由 JS 按滚动位置挂 tgf-l / tgf-r，未溢出不加遮罩 */
.memo-tagbar .chip-scroll.tgf-l, .todo-catbar .chip-scroll.tgf-l, .date-typebar .chip-scroll.tgf-l {
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 16px, #000 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 16px, #000 100%);
}
.memo-tagbar .chip-scroll.tgf-r, .todo-catbar .chip-scroll.tgf-r, .date-typebar .chip-scroll.tgf-r {
  -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 16px), transparent 100%);
          mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 16px), transparent 100%);
}
.memo-tagbar .chip-scroll.tgf-l.tgf-r, .todo-catbar .chip-scroll.tgf-l.tgf-r, .date-typebar .chip-scroll.tgf-l.tgf-r {
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
}
/* 固定「全部…」入口：不参与收缩，压在滚动区右侧 */
.memo-tagbar .chip-more, .todo-catbar .chip-more, .date-typebar .chip-more { flex: 0 0 auto; color: var(--text-3); }
.memo-tagbar .chip-more svg, .todo-catbar .chip-more svg, .date-typebar .chip-more svg { width: 13px; height: 13px; }
@media (max-width: 768px) {
  .memo-tagbar .chip-more svg, .todo-catbar .chip-more svg, .date-typebar .chip-more svg { width: 15px; height: 15px; }
  .memo-tagbar .chip-scroll, .todo-catbar .chip-scroll, .date-typebar .chip-scroll { scroll-padding: 0 var(--content-px); }
}

/* 浮层内容：白卡内 chip 全量平铺（复用 .chip 壳，不另造样式） */
.tag-pick-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px 2px; }
.tag-pick-cap { font-size: var(--fs-micro); color: var(--text-4); }
.tag-pick-head.no-sel #tpClear { display: none; }
.tag-pick { display: flex; flex-wrap: wrap; gap: 10px; padding: 10px 16px 14px; }
.tag-pick-empty { padding: 6px 16px 14px; color: var(--text-4); font-size: 14px; }
/* 管理入口：dd-row 语言的内联行（图标 + 文本 + 右箭头），替代旧底部固定栏 */
.tp-mgr {
  width: 100%; text-align: left; cursor: pointer;
  border: 0; border-top: 1px solid var(--border); border-radius: 0;
  background: none; color: inherit; font: inherit;
  transition: background var(--transition-fast);
}
.tp-mgr:hover, .tp-mgr:active { background: var(--bg-hover); }
.tp-chev { flex: none; width: 16px; height: 16px; color: var(--text-disabled); }
.tp-chev svg { width: 16px; height: 16px; }
/* —— 手机端底部抽屉：与滚轮时间选择器同款 .wp-mask/.wp-sheet 壳，网格 56vh 比滚轮窗更高 —— */
.tp-sheet .tp-grid {
  display: flex; flex-wrap: wrap; align-content: flex-start; gap: 10px;
  min-height: 40vh; max-height: 56vh; overflow-y: auto; margin-bottom: 14px;
  -webkit-overflow-scrolling: touch;
}
.tp-sheet .tps-mgr { width: 100%; margin-bottom: 14px; }
.tp-sheet .wp-btn-cancel.is-off { opacity: .45; pointer-events: none; }
/* 全部分类浮层行组：桌面进白卡加衬；手机抽屉保底高度（同标签抽屉的「更长」取向） */
.dd-group .cat-list { padding: 12px 12px 0; margin-bottom: 0; }
.tp-sheet .cat-list { min-height: 32vh; max-height: 56vh; }
/* —— 手机端体检补丁：触控地板 ≥38（热区扩展走 .modal-head-act ::after 先例，视觉尺寸不动）—— */
@media (max-width: 768px) {
  .cat-swatch::after { content: ""; position: absolute; inset: -4px; } /* 30px 色块 → 38px 热区，正好吃掉 8px 间隙、互不重叠 */
  .tag-pick-head #tpClear { position: relative; }
  .tag-pick-head #tpClear::after { content: ""; position: absolute; inset: -11px; }
  .pf-login-act { min-height: 38px; }
}

/* 取色抽屉 · 桌面形态：同一套外壳转成居中对话框。
   特异性必须压过 .wp-sheet（width:100% / 24px 顶圆角 / translateY 贴底），故带 .wp-mask 前缀且排在其后 */
@media (min-width: 769px) {
  .wp-mask.cp-mask { align-items: center; justify-content: center; }
  .wp-mask .cp-sheet {
    width: 420px; max-width: calc(100vw - 48px);
    border-radius: 20px; padding: 22px 22px 20px;
    transform: translateY(10px) scale(.985); opacity: 0;
    transition: transform .28s var(--ease-enter), opacity .22s ease;
  }
  .wp-mask.cp-mask.is-open .cp-sheet { transform: none; opacity: 1; }
  .wp-mask .cp-sv { height: 168px; }
}

/* ============================================================
   详情热力 · 动效卡顿修正
   ============================================================ */
/* 内联操作区（mobDetailify 事后挂进 body 的「编辑 / 删除」）：
   吃到 .modal-body > *:nth-child(n) 的错峰延迟，会在弹窗开完后「晚一拍冒出来」，
   看着就是闪一下。这里给它独立的零延迟淡入，必须排在级联规则之后才能压住同特异性 */
@media (max-width: 768px) {
  .modal-card.cascade .modal-body > .dd-foot-inline,
  .modal-card.chain-in .modal-body > .dd-foot-inline {
    animation: ddFootIn .24s var(--ease-enter);
  }
}
@keyframes ddFootIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .modal-card.cascade .modal-body > .dd-foot-inline,
  .modal-card.chain-in .modal-body > .dd-foot-inline { animation: none; }
}

/* ============================================================
   分类 / 标签管理卡改版（2026-09-16）
   旧 dc-block 扁平 → dd-modal 语言：白卡 + tb-head 图标行首 +
   dd-row 发丝线条目 + 行内编辑区（井式输入 + 色板 + 双按钮）。
   条目行 = .mg-row；操作钮 = .mg-act（38px 触控）；编辑器 = .mg-edit。
   ============================================================ */
.mg-row .dd-k { font-size: 15px; }
.mg-row .dd-v { flex: none; max-width: none; margin-left: auto; }
.mg-act {
  flex: none; width: 38px; height: 38px; margin-right: -8px;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; background: transparent; border-radius: 10px;
  color: var(--text-4); cursor: pointer;
  transition: background var(--transition-fast);
}
.mg-act svg { width: 16px; height: 16px; }
.mg-act:active { background: var(--bg-hover); }
.mg-act-del { color: var(--tag-bad-fg); }
/* 行内编辑区：从被编辑的行下方长出来，与列表同一张白卡 */
.mg-edit { border-top: 1px solid var(--border); padding: 14px 16px 16px; }
.mg-edit-top { display: flex; align-items: center; gap: 10px; }
.mg-edit-top .mg-well { flex: 1; min-width: 0; }
.mg-edit-top .tag { flex: none; max-width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mg-arrow { flex: none; color: var(--text-4); font-size: 15px; }
.mg-well {
  border: none; background: var(--bg-muted); border-radius: 12px;
  height: 46px; padding: 0 14px; font-size: 16px; color: var(--text-1);
  transition: box-shadow var(--transition-fast);
}
.mg-well:focus { outline: none; box-shadow: 0 0 0 2px var(--border-strong); }
.mg-well::placeholder { color: var(--text-4); }
.mg-edit .cat-palette { margin-top: 12px; }
.mg-edit-acts { display: flex; gap: 10px; margin-top: 14px; }
.mg-edit-acts .btn { flex: 1; height: 44px; border-radius: 12px; justify-content: center; font-size: 15px; }
.mg-empty { padding: 26px 16px; text-align: center; color: var(--text-4); font-size: 14px; }
/* 单卡弹窗（管理/浮层）首卡不带 12px 顶距（同 .tb-card:first-child 先例） */
.dd-modal .modal-body > .dd-group:first-child { margin-top: 0; }

/* 管理抽屉（分类/标签 · 手机）：行组通铺抵消 sheet 16px 内衬，列表区 52vh 内滚动 */
.mgr-sheet .mg-inner { margin: 0 -16px 4px; max-height: 52vh; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.mgr-sheet .wp-foot { margin-top: 16px; }

/* 管理抽屉叠在选择抽屉上时：透明遮罩（暗底由下层负责），只承接点击与动画 */
.wp-mask.wp-mask-bare { background: transparent; }

/* ============================================================
   管理抽屉 · 行级直改（样板：标签管理，2026-09-17）
   点行即改：名称原地变常驻输入（子任务行 input 同款思路），
   行高不变 → 键盘抬升只动一次，无展开跳动。
   ============================================================ */
.mg-row[data-tag] { cursor: text; -webkit-tap-highlight-color: transparent; }
.mg-row[data-tag]:active { background: var(--bg-hover); }
.mg-inline {
  flex: 1; min-width: 0; width: auto; height: auto; padding: 0;
  border: none; border-bottom: 1.5px solid transparent; border-radius: 0;
  background: transparent; outline: none;
  font: inherit; font-size: 16px; color: var(--text-1); caret-color: var(--primary);
  transition: border-color var(--transition-fast);
}
.mg-row.is-editing .mg-inline { border-bottom-color: var(--primary); }
.mg-row.is-editing .dd-v { opacity: .55; }

/* 行级直改推广到分类/类型：色点可点（14px 视觉 + ::after 热区到 38px）、迷你色板条 */
.mg-row[data-id] { cursor: text; -webkit-tap-highlight-color: transparent; }
.mg-row[data-id]:active { background: var(--bg-hover); }
.mg-dot {
  width: 14px; height: 14px; border: none; padding: 0; cursor: pointer;
  position: relative; flex-shrink: 0; border-radius: 50%;
  -webkit-tap-highlight-color: transparent;
}
.mg-dot::after { content: ""; position: absolute; inset: -12px; } /* 14px 色点 → 38px 热区 */
.mg-palette { padding: 0 16px 12px; }
.mg-palette .cat-palette { margin-top: 0; }

/* ============================================================
   概览 · 今日时间线 v1.0（2026-09-17）
   ------------------------------------------------------------
   取代原「KPI 六卡 + 进度环 + 四张面板」。一屏只回答两件事：
   今天该做什么（时间线一条流）、做得怎么样（hero 进度条）。
   · hero 是全站唯一一张反白卡，用它压住整页层级
   · 时间线：图标列 + 贯穿轨道线 = 一条「今天」的流水
   · 洞察三卡合并成一张「本周」；数据说明迁到「关于」(.ab-*)
   桌面 ≥1024 走「左内容 / 右本周」两栏；手机端单列走间距规范 v1.0。
   ============================================================ */

/* ---- 1. 今日 hero（白卡：层级靠字号、进度条与主胶囊的黑色块承担） ---- */
.ov-day {
  --ovd-bg: var(--bg-card);
  --ovd-ink: var(--text-1);
  --ovd-dim: var(--text-3);
  --ovd-faint: var(--text-4);
  --ovd-line: var(--border);
  --ovd-well: var(--bg-muted);
  background: var(--ovd-bg); color: var(--ovd-ink);
  border: 1px solid var(--ovd-line); border-radius: var(--radius-lg);
  padding: 22px 24px 18px; box-shadow: var(--shadow-card);
}
.ov-day-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px 16px; flex-wrap: wrap; }
.ov-hi { margin: 0; font-size: 24px; font-weight: var(--fw-bold); line-height: 1.25; letter-spacing: -.02em; }
.ov-date { margin: 0; font-size: var(--fs-caption); color: var(--ovd-dim); font-variant-numeric: tabular-nums; }
.ov-meter { margin-top: 18px; }
.ov-meter-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.ov-meter-l { font-size: var(--fs-label); letter-spacing: .06em; color: var(--ovd-faint); }
.ov-meter-l em { font-style: normal; margin-left: 6px; color: var(--ovd-dim); letter-spacing: 0; }
.ov-meter-n { font-size: var(--fs-caption); color: var(--ovd-dim); font-variant-numeric: tabular-nums; }
.ov-meter-n b { font-size: 15px; font-weight: var(--fw-semibold); color: var(--ovd-ink); }
.ov-meter-track { display: block; height: 7px; margin-top: 8px; border-radius: 999px; background: var(--ovd-well); overflow: hidden; }
.ov-meter-fill { display: block; height: 100%; border-radius: 999px; background: var(--ovd-ink); transition: width .55s var(--ease-float); }
.ov-status { display: block; margin-top: 10px; padding-left: 13px; text-indent: -13px; font-size: var(--fs-caption); line-height: 1.6; color: var(--ovd-dim); }
.ov-status-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; margin-right: 7px; vertical-align: 1px; background: var(--warning); box-shadow: 0 0 0 3px rgba(245, 158, 11, .2); }
.ov-status.is-clear .ov-status-dot { background: var(--ovd-ink); box-shadow: 0 0 0 3px var(--ovd-well); }
.ov-quote { display: flex; align-items: flex-start; gap: 9px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--ovd-line); flex: none; color: var(--ovd-dim); }
.ov-quote-ico { width: 16px; height: 16px; color: var(--ovd-faint); flex-shrink: 0; margin-top: 3px; }
.ov-quote-text { font-size: var(--fs-body); line-height: 1.6; color: var(--ovd-dim); white-space: normal; overflow: visible; text-overflow: clip; }

/* 快捷录入：单行横滑胶囊（概览不在 dock 内、也无 FAB） */
.ov-quick {
  display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; flex-shrink: 1;
  margin-top: 14px; padding-bottom: 2px;
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.ov-quick::-webkit-scrollbar { display: none; }
.ov-quick.tgf-l { -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 20px); mask-image: linear-gradient(90deg, transparent 0, #000 20px); }
.ov-quick.tgf-r { -webkit-mask-image: linear-gradient(270deg, transparent 0, #000 20px); mask-image: linear-gradient(270deg, transparent 0, #000 20px); }
.ov-quick.tgf-l.tgf-r {
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 20px, #000 calc(100% - 20px), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 20px, #000 calc(100% - 20px), transparent 100%);
}
.qbtn {
  display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0;
  height: 34px; padding: 0 13px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--ovd-line); background: transparent; color: var(--ovd-dim);
  font-family: inherit; font-size: var(--fs-caption); white-space: nowrap;
  transition: background var(--transition-fast), color var(--transition-fast),
              border-color var(--transition-fast), transform .12s ease;
}
.qbtn svg { width: 14px; height: 14px; flex-shrink: 0; }
.qbtn-lead { background: var(--ovd-ink); color: var(--ovd-bg); border-color: var(--ovd-ink); font-weight: var(--fw-medium); }
@media (hover: hover) and (pointer: fine) {
  .qbtn:hover { background: var(--ovd-well); color: var(--ovd-ink); border-color: var(--ovd-dim); }
  .qbtn-lead:hover { background: var(--ovd-ink); color: var(--ovd-bg); border-color: var(--ovd-ink); opacity: .88; }
}
.qbtn:active { transform: scale(.95); }

/* ---- 2. 今日时间线 ---- */
#ovTimeline { margin-top: var(--module-gap); }
.tl-group { display: flex; align-items: center; gap: 8px; margin: 22px 0 10px; }
#ovTimeline > .tl-group:first-child { margin-top: 0; }
.tl-group-l { font-size: var(--fs-label); font-weight: var(--fw-semibold); letter-spacing: .08em; color: var(--text-3); flex-shrink: 0; }
.tl-group-n {
  flex-shrink: 0; min-width: 18px; height: 18px; padding: 0 6px; border-radius: 999px;
  background: var(--bg-count); color: var(--text-4);
  font-family: var(--font-mono); font-size: var(--fs-micro); line-height: 18px;
  display: inline-flex; align-items: center; justify-content: center; font-variant-numeric: tabular-nums;
}
.tl-group::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.tl-group.is-bad .tl-group-l { color: var(--tag-bad-fg); }
.tl-group.is-bad .tl-group-n { background: var(--tag-bad-bg); color: var(--tag-bad-fg); }

.tl-item {
  position: relative; display: flex; align-items: center; gap: 12px;
  margin-bottom: 10px; padding: 12px 14px 12px 12px;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-card); box-shadow: var(--shadow-card);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast),
              transform .14s var(--ease-float), opacity .2s ease;
}
/* 贯穿轨道：1px 竖线落在图标列中心，被不透明的图标底盘截断 */
.tl-item::before {
  content: ""; position: absolute; left: 25px; top: -11px; bottom: -11px;
  width: 1px; background: var(--border);
}
.tl-group + .tl-item::before { top: 50%; }
.tl-item:last-child::before,
.tl-item:has(+ .tl-group)::before,
.tl-item:has(+ .tl-more)::before,
.tl-item:has(+ .tl-empty)::before { bottom: 50%; }
.tl-item[data-tl-id] { cursor: pointer; }
@media (hover: hover) and (pointer: fine) {
  .tl-item[data-tl-id]:hover { border-color: var(--border-strong); box-shadow: var(--shadow-hover); }
  .tl-item[data-tl-id]:hover .tl-title { color: var(--primary); }
}
.tl-item:active { transform: scale(.99); }
.tl-ico {
  position: relative; z-index: 1; flex-shrink: 0;
  width: 26px; height: 26px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-card); border: 1px solid var(--border); color: var(--text-4);
}
.tl-ico svg { width: 14px; height: 14px; }
.tl-todo .tl-ico { color: var(--text-2); }
.tl-item.is-overdue .tl-ico { background: var(--tag-bad-bg); border-color: transparent; color: var(--tag-bad-fg); }
.tl-item.is-done { background: var(--bg-soft); box-shadow: none; }
.tl-item.is-done .tl-title { color: var(--text-3); }
.tl-item.is-done .tl-ico { border-color: transparent; background: var(--bg-count); }
.tl-item.is-hit { border-color: color-mix(in srgb, var(--warning) 50%, var(--border)); }
.tl-item.is-pending { background: transparent; border-style: dashed; box-shadow: none; }
.tl-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.tl-title { font-size: var(--fs-body); font-weight: var(--fw-medium); color: var(--text-1); line-height: 1.4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tl-meta { display: flex; align-items: center; min-width: 0; overflow: hidden; font-size: var(--fs-micro); color: var(--text-4); line-height: 1.5; white-space: nowrap; }
.tl-meta > span { flex-shrink: 0; }
.tl-meta .cat-dot { vertical-align: 0; }
.tl-sep { margin: 0 5px; color: var(--text-disabled); }
.tl-strong { color: var(--tag-warn-fg); font-weight: var(--fw-medium); }
/* 摘要是整行唯一可收缩项：空间不够时它自己出省略号，不连累前面的色点与分类 */
.tl-desc { min-width: 2.5em; max-width: 12em; flex-shrink: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tl-act { flex-shrink: 0; display: flex; align-items: center; gap: 8px; }

/* 行内完成：空圈 → 悬停点亮，语义即「把这件事划掉」 */
.tl-check {
  position: relative; width: 30px; height: 30px; padding: 0; flex-shrink: 0;
  border-radius: 50%; cursor: pointer;
  border: 1.5px solid var(--border-strong); background: var(--bg-card); color: var(--text-disabled);
  display: inline-flex; align-items: center; justify-content: center;
  transition: border-color var(--transition-fast), color var(--transition-fast),
              background var(--transition-fast), transform .12s ease;
}
.tl-check svg { width: 15px; height: 15px; }
@media (hover: hover) and (pointer: fine) {
  .tl-check:hover { border-color: var(--primary); color: var(--primary); background: var(--bg-hover); }
}
.tl-check:active { transform: scale(.88); background: var(--primary); border-color: var(--primary); color: var(--on-primary); }

.tl-tag {
  padding: 3px 8px; border-radius: var(--radius-badge); background: var(--bg-muted);
  color: var(--text-3); font-size: var(--fs-micro); white-space: nowrap; font-variant-numeric: tabular-nums;
}
.tl-tag.is-warn { background: var(--tag-warn-bg); color: var(--tag-warn-fg); }
.tl-tag.is-bad { background: var(--warning); color: #FFFFFF; font-weight: var(--fw-medium); }
.tl-mini {
  height: 28px; padding: 0 12px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--primary); background: transparent; color: var(--primary);
  font-family: inherit; font-size: var(--fs-caption);
  transition: background var(--transition-fast), color var(--transition-fast);
}
@media (hover: hover) and (pointer: fine) {
  .tl-mini:hover { background: var(--primary); color: var(--on-primary); }
}
.tl-more {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%;
  margin: 0 0 10px; padding: 9px 14px 9px 51px; cursor: pointer;
  border: 1px dashed var(--border-strong); border-radius: var(--radius-card);
  background: transparent; color: var(--text-3); font-family: inherit; font-size: var(--fs-caption);
  transition: border-color var(--transition-fast), color var(--transition-fast), background var(--transition-fast);
}
.tl-more-go { color: var(--text-4); font-size: var(--fs-micro); flex-shrink: 0; }
@media (hover: hover) and (pointer: fine) {
  .tl-more:hover { border-color: var(--text-4); color: var(--text-1); background: var(--bg-hover); }
}
.tl-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  padding: 34px 16px; text-align: center;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-card); box-shadow: var(--shadow-card);
  color: var(--text-4); font-size: var(--fs-caption);
}
.tl-empty .empty-ico { width: 32px; height: 32px; margin: 0 0 4px; }
.tl-empty-t { font-size: var(--fs-body); font-weight: var(--fw-medium); color: var(--text-2); }
.tl-empty-acts { display: flex; gap: 10px; margin-top: 12px; }

/* ---- 3. 本周（趋势 + 分布 + 模块计数，三卡合一） ---- */
.ov-week-sum { font-size: var(--fs-label); font-weight: var(--fw-regular); color: var(--text-4); }
.ov-week-sum b { color: var(--text-1); font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.ov-week-body { display: grid; grid-template-columns: 1.05fr 1fr; gap: 24px; }
.ov-week-col { min-width: 0; }
.ov-week-l { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; font-size: var(--fs-label); color: var(--text-4); }
.ov-week-l > span { font-weight: var(--fw-medium); color: var(--text-3); }
.ov-week-l .insight-empty { min-height: 92px; }
.ov-week-foot { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
.ov-week-foot button {
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: inherit; font-size: var(--fs-caption); color: var(--text-4);
  transition: color var(--transition-fast);
}
.ov-week-foot button b { color: var(--text-2); font-family: var(--font-mono); font-weight: var(--fw-medium); font-variant-numeric: tabular-nums; }
@media (hover: hover) and (pointer: fine) {
  .ov-week-foot button:hover { color: var(--text-1); }
}

/* 桌面：左内容 + 右本周（把 1000px 宽度用起来，时间线不再被拉成空长条） */
@media (min-width: 1024px) {
  #view-overview { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 24px; align-items: start; }
  #view-overview > #ovHero, #view-overview > #ovTimeline { grid-column: 1; min-width: 0; }
  #view-overview > #insightGrid { grid-column: 2; grid-row: 1 / span 3; margin-top: 0; }
  .ov-week-body { grid-template-columns: 1fr; gap: 18px; }
}

/* ---- 4. 手机端（≤768）：间距规范 v1.0 ---- */
@media (max-width: 768px) {
  .ov-day { padding: 18px var(--card-pad) 16px; }
  .ov-hi { font-size: 22px; }
  .ov-date { font-size: 12px; }
  .ov-meter { margin-top: var(--module-gap); }
  .ov-quote { margin-top: var(--module-gap); padding-top: 14px; }
  .ov-quote-text { font-size: 15px; }
  .qbtn { height: 38px; padding: 0 14px; font-size: 13px; }        /* icon 类触控 ≥38 */
  .qbtn svg { width: 15px; height: 15px; }

  #ovTimeline { margin-top: var(--module-gap); }
  .tl-group { margin: var(--module-gap) 0 var(--card-gap); }
  .tl-item { padding: 14px var(--card-pad) 14px 14px; margin-bottom: var(--card-gap); }
  .tl-item::before { left: 27px; }                                  /* 14 + 26/2，图标列中心 */
  .tl-title { font-size: 16px; }                                    /* 与列表卡片主标同档 */
  .tl-meta { font-size: 12px; }                                     /* 次级 12px 地板 */
  .tl-desc { max-width: 8em; }                                      /* 省略号落在摘要自身 */
  .tl-check { width: 38px; height: 38px; }
  .tl-check::after { content: ""; position: absolute; inset: -3px; } /* 热区 44 */
  .tl-check svg { width: 17px; height: 17px; }
  .tl-mini { height: 38px; padding: 0 16px; font-size: 14px; }
  .tl-tag { font-size: 12px; padding: 4px 9px; }
  .tl-more { min-height: 44px; padding-left: 51px; margin-bottom: var(--card-gap); font-size: 13px; }
  .tl-item:active { transform: scale(.985); }

  .ov-week-body { grid-template-columns: 1fr; gap: var(--module-gap); }
  .ov-week-foot { gap: 10px 16px; margin-top: var(--module-gap); }
  .ov-week-foot button { min-height: 32px; font-size: 13px; }
  .ov-bars { padding-top: 0; }
}

/* ---- 5. 关于（个人中心 → 设置 → 关于）：沿用 dd-modal 详情页语言 ---- */
.ab-brand { display: flex; align-items: center; gap: 16px; }
.ab-logo { width: 56px; height: 56px; flex-shrink: 0; border-radius: 15px; overflow: hidden; display: block; box-shadow: var(--shadow-card); }
.ab-logo svg { width: 100%; height: 100%; display: block; }
.ab-id { min-width: 0; }
.ab-name { font-size: 22px; font-weight: var(--fw-bold); color: var(--text-1); line-height: 1.2; letter-spacing: -.01em; }
.ab-badge { display: flex; align-items: center; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.ab-ver { display: inline-flex; align-items: center; height: 22px; padding: 0 9px; border-radius: 9999px;
  background: var(--primary); color: var(--on-primary); font-size: var(--fs-micro); font-weight: var(--fw-semibold);
  font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.ab-dot { color: var(--text-4); font-size: var(--fs-micro); }
.ab-date { font-size: var(--fs-caption); color: var(--text-3); font-variant-numeric: tabular-nums; }
.ab-slogan { margin-top: 8px; font-size: var(--fs-caption); color: var(--text-4); }
.ab-text { padding: 14px 16px; font-size: var(--fs-caption); line-height: 1.85; color: var(--text-2); }
.ab-text b { color: var(--text-1); font-weight: var(--fw-medium); }
.ab-copy { text-align: center; margin-top: 20px; font-size: var(--fs-micro); color: var(--text-4); letter-spacing: .02em; }
.pf-chip-ver { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
@media (max-width: 768px) {
  .ab-text { font-size: 14px; padding: var(--card-pad); }
  .ab-brand { gap: 14px; }
}

/* 更新日志（整屏层内容语言：白圆角卡列表） */
.cl-list { padding: 2px 2px 0; }
.cl-item { background: var(--bg-card); border-radius: 16px; box-shadow: var(--shadow-card); padding: 14px 16px 16px; margin-bottom: 12px; }
.cl-head { display: flex; align-items: center; gap: 8px; }
.cl-ver { font-family: var(--font-mono); font-size: 15px; font-weight: var(--fw-bold); color: var(--text-1); font-variant-numeric: tabular-nums; }
.cl-date { font-size: var(--fs-caption); color: var(--text-4); font-variant-numeric: tabular-nums; }
.cl-cur { margin-left: auto; font-size: var(--fs-micro); font-weight: var(--fw-medium); color: var(--on-primary); background: var(--primary); border-radius: 9999px; padding: 2px 9px; }
.cl-ul { margin: 10px 0 0; padding: 0; list-style: none; }
.cl-ul li { position: relative; padding-left: 15px; margin-top: 6px; font-size: var(--fs-caption); line-height: 1.7; color: var(--text-2); }
.cl-ul li::before { content: ""; position: absolute; left: 3px; top: 9px; width: 5px; height: 5px; border-radius: 50%; background: var(--text-4); }
.cl-foot { text-align: center; font-size: var(--fs-micro); color: var(--text-4); margin: 2px 0 6px; font-variant-numeric: tabular-nums; }
/* 抽屉态：灰底画布 + 内部可滚动，顶栏/底栏固定 */
.ab-sheet { background: var(--bg-page); display: flex; flex-direction: column; max-height: 88vh; }
.ab-sheet .wp-grab, .ab-sheet .wp-title, .ab-sheet .wp-foot { flex: none; }
.ab-sheet .cl-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 2px 2px 8px; }
/* 桌面（≥769）：同一只已接入 WbBack 的整屏层，居中成紧凑对话框，隐去把手 */
@media (min-width: 769px) {
  .ab-mask { align-items: center; justify-content: center; }
  .ab-mask .ab-sheet { width: auto; max-width: 460px; max-height: 82vh; border-radius: 24px; padding-bottom: 18px;
    transform: translateY(12px); }
  .ab-mask.is-open .ab-sheet { transform: translateY(0); }
  .ab-mask .ab-sheet .wp-grab { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .ab-mask .ab-sheet { transition: none !important; }
}

/* ============================================================
   抽屉把手（拖拽伸缩 · 2026-09-17）
   标题上方横线：上拉把列表区从 56vh 拉到 80vh（跟手），松手就近吸附；
   下拉跟手位移，过阈值/甩动关闭；点按切换高矮。
   与 JS wireSheetGrab 的 BASE/TALL 常量成对，改一处要同步另一处。
   ============================================================ */
.wp-sheet { --sheet-max: 56vh; --sheet-tall: 80vh; }
.wp-sheet.is-tall { --sheet-max: var(--sheet-tall); }
.wp-grab {
  position: relative; width: 100%; height: 30px; margin: -8px 0 6px;
  background: transparent; touch-action: none; cursor: grab;
  display: flex; align-items: center; justify-content: center;
}
.wp-grab::before { /* 视觉小杠与通栏热区分开：看得见 40×5，摸得到一整条 */
  content: ""; width: 40px; height: 5px; border-radius: 9999px;
  background: var(--border-strong);
  transition: background .22s var(--ease-float), transform .3s var(--ease-float);
}
.wp-grab:active { cursor: grabbing; }
.wp-grab:active::before { background: var(--text-4); transform: scaleX(1.18); }
/* 按住/拖动态由 JS 切 is-on（触屏 :active 会被 preventDefault 吞掉），变长走过渡更顺 */
.wp-grab.is-on::before { background: var(--text-4); transform: scaleX(1.5); }
.tp-sheet .tp-grid, .tp-sheet .cat-list, .mgr-sheet .mg-inner { max-height: var(--sheet-max); }
/* 高档：选择类抽屉保底 60vh 内容高（拉长对短内容也有反馈） */
.wp-sheet.is-tall .tp-grid, .wp-sheet.is-tall .cat-list, .wp-sheet.is-tall .tf-list { min-height: 60vh; }
.tp-grid, .cat-list, .mg-inner { transition: max-height .3s var(--ease-enter); }
/* 抽屉内容下拉到顶后再拖直接关：拦住链式滚动，避免连带页/底层滚动回弹 */
.wp-sheet .tp-grid, .wp-sheet .cat-list, .wp-sheet .tf-list, .wp-sheet .mg-inner { overscroll-behavior: contain; }
@media (prefers-reduced-motion: reduce) {
  .tp-grid, .cat-list, .mg-inner, .wp-grab, .wp-grab::before { transition: none; }
}

/* （v3 修订）管理抽屉改全屏后不再泊藏下层：关闭直接下滑露出，零复播 */
/* 键盘升起：遮罩已缩到键盘上方，列表区同步收高保证标题/底栏都在框内 */
.mgr-sheet.is-kbd .mg-inner { max-height: 34vh; }

/* ============================================================
   全屏管理抽屉（2026-09-17）：与全屏详情同一语言。
   遮罩跟随可视视口 → 键盘升起时 flex 内容区自动压缩，
   顶栏常驻、列表滚动，输入框天然露在键盘上方。
   ============================================================ */
.mgr-full {
  height: 100%; border-radius: 0;
  padding: 6px 0 calc(10px + env(safe-area-inset-bottom, 0px));
  display: flex; flex-direction: column;
}
.mgr-full .wp-grab { margin: 0 0 2px; flex: none; }
.mgr-full .mf-head { display: flex; align-items: center; gap: 4px; padding: 0 6px 10px; flex: none; }
.mgr-full .wp-title { flex: 1; min-width: 0; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mgr-full .mf-back, .mgr-full .mf-done {
  border: none; background: transparent; cursor: pointer; flex: none;
  height: 40px; min-width: 44px; padding: 0 10px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 12px; -webkit-tap-highlight-color: transparent;
}
.mgr-full .mf-back { color: var(--text-1); }
.mgr-full .mf-back svg { width: 22px; height: 22px; }
.mgr-full .mf-back:active, .mgr-full .mf-done:active { background: var(--bg-hover); }
.mgr-full .mf-done { color: var(--primary); font-size: 15px; font-weight: var(--fw-medium); }
.mgr-full .mg-inner { flex: 1; min-height: 0; max-height: none; margin: 0; }
.mgr-full.is-kbd .mg-inner { max-height: none; }
