:root {
  --primary: #ff8fab;
  --primary-soft: #ffd6e0;
  --primary-deep: #b0355b;  /* 粉色文字 / 小徽章：白底 6:1、浅粉底 4.5:1（旧的 #f06b93 只有 2.9:1） */
  /* 主题色 RGB 分量：半透明强调 / 焦点环 / 阴影都由这三组变量派生，切换主题时自动跟随 */
  --primary-rgb: 255, 143, 171;
  --accent-rgb: 176, 53, 91;
  --btn-rgb: 204, 69, 108;
  --bg: #fff7f9;
  --card: #ffffff;
  --text: #4a3b40;
  --text-soft: #7d6b72;     /* 次要文字：白底 5:1（旧的 #9b8a90 只有 3.3:1） */
  --border: #ffe3ea;
  /* 阴影统一为双层：贴地阴影收紧轮廓 + 环境阴影四周均匀扩散，避免单层阴影的硬边与发光感。
     环境层不向下偏移（0 0），否则大 blur 下只有下方可见，左右和上方会像被裁掉。
     浅色模式用低饱和玫瑰调（--primary-deep 的 RGB），白底上不会出现发黑的灰影；
     深色模式仍用黑色阴影（见 body.dark），那样在暗底上层次才清楚。
     卡片用 --shadow，浮层用 --shadow-float，粉色按钮用 --shadow-accent。 */
  --shadow: 0 1px 2px rgba(var(--accent-rgb), .05), 0 0 16px rgba(var(--accent-rgb), .10);
  --shadow-float: 0 2px 6px rgba(var(--accent-rgb), .06), 0 16px 40px rgba(var(--accent-rgb), .12);
  --shadow-float-sm: 0 1px 3px rgba(var(--accent-rgb), .06), 0 6px 16px rgba(var(--accent-rgb), .11);
  --shadow-accent: 0 0 8px rgba(var(--btn-rgb), .10), 0 0 18px rgba(var(--btn-rgb), .05);
  --shadow-accent-strong: 0 0 12px rgba(var(--btn-rgb), .14), 0 0 24px rgba(var(--btn-rgb), .06);
  --shadow-hover: 0 2px 6px rgba(var(--accent-rgb), .06), 0 14px 34px rgba(var(--btn-rgb), .14);
  --radius: 18px;
  /* 下拉面板统一层级：高于页面内容 / 吸顶条 / 地图图层，低于弹窗遮罩（100）。
     日期选择器在弹窗内也要能用，单独用 120（见 .dp-panel）。 */
  --z-dropdown: 90;
  --tabbar-h: 62px;
  --topbar-h: 59px; /* 顶栏高度（12px 上下内边距 + 34px 按钮 + 1px 下边框）；PC 端在 .pc-pane 的媒体查询里覆盖为 52px */
  /* 输入框 / 卡片内控件的底色：浅色下是纯白，深色下为浅灰（避免与卡片同色看不出边界） */
  --surface: #ffffff;
  --surface-2: #ffffff;
  --tabbar-bg: rgba(255, 255, 255, 0.96);
  --topbar-bg: rgba(255, 247, 249, 0.92);
  --on-primary: #ffffff;   /* 压在 --btn-grad 实心块上的文字/图标色 */
  --overlay: rgba(74, 59, 64, .96); /* 遮罩层底色 */
  /* 浅粉面板底色：首页 hero、倒计时卡、衣柜搭配入口这类「粉底强调块」 */
  --panel-soft: #fff0f4;
  --hero-grad: linear-gradient(135deg, #ff8fab, #ffb3c6 55%, #ffc9d5);
  /* 主色实心块：凡是「有文字/图标压在上面」的粉底都走这支（主按钮 / 选中胶囊 / 开关 / 徽章）。
     浅色下取深一档玫瑰粉：白字对比 4.5:1；亮粉 --primary 只做装饰与浅底强调，不再垫文字。
     变量名沿用旧名 --btn-grad，避免全站改名 */
  --btn-grad: #cc456c;
  /* 开关（switch）滑轨未选中态底色 */
  --switch-track: #d8d8e0;
  /* 代码块 / 行内代码底色 */
  --code-bg: rgba(0, 0, 0, .06);
  /* 状态色（成功/危险/警示）：深色模式下需提亮，否则在深底上对比不足 */
  --ok: #3ba55d;
  --danger: #e5484d;
  --warn: #e6a23c;
  /* 状态软底：浅色下「浅底 + 深墨」，深色下换成暗底 + 亮墨。
     每组的 ink 都按在 soft 上 ≥4.5:1 反推，状态块里不要再写死 #fff / 浅粉底 */
  --ok-soft: #e8f6ed;
  --ok-border: #cdeed8;
  --ok-ink: #1f7a44;
  --danger-soft: #fdecea;
  --danger-border: #ffd9d3;
  --danger-ink: #b42318;
  --overdue-soft: #fff1ea;
  --overdue-border: #ffd9c7;
  --overdue-ink: #a8441c;
  /* 经期实心底：与「吃药打卡」的 --btn-grad 保持一档色差，白字 6:1 */
  --period-fill: #b0355b;
  /* 展示页 / 登录页固定「浅色海报」：这里存一份当前主题的浅色快照（--sc-*）。
     即使站内开了深色模式，海报页也只用这套浅色值，避免深底 + 深字不可读。 */
  --sc-primary: #ff8fab;
  --sc-primary-soft: #ffd6e0;
  --sc-primary-deep: #b0355b;
  --sc-btn-grad: #cc456c;
  --sc-primary-rgb: 255, 143, 171;
  --sc-accent-rgb: 176, 53, 91;
  --sc-btn-rgb: 204, 69, 108;
  --sc-bg: #fff7f9;
  --sc-card: #ffffff;
  --sc-text: #4a3b40;
  --sc-text-soft: #7d6b72;
  --sc-border: #ffe3ea;
  --sc-panel-soft: #fff0f4;
  --sc-surface: #ffffff;
  --sc-switch-track: #d8d8e0;
  --sc-topbar-bg: rgba(255, 247, 249, .92);
  --sc-tabbar-bg: rgba(255, 255, 255, .96);
  --sc-hero-grad: linear-gradient(135deg, #ff8fab, #ffb3c6 55%, #ffc9d5);
  /* 海报页深色背景：展示页 / 登录页铺的深品牌渐变，白字需 ≥4.5:1，故每套主题单独取值 */
  --sc-auth-grad: linear-gradient(180deg, #9e3455, #b03f63 55%, #c04a6e);
  /* 手写字体（本地内嵌，SIL OFL）：霞鹜文楷，用于「关于我们」「日记正文」「祝福语」。
     回退链保证字体未加载完或缺字时仍有可读字体 */
  --font-hand: "LXGW WenKai", -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
  /* 衬线字体：相册标题 / 月份与日期分组 / 查看器信息标题，与设计稿的宋体标题一致 */
  --font-serif: "Songti SC", "Noto Serif SC", "Source Han Serif SC", Georgia, serif;
}

/* 深色模式：body.dark 时覆盖上方变量。
   做法是给「底色 / 文字 / 边框」三组换值，而非逐个组件写深色规则——
   这样新增组件时只要用了变量就自动适配，不会漏。 */
body.dark:not(.is-showcase):not(.is-auth) {
  /* 文字/图标用的亮粉：深底上对比 9:1，只做强调，不再垫白字 */
  --primary: #ff9bb5;
  --primary-soft: rgba(255, 155, 181, .18);
  --primary-deep: #ffb3c8;
  --bg: #100d14;
  --card: #1b1520;
  --text: #ece7ee;
  --text-soft: #a9a1b3;
  --border: #3d3450;
  --shadow: 0 1px 2px rgba(0, 0, 0, .16), 0 8px 24px rgba(0, 0, 0, .28);
  --shadow-float: 0 2px 8px rgba(0, 0, 0, .22), 0 18px 44px rgba(0, 0, 0, .38);
  --shadow-float-sm: 0 1px 3px rgba(0, 0, 0, .20), 0 6px 18px rgba(0, 0, 0, .30);
  --shadow-accent: 0 0 10px rgba(175, 79, 116, .22), 0 0 20px rgba(175, 79, 116, .10);
  --shadow-accent-strong: 0 0 14px rgba(175, 79, 116, .26), 0 0 28px rgba(175, 79, 116, .12);
  --shadow-hover: 0 2px 6px rgba(0, 0, 0, .18), 0 14px 34px rgba(175, 79, 116, .24);
  --surface: #272030;
  --surface-2: #2f2739;
  --tabbar-bg: rgba(16, 13, 20, 0.96);
  --topbar-bg: rgba(16, 13, 20, 0.92);
  --on-primary: #ffffff;
  --overlay: rgba(12, 9, 15, .92);
  /* 深色下的「粉底强调块」：保留品牌粉调，但不再刺眼 */
  --panel-soft: #291f2c;
  --hero-grad: linear-gradient(135deg, #5c2d42, #6d3a52 55%, #7a4359);
  /* 实心块：暗玫瑰，白字 5:1；亮粉留在 --primary 做文字/图标 */
  --btn-grad: #af4f74;
  --switch-track: #4e4459;
  --code-bg: rgba(255, 255, 255, .08);
  --ok: #4fc98a;
  --danger: #ff6b72;
  --warn: #e8b04b;
  /* 状态软底（深色版）：暗底 + 亮墨，ink 在 soft 上 7:1 以上 */
  --ok-soft: #16281d;
  --ok-border: #2a5038;
  --ok-ink: #7fd39a;
  --danger-soft: #2e1a19;
  --danger-border: #552b28;
  --danger-ink: #ff8a80;
  --overdue-soft: #2e1f16;
  --overdue-border: #54301f;
  --overdue-ink: #ffa77a;
  /* 经期实心底（深色）：暗酒红，白字 6.9:1，和吃药打卡的 #af4f74 仍能区分 */
  --period-fill: #8f3f61;
  color-scheme: dark;
}

/* 深色补丁：这些控件是「盖在内容上的半透明白遮罩」，不能靠变量换值，需按底色单独调整 */
body.dark .ai-polish-mask { background: rgba(27, 21, 32, .88); color: var(--text-soft); }
body.dark .up-ring { background: rgba(27, 21, 32, .6); }

/* 展示页 / 登录页是「固定浅色海报」：不跟随深色模式，否则会出现「深底 + 深字」看不清。
   配色取当前主题的浅色快照（--sc-*），所以换主题时海报页同步换色，但不会被深色模式拖暗。 */
body.is-showcase, body.is-auth {
  --bg: var(--sc-bg);
  --card: var(--sc-card);
  --text: var(--sc-text);
  --text-soft: var(--sc-text-soft);
  --border: var(--sc-border);
  --surface: var(--sc-surface);
  --panel-soft: var(--sc-panel-soft);
  --switch-track: var(--sc-switch-track);
  --code-bg: rgba(0, 0, 0, .06);
  --topbar-bg: var(--sc-topbar-bg);
  --tabbar-bg: var(--sc-tabbar-bg);
  --overlay: rgba(74, 59, 64, .96);
  /* 主色系用主题浅色快照：深色模式的亮色主色不会落到浅色海报上 */
  --primary: var(--sc-primary);
  --primary-soft: var(--sc-primary-soft);
  --primary-deep: var(--sc-primary-deep);
  --btn-grad: var(--sc-btn-grad);
  --primary-rgb: var(--sc-primary-rgb);
  --accent-rgb: var(--sc-accent-rgb);
  --btn-rgb: var(--sc-btn-rgb);
  --hero-grad: var(--sc-hero-grad);
  /* 状态软底同理：深色版是暗底 + 亮墨，落在浅色海报页上会变成「暗块 + 亮字」 */
  --ok-soft: #e8f6ed;
  --ok-border: #cdeed8;
  --ok-ink: #1f7a44;
  --danger-soft: #fdecea;
  --danger-border: #ffd9d3;
  --danger-ink: #b42318;
  --overdue-soft: #fff1ea;
  --overdue-border: #ffd9c7;
  --overdue-ink: #a8441c;
  --period-fill: #b0355b;
  /* 展示页 / 登录页固定浅色：阴影也回到浅色档，避免深色模式的黑色投影落在海报上 */
  --shadow: 0 1px 2px rgba(var(--sc-accent-rgb), .05), 0 0 16px rgba(var(--sc-accent-rgb), .10);
  --shadow-float: 0 2px 6px rgba(var(--sc-accent-rgb), .06), 0 16px 40px rgba(var(--sc-accent-rgb), .12);
  --shadow-float-sm: 0 1px 3px rgba(var(--sc-accent-rgb), .06), 0 6px 16px rgba(var(--sc-accent-rgb), .11);
  --shadow-accent: 0 0 8px rgba(var(--sc-btn-rgb), .10), 0 0 18px rgba(var(--sc-btn-rgb), .05);
  --shadow-accent-strong: 0 0 12px rgba(var(--sc-btn-rgb), .14), 0 0 24px rgba(var(--sc-btn-rgb), .06);
  --shadow-hover: 0 2px 6px rgba(var(--sc-accent-rgb), .06), 0 14px 34px rgba(var(--sc-btn-rgb), .14);
}

/* ===== 主题色预设 =====
   切换 html[data-theme-color] 即可整站换色；每套只换品牌色与中性底色，
   收入绿 / 支出红等语义色保持不变。展示页 / 登录页保持固定品牌色（见上方 body.is-showcase）。 */
html[data-theme-color="lemon"] {
  --primary: #ffd447;
  --primary-soft: #fff3c4;
  --primary-deep: #8a6a00;
  --btn-grad: #8a6a00;
  --primary-rgb: 255, 212, 71;
  --accent-rgb: 138, 106, 0;
  --btn-rgb: 138, 106, 0;
  --bg: #fffdf2;
  --text: #4a4232;
  --text-soft: #7d7358;
  --border: #f2e8bf;
  --panel-soft: #fff8d9;
  --tabbar-bg: rgba(255, 255, 255, .96);
  --topbar-bg: rgba(255, 253, 242, .92);
  --hero-grad: linear-gradient(135deg, #ffd447, #ffe27a 55%, #ffefb0);
  --sc-primary: #ffd447;
  --sc-primary-soft: #fff3c4;
  --sc-primary-deep: #8a6a00;
  --sc-btn-grad: #8a6a00;
  --sc-primary-rgb: 255, 212, 71;
  --sc-accent-rgb: 138, 106, 0;
  --sc-btn-rgb: 138, 106, 0;
  --sc-bg: #fffdf2;
  --sc-card: #ffffff;
  --sc-text: #4a4232;
  --sc-text-soft: #7d7358;
  --sc-border: #f2e8bf;
  --sc-panel-soft: #fff8d9;
  --sc-surface: #ffffff;
  --sc-switch-track: #d8d8e0;
  --sc-topbar-bg: rgba(255, 253, 242, .92);
  --sc-tabbar-bg: rgba(255, 255, 255, .96);
  --sc-hero-grad: linear-gradient(135deg, #ffd447, #ffe27a 55%, #ffefb0);
  --sc-auth-grad: linear-gradient(180deg, #6e5200, #826100 55%, #947000);
}
html[data-theme-color="lemon"] body.dark:not(.is-showcase):not(.is-auth) {
  --primary: #ffd95e;
  --primary-soft: rgba(255, 217, 94, .18);
  --primary-deep: #ffe89a;
  --btn-grad: #8a6a00;
  --primary-rgb: 255, 217, 94;
  --accent-rgb: 176, 138, 26;
  --btn-rgb: 138, 106, 0;
  --bg: #14110a;
  --card: #201b10;
  --text: #f0ead8;
  --text-soft: #b8ae93;
  --border: #4a4024;
  --panel-soft: #2b2413;
  --tabbar-bg: rgba(20, 17, 10, .96);
  --topbar-bg: rgba(20, 17, 10, .92);
  --hero-grad: linear-gradient(135deg, #6b5410, #7d6418 55%, #8f7320);
  --surface: #2b2413;
  --surface-2: #332b18;
  --switch-track: #5a4e2e;
}
html[data-theme-color="sky"] {
  --primary: #6fb4e8;
  --primary-soft: #d8ecfa;
  --primary-deep: #21618c;
  --btn-grad: #2f7fb8;
  --primary-rgb: 111, 180, 232;
  --accent-rgb: 33, 97, 140;
  --btn-rgb: 47, 127, 184;
  --bg: #f4f9fd;
  --text: #394550;
  --text-soft: #68798a;
  --border: #d9e9f6;
  --panel-soft: #eaf4fc;
  --tabbar-bg: rgba(255, 255, 255, .96);
  --topbar-bg: rgba(244, 249, 253, .92);
  --hero-grad: linear-gradient(135deg, #6fb4e8, #9fcdf0 55%, #c6e3f8);
  --sc-primary: #6fb4e8;
  --sc-primary-soft: #d8ecfa;
  --sc-primary-deep: #21618c;
  --sc-btn-grad: #2f7fb8;
  --sc-primary-rgb: 111, 180, 232;
  --sc-accent-rgb: 33, 97, 140;
  --sc-btn-rgb: 47, 127, 184;
  --sc-bg: #f4f9fd;
  --sc-card: #ffffff;
  --sc-text: #394550;
  --sc-text-soft: #68798a;
  --sc-border: #d9e9f6;
  --sc-panel-soft: #eaf4fc;
  --sc-surface: #ffffff;
  --sc-switch-track: #d8d8e0;
  --sc-topbar-bg: rgba(244, 249, 253, .92);
  --sc-tabbar-bg: rgba(255, 255, 255, .96);
  --sc-hero-grad: linear-gradient(135deg, #6fb4e8, #9fcdf0 55%, #c6e3f8);
  --sc-auth-grad: linear-gradient(180deg, #1d5580, #26699b 55%, #2c78b0);
}
html[data-theme-color="sky"] body.dark:not(.is-showcase):not(.is-auth) {
  --primary: #8fc9f0;
  --primary-soft: rgba(143, 201, 240, .18);
  --primary-deep: #b3dcf7;
  --btn-grad: #2f7fb8;
  --primary-rgb: 143, 201, 240;
  --accent-rgb: 47, 127, 184;
  --btn-rgb: 47, 127, 184;
  --bg: #0d1117;
  --card: #151d25;
  --text: #e6edf3;
  --text-soft: #a3b4c2;
  --border: #2b3f50;
  --panel-soft: #1a2530;
  --tabbar-bg: rgba(13, 17, 23, .96);
  --topbar-bg: rgba(13, 17, 23, .92);
  --hero-grad: linear-gradient(135deg, #244a66, #2f5c7d 55%, #3a6f94);
  --surface: #1a2530;
  --surface-2: #22303d;
  --switch-track: #3a5063;
}
html[data-theme-color="lilac"] {
  --primary: #b9a3e3;
  --primary-soft: #e9defa;
  --primary-deep: #6b4fa0;
  --btn-grad: #7d5bb8;
  --primary-rgb: 185, 163, 227;
  --accent-rgb: 107, 79, 160;
  --btn-rgb: 125, 91, 184;
  --bg: #faf7ff;
  --text: #453d52;
  --text-soft: #786d8a;
  --border: #e7ddf7;
  --panel-soft: #f2ecfc;
  --tabbar-bg: rgba(255, 255, 255, .96);
  --topbar-bg: rgba(250, 247, 255, .92);
  --hero-grad: linear-gradient(135deg, #b9a3e3, #d2c2ef 55%, #e6dcf8);
  --sc-primary: #b9a3e3;
  --sc-primary-soft: #e9defa;
  --sc-primary-deep: #6b4fa0;
  --sc-btn-grad: #7d5bb8;
  --sc-primary-rgb: 185, 163, 227;
  --sc-accent-rgb: 107, 79, 160;
  --sc-btn-rgb: 125, 91, 184;
  --sc-bg: #faf7ff;
  --sc-card: #ffffff;
  --sc-text: #453d52;
  --sc-text-soft: #786d8a;
  --sc-border: #e7ddf7;
  --sc-panel-soft: #f2ecfc;
  --sc-surface: #ffffff;
  --sc-switch-track: #d8d8e0;
  --sc-topbar-bg: rgba(250, 247, 255, .92);
  --sc-tabbar-bg: rgba(255, 255, 255, .96);
  --sc-hero-grad: linear-gradient(135deg, #b9a3e3, #d2c2ef 55%, #e6dcf8);
  --sc-auth-grad: linear-gradient(180deg, #5a3f8a, #6c4ca2 55%, #7d5bb8);
}
html[data-theme-color="lilac"] body.dark:not(.is-showcase):not(.is-auth) {
  --primary: #c9b6ef;
  --primary-soft: rgba(201, 182, 239, .18);
  --primary-deep: #dccbf7;
  --btn-grad: #7d5bb8;
  --primary-rgb: 201, 182, 239;
  --accent-rgb: 125, 91, 184;
  --btn-rgb: 125, 91, 184;
  --bg: #100d16;
  --card: #1a1622;
  --text: #ece7f2;
  --text-soft: #b0a6bf;
  --border: #3d3452;
  --panel-soft: #241e2f;
  --tabbar-bg: rgba(16, 13, 22, .96);
  --topbar-bg: rgba(16, 13, 22, .92);
  --hero-grad: linear-gradient(135deg, #3d2f57, #4a3a66 55%, #574574);
  --surface: #241e2f;
  --surface-2: #2d2639;
  --switch-track: #4b4060;
}

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

/* 消息中心条目：左侧类型标签 + 中间文本时间 + 右侧操作 */
.nt-item { display: flex; align-items: center; gap: 10px; padding: 12px 0; border-bottom: 1px solid var(--border); }
.nt-item:last-child { border-bottom: none; }
.nt-item.handled { opacity: .6; }
.nt-kind { flex: none; font-size: 11px; padding: 2px 8px; border-radius: 999px; background: var(--primary-soft); color: var(--primary-deep); }
.nt-kind.message { background: rgba(90, 150, 200, .16); color: #4a7fa5; }
body.dark .nt-kind.message { color: #7fb2d8; }
/* 「我的申请」徽章：中性色，与「待我处理的修改申请」区分开 */
.nt-kind.mine { background: var(--surface); color: var(--text-soft); border: 1px solid var(--border); }
.nt-body { flex: 1; min-width: 0; }
.nt-text { font-size: 14px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nt-time { font-size: 11px; color: var(--text-soft); margin-top: 2px; }
/* 经期提醒徽章：与打卡 / 申请的粉底区分开，便于一眼扫到 */
.nt-kind.period { background: rgba(199, 120, 221, .16); color: #9a5cb8; }
body.dark .nt-kind.period { color: #c79ad8; }
/* 节日提醒徽章：暖色，与其它提醒区分开 */
.nt-kind.holiday { background: rgba(237, 108, 49, .16); color: #c25a22; }
body.dark .nt-kind.holiday { color: #eda06f; }

.nt-kind.plan { background: rgba(59, 165, 93, .13); color: #3ba55d; }
body.dark .nt-kind.plan { color: #7fd39a; }
/* 登录后的未读消息弹窗：复用消息中心条目样式，正文允许换行 */
.nt-pop .nt-text { white-space: normal; }
.nt-more { font-size: 12px; color: var(--text-soft); padding-top: 10px; }
.nt-pop-btns { display: flex; gap: 10px; margin-top: 14px; }
.nt-pop-btns .btn { flex: 1; }

/* ===== 未读消息弹窗（分组版） ===== */
/* 头 / 底固定、中段滚动：靠 .ntp-pop 是否存在给 .modal 换成 flex 列布局。
   类名统一 ntp- 前缀：消息记录详情弹窗已占用 .nt-row 等，避免互相污染。 */
/* 未读消息弹窗：整列布局 + 固定高度。
   固定高度是为了切分类时不跳——消息多时列表在弹窗内部滚动，
   否则从「访客足迹 · 8 条」切到「日常提醒 · 1 条」，弹窗会当场缩一截。 */
.modal:has(.ntp-pop) { display: flex; flex-direction: column; overflow: hidden; height: min(560px, 82vh); }
.modal:has(.ntp-pop) .modal-body { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.ntp-pop { flex: 1 1 auto; min-height: 0; overflow-y: auto; margin: 0 -4px; padding: 0 4px; }
/* 分类筛选：只列「有消息的分类」，只剩一个分类时整块隐藏（没什么可筛的）。
   flex: none 是为了在固定高度里不被压缩——要缩也该让下面的列表去缩。 */
.ntp-cats { flex: none; margin-bottom: 12px; }

.ntp-sec { margin-bottom: 14px; }
.ntp-sec:last-child { margin-bottom: 4px; }
.ntp-sec-h { display: flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 700; color: var(--text-soft); padding: 0 2px 6px; }
.ntp-sec-h span { font-weight: 600; color: var(--text-soft); }

.ntp-row { display: flex; align-items: flex-start; gap: 10px; padding: 10px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface); margin-bottom: 7px; }
.ntp-row:last-child { margin-bottom: 0; }
.ntp-row.act { border-color: rgba(229, 72, 77, .28); background: rgba(229, 72, 77, .045); }
.ntp-row.muted { opacity: .6; }
.ntp-ico { flex: none; width: 30px; height: 30px; border-radius: 10px; display: flex; align-items: center; justify-content: center; }
.ntp-ico svg { width: 18px; height: 18px; }
.ntp-main { flex: 1; min-width: 0; }
/* 行内排版：与消息中心的列表行同一套——标题 / 描述 / 分类·时间 */
.ntp-ch { font-size: 13.5px; font-weight: 700; line-height: 1.45; color: var(--text); word-break: break-word; }
.ntp-text { margin-top: 3px; font-size: 12.5px; line-height: 1.5; color: var(--text-soft); word-break: break-word; }
.ntp-meta { display: flex; align-items: center; gap: 8px; margin-top: 6px; font-size: 11px; color: var(--text-soft); }
.ntp-kind { font-size: 10.5px; font-weight: 700; padding: 1px 7px; border-radius: 999px; background: var(--panel-soft); color: var(--primary-deep); }
/* 右侧操作列：待我处理的申请在这里放「拒绝 · 同意」，其余行只用 .ntp-trail 的箭头 */
.ntp-end { flex: none; display: flex; align-items: center; }
.ntp-acts { display: flex; gap: 6px; }
.ntp-btn { flex: none; font-family: inherit; font-size: 12px; font-weight: 700; cursor: pointer; padding: 6px 12px; border-radius: 9px; border: 1px solid var(--border); background: var(--surface); color: var(--text); }
.ntp-btn.go { border: none; background: var(--btn-grad); color: #fff; }
.ntp-btn.no { color: var(--danger, #e5484d); border-color: rgba(229, 72, 77, .3); background: rgba(229, 72, 77, .06); }
/* 消息中心列表右侧的操作按钮：浅粉底，与主色呼应 */
.ntp-btn.plain { font-weight: 600; color: var(--primary-deep); border-color: var(--primary-soft); background: var(--panel-soft); }
.ntp-trail { flex: none; align-self: center; color: var(--text-soft); display: flex; }
.ntp-trail svg { width: 16px; height: 16px; }
.ntp-foot { display: flex; gap: 10px; margin-top: 12px; flex: none; }
.ntp-foot .btn { flex: 1; }

/* 各类通知的专属配色：申请 / 打卡 / 经期 / 健康提醒 / 节日 / 留言 */
.ntp-ico.k-approval { background: rgba(229, 72, 77, .10); color: #e5484d; }
.ntp-ico.k-checkin { background: rgba(47, 158, 143, .13); color: #2f9e8f; }
.ntp-ico.k-period { background: rgba(199, 120, 221, .16); color: #9a5cb8; }
.ntp-ico.k-plan { background: rgba(59, 165, 93, .13); color: #3ba55d; }
.ntp-ico.k-holiday { background: rgba(237, 108, 49, .16); color: #c25a22; }
.ntp-ico.k-message { background: rgba(90, 150, 200, .16); color: #4a7fa5; }
/* 消息中心新增的几类（访客 / 系统 / 解除关系）：未读弹窗同样要能展示 */
.ntp-ico.k-visit { background: rgba(199, 120, 221, .16); color: #9a5cb8; }
.ntp-ico.k-system { background: var(--primary-soft); color: var(--primary-deep); }
.ntp-ico.k-bill { background: rgba(47, 125, 158, .13); color: #2f7d9e; }
/* 解除关系申请：与「修改申请」同属红色警示系，但整体更深一档以示区别 */
.ntp-ico.k-dissolve { background: rgba(200, 40, 60, .14); color: #c8283c; }

/* ===== 消息中心（PC 两栏 / 移动单列） ===== */
/* 类名统一 ntm- 前缀。左栏放概览与分类入口，右栏放搜索筛选与消息列表；
   1024px 以下回落单列（与全站断点一致）。配色与未读弹窗同源，沿用同一批 rgba。 */
.ntm-col { min-width: 0; }
.ntm-side .card:first-child { margin-top: 0; }

/* 概览统计 */
.ntm-title { display: inline-flex; align-items: center; gap: 6px; }
.ntm-title svg { width: 17px; height: 17px; }
.ntm-stat { display: flex; gap: 10px; }
.ntm-stat-i { flex: 1; padding: 10px 4px; text-align: center; border-radius: 12px; background: var(--panel-soft); }
.ntm-num { font-size: 20px; font-weight: 800; line-height: 1.1; color: var(--primary-deep); }
.ntm-lb { margin-top: 2px; font-size: 11px; color: var(--text-soft); }
.ntm-acts { display: flex; gap: 8px; margin-top: 12px; }

/* 小按钮：概览操作与行内操作共用 */
.ntm-btn {
  flex: 1; font-family: inherit; font-size: 12px; font-weight: 700; cursor: pointer;
  padding: 7px 12px; border-radius: 9px; white-space: nowrap;
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
}
.ntm-btn.go { border: none; background: var(--btn-grad); color: #fff; }
.ntm-btn.plain { font-weight: 600; color: var(--primary-deep); border-color: var(--primary-soft); background: var(--panel-soft); }

/* 分类入口卡 */
.ntm-entry { display: flex; align-items: center; gap: 12px; padding: 12px 14px; cursor: pointer; transition: border-color .15s, background .15s; }
.ntm-entry:hover { border-color: var(--primary-soft); }
.ntm-entry.on { border-color: var(--primary); background: var(--panel-soft); }
.ntm-eico { flex: none; width: 38px; height: 38px; border-radius: 12px; display: flex; align-items: center; justify-content: center; }
.ntm-eico svg { width: 21px; height: 21px; }
.ntm-emain { flex: 1; min-width: 0; }
.ntm-ename { font-size: 13.5px; font-weight: 700; color: var(--text); }
.ntm-esub { margin-top: 2px; font-size: 11.5px; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ntm-eright { flex: none; display: flex; align-items: center; gap: 6px; }
.ntm-tagon { font-size: 10.5px; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: rgba(229, 72, 77, .10); color: var(--danger-ink); }
.ntm-earrow { display: flex; color: var(--text-soft); }
.ntm-earrow svg { width: 16px; height: 16px; }

/* 搜索 + 只看未读 */
.ntm-search { display: flex; align-items: center; gap: 8px; }
.ntm-sbox {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 7px;
  padding: 8px 12px; border: 1px solid var(--border); border-radius: 11px;
  background: var(--surface); color: var(--text-soft);
}
.ntm-sbox input { flex: 1; min-width: 0; border: none; outline: none; background: transparent; font-family: inherit; font-size: 13px; color: var(--text); }
.ntm-sbtn {
  flex: none; display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  font-family: inherit; font-size: 12px; font-weight: 600; padding: 8px 12px; border-radius: 11px;
  border: 1px solid var(--border); background: var(--surface); color: var(--text-soft);
}
.ntm-sbtn.on { border-color: var(--primary); background: var(--panel-soft); color: var(--primary-deep); }

/* 列表：未读 / 已读两组 */
.ntm-gh { display: flex; align-items: center; gap: 6px; margin: 14px 2px 6px; font-size: 12px; font-weight: 700; color: var(--text-soft); }
.ntm-gh:first-child { margin-top: 0; }
.ntm-gh span { font-weight: 600; color: var(--text-soft); }
.ntm-item {
  display: flex; align-items: flex-start; gap: 11px; margin-bottom: 8px; padding: 11px 12px;
  border: 1px solid var(--border); border-radius: 14px; background: var(--surface);
  cursor: pointer; transition: border-color .15s, background .15s, opacity .15s;
}
.ntm-item:last-child { margin-bottom: 0; }
.ntm-item:hover { border-color: var(--primary-soft); }
.ntm-item.act { border-color: rgba(229, 72, 77, .28); background: rgba(229, 72, 77, .045); }
.ntm-item.read { opacity: .7; }
.ntm-item.read:hover { opacity: 1; }
.ntm-ico { flex: none; width: 34px; height: 34px; border-radius: 11px; display: flex; align-items: center; justify-content: center; }
.ntm-ico svg { width: 19px; height: 19px; }
.ntm-item-main { flex: 1; min-width: 0; }
.ntm-ch { font-size: 13.5px; font-weight: 700; line-height: 1.45; color: var(--text); word-break: break-word; }
.ntm-text { margin-top: 3px; font-size: 12.5px; line-height: 1.5; color: var(--text-soft); word-break: break-word; }
.ntm-meta { display: flex; align-items: center; gap: 8px; margin-top: 6px; font-size: 11px; color: var(--text-soft); }
.ntm-kind { font-size: 10.5px; font-weight: 700; padding: 1px 7px; border-radius: 999px; background: var(--panel-soft); color: var(--primary-deep); }
.ntm-end { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
/* 行内操作竖排（概览卡里是横排） */
.ntm-item .ntm-acts { flex-direction: column; gap: 6px; margin-top: 0; }
.ntm-item .ntm-btn { flex: none; padding: 5px 10px; font-size: 11.5px; }

/* 空状态 */
.ntm-empty { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 34px 12px; text-align: center; color: var(--text-soft); }
.ntm-empty-ico { width: 56px; height: 56px; border-radius: 50%; background: var(--panel-soft); display: flex; align-items: center; justify-content: center; color: var(--primary); }
.ntm-empty-ico svg { width: 26px; height: 26px; }
.ntm-empty-title { font-size: 14px; font-weight: 600; color: var(--text); }
.ntm-empty-sub { font-size: 12px; }

/* 配色：入口卡按分类（cat）、列表行按业务类型（kind），两套键名含义不同故分组书写；
   横幅与列表行、未读弹窗共用同一批 kind 配色，故一起挂上选择器 */
.ntm-eico.k-approval, .ntm-ico.k-approval, .nt-banner-ico.k-approval { background: rgba(229, 72, 77, .10); color: #e5484d; }
.ntm-eico.k-remind, .ntm-ico.k-checkin, .nt-banner-ico.k-checkin { background: rgba(47, 158, 143, .13); color: #2f9e8f; }
.ntm-eico.k-interact, .ntm-ico.k-message, .nt-banner-ico.k-message { background: rgba(90, 150, 200, .16); color: #4a7fa5; }
.ntm-eico.k-visit, .ntm-ico.k-visit, .ntm-ico.k-period, .nt-banner-ico.k-visit, .nt-banner-ico.k-period { background: rgba(199, 120, 221, .16); color: #9a5cb8; }
.ntm-eico.k-system, .ntm-ico.k-system, .nt-banner-ico.k-system { background: var(--primary-soft); color: var(--primary-deep); }
.ntm-ico.k-plan, .nt-banner-ico.k-plan { background: rgba(59, 165, 93, .13); color: #3ba55d; }
.ntm-ico.k-holiday, .nt-banner-ico.k-holiday { background: rgba(237, 108, 49, .16); color: #c25a22; }
.ntm-ico.k-dissolve, .nt-banner-ico.k-dissolve { background: rgba(200, 40, 60, .14); color: #c8283c; }
/* 修改提醒（对方按「提醒」改的，已直接生效）：用蓝色与「待我处理的申请」（红）区分开 */
.ntm-ico.k-notice, .ntp-ico.k-notice, .nt-banner-ico.k-notice { background: rgba(90, 150, 200, .16); color: #4a7fa5; }
.ntm-ico.k-bill, .nt-banner-ico.k-bill { background: rgba(47, 125, 158, .13); color: #2f7d9e; }
body.dark .ntm-ico.k-system, body.dark .ntm-eico.k-system, body.dark .nt-banner-ico.k-system, body.dark .ntp-ico.k-system { color: var(--primary); }
body.dark .ntm-tagon { color: #f08a8d; }

/* 提醒档位：互斥单选。四个小胶囊紧挨着——比一排开关更容易一眼看出当前选了哪一档 */
.nt-seg { flex: none; flex-wrap: nowrap; gap: 6px; }
.nt-seg .chip { padding: 4px 10px; font-size: 12px; }
/* 渠道「提醒内容」（邮箱 / 微信）：与站内通知同一套消息清单，只是每行是「模板 + 开关」。
   模块名做小标题分隔，不再一个模块一张卡——这两个渠道可推的消息不多，摊成多张卡太空。 */
.nt-ch-group { margin: 14px 0 2px; font-size: 12px; font-weight: 700; color: var(--text-soft); }
.nt-ch-group:first-of-type { margin-top: 4px; }
.nt-ch-acts { display: flex; align-items: center; gap: 8px; }
/* 行内「预览 / 模板」两个文字按钮 + 开关同排，收紧一点避免窄屏挤到消息名 */
.nt-ch-acts .nt-tpl { padding: 3px 6px; font-size: 12px; }
/* 记账日报发送时间：沿用「记一笔」的时间选择器（两个小框 + 双列弹层），
   只收窄横向留白，让它在设置行右侧和左侧两行说明并排时不挤 */
.setting-row .tp-box { min-width: 42px; padding: 12px 6px; }
.nt-tpl {
  border: 0; background: none; padding: 3px 7px; border-radius: 8px;
  font-size: 12.5px; color: var(--primary-deep); cursor: pointer;
}
.nt-tpl:hover { opacity: .65; }
/* 模块总开关收起后的内容区。hidden 本就是 block 元素的原生行为，显式写出来免得被别的 display 覆盖 */
.nt-group-body[hidden] { display: none; }

/* 顶部弹屏横幅：页面开着时新提醒到达，从顶部滑出；点击跳转，关闭不影响已读 */
.nt-banner-box {
  position: fixed; top: 12px; left: 50%; transform: translateX(-50%);
  z-index: 300; width: min(420px, calc(100% - 24px));
}
.nt-banner-box[hidden] { display: none; }
.nt-banner {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  border: 1px solid var(--border); border-radius: 14px; background: var(--card);
  box-shadow: var(--shadow-float); cursor: pointer;
  opacity: 0; transform: translateY(-12px); transition: opacity .2s ease, transform .2s ease;
}
.nt-banner.in { opacity: 1; transform: translateY(0); }
.nt-banner:hover { border-color: var(--primary-soft); }
.nt-banner-ico { flex: none; width: 32px; height: 32px; border-radius: 10px; display: flex; align-items: center; justify-content: center; }
.nt-banner-ico svg { width: 18px; height: 18px; }
.nt-banner-main { flex: 1; min-width: 0; }
.nt-banner-t { font-size: 13px; font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nt-banner-s { margin-top: 2px; font-size: 12px; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nt-banner-more { flex: none; padding: 2px 7px; border-radius: 999px; font-size: 11px; font-weight: 700; color: var(--primary-deep); background: var(--panel-soft); }
.nt-banner-x { flex: none; padding: 0 2px; border: none; background: transparent; color: var(--text-soft); font-size: 18px; line-height: 1; cursor: pointer; }


/* PC：左栏固定宽度，右栏吃满剩余空间 */
@media (min-width: 1024px) {
  .ntm-wrap { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 16px; align-items: start; }
  .ntm-main .card:first-child { margin-top: 0; }
  /* 消息列表独立滚动（与账单页 #billHomeList 同口径）：高度封顶到
     「视口 − 顶栏 − 列表以上的页面内容 − 内容下内边距 40」，超出就在列表内滚动，整页不再被长列表撑高。
     237px = 内容上内边距 + 搜索筛选卡 + 卡间距 + 列表卡上内边距与标题。 */
  .ntm-list {
    max-height: calc(100vh - var(--topbar-h) - 237px);
    overflow-y: auto; overscroll-behavior: contain; padding-right: 4px;
  }
}

/* 移动端：只留「概览 + 列表」。分类入口卡与搜索 / 分类筛选卡都收起——
   窄屏一屏看到的条目本来就少，先把位置让给消息本身。 */
@media (max-width: 1023px) {
  .ntm-entry,
  .ntm-filter { display: none; }
}

/* ===== 主题切换 / 消息铃铛（顶栏右侧） ===== */
/* 用品牌粉（--primary-deep）而非中性灰：与全站粉嫩调性一致，不至于像系统工具按钮 */
.topbar-btn {
  position: relative; flex: none;
  width: 34px; height: 34px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; border-radius: 50%;
  background: transparent; color: var(--primary-deep);
  cursor: pointer; transition: background .15s, color .15s, transform .15s;
}
.topbar-btn:hover { background: var(--primary-soft); }
.topbar-btn:active { transform: scale(.94); }
.topbar-btn svg { width: 21px; height: 21px; display: block; }

/* 铃铛：有未读时循环摆动（CSS 关键帧实现，等价于 motion 的 rotate 动画） */
.topbar-btn.bell.has-unread .bell-svg { animation: bellSwing 1.6s ease-in-out infinite; transform-origin: 50% 12%; }
@keyframes bellSwing {
  0%, 62%, 100% { transform: rotate(0); }
  70% { transform: rotate(-11deg); }
  78% { transform: rotate(9deg); }
  86% { transform: rotate(-6deg); }
  93% { transform: rotate(3deg); }
}
/* 红点：未读计数（0 不显示，超过 99 显示 99+） */
.bell-dot {
  position: absolute; top: 2px; right: 1px;
  min-width: 16px; height: 16px; padding: 0 4px;
  display: none; align-items: center; justify-content: center;
  border-radius: 999px; background: var(--danger); color: #fff;
  font-size: 10px; font-weight: 700; line-height: 1;
  border: 1.5px solid var(--card);
}
.topbar-btn.bell.has-unread .bell-dot { display: inline-flex; animation: bellDotPop .3s ease; }
@keyframes bellDotPop { from { transform: scale(.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }

/* 主题图标：图标与当前模式一致——浅色显示太阳、深色显示月亮 */
.theme-btn .icon-moon { display: none; }
body.dark .theme-btn .icon-moon { display: block; }
body.dark .theme-btn .icon-sun { display: none; }
/* 切换时的转圈反馈 */
.theme-btn.spinning .icon-sun, .theme-btn.spinning .icon-moon { animation: themeSpin .5s ease; }
@keyframes themeSpin { from { transform: rotate(0); } to { transform: rotate(360deg); } }

/* 尊重系统「减少动态效果」偏好：关掉循环动画 */
@media (prefers-reduced-motion: reduce) {
  .topbar-btn.bell.has-unread .bell-svg,
  .topbar-btn.bell.has-unread .bell-dot,
  .theme-btn.spinning .icon-sun, .theme-btn.spinning .icon-moon { animation: none; }
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
  font-size: 15px;
  -webkit-font-smoothing: antialiased;
}

body { padding: env(safe-area-inset-top) 0 0; }

#app {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

/* ===== 顶部栏 ===== */
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 12px 16px;
  background: var(--topbar-bg);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
/* 标题在整条顶栏里真正居中：顶栏左侧没有元素，若靠 flex:1 撑满剩余空间，
   文字会在「总宽 - 右侧按钮区」里居中，实际被挤偏。故改为绝对定位铺满整条、
   文字居中，并让点击穿透（pointer-events:none）不会挡住右侧按钮。 */
.topbar-title {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  margin: 0;
  padding: 0 16px;
  font-size: 17px;
  font-weight: 700;
  text-align: center;
  letter-spacing: 1px;
  pointer-events: none;
}
.topbar-actions { display: flex; gap: 8px; margin-left: auto; position: relative; z-index: 1; }

/* ===== 扫码登录（顶栏二维码按钮 + 弹窗） ===== */
.qr-wrap {
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  padding: 4px 0 6px;
}
.qr-card {
  padding: 12px; border-radius: 18px; background: #fff;
  border: 1px solid var(--border);
  box-shadow: 0 6px 22px rgba(176, 53, 91, .10);
}
.qr-card img { display: block; width: 220px; height: 220px; }
/* 过期后压暗，避免用户继续拿旧码去扫 */
.qr-card img.expired { opacity: .2; filter: grayscale(1); }
.qr-state { min-height: 18px; font-size: 12px; font-weight: 600; color: var(--primary-deep); text-align: center; }
.qr-state.ok { color: var(--ok); }
.qr-tip { font-size: 12px; color: var(--text-soft); line-height: 1.75; text-align: center; }
.qr-addr {
  max-width: 100%; padding: 4px 11px; border-radius: 999px;
  background: var(--primary-soft); color: var(--text-soft);
  font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.qr-refresh { min-width: 140px; }
/* 手机端扫码后：网页端弹「登录请求」，由用户确认 / 拒绝 */
.qr-req {
  width: 100%; max-width: 300px; box-sizing: border-box;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 12px; border-radius: 14px;
  background: var(--primary-soft); border: 1px solid var(--border);
}
.qr-req-avatar {
  width: 44px; height: 44px; border-radius: 50%; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: #fff; color: var(--primary-deep);
}
.qr-req-avatar img, .qr-req-avatar svg { width: 100%; height: 100%; object-fit: cover; display: block; }
.qr-req-main { text-align: center; }
.qr-req-title { font-size: 13.5px; font-weight: 700; color: var(--text); }
.qr-req-sub { margin-top: 2px; font-size: 12px; line-height: 1.6; color: var(--text-soft); }
.qr-req-actions { display: flex; gap: 8px; width: 100%; }
.qr-req-actions .btn { flex: 1; justify-content: center; }
/* 扫码登录入口只给 PC：手机上直接用账号密码登录，不占顶栏 */
@media (max-width: 1023px) {
  #btnQr.qr-entry { display: none; }
}
.qr-fail { color: var(--danger); font-size: 12.5px; text-align: center; padding: 8px 0; }
.qr-warn {
  max-width: 300px; font-size: 11.5px; line-height: 1.7; text-align: center;
  color: var(--danger); background: rgba(229, 72, 77, .08);
  border: 1px dashed rgba(229, 72, 77, .35); border-radius: 10px; padding: 8px 10px;
}
@media (max-width: 420px) {
  .qr-card img { width: 190px; height: 190px; }
}
/* 顶栏右侧多了一个按钮：窄屏收一点间距与尺寸，避免压到居中的标题 */
@media (max-width: 380px) {
  .topbar-actions { gap: 4px; }
  .topbar-btn { width: 30px; height: 30px; }
  .topbar-btn svg { width: 19px; height: 19px; }
}
.iconbtn {
  border: none;
  background: transparent;
  font-size: 26px;
  line-height: 1;
  color: var(--primary-deep);
  cursor: pointer;
  padding: 0 8px;
}
/* 返回键图标：chevron 在 24 视窗内留白较多，按 40px 渲染才有合适视觉尺寸 */
#backBtn .ico { width: 40px; height: 40px; }

/* ===== 内容区 ===== */
/* 全局隐藏滚动条、保留滚动功能（Chrome/Safari/Edge/Firefox/IE 兼容） */
* { -ms-overflow-style: none; scrollbar-width: none; }
*::-webkit-scrollbar { width: 0; height: 0; display: none; }

.content {
  flex: 1;
  padding: 16px 16px calc(var(--tabbar-h) + 10px);
}
/* 底部导航被滑出时（详情 / 编辑等子页，以及没放进底栏的模块页，如未入底栏的经期历史），
   内容区不能再按「导航高度 + 10」预留底部空间 —— 导航不在，那 62px 全是纯空白。 */
@media (max-width: 1023.98px) {
  body.nav-hidden .content { padding-bottom: 10px; }
}

.page { animation: fadeIn .25s ease; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(6px);} to { opacity: 1; transform: none;} }
/* 同一模块内切子页（如经期 记录/历史/分析）不播入场动画：.page 的 fadeIn 带 6px 位移，
   会把两页共用的页签排（#ppNav）带着上下跳一下，看着就是抖动。判定见 renderRoute 的 no-anim。 */
#content.no-anim > .page { animation: none; }

/* ===== 底部 Tab ===== */
.tabbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 10; /* 置于顶栏 z-index:20 之下，避免覆盖 header */
  display: flex;
  justify-content: space-around;
  height: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
  background: var(--tabbar-bg, rgba(255, 255, 255, 0.96));
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--border);
  box-shadow: 0 -4px 20px rgba(var(--accent-rgb), 0.06);
  transition: transform .3s ease;
}
/* PC 侧栏品牌区：默认隐藏（仅 PC 大屏显示） */
.sidebar-brand { display: none; }
/* 子页面：底栏从下方滑出隐藏；多移一段，确保凸出的 “+” 圆钮也完全移出视口 */
.tabbar.is-hidden { transform: translateY(calc(100% + 40px)); pointer-events: none; }
/* 首屏启动阶段先不画导航：路由尚未判定时避免侧栏 / 底栏先出现再滑走。
   app-booting 由 app.js 在首屏路由渲染完成后移除；nav-no-anim 用来跳过首屏那一次过渡。 */
body.app-booting .tabbar { visibility: hidden; }
body.nav-no-anim .tabbar { transition: none !important; }
.tab {
  position: relative;
  z-index: 1;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  border: none;
  background: transparent;
  color: var(--text-soft);
  font-size: 11px;
  cursor: pointer;
  transition: color .2s;
}
.tab-icon { font-size: 22px; filter: grayscale(0.4); transition: .2s; }
/* 底栏/侧栏图标走主题色：未选中浅粉、选中深粉（文字标签维持原有处理） */
.tab .tab-icon { color: var(--primary); }
.tab.active { color: var(--primary-deep); font-weight: 600; }
.tab.active .tab-icon { color: var(--primary-deep); filter: none; transform: translateY(-1px) scale(1.08); }

/* 底部中间凸起 + 按钮：中心发散光晕压在其它 tab 之下，避免盖住相邻按钮 */
.tab-center {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  padding: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  position: relative;
  z-index: 0;
  user-select: none;
}
.tab-center:focus-visible { outline: none; }
.tab-center:focus-visible .tab-plus {
  box-shadow: 0 0 0 3px var(--primary-soft), var(--shadow-accent-strong);
}
.tab-plus {
  width: 50px; height: 50px;
  border-radius: 50%;
  margin-top: -26px;
  background: var(--btn-grad);
  color: #fff;
  font-size: 30px;
  font-weight: 300;
  line-height: 1;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-accent-strong);
  transition: transform .15s;
}
.tab-center:active .tab-plus { transform: scale(0.92); }

/* ===== 底部导航栏设置：模拟底栏 + 下拉选择入口 ===== */
/* 模拟手机底栏：限宽居中，避免在 PC 上被拉成一整条 */
.nav-mock {
  display: flex; align-items: stretch; gap: 4px;
  max-width: 400px; margin: 0 auto;
  padding: 8px 6px;
  border: 1px dashed var(--border); border-radius: 14px; background: var(--bg);
}
.nav-mock-slot {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  padding: 8px 2px;
  border: 1px solid transparent; border-radius: 10px;
  background: transparent; color: var(--text-soft);
  font-size: 11px; font-family: inherit; cursor: pointer; transition: .2s;
}
.nav-mock-slot .nav-mock-ico { display: inline-flex; width: 22px; height: 22px; color: var(--primary); }
.nav-mock-slot.active .nav-mock-ico { color: var(--primary-deep); }
.nav-mock-slot .nav-mock-ico svg { width: 100%; height: 100%; }
.nav-mock-slot.locked { cursor: default; opacity: .8; }
/* 空槽位的虚线框。注意类名不能叫 .empty —— 那是全局空状态样式（padding: 40px 20px），
   两者特异性相同会由后写的 .empty 覆盖掉槽位自身的 padding，把空槽撑高一倍 */
.nav-mock-slot.is-empty { border-style: dashed; border-color: var(--border); }
.nav-mock-slot.active { border-color: var(--primary); background: var(--primary-soft); color: var(--primary-deep); font-weight: 600; }
.nav-picker { margin-top: 10px; padding: 12px; border: 1px solid var(--border); border-radius: 12px; background: var(--bg); }
.nav-picker-title { font-size: 12px; color: var(--text-soft); margin-bottom: 8px; }
/* 已被其它槽位占用的入口：置灰不可选（每个入口只能选一次） */
.nav-picker .chip.used { opacity: .45; cursor: not-allowed; }

/* ===== 首页模块设置：与首页一致的卡片 + 拖拽排序 / 隐藏 ===== */
.hm-card { position: relative; }
/* z-index 必须高于预览内容：hero / 倒计时等区块带 position:relative，DOM 顺序在后会盖住绝对定位的工具栏，
   表现为按钮只露出上半截，看起来「点不中」 */
.hm-tools { position: absolute; top: 3px; right: 3px; z-index: 2; display: flex; align-items: center; gap: 2px; }
/* 手柄 / 隐藏按钮：图标维持 16~18px，但触控区放大到 30×30（原来手柄 16px、× 几乎没有内边距，
   手指在小卡片右上角很难点准）；浅色药丸底让按钮压在 hero 粉底上也能看清 */
.hm-grip, .hm-x {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0;
  border: none; border-radius: 9px;
  background: var(--card);
  box-shadow: var(--shadow-float-sm);
  color: var(--text-soft);
  line-height: 1;
  -webkit-tap-highlight-color: transparent;
  transition: background .15s, color .15s;
}
.hm-grip { cursor: grab; touch-action: none; }
.hm-grip svg { width: 16px; height: 16px; display: block; }
.hm-x { font-size: 18px; cursor: pointer; }
.hm-grip:hover, .hm-x:hover { background: var(--primary-soft); color: var(--primary-deep); }
.hm-card.hm-dragging { opacity: .65; box-shadow: var(--shadow-float); transform: none; }
.hm-card.hm-off { opacity: .55; border-style: dashed; }
.hm-show-tip { margin-top: 6px; font-size: 11px; color: var(--primary-deep); }
/* 区块（情侣头像 / 恋爱天数 / 消息通知 / 倒计时）在首页占整行 → 编辑卡片同样跨两列 */
.hm-card.hm-wide { grid-column: 1 / -1; }
/* 编辑页的卡片比首页更紧凑：首页的 18px 圆角放在窄卡片上显得笨重，圆角还会切进右上角的工具栏。
   用 .module-card.hm-card（而不是 #hmList）：拖动浮层是 DOM 副本，也要拿到同一套圆角 / 预览样式 */
.module-card.hm-card { border-radius: 12px; }
/* 「恋爱天数」在首页本身就是整块粉色 hero：预览里再套一层白卡会露出白边，形成两层。
   这里让 hero 铺满编辑卡片，外层只留圆角与阴影，顶部多留空间给右上角的拖动 / 隐藏按钮 */
.hm-card[data-hm-key="hero"] { background: transparent; border-color: transparent; box-shadow: none; }
.hm-card[data-hm-key="hero"] .hm-preview .hero {
  margin: -16px -10px;
  padding: 40px 16px 24px;
  border-radius: 12px;
}
/* 倒计时区块自带 .card 外壳，直接套进编辑卡片会出现两层白卡（边框 + 阴影 + 双层内边距）。
   预览里只保留内容，外壳交给外层编辑卡片，避免套娃 */
.hm-card .hm-preview .card {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  margin-bottom: 0;
}
/* 区块（情侣头像 / 恋爱天数 / 消息通知 / 倒计时）在编辑卡片里直接复用首页区块的渲染：
   pointer-events:none 屏蔽区块自带的点击（如点情侣头像跳公开展示页），并把尺寸收一点以适配卡片 */
.hm-preview { pointer-events: none; }
/* 「恋爱天数」卡片点一下就能改顶部文案 + 一言，给个手型提示 */
.hm-card[data-hm-key="hero"] { cursor: pointer; }
.hm-preview .couple-avatars { gap: 26px; margin: 4px 0 8px; }
/* 首页头像区去掉了中间的爱心：用 gap 补回原来「头像—爱心—头像」的总间距（26+28+26=80） */
.hm-preview .couple-avatars.no-heart { gap: 80px; }
.hm-preview .couple-avatars .arco-avatar { width: 68px !important; height: 68px !important; font-size: 34px !important; }
.hm-preview .couple-avatars .heart,
.hm-preview .couple-avatars .heart::before,
.hm-preview .couple-avatars .heart::after { width: 28px; height: 28px; }
.hm-preview .couple-avatars .heart { margin-bottom: 24px; }
.hm-preview .couple-avatars .heart::before { top: -14px; }
.hm-preview .couple-avatars .heart::after { left: -14px; }
.hm-preview .hero { padding: 20px 16px; }
.hm-preview .hero .days .love-main { font-size: 34px; }
.hm-preview-empty { font-size: 12px; color: var(--text-soft); }
/* 自定义上传图片作为图标时，与内置 SVG 图标同样按 30×30 占位 */
.hm-img { width: 30px; height: 30px; border-radius: 8px; object-fit: cover; display: block; }
/* 编辑弹窗里的图标选择器 */
.hm-icon-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; max-height: 176px; overflow: auto; }
.hm-icon-cell { display: flex; align-items: center; justify-content: center; aspect-ratio: 1;
  border: 1px solid var(--border); border-radius: 12px; background: var(--surface); cursor: pointer; overflow: hidden; }
.hm-icon-cell svg { width: 22px; height: 22px; }
.hm-icon-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hm-icon-cell.active { border-color: var(--primary); background: var(--primary-soft);
  box-shadow: 0 0 0 2px rgba(var(--primary-rgb), .28) inset; }
.hm-icon-up { border-style: dashed; flex-direction: column; gap: 2px; font-size: 10px; color: var(--text-soft); }
.hm-icon-up svg { width: 18px; height: 18px; }

/* ===== 卡片 ===== */
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px;
  margin-bottom: 14px;
}
/* 页面里最后一张卡片不再留外间距：底部留白统一由 .content 的 padding-bottom 控制，
   否则「内边距 + 卡片外间距」会把页面底部空出一整条（关于我们这类纯卡片页尤其明显）。 */
.page > .card:last-child { margin-bottom: 0; }
/* 卡片内滚动列表被撑到贴住下边框时（syncLogScroll 写入负外边距），
   列表的直角会把卡片底部圆角盖掉。加这层裁剪，让列表边角跟着卡片圆角走。
   log-clip-last 给「整页最后一块内容」再加一条：清掉卡片自身的下外间距 ——
   它会穿透中间没有内边距的容器，凭空给页面多撑出一截滚动。 */
.log-clip { overflow: hidden; }
.log-clip-last { margin-bottom: 0; }
.card-title {
  font-size: 15px;
  font-weight: 700;
  margin: 0 0 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* 可折叠卡（.card.fold-card）：点标题收起 / 展开，标题右侧的 chevron 指示状态。
   内容必须包在 .card-body 里（收起时整块隐藏），交互见 app.js 的 bindCardCollapse。
   用于内容较长的设置卡：模型管理页的四张模型卡、账单设置页的「AI 接入」与「导入导出」。 */
.card.fold-card > .card-title { cursor: pointer; user-select: none; }
.card.fold-card .ct-right { display: flex; align-items: center; gap: 6px; min-width: 0; }
.card.fold-card .ct-model {
  font-size: 12px; font-weight: normal; color: var(--text-soft);
  max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.card.fold-card .ct-caret { display: flex; color: var(--text-soft); transition: transform .2s ease; flex: none; }
.card.fold-card .ct-caret .ico { width: 15px; height: 15px; margin: 0; }
.card.fold-card.collapsed > .card-title { margin-bottom: 0; }
.card.fold-card.collapsed .ct-caret { transform: rotate(-90deg); }
.card.fold-card.collapsed > .card-body { display: none; }

/* 首页模块卡片网格 */
.module-grid { display: grid; gap: 12px; margin-bottom: 14px; }
.module-grid.cols-2 { grid-template-columns: repeat(2, 1fr); }
.module-grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
.module-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px 10px;
  text-align: center;
  cursor: pointer;
  transition: transform .12s, box-shadow .15s;
}
.module-card:active { transform: scale(0.97); box-shadow: var(--shadow-accent); }
.module-card .module-icon { font-size: 30px; margin-bottom: 8px; }
.module-card .module-title { font-size: 15px; font-weight: 700; color: var(--text); }
.module-card .module-sub { font-size: 11px; color: var(--text-soft); margin-top: 4px; }

/* 首页设置「公开内容」卡片编辑器：空槽/末尾的「添加入口」占位卡 + 超量警示 */
.pub-add { border-style: dashed; box-shadow: none; color: var(--primary-deep); }
.pub-add .module-icon { font-size: 22px; }
/* 卡片可拖动：禁掉文字选中与原生拖拽（含 <img>）与 iOS 长按弹层。
   不覆盖 cursor：grab/grabbing 在部分 Linux 光标主题下没有字形，会渲染成空白（鼠标像消失了）。 */
#pubEditor .module-grid .hm-card { user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
#pubEditor .module-grid .hm-card img { -webkit-user-drag: none; }
/* 拖动中的源卡只留一个淡位（真正跟手的是浮层），与相册九宫格的观感一致 */
#pubEditor .module-grid .hm-card.hm-dragging { opacity: .35; box-shadow: none; }
/* 拖动动画：网格单元统一走 transform 过渡，配合 JS 的 FLIP 让其余卡片平滑让位 */
#pubEditor .module-grid > * { transition: transform .18s cubic-bezier(.2, .8, .2, 1); }
/* 拖动浮层：跟随光标的卡片副本（"抓住卡片移动"），落下时缩回并淡出 */
.pub-drag-ghost { position: fixed; left: 0; top: 0; z-index: 9999; pointer-events: none; will-change: transform; }
.pub-drag-ghost > .module-card { width: 100%; height: 100%; margin: 0; transform: scale(1); transition: transform .14s ease, box-shadow .14s ease, opacity .14s ease; }
.pub-drag-ghost.on > .module-card { transform: scale(1.05); box-shadow: var(--shadow-float); }
/* 首页布局编排：和公开内容编辑器同一套拖动观感 —— 源卡留淡位、副本跟手、其余卡片 FLIP 让位 */
#hmVisible > .hm-card { transition: transform .18s cubic-bezier(.2, .8, .2, 1), box-shadow .15s;
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
#hmVisible > .hm-card img { -webkit-user-drag: none; }
#hmVisible .hm-card.hm-dragging { opacity: .35; box-shadow: none; transform: none; }
/* 「添加入口」选择弹窗：图标 + 名称 + 加号行 */
.pub-pick-row { cursor: pointer; }
.pub-pick-ico { flex: none; width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; }
.pub-pick-ico .ico { width: 28px; height: 28px; }
/* 库内自定义入口行：副标题弱化；行末 × 从库里彻底删除 */
.pub-pick-sub { color: var(--text-soft); font-size: 12px; margin-left: 6px; }
.pub-pick-del { flex: none; width: 26px; height: 26px; border: none; background: none; color: var(--text-soft);
  font-size: 18px; line-height: 1; cursor: pointer; border-radius: 50%; }
.pub-pick-del:hover { background: var(--border); color: var(--danger); }

/* 关于我们正文 */
.about-body { font-size: 14px; line-height: 1.8; color: var(--text); white-space: pre-wrap; }
/* 照片墙格子的图片容器：铺满整格（绝对定位由 .ab-photo .about-photo 覆盖），
   简介叠在照片内部左下角，故图片必须块级，否则行内基线会带出空隙、简介跟着上浮 */
.about-photo { position: relative; }
.about-photo img { display: block; max-width: 100%; height: auto; }
/* 照片简介：贴照片底部通栏的粉色渐变条（对齐设计稿 .ab-cap），保证浅色照片上也清晰可读 */
.about-img-cap {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 14px 8px 6px;
  font-size: 12px; line-height: 1.5; color: #fff;
  font-family: var(--font-hand);
  text-shadow: 0 1px 5px rgba(0, 0, 0, .55);
  pointer-events: none;
  text-align: left;
  background: linear-gradient(transparent, rgba(var(--accent-rgb), .55));
}
/* 关于本站：版本号与更新日志 */
.about-version { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.version-badge {
  font-size: 13px; font-weight: 700; color: var(--on-primary); background: var(--btn-grad);
  padding: 3px 10px; border-radius: 999px; letter-spacing: 0.5px;
}
.version-date { font-size: 12px; color: var(--text-soft); }
/* 更新日志很长：限高后内部滚动，标题 / 版本号 / 备份按钮保持可见。
   滚动条已由全局 * 规则隐藏，这里只负责让内容装进固定高度。
   overscroll-behavior 防止滚到顶 / 底时把外层页面一起带着滚。 */
.changelog { max-height: min(46vh, 360px); overflow-y: auto; overscroll-behavior: contain; }
.changelog-group { margin-bottom: 12px; }
.changelog-group:last-child { margin-bottom: 0; }
.changelog-label { font-size: 13px; font-weight: 700; color: var(--primary-deep); margin-bottom: 6px; }
.changelog-list { margin: 0; padding-left: 18px; font-size: 13px; line-height: 1.8; color: var(--text); }
.changelog-list li { margin-bottom: 4px; }
.changelog-list li:last-child { margin-bottom: 0; }
/* 支持开发者：赞赏码居中展示，点击可放大 */
.reward-qr {
  display: block; width: 100%; max-width: 240px; margin: 12px auto 0;
  border-radius: 12px; border: 1px solid var(--border); cursor: pointer;
}
.reward-qr-full { display: block; width: 100%; max-width: 320px; margin: 0 auto; border-radius: 12px; }
/* 解除关系前的回忆快闪：全屏沉浸播放，结尾显示头像 + 诗句 + 确认解除 */
body.dissolve-open { overflow: hidden; }
/* 进入快闪前的纯黑屏（至少 3 秒） */
.dissolve-blackout {
  position: fixed; inset: 0; z-index: 10001; background: #000;
  display: flex; align-items: center; justify-content: center;
  opacity: 1; transition: opacity .9s ease;
}
.dissolve-blackout-hint {
  font-size: 13px; letter-spacing: .18em; color: rgba(255, 255, 255, .35);
  animation: dissolveHint 1.6s ease-in-out infinite;
}
@keyframes dissolveHint { 50% { opacity: .55; } }
/* 整理结束后在全屏黑底上的预览询问（只有一个确定按钮） */
.dissolve-ask {
  display: flex; flex-direction: column; align-items: center; gap: 20px;
  max-width: min(440px, 86vw); text-align: center;
  opacity: 1; transition: opacity 1.6s ease;
}
.dissolve-ask.leaving { opacity: 0; pointer-events: none; }
.dissolve-ask-text { font-size: 15px; line-height: 1.9; color: rgba(255, 255, 255, .72); }
.dissolve-ask .btn { width: min(240px, 80vw); }
.dissolve-overlay { position: fixed; inset: 0; z-index: 10000; background: #140d11; overflow: hidden; }
/* 樱花花瓣层：只在照片播完后的时间线阶段出现，快闪照片阶段完全隐藏 */
.dissolve-sakura {
  position: absolute; inset: 0; z-index: 2; display: block; width: 100%; height: 100%;
  pointer-events: none; opacity: 0; transition: opacity .8s ease;
}
.dissolve-overlay.done .dissolve-sakura { opacity: 1; }
.dissolve-overlay-imgs { position: absolute; inset: 0; z-index: 1; opacity: 1; transition: opacity .45s ease; }
.dissolve-overlay.done .dissolve-overlay-imgs { opacity: 0; }
.dissolve-flash-frame {
  position: absolute; inset: 0; opacity: 0;
  transition: opacity .45s ease;
}
.dissolve-flash-frame.on { opacity: 1; will-change: opacity, transform; }
/* 每张照片：以随机中心点、随机方向旋转着缓缓放大，铺满整屏（object-fit: cover） */
.dissolve-flash-img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transform-origin: var(--ox, 50%) var(--oy, 50%);
  transform: scale(1.06) rotate(0deg);
  transition: transform .56s cubic-bezier(.22, .61, .36, 1);
}
.dissolve-flash-frame.on .dissolve-flash-img {
  transform: scale(1.4) rotate(var(--r, 4deg));
}
/* 每张照片叠加所属日常的日期与正文 */
.dissolve-flash-cap {
  position: absolute; left: 50%; top: clamp(64px, 9vh, 110px); transform: translateX(-50%);
  width: min(860px, calc(100% - 48px)); padding: 14px 20px; border-radius: 14px;
  background: rgba(20, 13, 17, .55); backdrop-filter: blur(8px);
  text-align: center; pointer-events: none;
}
.dissolve-flash-date { font-size: 12px; letter-spacing: .08em; color: #f6c9d6; margin-bottom: 6px; }
.dissolve-flash-text {
  font-size: clamp(14px, 1.4vw, 17px); line-height: 1.7; color: rgba(255, 255, 255, .92);
  white-space: pre-line;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.dissolve-overlay-final {
  position: absolute; inset: 0; z-index: 3; display: flex;
  padding: clamp(24px, 4vh, 44px) clamp(24px, 5vw, 72px) 110px;
  opacity: 0; pointer-events: none; transition: opacity .45s ease; overflow: hidden;
}
.dissolve-overlay.done .dissolve-overlay-final { opacity: 1; pointer-events: auto; }
.dissolve-final-right {
  flex: 1; width: 100%; max-width: 980px; margin: 0 auto;
  min-width: 0; min-height: 0; overflow-y: auto; padding: 8px 8px 40px 4px;
  scrollbar-width: none; -ms-overflow-style: none;
}
.dissolve-final-right::-webkit-scrollbar { display: none; width: 0; height: 0; }
.dissolve-confirm-bar {
  position: absolute; left: 50%; bottom: calc(32px + env(safe-area-inset-bottom)); z-index: 4;
  transform: translateX(-50%); display: flex; gap: 14px;
  width: min(560px, calc(100% - 48px));
  opacity: 0; pointer-events: none; transition: opacity .45s ease;
}
.dissolve-overlay.done .dissolve-confirm-bar { opacity: 1; pointer-events: auto; }
.dissolve-confirm-bar .btn {
  flex: 1; padding: 15px 0; font-size: 17px; font-weight: 600; letter-spacing: .06em;
}
/* 与「取消解除」同一套暗色描边风格，用量色区分：确认＝危险红，取消＝中性粉 */
.dissolve-confirm-bar .dissolve-confirm {
  background: rgba(229, 72, 77, .20); color: #ff9aa0;
  border: 1px solid rgba(229, 72, 77, .55);
}
.dissolve-confirm-bar .dissolve-confirm:hover { background: rgba(229, 72, 77, .32); color: #ffc0c3; }
.dissolve-confirm-bar .dissolve-confirm:disabled { opacity: .6; cursor: default; }
.dissolve-cancel {
  background: rgba(255, 255, 255, .08); color: #f6c9d6; border: 1px solid rgba(246, 201, 214, .45);
}
.dissolve-cancel:hover { background: rgba(255, 255, 255, .16); }
/* 右侧时间线：线条随节点逐段下行，到达后淡入该条内容 */
.dissolve-timeline { position: relative; padding: 4px 0 0 28px; }
.dissolve-tl-line {
  position: absolute; left: 8px; top: 4px; width: 2px; height: 0;
  background: linear-gradient(180deg, #f6c9d6, rgba(246, 201, 214, .28));
}
.dissolve-tl-item {
  position: relative; margin-bottom: 26px;
  opacity: 0; transform: translateY(10px); transition: opacity .45s ease, transform .45s ease;
}
.dissolve-tl-item.on { opacity: 1; transform: none; }
.dissolve-tl-dot {
  position: absolute; left: -25px; top: 5px; width: 10px; height: 10px; border-radius: 50%;
  background: #f6c9d6; box-shadow: 0 0 0 4px rgba(246, 201, 214, .14);
}
.dissolve-tl-date { font-size: 12px; color: rgba(246, 201, 214, .7); letter-spacing: .04em; }
.dissolve-tl-title {
  margin-top: 4px; min-height: 1.45em; font-size: 16px; font-weight: 600; color: #fff;
}
/* 打字机光标 */
.dissolve-tl-title.typing::after {
  content: ""; display: inline-block; width: 1px; height: 1em; margin-left: 2px;
  vertical-align: -2px; background: #f6c9d6; animation: dissolveCaret .7s steps(1) infinite;
}
@keyframes dissolveCaret { 50% { opacity: 0; } }
.dissolve-tl-desc {
  margin-top: 4px; font-size: 13px; line-height: 1.7; color: rgba(255, 255, 255, .62); white-space: pre-wrap;
  opacity: 0; transform: translateY(4px); transition: opacity .35s ease, transform .35s ease;
}
.dissolve-tl-desc.on { opacity: 1; transform: none; }
.dissolve-tl-kind {
  display: inline-block; margin-top: 6px; padding: 1px 8px; border-radius: 999px;
  font-size: 11px; color: #f6c9d6; background: rgba(246, 201, 214, .12);
}
.dissolve-tl-empty { color: rgba(255, 255, 255, .55); font-size: 14px; padding: 12px 0; }
/* 时间线统一使用站内自带的手写字体（霞鹜文楷） */
.dissolve-final-right { font-family: var(--font-hand); }
/* 时间线收尾：未完成的心愿 */
.dissolve-wishes {
  margin-top: 30px; padding-top: 22px; border-top: 1px dashed rgba(246, 201, 214, .28);
  opacity: 0; transform: translateY(10px); transition: opacity .6s ease, transform .6s ease;
}
.dissolve-wishes.on { opacity: 1; transform: none; }
.dissolve-wishes-title { font-family: var(--font-hand); font-size: 19px; color: #f6c9d6; margin-bottom: 12px; }
.dissolve-wish {
  display: flex; align-items: baseline; gap: 10px; margin-bottom: 8px;
  font-size: 14px; line-height: 1.7; color: rgba(255, 255, 255, .78);
}
.dissolve-wish::before { content: "·"; color: #f6c9d6; }
.dissolve-wish em { font-style: normal; font-size: 12px; color: rgba(246, 201, 214, .6); }
.dissolve-overlay-close {
  position: absolute; top: calc(12px + env(safe-area-inset-top)); right: 16px; z-index: 5;
  width: 40px; height: 40px; border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(255, 255, 255, .08); color: #fff; font-size: 26px; line-height: 1;
}
/* 窄屏：整屏滚动 */
@media (max-width: 760px) {
  .dissolve-overlay-final {
    display: block;
    padding: 20px 18px 100px; overflow-y: auto;
    scrollbar-width: none; -ms-overflow-style: none;
  }
  .dissolve-overlay-final::-webkit-scrollbar { display: none; width: 0; height: 0; }
  .dissolve-final-right { overflow: visible; padding: 0 4px; }
}
/* PC：时间线整体放大，字号同步放大 */
@media (min-width: 761px) {
  .dissolve-final-right {
    max-width: 1240px; padding: 12px 20px 48px 10px;
    font-size: 18px;
  }
  .dissolve-timeline { padding-left: 38px; }
  .dissolve-tl-line { left: 10px; width: 3px; }
  .dissolve-tl-item { margin-bottom: 34px; }
  .dissolve-tl-dot { left: -34px; top: 7px; width: 13px; height: 13px; }
  .dissolve-tl-date { font-size: 15px; }
  .dissolve-tl-title { margin-top: 6px; font-size: 23px; }
  .dissolve-tl-desc { margin-top: 6px; font-size: 17px; line-height: 1.8; }
  .dissolve-tl-kind { margin-top: 8px; padding: 2px 11px; font-size: 13px; }
  .dissolve-wishes { margin-top: 38px; padding-top: 26px; }
  .dissolve-wishes-title { font-size: 27px; margin-bottom: 16px; }
  .dissolve-wish { margin-bottom: 12px; font-size: 18px; line-height: 1.75; gap: 12px; }
  .dissolve-wish em { font-size: 14px; }
}
/* 关于我们站内页 / 展示页版式：
   两栏（正文 + 大事记）各自内部滚动，页面本身不因长文而变长，照片墙仍完整显示在下方。
   做法：.page-fill 撑满可视高度并把剩余空间给 .about-cols，.about-cols 铺满后，
   两张卡 height:100% + overflow-y:auto 各自成滚动区。
   公开展示页没有 .page-fill（整页滚动），两栏仍靠 grid 默认的 stretch 等高。 */
.page-fill { height: 100%; display: flex; flex-direction: column; }
.page-fill > .about-cols { flex: 1; min-height: 0; }
.page-fill > .about-cols > .card { height: 100%; overflow-y: auto; }
/* 只有大事记时（无两栏）：正文卡独自撑满并内部滚动 */
.page-fill > .about-card { flex: 1; min-height: 0; overflow-y: auto; }

/* ===== Markdown 富文本排版（关于我们 / 日记正文共用 .md-body） ===== */
/* 必须覆盖 .about-body / .sp-text 的 pre-wrap：marked 输出的 HTML 自带换行缩进，
   若继续 pre-wrap 会把源码空白渲染成额外空行 */
/* 富文本字体：霞鹜文楷（「关于我们」与「日记正文」共用）。
   字体按 unicode-range 分片加载，实际只会请求页面上用到的分片 */
.md-body {
  white-space: normal;
  word-break: break-word;
  font-family: var(--font-hand);
}
.md-body > *:first-child { margin-top: 0; }
.md-body > *:last-child { margin-bottom: 0; }
.md-body p { margin: 0 0 10px; }
.md-body h1, .md-body h2, .md-body h3, .md-body h4, .md-body h5, .md-body h6 {
  margin: 16px 0 8px; line-height: 1.4; font-weight: 700; color: var(--text);
}
.md-body h1 { font-size: 20px; }
/* 关于我们正文里的大标题（如「兜兜转转，终是我们」）作为开篇居中，h2 及以下仍左对齐。
   注意 .about-body 与 .md-body 在同一元素上（class="about-body md-body"），故用后代而非复合选择器 */
.about-body h1 { text-align: center; }
.md-body h2 { font-size: 18px; }
.md-body h3 { font-size: 16px; }
.md-body h4, .md-body h5, .md-body h6 { font-size: 15px; }
.md-body ul, .md-body ol { margin: 0 0 10px; padding-left: 22px; }
.md-body li { margin: 4px 0; }
.md-body li > ul, .md-body li > ol { margin: 4px 0 0; }
.md-body blockquote {
  margin: 0 0 10px; padding: 6px 12px; border-left: 3px solid var(--primary);
  background: rgba(var(--primary-rgb), 0.08); border-radius: 0 8px 8px 0; color: var(--text-soft);
}
.md-body code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.92em;
  background: var(--code-bg); padding: 1px 5px; border-radius: 5px;
}
.md-body pre { margin: 0 0 10px; padding: 10px 12px; overflow-x: auto; background: var(--code-bg); border-radius: 10px; }
.md-body pre code { background: none; padding: 0; }
.md-body a { color: var(--primary-deep); text-decoration: underline; word-break: break-all; }
.md-body img { max-width: 100%; height: auto; border-radius: 10px; display: block; margin: 8px 0; }
.md-body hr { border: none; border-top: 1px solid var(--border); margin: 16px 0; }
.md-body table { display: block; width: 100%; border-collapse: collapse; margin: 0 0 10px; font-size: 13px; overflow-x: auto; }
.md-body th, .md-body td { border: 1px solid var(--border); padding: 6px 10px; text-align: left; }
.md-body th { background: var(--bg); font-weight: 600; }
/* GFM 任务列表：勾选框仅作展示，负边距抵消 ul 的左内边距 */
.md-body li.task-list-item { list-style: none; margin-left: -20px; }
.md-body input[type="checkbox"] { margin-right: 6px; vertical-align: middle; accent-color: var(--primary); }

/* 「关于我们」编辑 / 预览 切换：两段式滑轨，滑块随选中态平移（默认预览）。
   两段文案同为 2 个汉字、等宽，故滑块按 50% 定位即可精确覆盖选中段 */
.ab-seg {
  position: relative; flex: none; display: inline-flex;
  padding: 3px; border-radius: 999px; background: var(--panel-soft);
}
.ab-seg-i {
  position: relative; z-index: 1; text-align: center;
  padding: 5px 14px; font-size: 12.5px; font-weight: 600;
  color: var(--text-soft); border-radius: 999px;
  cursor: pointer; user-select: none; transition: color .2s;
}
.ab-seg-i.active { color: #fff; }
.ab-seg-thumb {
  position: absolute; top: 3px; left: 3px; width: calc(50% - 3px); height: calc(100% - 6px);
  border-radius: 999px; background: var(--btn-grad);
  transition: transform .22s cubic-bezier(.4, 0, .2, 1);
}
.ab-seg[data-mode="preview"] .ab-seg-thumb { transform: translateX(100%); }
/* 「关于我们」正文：编辑 / 预览共用一个框 ——
   编辑态给同一个 div 加 contenteditable 显示源码，预览态用 md 渲染；
   框体沿用原输入框的外观（padding / border / radius / min-height） */
.about-editor {
  width: 100%;
  min-height: 100px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  outline: none;
  transition: border-color .2s, box-shadow .2s;
}
.about-editor:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.14); }
/* 编辑态是纯文本源码：保留换行、用常规字体（覆盖 .md-body 的渲染排版） */
.about-editor[contenteditable="true"] { white-space: pre-wrap; word-break: break-word; font-family: inherit; }
/* 源码被清空时给个提示，替代原 textarea 的 placeholder */
.about-editor[contenteditable="true"]:empty::before { content: "写写你们的故事…"; color: var(--text-soft); }
/* 保存按钮与上方内容的间距 */
#saveAboutUs { margin-top: 14px; }

/* 「关于我们」编辑页标题：文字居中，「编辑 / 预览」滑轨绝对定位在右侧。
   .card-title 默认是 space-between，滑轨绝对定位后由 .about-title-txt 独占一行并居中。
   标题独占一张卡：去掉卡片的白底 / 边框 / 阴影 / 内边距，只留文字与滑轨 */
.about-head { background: transparent; border: none; box-shadow: none; padding: 0 0 6px; }
.about-head .about-title { margin-bottom: 0; }
.about-title { position: relative; justify-content: center; }
.about-title .ab-seg { position: absolute; right: 0; top: 50%; transform: translateY(-50%); }

/* 编辑页正文卡 + 大事记卡并排（宽屏左正文 / 右大事记，窄屏堆叠）
   两卡各自是 .card（白底 + 边框），间距由 grid gap 给，不再叠 .card 的 margin-bottom */
.about-edit-cols { display: grid; gap: 14px; align-items: stretch; }
.about-edit-cols > .card { margin-bottom: 0; }
@media (min-width: 1024px) {
  .about-edit-cols {
    grid-template-columns: minmax(0, 1fr) minmax(260px, 320px);
    /* 两卡同高：行高由正文框的 40vh 上限决定，再补上卡片自身的内边距（16×2）与边框（1×2）。
       大事记卡不再按视口底部自行撑高，跟随行高、列表内部滚动，
       否则右栏会比左栏长出一大截、左卡下方空出大片白 */
    grid-template-rows: calc(40vh + 34px);
  }
  .about-edit-cols > .card { min-height: 0; overflow: hidden; }
  /* 正文预览 / 编辑框过长时在框内滚动：右侧大事记和下方照片墙不会被长文一路顶走。
     只在宽屏生效，移动端保持「整页滚动」，避免触屏上套一层内滚动 */
  .about-editor { height: 100%; overflow-y: auto; overscroll-behavior: contain; }
  /* 列高已由网格给定，列表不再另设上限（.ab-tl-scroll 的 46vh 会让右卡底部留白） */
  #abTlList { max-height: none; }
}
/* 大事记 / 照片墙两个卡片：与正文同页就地增删改 */
.about-sub { min-width: 0; display: flex; flex-direction: column; }
/* 编辑页大事记卡被网格拉高时，列表与未来节点一起撑满，虚线才能落到卡底 */
#abTlList { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.about-sub .sub-title { margin-bottom: 10px; }
.about-sub .sub-title .btn, .about-sub .sub-title .badge { margin-left: auto; }
.about-sub-wall { margin-top: 16px; }
/* 添加格是照片墙的一个网格单元，不能再吃外边距：margin-top 会把它往下推、
   并让它在格子里被压矮，看起来就和照片格对不齐了 */
.about-sub-wall #abWallAdd { margin-top: 0; }
/* 大事记时间线（编辑页列表与展示页共用一套样式）
   对齐口径：竖线 left:6px + 宽 2px → 中轴在 7px；
   圆点用 border-box（全局 box-sizing:border-box），10px 含 2.5px 描边，
   故左边缘取 -18px（20px 缩进 - 18px = 2px），中心正好落在 7px 的竖线上。
   竖线改为逐条绘制（每条从圆点下沿连到下一条圆点），于是「未来」节点之后
   可以换成渐隐虚线，表达故事还没写完。 */
.ab-tl { position: relative; padding-left: 20px; flex: 1; display: flex; flex-direction: column; }
.ab-tl::before { display: none; }
.ab-tl-item { position: relative; padding-bottom: 14px; cursor: pointer; }
.ab-tl-item:last-child { padding-bottom: 0; }
.ab-tl-item::before {
  content: ""; position: absolute; left: -18px; top: 4px; width: 10px; height: 10px;
  border-radius: 50%; background: var(--surface); border: 2.5px solid var(--primary);
}
/* 连线：top 14px 是圆点下沿（4 + 10），bottom -4px 接到下一条圆点的上沿 */
.ab-tl-item::after {
  content: ""; position: absolute; left: -14px; top: 14px; bottom: -4px; width: 2px;
  background: var(--border);
}
.ab-tl-item:last-child::after { display: none; }
.ab-tl-date { font-size: 11.5px; font-weight: 600; color: var(--primary-deep); }
.ab-tl-title { font-size: 14px; font-weight: 700; margin-top: 2px; }
.ab-tl-desc { font-size: 12.5px; line-height: 1.7; color: var(--text-soft); margin-top: 2px; }
/* 未来节点：空心圆点 + 一圈很淡的光晕；卡片被拉高时它吃掉剩余高度，
   其后的线变成渐隐虚线，一路落到卡底 */
.ab-tl-item.is-future { flex: 1; cursor: default; padding-bottom: 18px; }
.ab-tl-item.is-future::before {
  background: var(--card); border-color: var(--primary);
  box-shadow: 0 0 0 4px rgba(var(--primary-rgb), .14);
}
.ab-tl-item.is-future::after {
  display: block; bottom: 0; opacity: .55;
  background: repeating-linear-gradient(to bottom, var(--primary) 0 6px, transparent 6px 12px);
  -webkit-mask-image: linear-gradient(to bottom, #000 55%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 55%, transparent 100%);
}
.ab-tl-item.is-future .ab-tl-title { color: var(--primary-deep); }

/* 照片墙：方形格子 + 照片简介（叠在格子内部下方，与正文配图同一套说明样式） */
/* 照片墙：固定 4 列 × 2 排 = 8 格（列数与排数同 aboutPhotoWallHTML 的常量一致）。
   超出的照片由 JS 折进最后一格的图层，故这里不做 overflow 隐藏。 */
.ab-wall { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.ab-photo {
  position: relative; aspect-ratio: 1 / 1; overflow: hidden;
  border-radius: 12px; background: var(--bg); cursor: pointer;
}
.ab-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 照片墙格子里复用 .about-photo 承载照片简介：铺满整格并去掉正文配图的上边距 */
.ab-photo .about-photo { position: absolute; inset: 0; margin-top: 0; }
.ab-photo .about-photo img { width: 100%; height: 100%; object-fit: cover; }
.ab-photo .about-img-cap { font-size: 11.5px; }
/* 照片墙末尾的「添加照片」格子：与上传控件 .up-add 同一套外观（虚线框 + 加号 + 文字），
   避免照片墙里出现一个和全站其它「添加」长得不一样的实心大图标 */
.ab-add {
  color: var(--primary-deep);
  background: var(--panel-soft);
  /* 用内缩 outline 画虚线：不参与盒模型，外框和照片格严格同宽同高、同一起止位置 */
  outline: 1.5px dashed var(--primary-soft);
  outline-offset: -1.5px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 5px; font-size: 11.5px;
  /* 兜底：格子窄的时候也不让图标/文字把格子的高度撑出正方形 */
  min-height: 0;
}
.ab-add .ico { width: 22px; height: 22px; }
.ab-add > span { line-height: 1.2; white-space: nowrap; }
.ab-add:hover { color: var(--primary); outline-color: var(--primary); }
.ab-add.is-busy { opacity: .45; pointer-events: none; }
.about-photo-preview { max-width: 220px; margin: 0 auto 14px; position: relative; }
/* 照片简介弹窗的操作行：替换 / 删除并排一行，保存独占一行（三个挤一行在窄屏会放不下） */
.ab-ph-acts { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
.ab-ph-acts #abPhReplace, .ab-ph-acts #abPhDel { flex: 1; }
.ab-ph-acts #abPhSave { flex: 1 0 100%; }
/* 末格的「还有 N 张」图层：整格蒙一层半透明黑，中间显示剩余张数 */
.ab-photo.is-more::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: rgba(0, 0, 0, .48);
}
.ab-more-num {
  position: absolute; inset: 0; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; font-weight: 800; color: #fff;
  text-shadow: 0 1px 6px rgba(0, 0, 0, .6);
}
/* 有叠加层时，下面的照片简介就没意义了（已被蒙层盖住），隐掉避免双层文字 */
.ab-photo.is-more .about-img-cap { display: none; }

/* 关于我们展示页版式：宽屏时正文在左、大事记在右；窄屏回退为上下堆叠。
   右栏（大事记）按内容自适应宽：minmax(0, auto) 让它只占标题+日期+描述的实际宽度，
   剩余空间全给正文（1fr）；条目文字过长时由卡内 min-width:0 + 换行收住，不会撑破布局。
   align-items 用默认的 stretch：两卡等高，各自内容超出时在卡内滚动（配合 .page-fill 的 height:100%）。
   卡片 margin-bottom 归零，间距统一由 grid gap 给。 */
.about-cols { display: grid; gap: 16px; }
@media (min-width: 1024px) {
  /* 右列用 max-content 而非 auto / 固定 fr：列宽贴着「日期+标题+描述」的实际内容宽度，
     剩余空间全给正文（1fr）。
     下限给 200px：max-content 在无内容时塌成 0，整列会只剩一条边线（卡片也没了），
     故用 minmax(200px, max-content) 兜一个底；minmax 的第二值仍可超过 200px 随内容变宽。 */
  .about-cols { grid-template-columns: minmax(0, 1fr) minmax(200px, max-content); }
}
.about-cols > .card { margin-bottom: 0; }
/* 右栏自适应宽时，卡内文字必须允许收缩换行，否则长标题会顶宽整列 */
.about-cols > .card > .ab-tl { min-width: 0; }
.about-cols > .card > .ab-tl > .ab-tl-item { min-width: 0; }
/* 照片墙不参与分栏、也不参与伸缩：在 .page-fill 的 flex column 里按内容高度原样显示。
   与上方两栏保持 16px 间距（.card 默认 14px 偏紧，这里放宽一档） */
.page-fill > .about-wall-card { flex: none; margin-top: 16px; }

/* 公开「关于我们」展示页：内容区由「95% / 限宽 1080px」放开为「视口宽度的 75%」，
   正文·大事记两栏与照片墙随之变宽；两块之间补 16px 间距
   （公开展示页不走 .page-fill，原来两块是贴在一起的）。 */
.showcase-public[data-mod="about"] { width: 75vw; max-width: none; }
.showcase-public[data-mod="about"] > .about-wall-card { margin-top: 16px; }

/* 首页设置底部操作行：预览 + 保存 并排等宽 */
.home-save-row { display: flex; gap: 10px; }
.home-save-row .btn { flex: 1; }

/* ===== 首页 hero ===== */
.hero {
  position: relative;
  overflow: hidden; /* 承载右下/左上的半透明白圆装饰，需裁剪 */
  border-radius: var(--radius);
  padding: 28px 20px;
  color: var(--on-primary);
  /* 精修：由 135° 粉色渐变改为纯色，右下补一个半透明白圆做层次（非渐变） */
  background: var(--btn-grad);
  box-shadow: var(--shadow-float);
  margin-bottom: 14px;
  text-align: center;
}
.hero::after { content: ""; position: absolute; right: -40px; bottom: -60px; width: 180px; height: 180px; border-radius: 50%; background: rgba(255, 255, 255, .14); }
.hero::before { content: ""; position: absolute; left: -30px; top: -50px; width: 120px; height: 120px; border-radius: 50%; background: rgba(255, 255, 255, .10); }
.hero > * { position: relative; }
.hero .couple { font-size: 18px; font-weight: 700; letter-spacing: 2px; }
.hero .days { margin: 8px 0 2px; }
.hero .days .love-main {
  font-size: 46px;
  font-weight: 800;
  line-height: 1.15;
}
.hero .days .love-sub {
  font-size: 17px;
  font-weight: 600;
  opacity: 0.92;
  margin-top: 4px;
  letter-spacing: 1px;
}
.hero .quote {
  margin-top: 12px;
  font-size: 13px;
  opacity: 0.95;
  font-style: italic;
}
/* hero 文案改用手写体（霞鹜文楷），与「关于我们 / 日记正文 / 祝福语」统一。
   注意：该字体没有 800 字重，love-main 的 800 会由浏览器合成加粗。 */
.hero .couple, .hero .days .love-main, .hero .days .love-sub, .hero .quote { font-family: var(--font-hand); }
/* 特殊纪念横幅 */
.hero .love-banner {
  margin-top: 12px;
  padding: 10px 14px;
  border-radius: 14px;
  background: rgba(255,255,255,0.25);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.5px;
  animation: fadeIn .3s ease;
}

/* 首页 hero：宽度足够时，「今天，是我们在一起的」「第 N 天」「时分秒」由纵向堆叠改为横向一排。
   窄屏（移动端）保持原有的纵向堆叠；装不下时靠 flex-wrap 自动折行，不会挤压。
   装饰圆 ::before/::after 是 absolute 定位，不参与 flex 排版。 */
@media (min-width: 1024px) {
  .hero { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center; gap: 16px; }
  .hero .days { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center; gap: 16px; margin: 0; }
  /* 引言行与纪念横幅始终单独占一行 */
  .hero .quote, .hero .love-banner { flex-basis: 100%; }
}

/* 移动端 hero：保留原渐变背景，仅按设计稿 .hm-hero 重排为左对齐 */
@media (max-width: 1023.98px) {
  .hero {
    padding: 20px 18px 18px;
    border-radius: 26px;
    color: var(--on-primary);
    text-align: left;
    background: var(--btn-grad);
    box-shadow: var(--shadow-float);
  }
  .hero .couple {
    z-index: 2;
    font-family: inherit;
    font-size: 9.5px;
    font-weight: 400;
    letter-spacing: .04em;
    color: rgba(255, 255, 255, .9);
  }
  .hero .days { z-index: 2; margin: 5px 0 2px; }
  .hero .days .love-main {
    font-family: var(--font-serif);
    font-size: 36px;
    font-weight: 600;
    line-height: 1.1;
    letter-spacing: -.03em;
    color: var(--on-primary);
  }
  .hero .days .love-main .love-num { font-style: normal; color: inherit; }
  .hero .days .love-sub {
    margin-top: 0;
    font-family: inherit;
    font-size: 11px;
    font-weight: 400;
    letter-spacing: .08em;
    opacity: 1;
    color: rgba(255, 255, 255, .92);
  }
  .hero .quote {
    z-index: 2;
    margin: 14px 0 0;
    padding-top: 12px;
    border-top: 1px dashed rgba(255, 255, 255, .3);
    font-family: var(--font-serif);
    font-size: 12.5px;
    font-style: normal;
    line-height: 1.7;
    opacity: 1;
    color: rgba(255, 255, 255, .95);
  }
  .hero .love-banner {
    z-index: 2;
    background: rgba(255, 255, 255, .25);
    color: var(--on-primary);
    font-size: 12px;
  }
}

/* 首页节日横幅（数据更新 → 日历更新的横幅提醒） */
.cal-banner {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 14px; padding: 12px 14px;
  border: 1px solid var(--primary); border-radius: 14px;
  background: var(--card);
  animation: fadeIn .3s ease;
}
.cal-banner-body { flex: 1; min-width: 0; }
.cal-banner-t { font-size: 14px; font-weight: 700; color: var(--primary-deep); }
.cal-banner-s { margin-top: 2px; font-size: 11px; color: var(--text-soft); }
.cal-banner-x {
  flex: none; width: 24px; height: 24px; line-height: 22px; text-align: center;
  border-radius: 50%; font-size: 18px; color: var(--text-soft); cursor: pointer;
}
.cal-banner-x:hover { background: var(--bg); color: var(--text); }

/* 节日日历（数据更新页）：只读月历 + 未来节日倒计时清单 */
.fc-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.fc-title { font-size: 14px; font-weight: 700; color: var(--text); }
.fc-nav {
  width: 28px; height: 28px; flex: none; user-select: none;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: 9px;
  font-size: 16px; line-height: 1; color: var(--primary-deep); cursor: pointer;
}
.fc-nav:hover { background: var(--panel-soft); }
.fc-week, .fc-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }
.fc-week span { padding: 2px 0; text-align: center; font-size: 11px; color: var(--text-soft); }
.fc-cell {
  position: relative; aspect-ratio: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  border-radius: 9px; font-size: 12.5px; color: var(--text);
}
.fc-empty { visibility: hidden; }
/* 普通节日浅底，法定假日 / 调休用主题底色；今天用内描边圈出来 */
.fc-fest { background: var(--panel-soft); }
.fc-rest { background: rgba(var(--primary-rgb), .14); }
.fc-today { box-shadow: inset 0 0 0 1.5px var(--primary); }
/* 格子小字：节日简称（主题色）与农历日（浅色）共用一套排布，只差颜色 */
.fc-short, .fc-lunar { margin-top: 1px; font-size: 9px; line-height: 1; font-style: normal; }
.fc-short { color: var(--primary-deep); }
.fc-lunar { color: var(--text-soft); }
/* 未来节日倒计时：名称 / 日期 / 剩余天数 + 剩余占比进度条。
   条数按全年排（可达二十多条），限高后列表内部滚动，不把整页撑长。 */
.fest-list {
  margin-top: 14px; display: flex; flex-direction: column; gap: 10px;
  max-height: 320px; overflow-y: auto; overscroll-behavior: contain; padding-right: 4px;
}
.fest-line { display: flex; align-items: baseline; gap: 8px; font-size: 13px; }
.fest-name { font-weight: 600; color: var(--text); }
.fest-date { font-size: 11.5px; color: var(--text-soft); }
.fest-days { margin-left: auto; font-size: 12px; font-weight: 600; color: var(--primary-deep); }
.fest-bar { margin-top: 5px; height: 5px; border-radius: 999px; background: var(--panel-soft); overflow: hidden; }
.fest-bar > i { display: block; height: 100%; border-radius: 999px; background: var(--btn-grad); }

/* 日历更新弹窗里的节假日汇总：一句话概述 + 可滚动的节日明细表 */
.cal-sum-txt { font-size: 13px; line-height: 1.75; }
.cal-sum-txt b { color: var(--primary-deep); }
.cal-sum { margin-top: 10px; max-height: 300px; overflow-y: auto; border-top: 1px solid var(--border); }
.cal-sum-row {
  display: grid; grid-template-columns: 1fr 84px 46px 46px; gap: 6px; align-items: center;
  padding: 7px 2px; border-bottom: 1px dashed var(--border); font-size: 12.5px;
}
.cal-sum-row.head { position: sticky; top: 0; z-index: 1; background: var(--card); color: var(--text-soft); font-size: 11.5px; }
.cal-sum-row .dt { color: var(--text-soft); }
.cal-sum-row .num { text-align: right; }
.cal-sum-row .adj { color: var(--text-soft); }

/* 情侣头像+爱心组合 */
.couple-avatars {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 38px;
  margin: 4px 0 14px;
}
/* 首页头像区兼作展示页入口，手型提示可点击 */
.couple-avatars[data-showcase] { cursor: pointer; }
.couple-avatars .fl-left, .couple-avatars .fl-right {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
.couple-avatars .arco-avatar {
  border-radius: 50%;
  overflow: hidden;
  border: 3px solid #fff;
  box-shadow: var(--shadow);
  background: var(--bg);
  animation: avatar-breathe 6s ease-in-out infinite;
}
/* 右侧头像错开半个周期，避免两边同起同落显得机械 */
.couple-avatars .fl-right .arco-avatar { animation-delay: -3s; }
.couple-avatars .arco-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.couple-avatars .arco-avatar svg { width: 100%; height: 100%; }
.couple-avatars .avatar-name { font-size: 14px; font-weight: 600; color: var(--text); }
/* 精修：爱心改为 SVG 心形（原先用方块旋转 45° + 两个伪元素圆拼），只做缩放脉动 */
.couple-avatars .heart {
  width: 58px; height: 58px;
  margin-bottom: 36px;
  flex: none;
  color: var(--primary);
  animation: heartbeat 1.6s ease-in-out infinite;
}
@keyframes heartbeat {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.12); }
}
/* 头像柔和呼吸 */
@keyframes avatar-breathe {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-3px); }
}
/* 系统开了「减少动态效果」时停掉这两处循环动画 */
@media (prefers-reduced-motion: reduce) {
  .couple-avatars .heart, .couple-avatars .arco-avatar { animation: none; }
}
/* 解除情侣关系后：实心爱心换成「心碎」图标 */
.couple-avatars .heart-broken {
  width: 44px; height: 44px;
  margin-bottom: 28px;
  flex: none;
}
/* 首页头像区没有中间爱心：用 gap 补回原来两段间距 + 爱心宽度（38+58+38=134），保持头像距离不变 */
.couple-avatars.no-heart { gap: 134px; }

/* 倒计时 */
.count-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 10px;
}
.count-head h3 {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
}
.count-head span {
  font-size: 9px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-soft);
}
.countdown-grid {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.count-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  /* 精修：去掉 card→primary-soft 的渐变，改白底 + 描边 */
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 12px;
  text-align: left;
}
.count-item .count-img { width: 48px; height: 48px; border-radius: 10px; object-fit: cover; flex-shrink: 0; border: 2px solid var(--border); }
/* 没配图的事件：用时钟占位图标补上行首，避免文字直接贴边 */
.count-item span.count-img { display: flex; align-items: center; justify-content: center; background: var(--panel-soft); color: var(--primary-deep); }
.count-item span.count-img .ico { width: 22px; height: 22px; }
.count-item .count-body { flex: 1; min-width: 0; }
/* 倒计时条目：事件名在上（主信息：大字加粗），时间提示在下（次信息：小字灰色） */
.count-item .c { font-size: 13px; font-weight: 700; color: var(--text); word-break: break-all; }
.count-item .count-line { font-size: 12px; color: var(--text-soft); margin-top: 3px; }
/* 「最近事件」不再整块渐变 + 白字：改淡粉底 + 粉描边 + 左侧色条，高亮还在但不靠渐变 */
.count-item.soon { background: var(--panel-soft); border-color: var(--primary); }
.count-item.soon .count-img { border-color: #fff; }
.count-item.soon::before { content: ""; position: absolute; left: 0; top: 14px; bottom: 14px; width: 3px; border-radius: 0 3px 3px 0; background: var(--primary-deep); }
.count-item.soon .c { color: var(--primary-deep); }
.count-item.soon .count-line { color: #b8788f; }

/* 留言板 */
.msg-list { display: flex; flex-direction: column; gap: 12px; }
.msg {
  padding: 14px 16px;
  border-radius: var(--radius);
  background: var(--card);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  font-size: 14px;
}
.msg-head-row { display: flex; align-items: flex-start; gap: 10px; }
.msg-avatar { flex: none; width: 36px; height: 36px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #2f1f28; font-size: 16px; font-weight: 700; }
.msg-body-wrap { flex: 1; min-width: 0; }
.msg .msg-meta { font-size: 12px; color: var(--text-soft); margin-top: 6px; display: flex; justify-content: space-between; }

/* 祝福墙（blessing 风） */
.blessing-count { text-align: center; font-size: 13px; color: var(--text-soft); margin-bottom: 14px; }
.blessing-count b { color: var(--primary-deep); font-size: 16px; }
.msg .msg-head { display: flex; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.msg .msg-author { font-weight: 600; color: var(--text); }
.msg .msg-time { font-size: 12px; color: var(--text-soft); }
/* 祝福语正文：与日记正文同字体（霞鹜文楷） */
.msg .msg-body { line-height: 1.6; font-family: var(--font-hand); }
/* 卡片头部左侧分组：作者 + 心情标签（右侧是「定位 · 时间」） */
.msg .mh-left { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.mood-tag { flex: none; font-size: 12px; font-weight: 600; padding: 2px 8px; border-radius: 999px; white-space: nowrap; color: var(--mc); background: var(--mb); }
/* 心情标签的颜色由行内 --mc/--mb 提供，深色下换用 --mcd，避免深底上仍用深色文字 */
body.dark .mood-tag { color: var(--mcd); }
/* 祝福标题：正文上方一行加粗小标题 */
.msg .msg-title { font-size: 15px; font-weight: 700; margin-bottom: 4px; }
/* 祝福卡片的「详情」操作按钮：对齐设计稿 .opbtn（图标 + 文案、透明底、悬停浅粉） */
.msg-opbtn {
  display: inline-flex; align-items: center; gap: 3px;
  border: none; background: transparent; color: var(--text-soft);
  font-size: 12px; font-family: inherit; padding: 4px 6px; border-radius: 8px; cursor: pointer;
}
.msg-opbtn .ico { width: 14px; height: 14px; }
.msg-opbtn:hover { background: var(--panel-soft); color: var(--primary-deep); }
/* 卡片底部行：左侧「定位 · 时间」，右侧操作（详情 / 删除）同一行排布 */
.msg .msg-meta { align-items: center; }
.msg .msg-meta .mops { display: inline-flex; align-items: center; gap: 2px; }
/* 祝福详情弹窗 */
.bless-detail .bd-head { display: flex; align-items: center; gap: 10px; }
.bless-detail .bd-who { min-width: 0; }
.bless-detail .bd-top { display: flex; align-items: center; gap: 8px; }
.bless-detail .bd-when { font-size: 12px; color: var(--text-soft); margin-top: 4px; }
.bless-detail .bd-title { font-size: 16px; font-weight: 700; margin: 14px 0 8px; }
/* 正文保留换行（祝福内容本身可能分段，卡片里靠 \\n 折叠，详情里按原样展示） */
.bless-detail .bd-body { font-size: 14px; line-height: 1.8; font-family: var(--font-hand); white-space: pre-wrap; }
.blessing-pager { display: flex; justify-content: center; flex-wrap: wrap; gap: 6px; margin: 14px 0; }
/* 祝福页底部为小鱼特效预留空间，避免遮挡内容 */
.page-blessing { padding-bottom: calc(var(--tabbar-h) + 24px + 150px); }
/* 祝福页顶部头像区：比展示页更紧凑 */
.page-blessing .showcase-avatars { gap: 60px; margin: 6px 0 18px; }
/* PC 宽屏：祝福卡片改双列（与设计稿一致），单列在宽屏下每行过长
   align-items:start 让同排两张卡各自按内容高度显示，不被拉齐 */
@media (min-width: 1024px) {
  .msg-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; align-items: start; }
}

/* 约定（视觉对齐 docs/promise-ui-reference.html：勾选 / 公开私密 / 完成信息全用 SVG，不用 emoji） */
.promise-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 13px 14px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: var(--shadow);
  margin-bottom: 10px;
  transition: border-color .15s, box-shadow .15s;
}
.promise-item[data-edit-item] { cursor: pointer; }
.promise-item[data-edit-item]:hover { border-color: var(--primary); box-shadow: 0 4px 14px rgba(var(--accent-rgb), .08); }
/* 勾选框：未完成空心圈 / 已完成实心圈对勾，均为内联 SVG */
.promise-item .tick {
  flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--primary);
}
.promise-item .tick .ico { width: 22px; height: 22px; }
.promise-item .tick[data-toggle] { cursor: pointer; }
.promise-item.done .tick { color: var(--primary-deep); }
.promise-item .promise-text { flex: 1; min-width: 0; }
.promise-item.done .promise-text { text-decoration: line-through; color: var(--text-soft); }
/* 归属标题：另起一行的浅色小字（真实应用特有：单人「NN的愿望清单」/ 两人「NN和NN的约定」） */
.promise-item .promise-owner { flex-basis: 100%; font-size: 11.5px; color: var(--text-soft); }
/* 条目右侧：谁提出的 + 公开/私密徽章 + 编辑铅笔（对齐参考稿的 promise-tail） */
.promise-item .promise-tail { flex: none; display: inline-flex; align-items: center; gap: 8px; }
.promise-item .promise-creator {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; color: var(--text-soft);
  min-width: 0; max-width: 12em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.promise-item .edit-hint { display: inline-flex; color: var(--primary); }
.promise-item .edit-hint .ico { width: 15px; height: 15px; }
/* 副信息行：分类徽章 + 描述 + 目标日期（对齐参考稿的 pt-sub） */
.promise-item .pt-sub {
  flex-basis: 100%;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 11.5px; color: var(--text-soft);
}
.promise-item .pt-sub .pt-desc { flex: 1; min-width: 0; }
.promise-item .pt-sub .pt-date { display: inline-flex; align-items: center; gap: 4px; flex: none; }
.promise-item .pt-sub .pt-date .ico { width: 12px; height: 12px; }
.promise-item .pt-sub .pt-saving { flex: none; color: var(--ok); font-weight: 600; }
/* 完成信息：整行右对齐；管理态左端多出「取消完成」 */
.promise-item .promise-done-meta {
  flex-basis: 100%;
  display: flex; align-items: center; justify-content: flex-end; gap: 6px;
  font-size: 12px; color: var(--text-soft);
}
.promise-item .promise-done-meta.manage { justify-content: space-between; }
.promise-item .promise-done-meta .meta-fin { display: inline-flex; align-items: center; gap: 5px; }
.promise-item .promise-done-meta .meta-fin .ico { width: 14px; height: 14px; color: var(--primary); }
/* 取消完成：空心圈胶囊按钮（走对方审批，与参考稿一致） */
.promise-item .undo {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; color: var(--primary-deep); font-family: inherit;
  background: var(--panel-soft); border: 1px solid var(--border);
  padding: 3px 9px; border-radius: 999px; cursor: pointer;
}
.promise-item .undo .ico { width: 13px; height: 13px; color: var(--primary); }
/* 待对方确认完成：整行右对齐的浅色提示 */
.promise-item .promise-pending {
  flex-basis: 100%;
  display: flex; align-items: center; justify-content: flex-end; gap: 5px;
  font-size: 12px; color: var(--text-soft);
}
.promise-item .promise-pending .ico { width: 14px; height: 14px; color: var(--primary); }
/* 锁定中的清单：存在待处理申请，双方都不能操作（勾选 / 编辑入口已移除），整体压暗提示 */
.promise-item.locked { opacity: .72; }
/* 「谁的约定」：预览标题单独一行；下方账号胶囊与公开/私密胶囊并排一行，账号名过长自动省略 */
.owner-preview {
  font-size: 13px; color: var(--primary-deep); font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.owner-config { display: flex; align-items: center; gap: 12px; margin-top: 8px; }
.owner-config .privacy-seg { margin-left: 0; }
.owner-picks { display: flex; gap: 8px; min-width: 0; }
.owner-chip {
  min-width: 0; max-width: 9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 13px; padding: 9px 15px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--card); color: var(--text); cursor: pointer;
}
.owner-chip.on { background: var(--btn-grad); border-color: var(--btn-grad); color: var(--on-primary); font-weight: 600; }
/* 约定归属的三段式胶囊：我 / 对方 / 共同约定，等宽列、滑块按段位移 */
.dp-cal-seg.owner-seg {
  display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  max-width: 100%; flex: none;
}
.owner-seg .dp-cal-i { min-width: 0; text-align: center; overflow: hidden; text-overflow: ellipsis; }
.owner-seg .dp-cal-thumb { width: calc((100% - 8px) / 3); }
.owner-seg[data-mode="partner"] .dp-cal-thumb { transform: translateX(100%); }
.owner-seg[data-mode="all"] .dp-cal-thumb { transform: translateX(200%); }
/* 清单页顶部两张卡：整体进度 + 分类筛选（对齐 docs/prototype 的清单页） */
.p-prog { display: flex; align-items: center; gap: 12px; }
.p-prog-ico {
  width: 38px; height: 38px; flex: none; border-radius: 12px;
  background: var(--panel-soft); border: 1px solid var(--border); color: var(--primary-deep);
  display: flex; align-items: center; justify-content: center;
}
.p-prog-ico .ico { width: 21px; height: 21px; }
.p-prog-main { flex: 1; min-width: 0; }
.p-prog-top { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; font-size: 13.5px; font-weight: 700; }
.p-prog-top .badge { margin-left: auto; }
.p-bar { height: 8px; border-radius: 999px; background: var(--panel-soft); overflow: hidden; }
.p-bar > i { display: block; height: 100%; border-radius: 999px; background: var(--btn-grad); transition: width .3s ease; }
.p-prog-pct { font-size: 20px; font-weight: 800; color: var(--primary-deep); flex: none; }
/* 顶部合并卡：整体进度 + 分类筛选同卡，两段之间用虚线分隔 */
/* 滚动时固定在顶栏下方，进度与分类筛选始终可见 */
.p-top-card { position: sticky; top: var(--topbar-h); z-index: 5; }
.p-top-card .p-filters { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--border); }
.p-filters { display: flex; flex-wrap: wrap; gap: 8px; }
.p-chip {
  cursor: pointer; display: inline-flex; align-items: center; gap: 5px;
  padding: 6px 12px; border-radius: 999px; border: 1px solid var(--border);
  background: var(--surface); font-size: 12.5px; color: var(--text);
}
.p-chip b { font-weight: 700; color: var(--text-soft); }
.p-chip.on { background: var(--panel-soft); border-color: var(--primary); color: var(--primary-deep); font-weight: 600; }
.p-chip.on b { color: var(--primary-deep); }
/* 单栏分区：第二组（已完成）标题与上一组时间轴之间留白 */
.p-list .timeline + .sub-title { margin-top: 18px; }
/* 清单时间轴（复用相册的 .timeline/.tl-*）：日期上提到卡片上方与圆点对齐，卡片间不加额外间距 */
.p-list .timeline .promise-item { margin-bottom: 0; }
.p-list .tl-item:last-child { margin-bottom: 0; }
.p-list .tl-dot { top: 2px; }
.p-list .tl-date { margin: 0 0 6px; display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
/* 日期行内的完成信息与审批提示（从卡片上收而来，原样式挂在 .promise-item 下不生效，这里补齐） */
.p-list .tl-date .meta-fin { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-soft); }
.p-list .tl-date .meta-fin .ico { width: 14px; height: 14px; color: var(--primary); }
.p-list .tl-date .promise-pending { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-soft); }
.p-list .tl-date .promise-pending .ico { width: 14px; height: 14px; color: var(--primary); }

/* ===== 爱情清单列表页：对齐设计稿（进度卡 + 分类胶囊 + 分组卡片） ===== */
.pr-page .pr-pagehead { display: none; }
.pr-page .p-list { display: block; }
.pr-page .pr-top {
  position: sticky; top: var(--topbar-h); z-index: 5;
  padding: 15px; border: 1px solid var(--border); border-radius: 20px;
  background: var(--card); box-shadow: var(--shadow);
}
.pr-page .pr-top-row { display: flex; align-items: center; gap: 9px; }
.pr-page .pr-top-row .fi {
  width: 28px; height: 28px; flex: none; border-radius: 9px;
  background: var(--panel-soft); color: var(--primary-deep);
  display: grid; place-items: center;
}
.pr-page .pr-top-row .fi .ico { width: 15px; height: 15px; }
.pr-page .pr-top-row b { font-size: 13.5px; font-weight: 600; color: var(--text); }
.pr-page .pr-top-row .badge {
  margin-left: auto; height: 22px; padding: 0 9px; border-radius: 999px;
  background: var(--panel-soft); color: var(--primary-deep);
  font-size: 10.5px; display: inline-flex; align-items: center;
}
.pr-page .pr-bar { height: 7px; margin-top: 11px; border-radius: 999px; background: var(--panel-soft); overflow: hidden; }
.pr-page .pr-bar i { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--primary), var(--primary-deep)); transition: width .3s ease; }
.pr-page .pr-pct { margin-top: 7px; display: flex; align-items: baseline; justify-content: space-between; font-size: 11px; color: var(--text-soft); }
.pr-page .pr-pct b { font-family: var(--font-serif); font-size: 18px; font-weight: 600; color: var(--text); }
.pr-page .pr-cats {
  display: flex; gap: 6px; overflow-x: auto;
  margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--border);
}
.pr-page .pr-cat {
  flex: none; height: 30px; padding: 0 12px;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface); color: var(--text-soft);
  font: inherit; font-size: 12px; cursor: pointer;
}
.pr-page .pr-cat b { margin-left: 4px; font-size: 10.5px; font-weight: 500; opacity: .6; }
.pr-page .pr-cat.is-on { background: var(--text); border-color: var(--text); color: var(--bg); }
.pr-page .pr-sec { display: flex; align-items: baseline; gap: 8px; margin: 18px 0 10px; }
.pr-page .pr-sec h3 { margin: 0; font-family: var(--font-serif); font-size: 18px; font-weight: 600; color: var(--text); }
.pr-page .pr-sec span {
  height: 20px; padding: 0 8px; border-radius: 999px;
  background: var(--panel-soft); color: var(--text-soft);
  font-size: 10.5px; display: inline-flex; align-items: center;
}
.pr-page .pr-item {
  display: flex; gap: 10px; margin-bottom: 10px; padding: 13px 14px;
  border: 1px solid var(--border); border-radius: 17px;
  background: var(--card); box-shadow: var(--shadow);
  transition: border-color .15s, box-shadow .15s;
}
.pr-page .pr-item[data-edit-item] { cursor: pointer; }
.pr-page .pr-item[data-edit-item]:hover { border-color: var(--primary); box-shadow: var(--shadow-hover); }
.pr-page .pr-check {
  width: 20px; height: 20px; flex: none; margin-top: 1px;
  border: 1.5px solid var(--switch-track); border-radius: 50%;
  display: grid; place-items: center; color: var(--on-primary);
}
.pr-page .pr-check[data-toggle] { cursor: pointer; }
.pr-page .pr-check[data-toggle]:hover { border-color: var(--primary); }
.pr-page .pr-item.done .pr-check { background: var(--btn-grad); border-color: var(--btn-grad); }
.pr-page .pr-check svg { width: 12px; height: 12px; }
.pr-page .pr-main { flex: 1; min-width: 0; }
.pr-page .pr-main h4 { margin: 0; font-size: 14px; font-weight: 600; line-height: 1.5; color: var(--text); }
.pr-page .pr-item.done .pr-main h4 { color: var(--text-soft); text-decoration: line-through; }
.pr-page .pr-main .who {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin-top: 5px; font-size: 11px; color: var(--text-soft);
}
.pr-page .pr-tag {
  height: 18px; padding: 0 7px; border-radius: 999px;
  background: var(--panel-soft); color: var(--text-soft);
  font-size: 10px; display: inline-flex; align-items: center;
}
.pr-page .pr-main .meta { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; font-size: 10.5px; color: var(--text-soft); }
.pr-page .pr-main .meta i {
  font-style: normal; height: 21px; padding: 0 7px; border-radius: 6px;
  background: var(--panel-soft); display: inline-flex; align-items: center; gap: 4px;
}
.pr-page .pr-main .meta i .ico { width: 12px; height: 12px; }
.pr-page .pr-main .meta i.is-lock { background: var(--overdue-soft); color: var(--overdue-ink); }
.pr-page .pr-desc {
  margin-top: 7px; font-size: 11.5px; line-height: 1.6; color: var(--text-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pr-page .pr-main .own { margin-top: 7px; font-size: 10.5px; color: var(--text-soft); opacity: .82; }
.pr-page .pr-side { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.pr-page .pr-side:empty { display: none; }
.pr-page .pr-edit { display: inline-flex; color: var(--text-soft); opacity: .7; }
.pr-page .pr-edit .ico { width: 15px; height: 15px; }
.pr-page .pr-undo {
  display: inline-flex; align-items: center; gap: 4px;
  height: 26px; padding: 0 9px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--panel-soft);
  color: var(--primary-deep); font: inherit; font-size: 11px; cursor: pointer;
}
.pr-page .pr-undo .ico { width: 13px; height: 13px; }
.pr-page .pr-item.locked { opacity: .75; }
.pr-page .privacy-badge {
  display: inline-flex; align-items: center; gap: 3px;
  margin-left: 0; padding: 1px 6px; font-size: 9.5px;
}
.pr-page .privacy-badge svg { width: 10px; height: 10px; margin-right: 0; vertical-align: middle; }
.pr-page .privacy-badge.public { background: var(--panel-soft); color: var(--primary-deep); }
.pr-page .privacy-badge.private { background: var(--surface); color: var(--text-soft); border: 1px solid var(--border); }

@media (min-width: 1024px) {
  .pr-page .pr-pagehead { display: flex; align-items: center; gap: 16px; margin-bottom: 14px; }
  .pr-page .pr-pagehead .eyebrow {
    margin: 0 0 4px; font-size: 9px; font-weight: 600;
    letter-spacing: .22em; text-transform: uppercase; color: var(--text-soft);
  }
  .pr-page .pr-pagehead .t h2 {
    margin: 0; font-family: var(--font-serif);
    font-size: 26px; font-weight: 600; line-height: 1.15; letter-spacing: -.01em; color: var(--text);
  }
  .pr-page .pr-pagehead .acts { margin-left: auto; display: flex; align-items: center; gap: 8px; }
  .pr-page .pr-new {
    display: inline-flex; align-items: center; gap: 5px;
    height: 36px; padding: 0 14px; border: 0; border-radius: 10px;
    background: var(--btn-grad); color: var(--on-primary);
    font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer;
    box-shadow: var(--shadow-accent);
  }
  .pr-page .pr-new .ico { width: 15px; height: 15px; }
  .pr-page .pr-top { top: calc(var(--topbar-h) + 4px); }
  body.promise-page .topbar-title { visibility: hidden; }
}
/* 空状态图标：与「还没有日常 / 相册」等保持同一套线描图标风格 */
.empty .empty-ico { display: block; width: 46px; height: 46px; margin: 0 auto 10px; color: var(--primary-soft); }

/* 字段式表单：清单新建页与编辑弹窗共用（外观对齐 docs/prototype 的 ls-sheet 表单） */
.ls-field { margin-bottom: 14px; }
.ls-field > label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 8px; }
.ls-input, .ls-textarea {
  width: 100%; border: 1px solid var(--border); border-radius: 12px;
  padding: 11px 12px; font-size: 14px; color: var(--text);
  background: var(--surface); font-family: inherit; outline: none;
}
.ls-input:focus, .ls-textarea:focus { border-color: var(--primary); }
.ls-textarea { min-height: 92px; resize: vertical; line-height: 1.6; }
.ls-pick { display: flex; flex-wrap: wrap; gap: 8px; }
.ls-pick .opt {
  position: relative; padding: 8px 14px; border-radius: 999px; border: 1px solid var(--border);
  background: var(--surface); color: var(--text); font-size: 13px; cursor: pointer;
  user-select: none; -webkit-touch-callout: none;
}
.ls-pick .opt.on { background: var(--panel-soft); border-color: var(--primary); color: var(--primary-deep); font-weight: 600; }
/* 分类胶囊可自定义：末尾「+」新增（到 20 个上限即隐藏）；PC 右键「修改 / 删除」；
   移动端长按进入编辑态：胶囊右上角出 ×，点胶囊改名，「+」变「确认」退出 */
.ls-pick .opt-add { display: inline-block; border-style: dashed; color: var(--text-soft); }
.ls-pick .opt-add.is-max { display: none; }
.ls-pick .opt-add .pro-done { display: none; }
.ls-pick.p-editing .opt-add {
  display: inline-block; border-style: solid; border-color: var(--primary);
  color: var(--primary-deep); font-weight: 600;
}
.ls-pick.p-editing .opt-add .pro-plus { display: none; }
.ls-pick.p-editing .opt-add .pro-done { display: inline; }
.ls-pick.p-editing .opt:not(.opt-add) { border-style: dashed; }
.ls-pick .pro-del {
  display: none; position: absolute; top: -6px; right: -6px;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--danger); color: #fff;
  font-size: 12px; line-height: 16px; text-align: center; cursor: pointer;
}
.ls-pick.p-editing .pro-del { display: block; }
.ls-row { display: flex; gap: 10px; margin-top: 14px; }
.ls-btn {
  flex: 1; height: 46px; border-radius: 14px; border: none; cursor: pointer;
  background: var(--btn-grad); color: var(--on-primary); font-size: 14.5px; font-weight: 700;
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.ls-btn.ghost { background: var(--surface); border: 1px solid var(--primary); color: var(--primary-deep); }
.ls-btn.danger { background: var(--danger); }
.ls-btn:disabled { opacity: .6; cursor: default; }
.ls-btn .ico { width: 16px; height: 16px; }
/* PC 端：进度卡与筛选更舒展 */
@media (min-width: 1024px) {
  .p-prog-ico { width: 44px; height: 44px; }
  .p-prog-ico .ico { width: 24px; height: 24px; }
  .p-chip { padding: 7px 14px; font-size: 13px; }
}

/* ===== 按钮 ===== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: none;
  border-radius: 14px;
  padding: 12px 18px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: transform .12s, opacity .2s;
  font-family: inherit;
}
.btn:active { transform: scale(0.97); }
/* 生成中按钮：秒数用等宽数字，避免每秒刷新时按钮宽度跳动 */
.btn.is-generating { font-variant-numeric: tabular-nums; }
.btn-primary { background: var(--btn-grad); color: var(--on-primary); box-shadow: var(--shadow-accent); }
.btn-ghost { background: var(--surface); color: var(--primary-deep); border: 1px solid var(--primary); }
/* 锁定态：不用 disabled 属性（会吞掉 click 导致无法提示），仅降透明度，点击时由 JS 弹出原因 */
.btn.is-locked { opacity: .5; }
.btn-block { width: 100%; }
.btn-sm { padding: 7px 12px; font-size: 13px; border-radius: 10px; }
/* 衣柜三视图处理按钮：三等分窄按钮，忙碌文案（识别中…/出图 95%）禁止换行 */
.wAIExec { white-space: nowrap; }

.fab {
  position: fixed;
  right: 18px;
  bottom: calc(var(--tabbar-h) + 24px);
  z-index: 25;
  width: 54px; height: 54px;
  border-radius: 50%;
  border: none;
  background: var(--btn-grad);
  color: #fff;
  font-size: 28px;
  box-shadow: var(--shadow-accent-strong);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
/* 祝福公开页右下角写信按钮 */
.bless-fab {
  position: fixed;
  right: 20px;
  bottom: 160px;
  z-index: 40;
  width: 52px; height: 52px;
  border-radius: 50%;
  border: none;
  background: var(--surface);
  box-shadow: var(--shadow-float-sm);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: transform .12s;
}
.bless-fab:hover { transform: scale(1.06); }
.count-hint { font-size: 12px; color: var(--text-soft); text-align: right; margin-top: 4px; }
.bless-textarea { min-height: 96px; }
.bless-tip { font-size: 12px; color: var(--text-soft); text-align: center; margin-top: 10px; line-height: 1.5; }

/* ===== 表单 ===== */
.field { margin-bottom: 14px; }
.field label { display: block; font-size: 13px; color: var(--text-soft); margin-bottom: 6px; }
/* 可收起字段（心情 / 天气）：默认收起，标题行右侧显示当前已选值，点标题行展开 / 收起。
   必须放在 .field label 之后：两者同为「单类 + 元素」选择器，靠定义顺序覆盖它的 margin-bottom。 */
.field-fold-head { display: flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; -webkit-user-select: none; }
.field-fold-head label { margin-bottom: 0; cursor: pointer; }
.field-fold .fold-cur { margin-left: auto; font-size: 12.5px; color: var(--text-soft); }
.field-fold .fold-chev { flex: none; font-size: 11px; line-height: 1; color: var(--text-soft); transition: transform .2s ease; }
.field-fold.open .fold-chev { transform: rotate(180deg); }
.field-fold .chip-row { margin-top: 10px; }
.field-label-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.field-label-row label { margin-bottom: 0; }
.ai-polish-btn { padding: 0; display: inline-flex; align-items: center; color: var(--primary); }
.ai-polish-btn svg { width: 20px; height: 20px; pointer-events: none; fill: currentColor; }
/* 模型名获取列表按钮与浮层 */
.model-field { position: relative; }
.model-row { display: flex; gap: 8px; align-items: center; }
.model-row input { flex: 1; }
.model-fetch-btn { color: var(--primary); flex: none; }
.model-fetch-btn svg { width: 20px; height: 20px; }
.model-fetch-btn:disabled { opacity: .5; }
.model-dd {
  display: none;
  position: absolute; left: 0; right: 0; top: calc(100% - 14px);
  z-index: calc(var(--z-dropdown) + 1);
  background: var(--card, #fff);
  border: 1px solid var(--border, #ffe3ea);
  border-radius: 12px;
  box-shadow: var(--shadow-float);
  max-height: 220px;
  overflow-y: auto;
}
.model-dd.on { display: block; }
.model-dd .dd-opt { padding: 10px 14px; font-size: 13px; color: var(--text, #4a3b40); cursor: pointer; }
.model-dd .dd-opt:hover { background: var(--bg, #fff7f9); color: var(--primary-deep, #b0355b); }
.ai-polish-btn:disabled { opacity: .5; cursor: not-allowed; }
.field-maskable { position: relative; }
.ai-polish-mask {
  position: absolute; inset: 0; z-index: 5; display: none;
  flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  background: rgba(255, 255, 255, .78); border-radius: 12px;
  font-size: 13px; color: #888;
}
.ai-polish-mask.on { display: flex; }
.ai-polish-mask .spinner {
  width: 22px; height: 22px; border-radius: 50%;
  border: 2px solid #e0b3f0; border-top-color: transparent;
  animation: aiSpin .8s linear infinite;
}
@keyframes aiSpin { to { transform: rotate(360deg); } }
.tip {
  position: relative; display: inline-block; margin-left: 5px;
  width: 14px; height: 14px; line-height: 14px; text-align: center;
  font-size: 10px; color: var(--on-primary); background: var(--btn-grad); border-radius: 50%;
  cursor: help; vertical-align: 1px;
}
.tip:focus-visible { outline: 2px solid var(--primary-deep); outline-offset: 2px; }
/* 触屏：放大帮助徽标，指尖可稳定点按（14px 对触摸目标过小） */
@media (hover: none) {
  .tip { width: 18px; height: 18px; line-height: 18px; font-size: 12px; margin-left: 6px; vertical-align: -2px; }
}

/* ===== 全站悬停提示浮层 =====
   由 JS 统一定位（见 app.js initTooltips）：单个浮层接管原生 title 与 [data-tip]，
   上方空间不足时自动翻转到下方，并贴合视口左右边界；深色底与 toast 呼应 */
.ui-tip {
  position: fixed; top: 0; left: 0; z-index: 400;
  max-width: 240px; padding: 8px 11px; border-radius: 10px;
  background: rgba(74, 59, 64, .96); color: #fff;
  font-size: 12px; line-height: 1.55; text-align: left;
  box-shadow: var(--shadow-float);
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translateY(3px);
  transition: opacity .16s ease, transform .16s ease, visibility .16s;
}
.ui-tip.on { opacity: 1; visibility: visible; transform: translateY(0); }
.ui-tip[data-pos="bottom"] { transform: translateY(-3px); }
.ui-tip[data-pos="bottom"].on { transform: translateY(0); }
.ui-tip .ui-tip-arrow {
  position: absolute; width: 10px; height: 10px;
  background: rgba(74, 59, 64, .96); transform: rotate(45deg);
}
.ui-tip[data-pos="top"] .ui-tip-arrow { bottom: -5px; }
.ui-tip[data-pos="bottom"] .ui-tip-arrow { top: -5px; }
@media (prefers-reduced-motion: reduce) {
  .ui-tip, .ui-tip[data-pos="bottom"], .ui-tip.on, .ui-tip[data-pos="bottom"].on { transform: none; }
  .ui-tip { transition: opacity .12s ease, visibility .12s; }
}

/* 一言自动获取开关 */
.field label.hk-switch { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13px; color: var(--text); user-select: none; margin-bottom: 8px; }
.hk-switch input { display: none; }
.hk-switch .sw { position: relative; width: 40px; height: 22px; border-radius: 999px; background: var(--switch-track); transition: background .2s; flex: none; }
.hk-switch .sw::after { content: ""; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: #fff; transition: left .2s; box-shadow: 0 1px 3px rgba(176, 53, 91, .16); }
.hk-switch input:checked + .sw { background: var(--btn-grad); }
.hk-switch input:checked + .sw::after { left: 20px; }
.hk-switch .hk-switch-label { color: var(--text); }
.hk-switch #hkSwitchText, .hk-switch .hk-switch-text { color: var(--text-soft); font-size: 12px; }
/* 一言：左侧标题 + 右侧总开关同一行 */
.hs-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.hs-row .hk-switch { margin-bottom: 0; }
.hk-types { margin-top: 10px; margin-bottom: 6px; }
.hk-types .chip { font-size: 12px; padding: 6px 11px; }
.field input, .field textarea, .field select {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  font-size: 15px;
  font-family: inherit;
  color: var(--text);
  outline: none;
  transition: border-color .2s, box-shadow .2s;
}
.field input:focus, .field textarea:focus, .field select:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.14);
}
.field textarea { min-height: 100px; resize: vertical; }
/* 关键词标签输入（快捷指令）：容器伪装成输入框，内部是可删除标签 + 行内输入框 */
.tag-input {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 8px 10px;
  border: 1px solid var(--border); border-radius: 12px;
  background: var(--surface);
  transition: border-color .2s, box-shadow .2s;
}
.tag-input:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.14); }
.kw-tags { display: contents; }
.field .tag-input input {
  flex: 1 1 90px; width: auto; min-width: 80px;
  padding: 4px 2px; border: 0; border-radius: 0;
  background: transparent; box-shadow: none; font-size: 15px;
}
.field .tag-input input:focus { box-shadow: none; }
.kw-tag {
  display: inline-flex; align-items: center; gap: 4px;
  max-width: 100%; padding: 4px 6px 4px 10px;
  border-radius: 999px;
  background: var(--primary-soft); color: var(--primary-deep);
  font-size: 13px; line-height: 1.5;
}
.kw-tag-x {
  border: 0; background: transparent; color: inherit;
  font-size: 14px; line-height: 1; padding: 0 2px;
  cursor: pointer; opacity: .65;
}
.kw-tag-x:hover { opacity: 1; }
.tag-add {
  flex: none; border: 0; background: transparent; color: var(--primary-deep);
  font-size: 13px; padding: 4px 6px; border-radius: 8px; cursor: pointer;
}
.tag-add:hover { background: var(--primary-soft); }
/* 快捷指令列表：左侧「名称 + 关键词标签」两行，右侧动作与操作 */
.qc-row { align-items: flex-start; gap: 12px; }
.qc-main { flex: 1; min-width: 0; }
.qc-name { font-size: 15px; font-weight: 600; color: var(--text); line-height: 1.5; }
.qc-kws { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.kw-tag-plain { padding: 3px 9px; }
.qc-actions { display: flex; align-items: center; gap: 8px; flex: none; padding-top: 2px; }
/* 正文话题高亮：textarea 不能给局部文字上色，所以在它背后铺一层排版完全一致的镜像层，
   只画 #话题 那几段的底色，textarea 的文字照常显示在上层。
   镜像的 padding / border / 字号 / 换行规则必须与 .field textarea 对齐，差一点文字就会错位；
   底色由 .ta-hl 承担（textarea 转透明），否则深色下会与卡片底色不一致。 */
.ta-hl { position: relative; background: var(--surface); border-radius: 12px; }
.ta-hl textarea { position: relative; z-index: 1; background: transparent; }
.ta-hl-mirror {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none;
  padding: 12px 14px; border: 1px solid transparent; border-radius: 12px;
  font-size: 15px; font-family: inherit; line-height: normal; color: transparent;
  white-space: pre-wrap; overflow-wrap: break-word;
}
.ta-hl-mirror mark { background: var(--primary-soft); color: transparent; border-radius: 4px; }

/* 多个表单控件同行显示（如衣柜的大类/小类/材质） */
.field-row { display: flex; gap: 10px; }
.field-row .field { flex: 1; min-width: 0; }

/* 自定义下拉组件：按钮 + 浮层选项列表（替代原生 select，风格与应用一致） */
.dd { position: relative; z-index: var(--z-dropdown); }
/* 展开中的下拉宿主再抬 1 级：确保它的选项压住相邻下拉按钮，而不是被后出现的同档宿主盖住 */
.dd.dd-open { z-index: calc(var(--z-dropdown) + 1); }
.dd-btn {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  font-size: 15px;
  font-family: inherit;
  color: var(--text);
  cursor: pointer;
  text-align: left;
  outline: 0;
  transition: border-color .15s ease, background .15s ease, box-shadow .15s ease, color .15s ease;
}
.dd-txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dd-arrow {
  flex: none; width: 8px; height: 8px; margin-right: 4px;
  border-right: 1.5px solid var(--text-soft); border-bottom: 1.5px solid var(--text-soft);
  transform: rotate(45deg) translateY(-2px);
  transition: transform .2s ease, border-color .15s ease;
}
.dd-btn:hover { border-color: var(--primary-soft); color: var(--primary-deep); }
.dd-btn:hover .dd-arrow { border-color: var(--primary-deep); }
.dd-btn:focus-visible { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(var(--primary-rgb), .14); }
.dd.dd-open .dd-btn { border-color: var(--primary); background: var(--panel-soft); color: var(--primary-deep); }
.dd.dd-open .dd-arrow { border-color: var(--primary-deep); transform: rotate(225deg) translateY(-1px); }
.dd-list {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: var(--z-dropdown);
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: var(--shadow-float);
  padding: 6px; max-height: 242px; overflow-y: auto;
}
/* 挂到 body 的浮层列表：fixed 定位，层级高于普通弹窗（100）与叠层弹窗（350），
   不受弹窗 overflow 裁剪；位置 / 宽度由 mountDD 按按钮 rect 写入内联样式。 */
.dd-list.dd-portal { position: fixed; left: auto; right: auto; top: auto; bottom: auto; z-index: 400; }
.dd-opt { padding: 10px 12px; border-radius: 8px; font-size: 15px; color: var(--text); cursor: pointer; }
.dd-opt:hover,
.dd-opt.dd-hover { background: var(--bg); }
.dd-opt.active { background: var(--primary-soft); font-weight: 600; }
.dd-opt.dd-hover.active { background: var(--primary-soft); }
/* 当前项标记：勾（不计数）。列表行是 block 时靠 float 贴右；
   排版面板那行是 flex，float 失效但 .ls-pick-txt 的 flex:1 会把它推到最右。 */
.dd-opt .pick-mark { --pick-sz: 18px; display: none; float: right; }
.dd-opt.active .pick-mark { display: inline-flex; }
/* 相册编辑页的摄影师 / 模特：默认显示站内下拉（.dd），选「自定义…」时就地换成输入框 ——
   同一槽位、同高同宽，切换不跳版。输入框始终是值的载体，下拉只负责把选中的候选写进去。 */
.credit-fields .credit-in { display: none; width: 100%; }
.credit-fields .field.custom .credit-in { display: block; }
.credit-fields .field.custom .credit-dd { display: none; }

/* 日期选择器（半 UI 风格） */
.dp { position: relative; }
.dp-input {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  font-size: 15px;
  color: var(--text);
  cursor: pointer;
  transition: border-color .2s;
}
.dp-input:active { border-color: var(--primary); }

/* 事件表单：「日历」「重复」并排一行（日期本身仍用 .dp 日期选择器） */
.field-row { display: flex; gap: 10px; }
.field-row .field { flex: 1; min-width: 0; }
/* 下拉自定义外观：去掉系统原生样式，自绘一个 chevron 箭头。
   两处容器都要覆盖：.field-row（事件表单）与 .form-row（备份管理 / 数据恢复的设置行） */
.field-row select,
.form-row select {
  appearance: none; -webkit-appearance: none;
  width: 100%; font-family: inherit; font-size: 15px; color: var(--text);
  padding: 11px 34px 11px 12px; border: 1px solid var(--border); border-radius: 12px;
  background-color: var(--surface);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239b8a90' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 11px center; background-size: 15px;
  cursor: pointer; transition: border-color .2s;
}
.field-row select:focus,
.form-row select:focus { border-color: var(--primary); outline: none; }
/* 农历事件在列表里附带的公历参照 */
.cd-solar-ref { font-size: 11.5px; color: var(--text-soft); }
/* 日期选择器：公历面板里逐日标注的农历日（无节日时才显示，与节日简称共用同一位置） */
.dp-lunar-t { display: block; font-size: 9px; line-height: 1.2; font-style: normal; color: var(--text-soft); opacity: .8; }

/* 「公历 / 农历」两段式胶囊：嵌在日期输入框内部右侧，整体高度与普通日期框一致 */
.dp-input.has-seg { display: flex; align-items: center; gap: 10px; padding: 6px 8px 6px 14px; }
.dp-input.has-seg .dp-input-txt { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dp-cal-seg {
  flex: none; position: relative; display: inline-flex; align-items: center;
  padding: 4px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--panel-soft); cursor: pointer; user-select: none;
}
.dp-cal-thumb {
  position: absolute; top: 4px; left: 4px; width: calc(50% - 4px); height: calc(100% - 8px);
  border-radius: 999px; background: var(--btn-grad);
  transition: transform .22s cubic-bezier(.4, 0, .2, 1);
}
/* 滑块位置＝「右段被选中」这一种状态：农历(lunar) / 每年重复(yearly) / 私密(private) 都在右段。
   注意两段式胶囊的 data-mode 取值随控件而不同，不能只认 lunar。 */
.dp-cal-seg[data-mode="lunar"] .dp-cal-thumb,
.dp-cal-seg[data-mode="yearly"] .dp-cal-thumb,
.dp-cal-seg[data-mode="private"] .dp-cal-thumb { transform: translateX(100%); }
.dp-cal-i {
  position: relative; z-index: 1; padding: 7px 16px; font-size: 13.5px; font-weight: 600;
  color: var(--text-soft); white-space: nowrap; transition: color .2s;
}
.dp-cal-i.active { color: #fff; }
.dp-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0; right: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: var(--shadow-float);
  padding: 12px;
  z-index: 120;
  /* 矮屏（手机横屏 / 小窗口）时面板可能比视口还高：限高并允许内部滚动，
     否则底部的日期会被切在屏幕外，点不到。 */
  max-height: calc(100vh - 16px);
  overflow-y: auto;
}
.dp-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.dp-title { font-size: 15px; font-weight: 700; }
.dp-nav { font-size: 20px; color: var(--text-soft); cursor: pointer; padding: 0 8px; user-select: none; }
.dp-nav:hover { color: var(--primary-deep); }
.dp-week { display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; font-size: 11px; color: var(--text-soft); margin-bottom: 4px; }
.dp-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.dp-cell {
  height: 36px;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px;
  border-radius: 50%;
  cursor: pointer;
}
/* 悬停：同款虚线圆环，取灰色（未选中态；选中格由下方 .dp-sel 覆盖，悬停不回退） */
.dp-cell:hover {
  background-color: transparent;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 28'%3E%3Cpath fill='%23999999' d='M12.123 2.146a12.1 12.1 0 0 1 3.754 0a.75.75 0 1 1-.233 1.482a10.6 10.6 0 0 0-3.288 0a.75.75 0 0 1-.233-1.482m-9.12 9.353a.75.75 0 0 1 .625.857a10.6 10.6 0 0 0 0 3.288a.75.75 0 0 1-1.482.233a12.1 12.1 0 0 1 0-3.754a.75.75 0 0 1 .857-.624m21.994 0a.75.75 0 0 1 .857.624a12.1 12.1 0 0 1 0 3.754a.75.75 0 0 1-1.482-.233a10.6 10.6 0 0 0 0-3.288a.75.75 0 0 1 .625-.857M11.499 24.997a.75.75 0 0 1 .857-.625a10.6 10.6 0 0 0 3.288 0a.75.75 0 1 1 .233 1.482a12.1 12.1 0 0 1-3.754 0a.75.75 0 0 1-.624-.857M21.055 4.29a12.1 12.1 0 0 1 2.654 2.654a.75.75 0 0 1-1.212.883a10.6 10.6 0 0 0-2.325-2.325a.75.75 0 0 1 .883-1.212m-13.062.164a.75.75 0 0 1-.165 1.048a10.6 10.6 0 0 0-2.325 2.325a.75.75 0 0 1-1.212-.883A12.1 12.1 0 0 1 6.945 4.29a.75.75 0 0 1 1.048.164m15.551 15.552a.75.75 0 0 1 .165 1.048a12.1 12.1 0 0 1-2.654 2.654a.75.75 0 1 1-.883-1.212a10.6 10.6 0 0 0 2.325-2.325a.75.75 0 0 1 1.047-.165m-19.089 0a.75.75 0 0 1 1.048.165a10.6 10.6 0 0 0 2.325 2.325a.75.75 0 1 1-.883 1.212a12 12 0 0 1-2.654-2.654a.75.75 0 0 1 .164-1.048'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 100% 100%;
}
.dp-cell.dp-empty { pointer-events: none; }
/* 选中日期：虚线圆环（原图标中心的心形已去掉，让位给日期数字） */
.dp-cell.dp-sel {
  background-color: transparent;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 28'%3E%3Cpath fill='%23f06b93' d='M12.123 2.146a12.1 12.1 0 0 1 3.754 0a.75.75 0 1 1-.233 1.482a10.6 10.6 0 0 0-3.288 0a.75.75 0 0 1-.233-1.482m-9.12 9.353a.75.75 0 0 1 .625.857a10.6 10.6 0 0 0 0 3.288a.75.75 0 0 1-1.482.233a12.1 12.1 0 0 1 0-3.754a.75.75 0 0 1 .857-.624m21.994 0a.75.75 0 0 1 .857.624a12.1 12.1 0 0 1 0 3.754a.75.75 0 0 1-1.482-.233a10.6 10.6 0 0 0 0-3.288a.75.75 0 0 1 .625-.857M11.499 24.997a.75.75 0 0 1 .857-.625a10.6 10.6 0 0 0 3.288 0a.75.75 0 1 1 .233 1.482a12.1 12.1 0 0 1-3.754 0a.75.75 0 0 1-.624-.857M21.055 4.29a12.1 12.1 0 0 1 2.654 2.654a.75.75 0 0 1-1.212.883a10.6 10.6 0 0 0-2.325-2.325a.75.75 0 0 1 .883-1.212m-13.062.164a.75.75 0 0 1-.165 1.048a10.6 10.6 0 0 0-2.325 2.325a.75.75 0 0 1-1.212-.883A12.1 12.1 0 0 1 6.945 4.29a.75.75 0 0 1 1.048.164m15.551 15.552a.75.75 0 0 1 .165 1.048a12.1 12.1 0 0 1-2.654 2.654a.75.75 0 1 1-.883-1.212a10.6 10.6 0 0 0 2.325-2.325a.75.75 0 0 1 1.047-.165m-19.089 0a.75.75 0 0 1 1.048.165a10.6 10.6 0 0 0 2.325 2.325a.75.75 0 1 1-.883 1.212a12 12 0 0 1-2.654-2.654a.75.75 0 0 1 .164-1.048'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 100% 100%;
  color: var(--primary-deep);
  font-weight: 700;
}
.dp-mask { position: fixed; inset: 0; z-index: 110; }

/* 标签行 */
.chip-row { display: flex; flex-wrap: wrap; gap: 8px; }
/* hidden 属性在 flex 元素上会被 display 覆盖，这里显式兜底（一言类型多选靠它隐藏） */
.chip-row[hidden] { display: none; }
.chip {
  padding: 8px 14px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--border);
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
  transition: .15s;
}
.chip.active { background: var(--btn-grad); color: var(--on-primary); border-color: var(--btn-grad); }
/* 选项胶囊里的心情/天气图标：略大于 13px 文字，与文字基线对齐 */
.chip .ico { width: 15px; height: 15px; vertical-align: -0.18em; }
/* 天气/心情 chip：彩色图标比线性图标占地方，故与常规胶囊等高——18px 图标 + 上下 8px = 34px（常规 33px）；
   同时去掉胶囊那圈 1px 边框，视觉更轻；大图标靠 vertical-align 对不齐文字，改弹性盒居中，间距用 gap 补 */
.chip[data-weather], .chip[data-mood] { display: inline-flex; align-items: center; gap: 6px; border: none; }
.chip[data-weather] .ico, .chip[data-mood] .ico { width: 18px; height: 18px; }
.chip-add { border-style: dashed; color: var(--text-soft); }
/* 只读胶囊：详情页展示已选标签用，外观同 .chip 但不可点击、弱化一档 */
.chip-static {
  display: inline-flex; align-items: center;
  padding: 5px 12px; border-radius: 999px;
  background: var(--bg); border: 1px solid var(--border);
  font-size: 12px; line-height: 1.4; color: var(--text-soft);
}

/* ===== 衣柜设置 · 分类设置列表（移动端侧滑操作 / PC 行内操作） ===== */
.wset-list { display: flex; flex-direction: column; border: 1px solid var(--border); border-radius: 12px; overflow: hidden; background: var(--surface); }
.wset-swipe { --wset-act-w: 144px; position: relative; overflow: hidden; border-bottom: 1px solid var(--border); }
/* 带「查看」的分类行：三个操作共 216px */
.wset-swipe.with-view { --wset-act-w: 216px; }
.wset-row {
  position: relative; z-index: 2; display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; background: var(--surface); cursor: pointer;
  transition: transform .22s cubic-bezier(.22, .61, .36, 1); touch-action: pan-y;
}
.wset-row.active { background: var(--panel-soft); }
.wset-row.active::before {
  content: ""; position: absolute; left: 0; top: 8px; bottom: 8px; width: 3px;
  border-radius: 0 3px 3px 0; background: var(--btn-grad);
}
.wset-row.active .wset-name { color: var(--primary-deep); font-weight: 600; }
.wset-swipe.open .wset-row { transform: translateX(calc(-1 * var(--wset-act-w))); }
/* 拖动中的行：弱化并抬高，明确「正在移动的是这一行」 */
.wset-swipe.dragging { opacity: .55; box-shadow: var(--shadow-hover); }
.wset-swipe.dragging .wset-row { background: var(--bg); }
.wset-grip { display: inline-flex; flex: none; padding: 2px; color: var(--text-soft); cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.wset-grip:active { cursor: grabbing; }
.wset-grip .ico { width: 16px; height: 16px; }
.wset-name { flex: 1; min-width: 0; font-size: 14px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wset-meta { flex: none; padding: 3px 8px; border: 1px solid var(--border); border-radius: 999px; background: var(--bg); font-size: 11.5px; color: var(--text-soft); }
/* 行内操作：移动端藏在行下方，左滑露出 */
.wset-actions { position: absolute; top: 0; right: 0; bottom: 0; z-index: 1; display: flex; width: var(--wset-act-w); }
.wset-act { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; padding: 0; border: none; border-left: 1px solid rgba(255, 255, 255, .7); font-family: inherit; font-size: 11px; font-weight: 600; cursor: pointer; }
.wset-act .ico { width: 17px; height: 17px; }
.wset-act-view { background: #f2edf4; color: #6b5b75; }
.wset-act-edit { background: var(--panel-soft); color: var(--primary-deep); }
.wset-act-del { background: var(--danger); color: #fff; }
.wset-add { display: flex; align-items: center; justify-content: center; gap: 6px; padding: 10px 12px; background: var(--surface); font-size: 13px; color: var(--text-soft); cursor: pointer; transition: background .15s, color .15s; }
.wset-add:hover { background: var(--bg); color: var(--primary-deep); }
.wset-add .ico { width: 15px; height: 15px; }
/* 删除确认：名称未输入正确前按钮不可点 */
.wset-confirm-del:disabled { opacity: .5; cursor: not-allowed; }
/* 分类提示词只读弹窗 */
.wset-prompt-src { margin-bottom: 8px; font-size: 12px; color: var(--text-soft); }
.wset-prompt-text { max-height: 50vh; overflow: auto; padding: 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg); font-size: 13px; line-height: 1.7; color: var(--text); white-space: pre-wrap; word-break: break-word; }
.wset-prompt-tip { margin-top: 10px; font-size: 12px; line-height: 1.6; color: var(--text-soft); }
/* PC：不启用侧滑，操作图标常显在行内 */
@media (min-width: 1024px) {
  .wset-swipe { display: flex; align-items: center; }
  .wset-row { order: 1; flex: 1; min-width: 0; transform: none !important; }
  .wset-actions { order: 2; position: static; width: auto; padding-right: 8px; background: var(--surface); opacity: .55; transition: opacity .15s; }
  .wset-swipe:hover .wset-actions { opacity: 1; }
  .wset-act { flex: none; width: 30px; height: 30px; gap: 0; border: none; border-radius: 8px; background: transparent; color: var(--text-soft); }
  .wset-act span { display: none; }
  .wset-act .ico { width: 16px; height: 16px; }
  .wset-act:hover { background: var(--bg); color: var(--primary-deep); }
  .wset-act-del:hover { background: var(--danger-soft); color: var(--danger-ink); }
}

/* ===== 列表搜索框 ===== */
.list-search { position: relative; margin-bottom: 12px; }
/* 搜索结果页：分类标签（全部 / 内容 / 图片 / 评论）+ 命中列表 */
.ai-sr-tabs { display: flex; gap: 6px; margin-bottom: 12px; flex-wrap: wrap; }
.ai-sr-tab { padding: 5px 12px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface);
  color: var(--text-soft); font-size: 13px; cursor: pointer; }
.ai-sr-tab b { margin-left: 4px; font-weight: 600; }
.ai-sr-tab.active { border-color: var(--btn-grad); background: var(--btn-grad); color: var(--on-primary); }
.ai-sr-item { display: flex; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.ai-sr-item:last-child { border-bottom: none; }
.ai-sr-thumb { flex: none; width: 56px; height: 56px; border-radius: 8px; object-fit: cover; background: var(--bg); }
.ai-sr-body { flex: 1; min-width: 0; }
.ai-sr-text { font-size: 14px; color: var(--text); line-height: 1.5; word-break: break-word; }
.ai-sr-meta { margin-top: 4px; font-size: 12px; color: var(--text-soft); }
/* 搜索结果提示条：说明「在搜什么、找到几条」，让搜索这件事在页面上看得见 */
.search-bar { margin: 0 0 10px; font-size: 13px; color: var(--text-soft); }
.search-bar b { color: var(--primary-deep); font-weight: 600; }
/* 搜图：比对过程在列表位置显示的进度条（上传走真实百分比，之后切成滚动的不确定动画） */
.ps-progress { padding: 26px 2px; }
.ps-progress-bar { height: 6px; border-radius: 999px; background: var(--border); overflow: hidden; }
.ps-progress-in { height: 100%; width: 0; border-radius: 999px; background: var(--primary); transition: width .25s; }
.ps-progress-in.indet { width: 40%; animation: psIndet 1.1s ease-in-out infinite; }
@keyframes psIndet {
  0% { margin-left: -42%; }
  100% { margin-left: 102%; }
}
.ps-progress-text { margin-top: 10px; text-align: center; font-size: 13px; color: var(--text-soft); }
/* 搜图结果：照片网格，每张下方注明出处；点开走站内查看器（可左右翻看这批结果）。
   单元格最小宽度 150px：比早前的 104px 明显大一圈，手机上稳定两列、桌面按宽度再多排。 */
.ai-sr-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.ai-sr-cell { display: flex; flex-direction: column; gap: 5px; cursor: zoom-in; }
.ai-sr-shot { position: relative; aspect-ratio: 1; border-radius: 10px; overflow: hidden;
  background: var(--bg); border: 1px solid var(--border); }
.ai-sr-shot img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .2s; }
.ai-sr-cell:hover .ai-sr-shot img { transform: scale(1.05); }
.ai-sr-sim { position: absolute; right: 4px; bottom: 4px; padding: 1px 6px; border-radius: 999px;
  background: rgba(0, 0, 0, .55); color: #fff; font-size: 10px; font-weight: 700; }
.ai-sr-cap { font-size: 11.5px; line-height: 1.4; color: var(--text-soft);
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
/* 文本结果的类型徽章，让「内容 / 评论」一眼分得清 */
.ai-sr-badge { display: inline-block; padding: 1px 7px; margin-right: 4px; border-radius: 999px;
  background: var(--panel-soft); color: var(--text-soft); font-size: 11px; }
/* 评论命中的卡片：外壳与日记卡片同构（.list-item.post），卡上是评论本身。
   正文用正文字体（不用日记的手写体）——评论是随手写下的话，不是日记正文。 */
.sr-cmt-where { font-size: 12.5px; color: var(--text-soft); }
.sr-cmt-body { margin-top: 4px; font-size: 14.5px; line-height: 1.7; color: var(--text);
  white-space: pre-wrap; word-break: break-word; }
.sr-cmt-meta { margin-top: 6px; font-size: 12px; color: var(--text-soft); }
.list-search .ls-icon { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); font-size: 14px; color: var(--text-soft); pointer-events: none; }
.list-search-input { width: 100%; padding: 11px 40px; border: 1px solid var(--border); border-radius: 12px; background: var(--surface); color: var(--text); font-size: 14px; font-family: inherit; outline: none; transition: border-color .2s, box-shadow .2s; }
.list-search-input::placeholder { color: var(--text-soft); }
.list-search-input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(var(--primary-rgb), .14); }
/* 输入框是 type=search，浏览器自带一个原生清除按钮，会与下方自定义的清空按钮重复，屏蔽掉只留自定义那个 */
.list-search-input::-webkit-search-cancel-button,
.list-search-input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }
.list-search-clear { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); visibility: hidden; width: 22px; height: 22px; border: none; border-radius: 50%; background: var(--bg); color: var(--text-soft); font-size: 14px; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; }
/* 「切换排版」按钮 + 下拉：按钮贴搜索框最右，点开列出「列表 / 网格 / 地图」。
   有它时输入框右侧留白加大、清空按钮让位到它左边。 */
.list-search.has-view .list-search-input { padding-right: 78px; }
.list-search.has-view .list-search-clear { right: 46px; }
/* 相册 / 日常列表：搜索框 + 发布按钮并排，发布直接进对应编辑页 */
.list-toolbar { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.list-toolbar .list-search { flex: 1; min-width: 0; margin-bottom: 0; }
.list-publish {
  flex: none; height: 40px; padding: 0 15px; border: none; border-radius: 12px;
  background: var(--btn-grad); color: var(--on-primary); font-family: inherit;
  font-size: 13px; font-weight: 600; white-space: nowrap; cursor: pointer;
  box-shadow: var(--shadow-accent); transition: filter .15s, transform .15s;
}
.list-publish:hover { filter: brightness(1.04); }
.list-publish:active { transform: scale(.97); }
.list-publish:focus-visible { outline: 2px solid var(--primary-deep); outline-offset: 2px; }
/* z-index 必需：这里的 transform 会让它自成层叠上下文，面板的 z-index 被封在里面，
   所以必须给容器本身定级（var(--z-dropdown)＝站内下拉统一档位），否则它只能按层级 0 与列表/网格内容拼 DOM 顺序。
   该档位仍低于弹窗遮罩（100），所以不会盖住「未读消息」这类弹窗。 */
.ls-view-wrap { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); z-index: calc(var(--z-dropdown) + 1); }
.ls-view {
  width: 30px; height: 30px; padding: 0; border: 0; border-radius: 9px;
  background: var(--surface); color: var(--primary-deep); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.ls-view .ico { width: 17px; height: 17px; }
.ls-view:hover { background: var(--panel-soft); }
/* 面板复用站内 .dd-list / .dd-opt 的观感，但贴按钮右缘、宽度固定。
   层级不另设：沿用 .dd-list 的 var(--z-dropdown)，与站内其它下拉同档。 */
.ls-view-list { left: auto; right: 0; width: 132px; }
/* 每行 = 左图标 + 右文字（图标与按钮上显示的同一枚）；当前项图标跟着主色，最右是站内的 ✓ */
.ls-view-list .dd-opt { display: flex; align-items: center; gap: 8px; }
.ls-view-list .ls-pick-txt { flex: 1; min-width: 0; }
.ls-view-list .ls-pick-ico { display: flex; flex: none; }
.ls-view-list .ls-pick-ico .ico { width: 16px; height: 16px; color: var(--text-soft); }
.ls-view-list .dd-opt.active .ls-pick-ico .ico { color: var(--primary); }
/* 分隔线：把「话题」这个非排版入口和三个排版选项分开 */
.ls-pick-sep { height: 1px; margin: 5px 6px; background: var(--border); }

/* 地图视图：地图铺满整个内容区（靠负外边距抵消 .content 的内边距），搜索框悬浮在地图上方；
   高度由 JS 按视口算（listMapFitHeight），铺到「底栏上方留一点距离」。 */
.page-map { position: relative; }
.page-map .list { margin: -16px -16px calc(-1 * (var(--tabbar-h) + 24px)); }
.page-map .vmap { border: none; border-radius: 0; }
/* 地图模式：悬浮的搜索框要压住地图图层（高德标记是 z-index:12），所以取站内「下拉」那一档——
   与 .dd-list 同档，既在列表内容/地图图层之上，又在弹窗遮罩（100）之下。 */
.page-map .list-search { position: absolute; z-index: var(--z-dropdown); left: 16px; right: 16px; top: 10px; margin: 0; }
/* 相册 / 日常地图排版：整个工具栏一起浮在地图上方，发布按钮跟随搜索框 */
.page-map .list-toolbar { position: absolute; z-index: var(--z-dropdown); left: 16px; right: 16px; top: 10px; margin: 0; }
.page-map .list-toolbar .list-search { position: relative; left: auto; right: auto; top: auto; margin: 0; }
/* 浮在地图上要压得住底图，给输入框加一层投影 */
.page-map .list-search-input { box-shadow: var(--shadow-float-sm); }
/* 高德徽标 / 版权：地图容器底部被底栏压住一段，它们原本贴容器左下、右下角会被挡掉，
   按「被压住的高度」（JS 写成 --vmap-foot）抬到底栏之上，也就是 tab 按钮上方 */
.page-map .amap-logo, .page-map .amap-copyright { bottom: calc(var(--vmap-foot, 0px) + 6px) !important; }
/* 比例尺：跟高德徽标同一套办法抬到底栏之上 */
.page-map .amap-scalecontrol { bottom: calc(var(--vmap-foot, 0px) + 12px) !important; }
/* 缩放按钮是自绘的（对齐参考稿的 .ctrl：白底圆角方块、竖排 + / −），不是高德 ToolBar。
   位置让开左下角的「高德地图」徽标；z-index 30 压住底图与标记（高德标记是 12） */
.vmap-zoom { position: absolute; left: 10px; bottom: calc(var(--vmap-foot, 0px) + 34px); z-index: 30; display: flex; flex-direction: column; gap: 6px; }
.vmap-zoom button {
  width: 28px; height: 28px; padding: 0; border: 1px solid var(--border); border-radius: 8px;
  background: #fff; color: var(--text-soft); font-size: 15px; line-height: 1; font-family: inherit;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.vmap-zoom button:active { background: var(--panel-soft); color: var(--primary-deep); }
/* 地图下面还有「未标地点」时（.page-map-rest）：地图照样铺满整屏，只是页面整体滚动。
   所以要收回上面那条「抵消 .content 底部内边距」的负底边距，否则下面的内容会被拉出可视区。
   高德徽标不必另调：地图始终铺到底栏，--vmap-foot 已经把它抬起来了。 */
.page-map-rest .list { margin-bottom: 0; }

/* 网格视图：按「年-月」分组的封面卡片网格（相册 / 日常共用） */
.vg-sec { margin-bottom: 18px; }
.vg-sec-title { display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 700; color: var(--text-soft); margin: 0 2px 10px; }
.vg-sec-num { font-size: 10.5px; font-weight: 600; color: var(--primary-deep); background: var(--panel-soft); border: 1px solid var(--border); border-radius: 999px; padding: 1px 7px; }
.vg-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.vg-cell { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; cursor: pointer; transition: transform .12s, box-shadow .15s; }
.vg-cell:active { transform: scale(.98); }
.vg-cover { position: relative; width: 100%; aspect-ratio: 1; background: var(--panel-soft); display: flex; align-items: center; justify-content: center; overflow: hidden; }
.vg-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vg-cover-empty { display: flex; }
.vg-cover-empty .ico { width: 26px; height: 26px; color: var(--primary-soft); }
.vg-count { position: absolute; right: 6px; bottom: 6px; font-size: 10.5px; font-weight: 700; color: #fff; background: rgba(74, 59, 64, .5); border-radius: 999px; padding: 1px 7px; }
.vg-title { font-size: 13.5px; font-weight: 600; padding: 8px 10px 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 通用小右键菜单（回收站照片、相册照片都用它） */
.ctx-menu {
  position: fixed; z-index: 300; min-width: 132px; padding: 5px;
  background: var(--panel, #fff); border: 1px solid var(--line, rgba(0,0,0,.08)); border-radius: 10px;
  box-shadow: var(--shadow-float); font-size: 13.5px;
}
/* 条目可带图标（照片右键菜单与查看器「⋯ 更多」同源），所以按 flex 排布 */
.ctx-menu .it { padding: 8px 10px; border-radius: 7px; cursor: pointer; display: flex; align-items: center; gap: 8px; }
.ctx-menu .it .ico { width: 15px; height: 15px; flex: none; color: var(--text-soft); }
.ctx-menu .it.dg .ico { color: inherit; }
.ctx-menu .it:hover { background: var(--panel-soft, rgba(0,0,0,.05)); }
.ctx-menu .it.dg { color: #e5484d; }
/* 回收站：照片上方「剩余 x 天 / 小时 / 分钟」的倒计时角标（.album-cell 本身是定位参照） */
.trash-left {
  position: absolute; top: 6px; left: 6px; z-index: 2; pointer-events: none;
  font-size: 10.5px; line-height: 1.6; color: #fff; padding: 1px 7px; border-radius: 999px;
  background: rgba(0, 0, 0, .55); backdrop-filter: blur(2px);
}
.vg-sub { display: flex; align-items: center; gap: 4px; font-size: 11px; color: var(--text-soft); padding: 3px 10px 10px; }
/* 卡片副标题里只有「定位图标 + 地点」时，没地点就没有内容——别留一块空白把卡片撑高 */
.vg-sub:empty { display: none; }
.vg-sub .vg-pin { display: flex; flex: none; }
.vg-sub .vg-pin .ico { width: 12px; height: 12px; }
/* 相册的网格卡片（对齐 docs/album-ui-reference.html 的 .wall .cell）：卡片留 8px 内边距，
   封面圆角内缩成一块，文字块另起一块、左右与封面左缘对齐（图片与文字不连在一起）。
   日常的格子保持原样，故用 data-album-detail 限定——只有相册的格子带这个属性。 */
.vg-cell[data-album-detail] { padding: 8px; }
.vg-cell[data-album-detail] .vg-cover { border-radius: 11px; background: var(--panel-soft); }
.vg-cell[data-album-detail] .vg-count { right: 7px; bottom: 7px; font-size: 11px; background: rgba(74, 59, 64, .52); padding: 2px 8px; }
.vg-cell[data-album-detail] .vg-title { padding: 9px 0 0; }
.vg-cell[data-album-detail] .vg-sub { padding: 3px 0 4px; gap: 6px; font-size: 11.5px; }
/* 没有定位的卡片（.vg-noloc，副标题是空的）：封面下方本来是一块空地，让标题居中填进去 ——
   否则同一行里跟「有定位」的卡片并排时，它显得空荡、标题也吊在封面下边。 */
.vg-cell.vg-noloc { display: flex; flex-direction: column; }
.vg-cell.vg-noloc .vg-sub { display: none; } /* 空 div 只贡献上下内边距，去掉 */
.vg-cell.vg-noloc .vg-title {
  flex: 1; min-width: 0; padding: 6px 10px;
  display: flex; align-items: center; justify-content: center;
}
/* 地图排版下方：没有坐标的相册用网格列出来（否则它们在「地图」这档里彻底看不见） */
.vmap-rest { margin-top: 16px; }

/* ===== 相册列表：对齐设计稿（PC 页头 / 衬线月份标题 / 4:3 封面 / 紧凑卡片） ===== */
.album-top { display: block; }
.album-pagehead { display: none; }
.album-top-tools .list-toolbar { margin-bottom: 12px; }
.page-album .vg-sec { margin-bottom: 20px; }
.page-album .vg-sec-title {
  gap: 7px; margin: 18px 2px 10px;
  font-family: var(--font-serif);
  font-size: 16px; font-weight: 600; color: var(--text);
}
.page-album .vg-sec:first-child .vg-sec-title { margin-top: 4px; }
.page-album .vg-sec-num {
  padding: 0; border: 0; background: transparent;
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
  font-size: 10px; font-weight: 500; color: var(--text-soft);
}
.page-album .vg-grid { gap: 11px; }
.page-album .vg-cell[data-album-detail] { padding: 6px; }
.page-album .vg-cell[data-album-detail] .vg-cover { aspect-ratio: 4 / 3; border-radius: 13px; }
.page-album .vg-cell[data-album-detail] .vg-count {
  right: 6px; bottom: 6px; height: 18px; padding: 0 7px;
  font-size: 9px; font-weight: 500; line-height: 18px;
  background: rgba(30, 22, 25, .52); backdrop-filter: blur(4px);
}
.page-album .vg-cell[data-album-detail] .vg-title { padding: 8px 4px 0; font-size: 13px; }
.page-album .vg-cell[data-album-detail] .vg-sub { padding: 4px 4px 3px; gap: 3px; font-size: 10px; }
.page-album .vg-sub-t { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.page-album .vg-cell[data-album-detail] .vg-sub .vg-pin .ico { width: 10px; height: 10px; }
/* 收藏 / 回收站的无封面图标：铺满封面容器后放大到封面的 70% */
.page-album .vg-cover-empty-special { width: 100%; height: 100%; align-items: center; justify-content: center; }
.page-album .vg-cover-empty-special .ico { width: 70%; height: 70%; }
@media (min-width: 1024px) {
  .album-top { display: flex; align-items: flex-end; gap: 26px; margin-bottom: 12px; }
  .album-pagehead { display: block; flex: none; min-width: 0; }
  .album-pagehead .eyebrow {
    margin: 0 0 4px; font-size: 9px; font-weight: 600;
    letter-spacing: .22em; text-transform: uppercase; color: var(--text-soft);
  }
  .album-pagehead h2 {
    margin: 0; font-family: var(--font-serif);
    font-size: 26px; font-weight: 600; line-height: 1.15; letter-spacing: -.01em; color: var(--text);
  }
  .album-top-tools { flex: 1; min-width: 0; max-width: 680px; margin-left: auto; }
  .album-top-tools .list-toolbar { margin-bottom: 0; justify-content: flex-end; }
  /* 页头里的搜索保持紧凑，右对齐到发布按钮旁，不拉满整行 */
  .album-top-tools .list-toolbar .list-search { flex: 0 1 360px; }
  /* PC 用内容区里的大标题替代顶栏标题；地图排版下页头隐藏，顶栏标题恢复 */
  body.album-page .topbar-title { visibility: hidden; }
  body.album-page:has(.page-map) .topbar-title { visibility: visible; }
  .page-map .album-pagehead { display: none; }
  .page-album .vg-grid { gap: 12px; }
  .page-album .vg-cell[data-album-detail]:hover { transform: translateY(-2px); box-shadow: var(--shadow-hover); }
  .page-album .vg-cell[data-album-detail]:active { transform: scale(.99); }
}
/* 地图排版：页头让位后搜索恢复整行宽度，发布按钮贴在右侧 */
.page-map .album-top-tools .list-toolbar { justify-content: stretch; }
.page-map .album-top-tools .list-toolbar .list-search { flex: 1 1 auto; }

/* ===== 相册详情：沿用列表页的衬线标题与紧凑信息层级 ===== */
.page-album-detail .album-detail-title {
  font-family: var(--font-serif);
  font-size: 20px; font-weight: 600; line-height: 1.35; letter-spacing: -.005em;
}
.page-album-detail .album-note { font-size: 12.5px; line-height: 1.75; -webkit-line-clamp: 3; }
.page-album-detail .album-meta { gap: 6px; margin-top: 10px; }
.page-album-detail .meta-pill { font-size: 10.5px; padding: 3px 9px; gap: 4px; }
.page-album-detail .loc-badge,
.page-album-detail .privacy-badge { margin-left: 0; padding: 2px 8px; font-size: 10px; }
.page-album-detail .album-acts {
  margin-top: 12px; padding-top: 11px; border-top: 1px solid var(--border);
}
.page-album-detail .album-acts .btn { font-size: 12.5px; }
.page-album-detail .vg-sec-title {
  gap: 7px; margin: 16px 2px 8px;
  font-family: var(--font-serif);
  font-size: 15px; font-weight: 600; color: var(--text);
}
.page-album-detail .vg-sec-num {
  padding: 0; border: 0; background: transparent;
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
  font-size: 10px; font-weight: 500; color: var(--text-soft);
}
.page-album-detail .album-wall .album-grid,
.page-album-detail .album-wall .album-grid:not(.single) { gap: 4px; }

/* 地图视图：高德实例由 JS 挂到 #listMapBox（高度也由 JS 撑到底栏上方）；
   标记有两种形态——缩略卡（默认）与图钉（放大到一定级别后收小，免得挡住地图）。
   isolation: isolate 让地图容器自成层叠上下文：高德内部的 z-index（徽标、版权、控件、标记）
   全部封在地图这一层里，无论多高都只能在图内排序，绝不会盖住搜索框、下拉和弹窗。 */
.vmap { position: relative; width: 100%; height: 340px; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--panel-soft); isolation: isolate; }
.vmap-tip { font-size: 12px; color: var(--text-soft); line-height: 1.7; background: var(--panel-soft); border: 1px dashed var(--primary-soft); border-radius: 12px; padding: 11px 13px; }
.vmap-pin { position: relative; width: 116px; padding: 5px; background: var(--card); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-float-sm); cursor: pointer; }
.vmap-pin:hover { border-color: var(--primary); }
/* 卡片下方的小尖角：让卡片「指向」实际坐标 */
.vmap-pin-tip { position: absolute; left: 50%; bottom: -4px; width: 8px; height: 8px; margin-left: -4px; background: var(--card); border-right: 1px solid var(--border); border-bottom: 1px solid var(--border); transform: rotate(45deg); }
.vmap-pin-thumbs { display: flex; gap: 3px; }
.vmap-pin-thumb { position: relative; flex: 1; min-width: 0; height: 34px; }
.vmap-pin-thumb img { width: 100%; height: 100%; object-fit: cover; border-radius: 6px; display: block; }
.vmap-pin-thumb.noimg { display: flex; align-items: center; justify-content: center; background: var(--panel-soft); border-radius: 6px; }
.vmap-pin-thumb.noimg .ico { width: 14px; height: 14px; color: var(--primary-soft); }
.vmap-pin-thumb.more i { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(74, 59, 64, .45); color: #fff; font-size: 10.5px; font-weight: 700; font-style: normal; border-radius: 6px; }
.vmap-pin-title { margin-top: 4px; font-size: 11px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 图钉形态（缩到一定级别以下）：站点主色的定位图标（尖端朝下对准坐标），加投影压住底图 */
.vmap-drop { display: block; width: 26px; height: 34px; color: var(--primary); filter: drop-shadow(0 2px 3px rgba(176, 53, 91, .18)); cursor: pointer; }
.vmap-drop .ico { width: 100%; height: 100%; display: block; }
/* 相册的地图标记（对齐 docs/album-ui-reference.html）：缩略卡用 .mini 的口径（120 宽 / 6 内边距 /
   12 圆角、一张 64px 高的大图），图钉用 .pin 的口径（30×30 主色水滴 + 2px 白边 + 中心白点）。
   这两个类只由相册的标记产出，日常没有，所以不会连带改到日常的地图。 */
.vmap-pin-big { width: 120px; padding: 6px; border-radius: 12px; box-shadow: var(--shadow-float-sm); }
.vmap-pin-big .vmap-pin-ph { height: 64px; border-radius: 8px; overflow: hidden; background: var(--panel-soft); }
.vmap-pin-big .vmap-pin-ph img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vmap-pin-big .vmap-pin-empty { display: flex; align-items: center; justify-content: center; height: 100%; }
.vmap-pin-big .vmap-pin-empty .ico { width: 18px; height: 18px; color: var(--primary-soft); }
.vmap-pin-big .vmap-pin-title { margin-top: 5px; font-size: 11.5px; }
.vmap-drop-dot {
  position: relative; width: 30px; height: 30px; border-radius: 50% 50% 50% 4px;
  transform: rotate(-45deg); background: var(--primary); border: 2px solid #fff;
  box-shadow: 0 3px 8px rgba(176, 53, 91, .24); filter: none;
}
.vmap-drop-dot i { position: absolute; left: 50%; top: 50%; width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%; background: #fff; }
@media (min-width: 1024px) {
  .vg-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ===== 列表 ===== */
.list { display: flex; flex-direction: column; gap: 12px; }
/* 日记列表条目间距比其它列表略大，卡片之间更透气 */
#diaryList { gap: 24px; }
.list-item {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  box-shadow: var(--shadow);
}
.list-item[data-edit-item] { cursor: pointer; transition: border-color .15s, box-shadow .15s; }
.list-item[data-edit-item]:hover { border-color: var(--primary); box-shadow: 0 4px 14px rgba(var(--accent-rgb), .08); }
.list-item .li-title { font-weight: 700; font-size: 15px; margin-bottom: 4px; }
.list-item .li-sub { font-size: 13px; color: var(--text-soft); }
.list-item .li-footer { display: flex; justify-content: space-between; align-items: center; margin-top: 8px; }
.list-item .li-main { display: flex; gap: 12px; align-items: center; }
.list-item .li-thumb { width: 44px; height: 44px; border-radius: 8px; object-fit: cover; flex-shrink: 0; border: 1px solid var(--border); }
/* 列表缩略图为内置图标时（非上传图片）：垫浅底并居中图标 */
.list-item span.li-thumb { display: flex; align-items: center; justify-content: center; background: var(--panel-soft); }
/* 图标占满缩略框的 95%（框高确定，百分比可解析；图标太小会显得空荡） */
.list-item span.li-thumb .ico { width: 95%; height: 95%; }

/* ===== 微博式列表条目（相册 / 日记共用）=====
   用网格把头像与内容拆成两栏：移动端头像与昵称同处首行、正文整宽；
   PC 端（见宽屏媒体查询）头像固定左栏跨满整卡高度，内容整体归入右栏成一列。 */
.list-item.post-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas:
    "avatar head"
    "body   body"
    "cmt    cmt";
  column-gap: 10px;
}
.post-item .post-avatar { grid-area: avatar; }
.post-item .li-head { grid-area: head; display: flex; justify-content: space-between; align-items: center; min-width: 0; }
.post-item .post-body { grid-area: body; min-width: 0; margin-top: 8px; }
.post-item .cmt-inline { grid-area: cmt; }

/* ===== 日记列表条目（对齐 docs/prototype 的微博式卡片：头像固定左栏、跨满整卡高度）=====
   评论区（cmt）跨两栏、用满整卡宽度：头像只对昵称/正文/配图那一段负责，
   评论是独立的一段内容，缩在右栏里既显窄又和上方正文错位。 */
/* 日记列表条目：去掉卡片外壳（底色 / 描边 / 圆角 / 投影 / 内边距），内容直接落在页面底色上。
   只作用于日记卡片（.diary-item）；搜索结果里的评论卡等同用 .post 的卡片保持原样。 */
.list-item.diary-item {
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
}
/* 日常列表：条目之间用一条虚线分隔。
   线绝对定位在 .list 的 24px 间隙中间（bottom:-12.5px），不改布局高度；
   最后一条不画，避免列表末尾留一条悬空的线。 */
.list-item.diary-item { position: relative; }
.list-item.diary-item:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -12.5px;
  border-top: 1px dashed var(--border);
  pointer-events: none;
}
.list-item.post {
  /* 头像栏宽度 + 栏间距：评论区没有头像，但要按这个宽度留空，才能和正文左对齐 */
  --post-av-w: 38px;
  --post-gap: 10px;
  display: grid;
  grid-template-columns: var(--post-av-w) minmax(0, 1fr);
  grid-template-areas:
    "av head"
    "av body"
    "cmt cmt";
  column-gap: var(--post-gap);
  align-items: start;
}
.post .p-av { grid-area: av; }
/* 列表头像：原型为 38px（PC 端在宽屏媒体查询里放大到 44px） */
.post .author-avatar { width: 38px; height: 38px; }
.post .p-head { grid-area: head; display: flex; align-items: center; gap: 8px; min-width: 0; }
.post .p-author { font-size: 14px; color: var(--text-soft); }
.post .p-head-right { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; }
.post .p-head-right .privacy-badge { margin-left: 0; }
.post .p-body { grid-area: body; min-width: 0; margin-top: 6px; }
.post .p-title { font-weight: 700; font-size: 15px; display: flex; align-items: center; gap: 4px 0; flex-wrap: wrap; }
.post .p-title .ico { width: 17px; height: 17px; }
.post .p-sum {
  font-family: var(--font-hand);
  font-size: 13.5px; line-height: 1.75; color: var(--text);
  margin-top: 6px; white-space: pre-line; word-break: break-word;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.post .p-imgs { display: grid; grid-template-columns: repeat(var(--cols, 3), 1fr); gap: 6px; margin-top: 8px; }
.post .thumb {
  position: relative; /* 实况标记 / 悬停视频的定位参照 */
  aspect-ratio: 1; border-radius: 4px; overflow: hidden;
  border: 1px solid var(--border); background: var(--panel-soft);
}
.post .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; cursor: pointer; }
/* 内容到位前先铺一层骨架微光：图片/封面一落地就把这层完全盖住，
   于是「先占位、再出图」在视觉上是连续的，而不是一片纯色突然变出内容。 */
.post .thumb::before,
.diary-body .thumb::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(100deg, var(--panel-soft) 30%, var(--border) 50%, var(--panel-soft) 70%);
  background-size: 200% 100%;
  animation: skelSweep 1.1s linear infinite;
}
.post .thumb img,
.diary-body .thumb img { position: relative; z-index: 1; }
/* 单图：按原图长宽比展示，宽图不再被 1:1 裁掉两侧；多图仍保持方形网格对齐。
   高度上限内等比缩放：图片自身宽度随高度收缩，外层用 fit-content 包住图片并居中，
   不会出现「容器仍是整行宽、图两边留一大片底色」的情况。 */
.post .p-imgs[data-cols="1"] .thumb {
  aspect-ratio: auto;
  width: fit-content;
  max-width: 100%;
  justify-self: center;
}
.post .p-imgs[data-cols="1"] .thumb img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: min(60vh, 420px);
  object-fit: contain;
}
/* 单图在预览图到位前先按 4:3 占位：避免加载完成那一刻整页高度往上跳一下（缩略图与原图同比例，
   就绪后尺寸就固定了，后面看大图不会再动）。.is-loaded 由 load 事件打上。 */
.post .p-imgs[data-cols="1"] .thumb:not(.is-loaded) { aspect-ratio: 4 / 3; width: 100%; }
.post .p-imgs[data-cols="1"] .thumb:not(.is-loaded) img { width: 100%; height: 100%; object-fit: cover; }
/* 徽章行：目前只有定位徽章一项，右对齐使其贴到卡片右侧（与上方标题/正文形成对位） */
.post .p-badges { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.post .p-badges .loc-badge, .post .p-badges .privacy-badge { margin-left: 0; }
/* 卡片底部信息行：发布时间在左，定位徽章紧随其后；点赞 / 评论靠右。
   与标题里的日记日期区分：标题是手填的日记日期，这里是真实发布时刻。 */
.post .p-foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.post .p-time { font-size: 12px; color: var(--text-soft); }
/* 列表卡片底部的操作组：点赞与评论靠右成组 */
.post .p-acts { margin-left: auto; display: inline-flex; align-items: center; gap: 12px; }
/* 点赞 / 评论：图标 + 数字（列表卡片底部与详情页正文底部共用同一套按钮样式） */
.p-like, .p-cmt-btn {
  border: none; background: none; padding: 0; font-family: inherit; cursor: pointer;
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 12px; color: var(--text-soft);
}
.p-like b, .p-cmt-btn b { font-size: 12px; font-weight: 600; }
.p-like .ico, .p-cmt-btn .ico { width: 15px; height: 15px; }
.p-like:hover, .p-cmt-btn:hover { color: var(--primary-deep); }
/* .on：点赞表示已赞（心形填充），评论表示输入区已展开 */
.p-like.on, .p-cmt-btn.on { color: var(--primary-deep); }
.p-like.on .ico path { fill: currentColor; }
/* 详情页正文底部操作行：左侧发布时刻，右侧点赞与评论计数，下方用一条淡分隔线隔开 */
.detail-acts { display: flex; align-items: center; gap: 8px; margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--border); }
.detail-acts .p-time { font-size: 12px; color: var(--text-soft); }
.detail-acts-btns { margin-left: auto; display: inline-flex; align-items: center; gap: 16px; }
/* 定位徽章紧跟发布时间：不参与右对齐，右侧由 .p-acts 的 auto 外边距占住 */
.post .p-foot > .loc-badge { margin-left: 0; }
.post .cmt-inline { grid-area: cmt; }

/* 倒计时事件弹窗：左侧图标框为固定 92×92 正方形，与右侧「日历/重复 + 日期」顶端对齐。 */
.cd-img-row { display: flex; gap: 12px; align-items: flex-start; }
.cd-img-fields { flex: 1; min-width: 0; }
.cd-img-upload { flex: none; width: 92px; height: 92px; border-radius: 14px; border: 1px dashed var(--border); background: var(--bg); display: flex; align-items: center; justify-content: center; cursor: pointer; overflow: hidden; }
/* 已选中内置图标：去掉虚线、垫一层浅底，让彩色图标更清楚 */
.cd-img-upload.has-ico { border-style: solid; background: var(--panel-soft); }
.cd-img-upload .cd-img-ico { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; }
.cd-img-upload .cd-img-ico .ico { width: 48px; height: 48px; }
.cd-img-upload:hover { border-color: var(--primary); }
.cd-img-upload img { width: 100%; height: 100%; object-fit: cover; }
/* 点图标框弹出的「内置图标库 + 上传」浮层（复用首页那套 .hm-icon-grid）。
   模态自身是 overflow-y: auto，absolute 会被裁掉，故用 fixed；位置与宽度由 JS 按图标框实测摆放。
   遮罩 110 / 浮层 120，与日期面板同级：既在弹窗（z-index 100）之上，点外部又能关闭。 */
.cd-icon-pick { position: fixed; background: var(--surface); border: 1px solid var(--border); border-radius: 14px; box-shadow: var(--shadow-float); padding: 12px; z-index: 120; }
.cd-icon-mask { position: fixed; inset: 0; z-index: 110; }
.cd-img-add { font-size: 24px; color: var(--text-soft); line-height: 1; }

/* 账目 */
.bill-row { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--border); }
.bill-row:last-child { border-bottom: none; }
/* 账目条目卡片：更紧凑，条目间留间距 */
.list-item.bill-card { padding: 8px 14px; margin-bottom: 12px; }
/* 账单卡片：移动端左滑露出「编辑 / 删除」；PC 端用卡片内按钮（.bill-actions-pc），不启用手势 */
.swipe-item { position: relative; margin-bottom: 12px; border-radius: 16px; overflow: hidden; touch-action: pan-y; }
.swipe-item .bill-card { margin-bottom: 0; }
.swipe-body { position: relative; z-index: 1; transition: transform .22s ease; }
.swipe-item.swiping .swipe-body { transition: none; }
.swipe-item.open .swipe-body { transform: translateX(-152px); }
.swipe-actions { position: absolute; top: 0; right: 0; height: 100%; display: flex; }
.swipe-btn { width: 76px; border: 0; padding: 0; background: var(--bg); color: var(--text); font-size: 13.5px; font-weight: 600; cursor: pointer; }
.swipe-btn.del { background: #b42318; color: #fff; }
@media (max-width: 1023px) { .bill-actions-pc { display: none; } }
@media (min-width: 1024px) { .swipe-actions { display: none; } }
.bill-card .bill-row { padding: 6px 0; border-bottom: none; }
.bill-icon {
  width: 42px; height: 42px;
  border-radius: 14px;
  display: flex; align-items: center; justify-content: center;
  font-size: 20px;
  /* 浅色是设计稿的暖粉底；深色跟随面板软底，否则暗色卡里会戳出一块近白方块 */
  background: var(--panel-soft);
  flex: none;
}
.bill-info { flex: 1; }
.bill-info .b-cat { font-weight: 600; font-size: 14px; }
.bill-info .b-note { font-size: 12px; color: var(--text-soft); margin-top: 2px; }
.bill-amount { font-weight: 700; font-size: 16px; }
.bill-amount.expense { color: var(--primary-deep); }
.bill-amount.income { color: var(--ok); }
/* 账单卡片底部：这笔账对应的具体账户（银行卡 / 信用卡 / 现金） */
.bill-account-row { display: flex; align-items: center; gap: 6px; margin-top: 4px; font-size: 12px; color: var(--text-soft); }
.bill-account-label { flex: none; }
.bill-account-name { color: var(--text); font-weight: 600; }
/* 账单管理页底部：账户信息与编辑/删除按钮同一行（账户靠左、按钮靠右）；
   移动端按钮行不渲染，账户仍单独占一行。 */
.bill-foot-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 4px; }
.bill-foot-row .bill-account-row { margin-top: 0; }
.bill-foot-row .li-footer { margin-top: 0; justify-content: flex-end; gap: 8px; }

/* 统计 */
/* 顶部概览卡：余额 + 本月支出 两个指标并排，中间用竖线分隔 */
.wallet-balance {
  display: flex;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 18px 12px;
  box-shadow: var(--shadow);
  margin-bottom: 12px;
  text-align: center;
}
.wallet-balance .wb-item { flex: 1; min-width: 0; }
.wallet-balance .wb-item + .wb-item { border-left: 1px solid var(--border); }
.wallet-balance .wb-label { font-size: 13px; color: var(--text-soft); }
.wallet-balance .wb-value { font-size: 24px; font-weight: 800; margin-top: 6px; }
.wallet-balance .wb-value.income { color: var(--ok); }
.wallet-balance .wb-value.expense { color: var(--primary-deep); }
/* 记账首页顶部「钱包」切换：三项等宽并排，统一样式 + hover/点击反馈 */
.wallet-tabs { display: flex; gap: 8px; margin-bottom: 12px; }
.wallet-tab {
  flex: 1 1 0; min-width: 0;
  padding: 10px 8px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  font-size: 13px;
  color: var(--text-soft);
  text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  cursor: pointer;
  user-select: none; -webkit-user-select: none;
  transition: background .18s, color .18s, border-color .18s, transform .1s;
}
.wallet-tab:hover { border-color: var(--primary); color: var(--primary-deep); }
.wallet-tab:active { transform: scale(.97); }
.wallet-tab.active { background: var(--btn-grad); border-color: var(--btn-grad); color: var(--on-primary); font-weight: 600; }
.stat-row { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 14px; }
.stat-box { flex: 1; min-width: 0; background: var(--card); border: 1px solid var(--border); border-radius: 16px; padding: 14px; text-align: center; box-shadow: var(--shadow); }
/* 结余金额在 1/3 宽度放不下时独占下一行，占满两个位置（由 fitStatValues 判定并加类） */
.stat-box.span-all { flex: 1 0 100%; }
.stat-box .s-v { font-size: 22px; font-weight: 800; white-space: nowrap; }
.stat-box .s-l { font-size: 12px; color: var(--text-soft); margin-top: 4px; }

/* 收支走势曲线 */
.bill-chart-card { margin-bottom: 12px; }
.bill-legend { display: flex; gap: 18px; justify-content: center; margin-bottom: 4px; font-size: 12px; color: var(--text-soft); }
.bill-legend .ic-legend { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 4px; vertical-align: 1px; }
/* 折线图（新风格）：网格与 Y 刻度画在 SVG 里，这里只管尺寸与图例取色 */
.chart-svg { width: 100%; height: auto; display: block; }
/* 坐标轴 / 刻度跟随主题变量：暗色主题不再用写死的浅色值 */
.chart-svg .ct-grid { stroke: var(--border); }
.chart-svg .ct-grid-base { stroke: var(--text-soft); opacity: .45; }
.chart-svg .ct-axis, .chart-svg .ct-x { fill: var(--text-soft); }
.chart-svg .ct-x { opacity: .85; }
/* 折线图悬停：竖向参考线随列高亮；数值浮层是 HTML，字号不随 SVG 缩放 */
.chart-wrap { position: relative; touch-action: pan-y; }
.chart-guide { stroke: var(--text-soft); stroke-width: 1; stroke-dasharray: 3 3; opacity: 0; transition: opacity .12s; }
.chart-col:hover .chart-guide,
.chart-col:has(.chart-hit.is-pinned) .chart-guide { opacity: 1; }
/* 触屏点按固定的列：淡色底提示当前选中 */
.chart-hit.is-pinned { fill: rgba(var(--accent-rgb), .06); }
.chart-hover-tip {
  position: absolute; top: 8px; z-index: 5; min-width: 132px;
  padding: 8px 10px; border-radius: 10px;
  background: var(--card); border: 1px solid var(--border);
  box-shadow: var(--shadow-float-sm);
  font-size: 13px; color: var(--text); pointer-events: none;
}
.chart-hover-tip[hidden] { display: none; }
.chart-hover-tip .ct-date { margin-bottom: 4px; font-size: 12px; color: var(--text-soft); }
.chart-hover-tip .ct-row { display: flex; align-items: center; gap: 6px; line-height: 1.6; white-space: nowrap; }
.chart-hover-tip .ct-row i { flex: none; width: 8px; height: 8px; border-radius: 50%; }
.chart-hover-tip .ct-name { color: var(--text-soft); }
.chart-hover-tip .ct-row b { margin-left: auto; padding-left: 12px; font-weight: 700; }
.bill-legend .ic-legend.lg-income { background: #3ba55d; }
.bill-legend .ic-legend.lg-expense { background: #f06b93; }
/* 两人对比图例：四项要能换行；虚线项（对方）用淡化色点表示 */
.bill-legend-4 { flex-wrap: wrap; gap: 6px 12px; }
.bill-legend .ic-legend.soft { opacity: .42; }

/* 记账首页：对齐设计稿（Bill · Money 页头 / 衬线数字 / 软粉概览 / 行式入口） */
.bill-pagehead { display: none; }
.bill-home .wallet-balance {
  gap: 10px; padding: 0; margin-bottom: 12px;
  background: transparent; border: 0; border-radius: 0; box-shadow: none;
  text-align: left;
}
.bill-home .wallet-balance .wb-item {
  padding: 14px 16px; border-radius: 18px;
  background: var(--primary-soft);
  border: 1px solid rgba(var(--primary-rgb), .16);
}
.bill-home .wallet-balance .wb-item + .wb-item { border-left: 1px solid rgba(var(--primary-rgb), .16); }
.bill-home .wallet-balance .wb-label { font-size: 12.5px; color: var(--text-soft); }
.bill-home .wallet-balance .wb-value {
  margin-top: 6px;
  font-family: var(--font-serif); font-size: 24px; font-weight: 600;
  line-height: 1.15; letter-spacing: -.01em;
}
.bill-home .wallet-balance .wb-value.income { color: var(--text); }
.bill-home .wallet-balance .wb-value.expense { color: var(--primary-deep); }

/* 钱包切换：胶囊标签，选中态用墨色底 */
.bill-home .bill-tabs-row { margin: 0 0 14px; }
.bill-home .wallet-tabs { gap: 7px; margin-bottom: 0; overflow-x: auto; scrollbar-width: none; }
.bill-home .wallet-tabs::-webkit-scrollbar { display: none; }
.bill-home .wallet-tab {
  flex: none; height: 34px; padding: 0 14px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--card); color: var(--text-soft);
  font-size: 12.5px; white-space: nowrap;
}
.bill-home .wallet-tab.active { background: var(--text); border-color: var(--text); color: var(--bg); font-weight: 500; }

/* 卡片标题：衬线标题 + 右侧分段控件 */
.bill-home .bill-sec-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.bill-home .bill-sec-head h3 {
  margin: 0; flex: none;
  font-family: var(--font-serif); font-size: 17px; font-weight: 600;
  line-height: 1.25; letter-spacing: -.005em; color: var(--text);
}
.bill-home .bill-seg {
  margin-left: auto; display: inline-flex; padding: 2px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--card);
}
.bill-home .bill-seg button {
  height: 26px; padding: 0 10px; border: 0; border-radius: 8px;
  background: transparent; color: var(--text-soft);
  font-family: inherit; font-size: 12px; cursor: pointer;
}
.bill-home .bill-seg button.active { background: var(--panel-soft); color: var(--primary-deep); font-weight: 600; }

.bill-home .bill-legend { justify-content: flex-start; gap: 14px; margin-bottom: 6px; }
.bill-home .bill-legend .ic-legend { width: 8px; height: 8px; border-radius: 2px; }

.bill-home .bsave-name { font-size: 14.5px; }
.bill-home .bsave-num { font-size: 13.5px; }
.bill-home .bsave-bar { height: 7px; margin: 8px 0 5px; }
.bill-home .bsave-people { font-size: 12px; }
.bill-home .bsave-sub { font-size: 12px; }

/* 入口：与打卡页筛选条同款的横排胶囊按钮（原来卡内三行竖排占 182px，
   横排后省下的高度都让给下方存钱计划列表）。 */
.bill-home .bill-entry-bar { display: flex; gap: 6px; margin: 0 0 12px; }
.bill-home .bill-entry-btn {
  flex: none; height: 32px; padding: 0 14px;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface); color: var(--text-soft);
  font-family: inherit; font-size: 12px; cursor: pointer;
}
.bill-home .bill-entry-btn:hover { color: var(--primary-deep); border-color: var(--primary); }
.bill-home .bill-entry-btn:active { transform: scale(.97); }
/* 当前展开在右栏的子页：与打卡筛选条选中态一致（深色实底） */
.bill-home .bill-entry-btn.is-on { background: var(--text); border-color: var(--text); color: var(--bg); }
/* 流水列表顶部的搜索：吸在顶栏下方（top = 顶栏高），滚动时列表从它下方穿过。
   必须有不透明底（含 12px 下间距，否则那一条会透出列表文字）；z-index 低于顶栏(20)、高于列表项 */
.bill-list-search { position: sticky; top: var(--topbar-h); z-index: 5; background: var(--bg); padding-bottom: 12px; }
.bill-list-search .list-search { margin-bottom: 0; }
/* 移动端记账主页不展示「最近流水」及其搜索框：完整列表统一从「账单流水」页进入 */
@media (max-width: 1023.98px) {
  .bill-list-search,
  #billHomeList { display: none; }
}
/* 记账设置「导入导出」卡：每行＝一项操作（微信导入 / 支付宝导入 / 导出当前钱包） */
.bill-io-row { display: flex; align-items: center; gap: 10px; padding: 11px 0; border-bottom: 1px solid var(--border); }
.bill-io-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.bill-io-name { font-size: 14px; }
.bill-io-sub { font-size: 12px; color: var(--text-soft); }
.bill-io-row > .btn { flex: none; }
/* 导入弹窗的分类映射：没认出来的组用暖色标出来（行内小标 + 按钮描边） */
.bill-map-tip { margin-left: 6px; font-size: 11px; font-weight: 400; color: var(--warn); }
.bill-map-need { color: var(--warn); border-color: var(--warn); }
/* 映射行的参考信息（这一组多为哪些交易对方），过长省略 —— 明细在选择层里看 */
.bill-map-ref { font-size: 11.5px; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 分类映射层顶部的说明块：这组是什么账 / 正在给谁指定 */
.bill-pick-ctx { background: var(--bg); border: 1px solid var(--border); border-radius: 10px; padding: 9px 11px; margin-bottom: 12px; }
.bill-pick-ctx-h { font-size: 12.5px; font-weight: 600; margin-bottom: 4px; }
.bill-pick-ctx-l { font-size: 11.5px; color: var(--text-soft); line-height: 1.6; }
/* 映射层里的商户清单：对方可能有几十个，超出后在框内滚动 */
.bill-peer-list { max-height: 46vh; overflow-y: auto; }
.bill-peer-list .bill-io-row:last-child { border-bottom: none; }

/* 分类设置：网格卡片（图标 + 名称），末尾一张「添加分类」虚线卡 */
.bill-cat-group { font-size: 13px; color: var(--text-soft); margin: 12px 0 8px; }
.bill-cat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 10px; }
.bill-cat-card { display: flex; flex-direction: column; align-items: center; gap: 7px; padding: 14px 6px; background: var(--bg); border: 1px solid var(--border); border-radius: 14px; cursor: pointer; transition: transform .16s ease; }
.bill-cat-card:active { transform: scale(.96); }
.bill-cat-card .bcc-ico { width: 26px; height: 26px; display: flex; align-items: center; justify-content: center; color: var(--text); }
.bill-cat-card .bcc-ico .ico { width: 26px; height: 26px; }
.bill-cat-card .bcc-name { font-size: 12.5px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bill-cat-card .bcc-plus { font-size: 22px; line-height: 1; color: var(--text-soft); }
.bill-cat-card.add { border-style: dashed; }
.bill-cat-card.add .bcc-name { color: var(--text-soft); }
/* 分类卡右上角的可见性角标：公开不抢眼，私密用主题色点明 */
.bill-cat-card { position: relative; }
.bill-cat-card .bcc-priv { position: absolute; top: 5px; right: 6px; font-size: 9.5px; line-height: 1; color: var(--text-soft); opacity: .75; padding: 1px 3px; border-radius: 6px; }
.bill-cat-card .bcc-priv.priv { color: var(--primary-deep); opacity: 1; font-weight: 700; }

/* ---- 记一笔弹窗：AA / 存钱模式 + 时间 + 钱包 ---- */
.bill-mode-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 14px; }
/* 记一笔：AA / 存钱提示紧跟在模式切换行下方，与金额字段留出常规间距 */
#bWalletHint { margin-top: 0; margin-bottom: 14px; }
.bill-mode-right { display: flex; gap: 8px; flex: none; }
.bill-mode-chip { padding: 7px 12px; font-size: 13px; }
.bill-mode-chip.active { background: var(--btn-grad); border-color: var(--btn-grad); color: var(--on-primary); }
.bill-dt-row { display: flex; align-items: center; gap: 10px; }
.bill-dt-row .dp { flex: 1; min-width: 0; }
/* 小时 / 分钟：两个可点的小框，点击弹出双列选择面板 */
.tp { position: relative; display: flex; align-items: center; gap: 2px; flex: none; }
.tp-box {
  min-width: 44px; padding: 12px 8px; text-align: center;
  border: 1px solid var(--border); border-radius: 12px; background: var(--surface);
  font-size: 15px; color: var(--text); cursor: pointer; transition: border-color .2s;
}
.tp-box:active { border-color: var(--primary); }
.tp-sep { font-size: 15px; color: var(--text-soft); }
.tp-panel {
  position: absolute; top: calc(100% + 6px); left: 0; width: 220px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  box-shadow: var(--shadow); padding: 12px; z-index: 120;
}
.tp-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; font-size: 14px; font-weight: 700; }
.tp-close { font-size: 18px; line-height: 1; color: var(--text-soft); cursor: pointer; padding: 0 4px; }
/* 时间滚轮：选中值永远是正中那一格，上下渐隐 + 停手后吸附（交互见 initTimePicker）。
   单项高 36px、可视高 190px 必须与 JS 的 TP_CELL_H / .tp-pad 保持一致。 */
.tp-cols { display: flex; gap: 8px; height: 190px; }
.tp-col {
  position: relative; flex: 1; overflow-y: auto; border-radius: 10px; background: var(--panel-soft);
  overscroll-behavior: contain; scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
}
.tp-col::-webkit-scrollbar { display: none; }
/* 上下留白 =(190 − 36) / 2：让 00 和 23 / 59 也能滚到正中 */
.tp-pad { height: 77px; }
.tp-cell {
  height: 36px; line-height: 36px; text-align: center; font-size: 14px;
  color: var(--text-soft); cursor: pointer; border-radius: 8px;
  font-variant-numeric: tabular-nums;
  transition: color .16s ease, background .16s ease, transform .2s cubic-bezier(.34, 1.56, .64, 1);
}
.tp-cell:hover { background: var(--primary-soft); }
.tp-cell.on {
  background: var(--card); color: var(--primary-deep); font-weight: 700; font-size: 15px;
  box-shadow: 0 2px 8px rgba(176, 53, 91, .12);
}
/* 棘轮：每吸附到新的一格，正中项弹一下 */
@keyframes tpTick {
  0% { transform: scale(1); }
  45% { transform: scale(1.14); }
  100% { transform: scale(1); }
}
.tp-cell.tick { animation: tpTick .24s ease-out; }
.tp-mask { position: fixed; inset: 0; z-index: 110; }
#bPromise { width: 100%; }

/* ---- 记一笔：账户下拉（自定义卡片列表） ---- */
.acct-select { position: relative; }
.acct-trigger {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--surface); color: var(--text); font-family: inherit; text-align: left;
  cursor: pointer; transition: border-color .2s;
}
.acct-trigger:active, .acct-trigger:focus-visible { border-color: var(--primary); outline: none; }
.acct-trigger-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.acct-trigger-main { font-size: 14.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct-trigger-sub { font-size: 12px; color: var(--text-soft); }
.acct-caret { display: inline-flex; color: var(--text-soft); flex: none; transition: transform .2s ease; }
.acct-caret .ico { width: 18px; height: 18px; }
.acct-trigger.open .acct-caret { transform: rotate(180deg); }
.acct-panel {
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  box-shadow: var(--shadow-float); padding: 6px; z-index: 130;
  max-height: 50vh; overflow-y: auto; scrollbar-width: thin;
}
.acct-mask { position: fixed; inset: 0; z-index: 125; }
.acct-opt {
  display: flex; align-items: center; gap: 10px; padding: 10px;
  border: 1px solid transparent; border-radius: 12px; cursor: pointer;
}
.acct-opt:hover { background: var(--panel-soft); }
.acct-opt.active { border-color: var(--primary); background: var(--panel-soft); }
.acct-opt-main { flex: 1; min-width: 0; }
.acct-opt-name { display: flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct-opt-sub { margin-top: 2px; font-size: 12px; color: var(--text-soft); }
.acct-opt-no {
  margin-top: 3px; font-size: 12px; letter-spacing: 1px; color: var(--text-soft);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.acct-opt-dot { flex: none; width: 10px; height: 10px; border-radius: 50%; border: 1px solid var(--border); }
.acct-opt.active .acct-opt-dot { background: var(--primary); border-color: var(--primary); }

/* ---- AA 状态标签与操作 ---- */
.bill-tag {
  display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 999px;
  font-size: 10.5px; font-weight: 600; line-height: 1.6; vertical-align: 1px;
  background: var(--panel-soft); color: var(--text-soft); border: 1px solid var(--border);
}
.bill-tag.aa { background: rgba(var(--primary-rgb), .13); color: var(--primary-deep); border-color: rgba(var(--primary-rgb), .35); }
.bill-tag.sv { background: rgba(59, 165, 93, .13); color: var(--ok); border-color: rgba(59, 165, 93, .3); }
.bill-tag.aa-pending { color: var(--text-soft); }
.bill-tag.aa-confirming { color: #c25a22; border-color: rgba(237, 108, 49, .35); background: rgba(237, 108, 49, .12); }
.bill-tag.aa-paid { color: var(--ok); border-color: rgba(59, 165, 93, .35); background: rgba(59, 165, 93, .12); }
.bill-tag.aa-rejected { color: #e5484d; border-color: rgba(229, 72, 77, .35); background: rgba(229, 72, 77, .1); }
.bill-aa-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--border); }
.bill-aa-hint { font-size: 12px; color: var(--text-soft); }
.bill-aa-btns { display: flex; gap: 8px; }
.bill-aa-act { padding: 5px 12px; font-size: 12.5px; }
.bill-aa-act.ok { color: var(--ok); border-color: rgba(59, 165, 93, .45); }
.bill-aa-act.no { color: #e5484d; border-color: rgba(229, 72, 77, .4); }
.bill-amount.saving { color: #2f7d9e; }

/* ---- 存钱进度卡 ---- */
.bill-save-card { margin-bottom: 12px; }
/* 存钱计划是左栏最后一张卡，去掉外间距，页面底部只留 .content 的 10px 留白 */
.bill-col-side > .card:last-child { margin-bottom: 0; }
/* 存钱计划列表在卡片内独立滚动（滚动条全站已隐藏）：条数多时不再把左栏越拉越长。
   高度由 syncLogScroll 实测写入，这里给一个兜底上限，避免脚本晚到前先撑开页面。 */
.bsave-scroll { max-height: 42vh; overflow-y: auto; overscroll-behavior: contain; }
.bsave-row { padding: 9px 0; border-bottom: 1px dashed var(--border); }
.bsave-row:last-child { border-bottom: none; padding-bottom: 2px; }
.bsave-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.bsave-name { font-size: 13.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bsave-num { flex: none; font-size: 13px; font-weight: 700; color: var(--primary-deep); }
.bsave-num i { font-style: normal; font-weight: 400; color: var(--text-soft); }
.bsave-bar { height: 6px; border-radius: 999px; background: var(--panel-soft); overflow: hidden; margin: 7px 0 4px; }
.bsave-bar i { display: block; height: 100%; border-radius: 999px; background: var(--btn-grad); transition: width .3s ease; }
.bsave-bar i.done { background: var(--ok); }
/* 存钱计划：进度条按双方贡献分段（我=绿 / 对方=粉），圆角交给容器裁剪两端 */
.bsave-bar-split { display: flex; }
.bsave-bar-split i.me { background: #0fbf6a; border-radius: 0; }
.bsave-bar-split i.partner { background: #ff4d6d; border-radius: 0; }
.bsave-people { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-bottom: 4px; font-size: 11.5px; color: var(--text-soft); }
.bsave-person { display: inline-flex; align-items: center; gap: 5px; }
.bsave-person i { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.bsave-person.me i { background: #0fbf6a; }
.bsave-person.partner i { background: #ff4d6d; }
/* 记一笔：新建存钱计划的展开表单 */
.bpromise-new-btn { margin-top: 8px; }
.bpromise-new { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.bpromise-new[hidden] { display: none; }
.bpromise-new input { flex: 1 1 140px; min-width: 0; }
.bsave-sub { font-size: 11.5px; color: var(--text-soft); }

/* ---- 记账设置：隐私与账户 ---- */
.bill-priv-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.bill-priv-controls { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.bill-priv-title { display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none; }
.bill-priv-caret { display: inline-flex; color: var(--text-soft); cursor: pointer; transition: transform .2s ease; }
.bill-priv-caret.open { transform: rotate(180deg); }
.bill-priv-head:not(.is-private) .bill-priv-caret { visibility: hidden; }
.bill-priv-caret .ico { width: 18px; height: 18px; }
.bill-priv-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); }
.bill-priv-label { font-size: 13.5px; }
.bill-priv-group { margin: 12px 0 2px; font-size: 12px; color: var(--text-soft); }
.bill-priv-item { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 7px 0; border-bottom: 1px dashed var(--border); }
#bPrivExp .bill-priv-item:last-child, #bPrivInc .bill-priv-item:last-child { border-bottom: none; }
.bill-priv-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13.5px; color: var(--text); }
.bill-priv-seg { flex: none; }
.bill-priv-seg .dp-cal-i { padding: 5px 12px; font-size: 12px; }
.bill-priv-empty { padding: 4px 0; font-size: 12px; color: var(--text-soft); }
.bill-acc-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.bacc-row { display: flex; align-items: center; gap: 8px; padding: 11px 0; border-bottom: 1px solid var(--border); }
.bacc-row:last-child { border-bottom: none; }
.bacc-main { flex: 1; min-width: 0; }
.bacc-name { font-size: 14px; font-weight: 600; }
.bacc-name .bill-tag { margin-left: 8px; }
.bacc-sub { margin-top: 3px; font-size: 11.5px; color: var(--text-soft); }
/* 卡号：默认只展示后端下发的脱敏值，完整卡号需密码验证 */
.bacc-card { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 4px; font-size: 11.5px; color: var(--text-soft); }
.bacc-reveal { padding: 0; border: 0; background: none; color: var(--primary-deep); font-family: inherit; font-size: 11.5px; cursor: pointer; }
.bacc-reveal:hover { text-decoration: underline; }
.bacc-card-edit { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 8px; font-size: 12px; color: var(--text-soft); }
.bill-card-full {
  padding: 18px 8px; text-align: center; word-break: break-all;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 20px; font-weight: 700; letter-spacing: 1px; color: var(--text);
}
/* 分类图标选择：内置图标网格 + 上传图片预览 */
.cat-icon-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); gap: 8px; max-height: 216px; overflow-y: auto; padding: 2px; }
.cat-icon { display: flex; align-items: center; justify-content: center; height: 44px; padding: 0; background: var(--bg); border: 1px solid var(--border); border-radius: 11px; color: var(--text); cursor: pointer; }
.cat-icon .ico { width: 22px; height: 22px; }
.cat-icon.active { border-color: var(--primary-deep); box-shadow: 0 0 0 2px rgba(255, 94, 120, .16); }
/* 末尾「添加」格：虚线框 + 加号 + 文字，点它上传自定义图片 */
.cat-icon-add { flex-direction: column; gap: 2px; border-style: dashed; color: var(--text-soft); font-size: 11px; line-height: 1; }
.cat-icon-add.active { border-style: solid; color: var(--text); }
/* 图片型图标（上传的图）：与内置图标同尺寸，裁成圆角方块 */
.cat-icon-img { object-fit: cover; border-radius: 5px; }
/* AI 权限：卡片内的「操作行」（账单设置页与权限管理页共用同一份渲染） */
.ai-op-row { display: flex; align-items: center; gap: 10px; padding: 11px 0; border-bottom: 1px solid var(--border); }
.ai-op-row:last-child { border-bottom: none; }
.ai-op-row .ai-op-name { flex: 1; font-size: 14px; }
/* 权限管理：每条＝「操作行 + 它的范围区」，分隔线画在条目底部（行本身不画） */
.ai-op-item { border-bottom: 1px solid var(--border); }
.ai-op-item:last-child { border-bottom: none; }
.ai-op-item .ai-op-row { border-bottom: none; }
.ai-op-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.ai-op-sub { font-size: 12px; font-weight: 400; color: var(--text-soft); }
/* 开关左侧的文字状态：开＝允许（绿），关＝禁止（灰） */
.perm-state { flex: none; font-size: 12px; color: var(--text-soft); }
.perm-state.on { color: var(--ok-ink); }
/* 范围选项区：由开关驱动——开则展开、关则收起 */
.ai-perm-range { display: none; padding: 0 0 14px; }
.ai-perm-range.show { display: block; }
/* 权限管理：调用规则行（每日次数上限） */
.rule-row { display: flex; align-items: center; gap: 10px; padding: 12px 0; border-bottom: 1px solid var(--border); }
.rule-main { flex: 1; min-width: 0; }
.rule-name { font-size: 14px; }
.rule-sub { font-size: 12px; color: var(--text-soft); margin-top: 3px; }
.rule-val {
  display: inline-flex; align-items: center; gap: 4px; flex: none;
  font: inherit; font-size: 14px; font-weight: 600; color: var(--primary-deep);
  background: var(--panel-soft); border: 1px solid var(--border);
  border-radius: 12px; padding: 8px 10px 8px 12px; cursor: pointer;
}
.rule-val .ico { width: 15px; height: 15px; }
/* 权限管理：用量统计 */
.usage-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; margin: 4px 0 12px; }
.usage-item { text-align: center; background: var(--panel-soft); border-radius: 14px; padding: 12px 6px; }
.usage-item .uv { font-size: 20px; font-weight: 800; color: var(--primary-deep); }
.usage-item .ul { font-size: 12px; color: var(--text-soft); margin-top: 3px; }
.usage-bar { height: 8px; border-radius: 999px; background: var(--switch-track); overflow: hidden; }
.usage-bar i { display: block; height: 100%; border-radius: 999px; background: var(--btn-grad); transition: width .3s ease; }
/* 权限管理：调用记录 */
.log-row { display: flex; align-items: center; gap: 10px; padding: 11px 0; border-bottom: 1px solid var(--border); }
.log-row:last-child { border-bottom: none; }
.log-ico { width: 30px; height: 30px; flex: none; border-radius: 9px; background: var(--panel-soft); color: var(--primary-deep); display: flex; align-items: center; justify-content: center; }
.log-ico .ico { width: 16px; height: 16px; }
.log-main { flex: 1; min-width: 0; }
.log-name { font-size: 13.5px; }
.log-sub { font-size: 12px; color: var(--text-soft); margin-top: 2px; }
.log-time { font-size: 12px; color: var(--text-soft); flex: none; }
.log-empty { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 22px 0; font-size: 13px; color: var(--text-soft); }
/* 卡片标题右侧的小按钮（调用记录「清空」） */
.mini-btn { font: inherit; font-size: 12.5px; color: var(--primary-deep); background: var(--surface); border: 1px solid var(--border); border-radius: 999px; padding: 5px 12px; cursor: pointer; flex: none; }
.mini-btn:hover { background: var(--panel-soft); }
/* 记账统计：钱包选项排在概览卡与分类卡之间 */
.bill-tabs-row { margin: 14px 0; }
/* AI 接入免责声明正文 */
.ai-terms { font-size: 13.5px; line-height: 1.7; color: var(--text-soft); background: var(--bg); border: 1px solid var(--border); border-radius: 12px; padding: 12px 14px; max-height: 240px; overflow-y: auto; }
.ai-terms p { margin: 0 0 8px; }
.ai-terms p:last-child { margin-bottom: 0; }
.ai-terms ul { margin: 6px 0 8px; padding-left: 18px; }
.ai-terms li { margin-bottom: 4px; }
.ai-terms b { color: var(--text); }
#aiTermsOk:disabled { opacity: .5; }
/* 账单管理：搜索框下方的筛选行（类型 / 分类 chips） */
.bill-filter-row { margin-top: 10px; }
/* 记账统计：分类占比条 */
.bstat-row { display: flex; align-items: center; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--border); }
.bstat-row:last-child { border-bottom: none; }
.bstat-name { width: 72px; flex: none; font-size: 13.5px; }
.bstat-bar { flex: 1; height: 8px; border-radius: 999px; background: var(--bg); overflow: hidden; }
.bstat-bar > i { display: block; height: 100%; border-radius: 999px; }
.bstat-bar > i.exp { background: linear-gradient(90deg, #ff8fab, #ff5e78); }
.bstat-bar > i.inc { background: linear-gradient(90deg, #7fd99a, #3ba55d); }
.bstat-num { flex: none; font-size: 13px; font-weight: 700; }
@media (min-width: 1024px) {
  /* 账单主页 PC 双栏（对齐 docs/wardrobe-redesign 记账屏）：左 460px 放概览（余额 + 走势 + 入口），
     右放流水列表。窄屏不加任何效果，仍是「先概览后列表」的单栏堆叠 */
  .bill-cols { display: grid; grid-template-columns: 460px minmax(0, 1fr); gap: 20px; align-items: start; }
  /* 记账首页 PC 页头：衬线大标题 + 右侧「记一笔」，顶栏标题让位 */
  .bill-pagehead { display: flex; align-items: flex-end; gap: 24px; margin-bottom: 16px; }
  .bill-pagehead .eyebrow {
    margin: 0 0 4px; font-size: 9px; font-weight: 600;
    letter-spacing: .22em; text-transform: uppercase; color: var(--text-soft);
  }
  .bill-pagehead h2 {
    margin: 0; font-family: var(--font-serif);
    font-size: 26px; font-weight: 600; line-height: 1.15; letter-spacing: -.01em; color: var(--text);
  }
  .bill-pagehead .acts { flex: 1; min-width: 0; display: flex; justify-content: flex-end; }
  .bill-add-btn { height: 38px; padding: 0 18px; border-radius: 999px; font-size: 13.5px; }
  .bill-home .wallet-balance .wb-value { font-size: 26px; }
  body.bill-page .topbar-title { visibility: hidden; }
  /* 右栏流水列表独立滚动（对齐设计稿「右侧流水列表独立滚动」）：
     高度不再写死 calc —— 由 syncLogScroll 按「视口 − 顶栏 − 页头 − 搜索框 − 卡片内边距」实测写入，
     这样页头 / 搜索框高度变了也不会算错，列表永远贴着视口底边收住。 */
  #billHomeList {
    padding: 4px 18px;
    background: var(--card); border: 1px solid var(--border);
    border-radius: 20px; box-shadow: var(--shadow);
  }
  /* 流水行：一整块面板内用分隔线，不再一条一张卡 */
  #billHomeList .list-item.bill-card {
    margin: 0; padding: 12px 0;
    background: transparent; border: 0; border-radius: 0;
    border-bottom: 1px solid var(--border); box-shadow: none;
  }
  #billHomeList .list-item.bill-card:last-child { border-bottom: 0; }
  #billHomeList .bill-card .bill-row { padding: 0; }
  #billHomeList .bill-icon {
    width: 38px; height: 38px; border-radius: 12px;
    background: rgba(59, 165, 93, .10); color: var(--ok);
  }
  #billHomeList .bill-icon .ico { width: 19px; height: 19px; }
  /* 右栏就地展开的子页（点左栏入口卡）：与流水列表同高，返回按钮固定在顶部、子页内容在下方滚动 */
  .bill-detail { display: flex; flex-direction: column; max-height: calc(100vh - var(--topbar-h) - 176px); }
  .bill-detail-back { align-self: flex-start; flex: none; margin-bottom: 10px; }
  /* 子页在右栏里应铺满这一栏（PC 上 .page 默认 90% 居中，那是给整页用的）。
     内边距需 ≥ 阴影模糊半径，避免卡片左右 / 上方投影被右栏的 overflow 裁掉。 */
  .bill-detail-body { flex: 1; min-height: 0; overflow-y: auto; padding: 18px 16px 12px; }
  .bill-detail-body .page { width: 100%; margin: 0; }
}

/* 衣柜：按大类分组 */
.w-group { margin-bottom: 18px; }
.w-group-title { font-weight: 700; font-size: 15px; margin-bottom: 10px; padding-left: 8px; border-left: 3px solid var(--primary); }
/* 衣柜条目卡片：小屏 3 列，大屏由媒体查询调整列数 */
.w-item { width: calc(33.33% - 6px); cursor: pointer; }

/* ===== 穿搭搭配 ===== */
/* 衣柜页顶部搭配入口 */
.w-outfit-entry {
  display: flex; align-items: center; gap: 12px;
  background: var(--panel-soft);
  border: 1px solid rgba(var(--primary-rgb), 0.3);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin-bottom: 12px;
  cursor: pointer;
  transition: .15s;
}
.w-outfit-entry:hover { border-color: var(--primary); box-shadow: var(--shadow); }
/* hidden 在设了 display 的元素上会被覆盖，这里显式兜底（同 .chip-row[hidden]）：搜索时隐藏入口 */
.w-outfit-entry[hidden] { display: none; }
/* 搭配卡片：缩略图横排 */
.outfit-thumbs { display: flex; gap: 6px; margin: 10px 0 8px; flex-wrap: wrap; }
.outfit-thumbs img,
.outfit-thumbs .ot-empty {
  width: 54px; height: 68px; object-fit: cover;
  border-radius: 8px; border: 1px solid var(--border); display: block; background: var(--bg);
}
.outfit-thumbs .ot-empty { display: flex; align-items: center; justify-content: center; font-size: 22px; opacity: .45; }
/* 搭配编辑页：衣物选择格子（复用 w-item 的列宽逻辑） */
.opick { width: calc(33.33% - 6px); position: relative; cursor: pointer; border-radius: 12px; }
.opick img { width: 100%; aspect-ratio: 3/4; object-fit: cover; border-radius: 12px; border: 1.5px solid var(--border); display: block; }
.opick.active img { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(var(--primary-rgb), 0.35); }
/* 选中标记：空的定位壳，内容（主色圆 + 序号）由 JS 按选中顺序填 */
.opick .opick-check { position: absolute; top: 6px; right: 6px; display: none; --pick-sz: 20px; }
.opick.active .opick-check { display: block; }
/* 搭配卡片内操作按钮 */
.outfit-acts { display: flex; gap: 8px; justify-content: flex-end; margin-top: 8px; }
/* 搭配编辑页：移动端单列（搭配信息 → 穿搭设定图 → 选择衣物）；
   PC 端搭配信息 + 选择衣物在左，穿搭设定图固定在右栏。 */
.oe-grid { display: block; }
.oe-main .card:last-child { margin-bottom: 0; }
@media (min-width: 1024px) {
  .oe-grid { display: grid; grid-template-columns: minmax(0, 1fr) 380px; column-gap: 14px; align-items: start; }
  .oe-main { display: contents; }
  .oe-info { grid-column: 1; grid-row: 1; }
  .oe-pick-card { grid-column: 1; grid-row: 2; }
  .oe-preview-card { grid-column: 2; grid-row: 1 / span 2; }
}
/* PC 上设定图与底部操作不要跟着整张卡片拉满，保持紧凑居中 */
@media (min-width: 1024px) {
  .oe-main .oe-preview-img,
  .oe-main .oe-preview-empty,
  .oe-main .upload-hint,
  .oe-main .oe-actions { max-width: 360px; margin-left: auto; margin-right: auto; }
}
.oe-preview-img { width: 100%; display: block; border-radius: 14px; border: 1px solid var(--border); }
.oe-preview-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; min-height: 180px; padding: 18px; text-align: center;
  border: 1.5px dashed var(--border); border-radius: 14px; background: var(--bg);
  color: var(--text-soft); font-size: 13px; line-height: 1.6;
}
.oe-preview-empty .ico { width: 28px; height: 28px; opacity: .55; }
@media (min-width: 1024px) { .oe-preview-empty { aspect-ratio: 3 / 4; min-height: 0; } }
/* 设定图卡片下方的操作区：PC 跟随卡片，移动端固定在视口底部 */
.oe-actions { display: flex; align-items: center; gap: 8px; margin-top: 14px; }
.oe-actions .btn { min-height: 46px; }
.oe-actions .btn-primary, .oe-actions .btn-ghost { flex: 1; }
.oe-actions .btn-danger { flex: none; }
/* 宽度不足时（fitOutfitActions 判定「生成设定图」会换行）：生成收成「图标 + 生成」 */
.oe-actions .oe-gen-short { display: none; }
.oe-actions.oe-compact .oe-gen-full { display: none; }
.oe-actions.oe-compact .oe-gen-short { display: inline; }
@media (max-width: 1023px) {
  .oe-actions {
    position: fixed; left: 14px; right: 14px; bottom: 14px; z-index: 20;
    margin: 0; padding: 8px; border-radius: 16px;
    background: transparent; border: 0; box-shadow: none;
  }
  .outfit-edit-page { padding-bottom: 86px; }
}
/* 搭配详情：只读标签行（场景 / 季节 / 性别） */
.outfit-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
/* 搭配详情弹窗：设定图轮播 */
.od-carousel { position: relative; border-radius: 12px; overflow: hidden; background: var(--bg); }
.od-img { width: 100%; display: block; border: 1px solid var(--border); border-radius: 12px; cursor: zoom-in; }
.od-noimg { border: 1.5px dashed var(--border); border-radius: 12px; padding: 26px 14px; text-align: center; color: var(--text-soft); font-size: 13px; }
.od-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 32px; height: 32px; padding: 0; border: 0; border-radius: 50%;
  background: rgba(30, 22, 25, .42); color: #fff; display: grid; place-items: center;
  cursor: pointer; backdrop-filter: blur(4px);
}
.od-nav .ico { width: 16px; height: 16px; }
.od-prev { left: 10px; }
.od-next { right: 10px; }
.od-prev .ico { transform: rotate(180deg); }
.od-dots {
  position: absolute; left: 50%; bottom: 10px; transform: translateX(-50%); z-index: 2;
  display: flex; gap: 4px; padding: 4px 6px; border-radius: 999px;
  background: rgba(30, 22, 25, .35); backdrop-filter: blur(6px);
}
.od-dots i { width: 5px; height: 5px; border-radius: 50%; background: rgba(255, 255, 255, .55); cursor: pointer; transition: .2s ease; }
.od-dots i.is-on { width: 12px; border-radius: 3px; background: #fff; }

/* 衣柜三视图上传 */
.wphoto-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.wphoto-cell {
  position: relative;
  aspect-ratio: 3/4;
  border-radius: 12px;
  border: 1.5px dashed rgba(var(--primary-rgb), 0.45);
  background: rgba(var(--primary-rgb), 0.12);
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.wphoto-cell.active { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(var(--primary-rgb), 0.2); }
/* 文件拖到某个角度格上时的高亮：明确显示本次会传到哪一格 */
.wphoto-cell.is-drop { border-color: var(--primary); background: rgba(var(--primary-rgb), .12); box-shadow: 0 0 0 3px rgba(var(--primary-rgb), .16); }
.wphoto-cell.is-drop .wphoto-add { transform: scale(1.12); }
.wphoto-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wphoto-add { font-size: 34px; font-weight: 300; color: var(--primary-deep); }
/* 格子右上角移除图标 */
.wphoto-del {
  position: absolute;
  top: 4px; right: 4px;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 14px;
  line-height: 20px;
  text-align: center;
  z-index: 2;
}
.wphoto-label {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 3px 0;
  font-size: 11px;
  text-align: center;
  background: rgba(255, 255, 255, 0.9);
  color: var(--text-soft);
}

/* 相册封面九宫格 */
.album-grid {
  display: grid;
  /* 列数由 --cols 决定（日记详情按张数写入）；未设置时沿用九宫格的 3 列 */
  grid-template-columns: repeat(var(--cols, 3), 1fr);
  gap: 6px;
  margin-bottom: 10px;
}
/* 只有一张照片时靠左显示：列宽保持九宫格单格宽度，靠左占首格 */
.album-grid.single { grid-template-columns: minmax(0, 33.333%); justify-content: start; }
/* 单张横图（宽>高）：宽度由单格宽放宽到 2/3，避免横图被压成一小条；竖图/方图不变。
   方向由 JS 在图片 load 后标记 .landscape（见 app.js 的 load 捕获） */
.album-grid.single.landscape { grid-template-columns: minmax(0, 66.666%); }
/* 单图：格子高度随图片比例自适应（不留空白），图片按容器宽度完整显示、不裁切 */
.album-grid.single .album-cell { aspect-ratio: auto; }
.album-grid.single .album-cell img { width: 100%; height: auto; }
/* 列表页：私密徽章挂在昵称行（.li-head）右侧；li-head 是 space-between 布局，直接靠右即可 */
.li-media-privacy { margin-left: auto; }
.album-cell {
  position: relative;
  aspect-ratio: 1;
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--border);
}
.album-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 上传占位格上的实况标记 */
.live-mini {
  position: absolute; right: 6px; bottom: 6px; z-index: 2; padding: 1px 6px; border-radius: 999px;
  background: rgba(0,0,0,.55); color: #ffd60a; font-size: 10px; font-weight: 700; letter-spacing: .06em;
}
/* 列表缩略图右上角的实况标记；鼠标悬停时在其下层插一段静音视频循环播放（只 PC 生效，见 vwLiveThumbPlay）。
   标记 pointer-events:none，不挡缩略图本身的点击（点开查看器）。 */
.thumb-live {
  position: absolute; top: 6px; right: 6px; z-index: 3; width: 22px; height: 22px;
  display: flex; align-items: center; justify-content: center; border-radius: 50%;
  background: rgba(0,0,0,.45); color: #fff; pointer-events: none; backdrop-filter: blur(3px);
}
.thumb-live .ico { width: 14px; height: 14px; }
/* 悬停播放中：标记里的射线跟着循环转动（与查看器里同一套动效） */
.thumb-live.playing .vw-ray { animation: vwRayIn .8s ease infinite; animation-delay: calc(var(--i) * .08s); }
.thumb-live-video {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 2; pointer-events: none;
}
/* 缩略图上的分级星级角标（相册照片墙）：1..n 颗点亮（实心）、其余空星；没有分级的图整块不渲染。
   压一层暗色渐变，浅色照片上星星也看得清。
   位置：移动端贴照片「顶部」（PC 端在下方 min-width:1024px 的媒体查询里改回底部）。 */
.rate-badge {
  position: absolute; left: 0; right: 0; top: 0; z-index: 2;
  display: flex; align-items: center; justify-content: center; gap: 1px;
  padding: 3px 4px 8px; pointer-events: none;
  background: linear-gradient(to bottom, rgba(0, 0, 0, .55), rgba(0, 0, 0, 0));
}
.rate-badge .ico { width: 12px; height: 12px; display: block; flex: none; }
.rate-badge .rb-on { color: var(--primary); }
.rate-badge .rb-off { color: rgba(255, 255, 255, .7); }
.album-more {
  position: absolute;
  inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  font-size: 18px;
  font-weight: 700;
}
/* PC 端专用的「第 5 格剩余张数」角标：移动端隐藏，仅 PC（min-width:1024px）显示 */
.album-more-pc { display: none; }

/* 图片上传预览网格（微信式九宫格） */
.photo-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 10px; }
.photo-cell {
  position: relative;
  aspect-ratio: 1;
  border-radius: 12px;
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--border);
}
.photo-cell img { width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none; }
.photo-cell { touch-action: pan-y; transition: transform .18s cubic-bezier(.2,.8,.2,1), box-shadow .18s ease, opacity .18s ease; }
.photo-cell.draggable-enabled { cursor: grab; user-select: none; -webkit-user-select: none; }
.photo-cell.dragging { cursor: grabbing; opacity: .35; } /* 源格留出"空位" */
.photo-cell.drop-target { transform: scale(.94); box-shadow: inset 0 0 0 2px var(--primary); }
/* 编辑页照片格上的序号与封面标记：告诉用户「保存后就是按这个顺序、第一格是封面」 */
.photo-cell .ph-no {
  position: absolute; left: 5px; top: 5px; min-width: 18px; height: 18px; padding: 0 4px;
  border-radius: 999px; background: rgba(74, 59, 64, .55); color: #fff;
  font-size: 10.5px; display: flex; align-items: center; justify-content: center;
}
.photo-cell .ph-cv {
  position: absolute; left: 5px; bottom: 5px; font-size: 10px; font-weight: 700;
  color: var(--on-primary); background: var(--btn-grad); border-radius: 999px; padding: 2px 7px;
}

/* ===== 相册编辑页：两步向导（对齐设计稿 docs/album-ui-reference.html） ===== */
/* 步骤条：① 选照片 → ② 填信息。刻意不叫 .st —— 那个类名已被打卡的「状态胶囊」占用 */
.album-steps { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; font-size: 12px; color: var(--text-soft); }
.album-step { display: flex; align-items: center; gap: 6px; }
.album-step.on { color: var(--primary-deep); font-weight: 700; }
.album-step-num {
  width: 20px; height: 20px; border-radius: 50%; border: 1px solid var(--border); background: var(--surface);
  display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700;
}
.album-step.on .album-step-num { background: var(--btn-grad); border-color: transparent; color: var(--on-primary); }
.album-step-line { flex: 1; height: 1px; background: var(--border); }
/* 第 1 步照片墙下方的说明：张数 + 封面口径 */
.album-shot-hint { margin-top: 10px; font-size: 11.5px; color: var(--text-soft); }
/* 底部操作行：下一步 / 上一步 / 取消 / 发布（等宽铺满一行） */
.album-edit-foot { display: flex; gap: 10px; margin-top: 14px; }
.album-edit-foot .btn { flex: 1; }

/* 拖动浮层：跟随光标的图片副本（"抓住图片移动"） */
.photo-ghost { position: fixed; left: 0; top: 0; z-index: 9999; pointer-events: none; will-change: transform; }
.photo-ghost-inner {
  width: 100%; height: 100%;
  border-radius: 12px; overflow: hidden;
  transform: scale(1);
  transition: transform .14s ease, box-shadow .14s ease;
}
.photo-ghost-inner.on { transform: scale(1.06); box-shadow: var(--shadow-float); }
.photo-ghost-inner img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-del {
  position: absolute;
  top: 2px; right: 2px;
  width: 20px; height: 20px;
  border: none;
  background: transparent;
  color: rgba(255,255,255,0.95);
  font-size: 20px;
  font-weight: 400;
  line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  text-shadow: 0 1px 3px rgba(0,0,0,0.5);
}

/* “+”添加格子（微信风格虚线） */
.photo-add {
  width: 100%;
  aspect-ratio: 1;
  border-radius: 12px;
  border: 1.5px dashed rgba(var(--primary-rgb), 0.5);
  background: rgba(var(--primary-rgb), 0.15);
  color: var(--primary-deep);
  font-size: 40px;
  font-weight: 300;
  line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background .15s, transform .1s;
}
.photo-add:active { background: rgba(var(--primary-rgb), 0.4); transform: scale(0.96); }

/* 拖拽上传：文件拖入落区时的高亮反馈 */
.drop-over { outline: 2px dashed var(--primary); outline-offset: 4px; background: rgba(var(--primary-rgb), 0.18); }

/* 上传失败格子：虚线框 + 叹号 + 重试 */
.photo-error {
  position: relative;
  aspect-ratio: 1;
  border-radius: 12px;
  border: 1.5px dashed var(--primary-deep);
  background: var(--bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  cursor: pointer;
}
.photo-error .pe-icon { font-size: 20px; line-height: 1; }
.photo-error .pe-text { font-size: 11px; color: var(--primary-deep); }
/* 失败格右上角删除角标 */
.photo-error .pe-del {
  position: absolute;
  top: 2px; right: 2px;
  width: 20px; height: 20px;
  border: none;
  background: transparent;
  color: rgba(255,255,255,0.95);
  font-size: 20px;
  font-weight: 400;
  line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  text-shadow: 0 1px 3px rgba(0,0,0,0.5);
}

.upload-hint { font-size: 12px; color: var(--text-soft); margin-top: 8px; line-height: 1.5; }

/* 记忆导入：拖放上传区（点击亦可选择文件） */
.dropzone { display: flex; flex-direction: column; align-items: center; gap: 7px;
  padding: 22px 14px; border: 1.5px dashed var(--border); border-radius: 14px;
  background: var(--card); cursor: pointer; text-align: center;
  transition: border-color .18s, background .18s; }
.dropzone:hover { border-color: var(--primary); }
.dropzone input[type="file"] { display: none; }
.dropzone .dz-ico { color: var(--primary); line-height: 0; }
.dropzone .dz-ico .ico { width: 26px; height: 26px; }
.dropzone .dz-main { font-size: 13px; color: var(--text); }
.dropzone .dz-sub { font-size: 11.5px; color: var(--text-soft); word-break: break-all; }
.dropzone.has-file .dz-sub { color: var(--primary); font-weight: 500; }

/* 记忆导入预览：条目多时在框内滑动查看，不把弹窗撑长 */
.imp-preview { max-height: 260px; overflow-y: auto; overscroll-behavior: contain; word-break: break-word; }
.photo-count { font-size: 12px; color: var(--text-soft); margin-left: auto; }

/* 快捷添加菜单 */
.quick-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.quick-row { display: flex; gap: 12px; margin-top: 12px; }
.quick-row .quick-item { flex: 1; }
.quick-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 18px 12px;
  border-radius: 16px;
  background: var(--bg);
  border: 1px solid var(--border);
  font-size: 14px;
  cursor: pointer;
  transition: transform .1s, background .15s;
}
.quick-item:active { transform: scale(0.96); background: var(--primary-soft); }
.quick-icon { font-size: 30px; }

/* ===== 评论（相册 / 日记共用，条目版式对齐截图） =====
   不再渲染头像：昵称已足够区分是谁，去掉头像后正文能多出一列宽度。
   条目 = 昵称行 + 正文 + 元信息行；元信息行左「时间 · 归属地」、右「点赞（带计数）· 更多」。 */
.cmt { margin-top: 12px; padding-top: 10px; }
.cmt-head { display: flex; align-items: center; gap: 5px; font-size: 12.5px; font-weight: 700; color: var(--text); margin-bottom: 8px; }
.cmt-head .ico { width: 15px; height: 15px; color: var(--primary-deep); }
.cmt-count { color: var(--primary-deep); }
.cmt-list { display: flex; flex-direction: column; gap: 12px; }
.cmt-empty { font-size: 13px; color: var(--text-soft); }
.cmt-item { font-size: 12.5px; line-height: 1.7; }
.cmt-main { min-width: 0; }
/* 列表卡片里的评论区：不挂头像，但左侧按头像栏宽度留空（移动端 38+10、PC 44+14），
   让昵称 / 正文 / 输入框与上方 .p-body 左对齐；回复块会在这条基准线上再缩进 */
.list-item.post .cmt { padding-left: calc(var(--post-av-w, 38px) + var(--post-gap, 10px)); }
/* 昵称独占一行（.cmt-who），评论内容另起一行占满宽度（.cmt-body） */
.cmt-who { font-size: 12.5px; line-height: 1.6; color: var(--text-soft); }
.cmt-body { line-height: 1.7; color: var(--text); word-break: break-word; }
/* 评论人昵称：独立成行后与「回复 @某某」同属昵称行 */
.cmt-who .who { font-weight: 600; color: var(--primary-deep); }
.cmt-text { white-space: pre-wrap; word-break: break-word; }
.cmt-at { color: var(--primary-deep); }
/* 元信息行：左组「时间 · 归属地」，右组「回复 · 点赞 · 更多」由 auto 外边距贴住右侧。
   移动端（见文件末尾窄屏规则）把回复与点赞收进「更多」菜单，行上只剩时间 / 归属地与 ⋮。
   行高写死成同一个像素值：时间 / 归属地是 11px、动作按钮是 12.5px，若各自按字号算行盒，
   两者就会一高一矮（时间那格看着矮一截）；统一成 20px 后每格行盒一样高，纵向也就齐了。 */
.cmt-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 3px; line-height: 20px; }
.cmt-region, .cmt-time { font-size: 11px; color: var(--text-soft); }
/* 评论批量管理列表（.cmt-mg-body）沿用「昵称高亮」样式，评论条目本身已改用 .who */
.cmt-author { font-weight: 600; color: var(--primary-deep); }
.cmt-meta-right { margin-left: auto; display: inline-flex; align-items: center; gap: 12px; }
/* 元信息行上的动作（回复 / 点赞 / 更多）：无边框文字按钮，靠主题色反馈点击。
   min-height 与 .cmt-meta 的行高对齐：纯图标的「更多」没有文字行，不写就会比同行的
   时间 / 点赞矮 5px（点哪儿倒是没坏，只是这一行看着不齐）。 */
.cmt-act {
  border: none; background: none; padding: 0; cursor: pointer;
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 12.5px; font-family: inherit; color: var(--text-soft);
  min-height: 20px;
}
.cmt-act:hover { color: var(--primary-deep); }
.cmt-act .ico { width: 15px; height: 15px; }
/* 「更多」⋮ 用正文色，比其他动作按钮的浅灰更醒目（移动端它是点赞 / 回复的唯一入口）。
   hover 也要单独写：.cmt-act:hover 与这里同特异性，会被这条默认色盖掉。 */
.cmt-act[data-cmt-more] { color: var(--text); }
.cmt-act[data-cmt-more] .ico { width: 16px; height: 16px; }
.cmt-act[data-cmt-more]:hover { color: var(--primary-deep); }
.cmt-like b { font-size: 12.5px; font-weight: 600; }
.cmt-like.on { color: var(--primary-deep); }
/* 心形点赞：默认只有描边，点过之后把同一段 path 填成实心（见 ICO_CMT_LIKE 的注释） */
.cmt-like.on .ico path { fill: currentColor; }
.cmt-subs { margin-top: 8px; padding-left: 10px; border-left: 2px solid var(--border); display: flex; flex-direction: column; gap: 8px; }
/* 「查看全部 N 条评论」链接专用。评论行右侧的 ⋯ 按钮不要再挂这个类：它是 .cmt-act 的文字/图标按钮，
   挂上来会连带吃到这里的外边距与主题色（曾导致 ⋯ 比「点赞」低 9px、颜色也不一致）。 */
.cmt-more { margin-top: 9px; font-size: 12.5px; font-weight: 600; color: var(--primary-deep); cursor: pointer; }
.cmt-replying { font-size: 12px; color: var(--text-soft); margin-top: 8px; }
/* 输入区默认收起：平时只露一行入口（占位按钮 / 卡片底部「评论」），点开才展开。
   .cmt-compose 自身没有 display，hidden 属性即可生效；里面 .cmt-form 仍是 flex。 */
.cmt-compose[hidden] { display: none; }
/* 占位入口：长得像输入框的按钮，点一下换成真正的输入区（详情页 / 相册列表 / 展示页用） */
.cmt-open {
  display: block; width: 100%; margin-top: 12px; padding: 9px 12px; text-align: left;
  font-family: inherit; font-size: 12.5px; color: var(--text-soft);
  background: var(--card); border: 1px solid var(--border); border-radius: 10px; cursor: pointer;
}
.cmt-open:hover { border-color: var(--primary); color: var(--primary-deep); }
/* .cmt-open 自己写了 display:block，会盖掉 [hidden] 的默认隐藏，这里补回来 */
.cmt-open[hidden] { display: none; }
/* 列表卡片里没有评论时，收起的评论区不占高度（展开时 bindCmt 会摘掉这个类） */
.cmt.is-empty { margin-top: 0; padding-top: 0; }
.cmt-form { display: flex; gap: 8px; margin-top: 12px; }
.cmt-input, .cmt-nick {
  flex: 1; min-width: 0; font-size: 12.5px; padding: 9px 12px;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--card); color: var(--text); outline: none;
}
.cmt-nick { display: block; width: 100%; flex: none; margin-bottom: 8px; }
/* 发表按钮：圆角渐变实心（与原型 .cmt-send 一致） */
.cmt-send {
  flex: none; border: none; border-radius: 10px; padding: 0 16px;
  background: var(--btn-grad); color: #fff; font-size: 12.5px; font-weight: 700;
  font-family: inherit; cursor: pointer;
}
/* 移动端：评论行只留时间 / 归属地与 ⋮，点赞和回复收进「更多」菜单里点开再用
   （菜单项在 bindCmt 的 [data-cmt-more] 处理中，与桌面端共用同一份点赞逻辑）。 */
@media (max-width: 639.98px) {
  .cmt-reply-btn, .cmt-like { display: none; }
}
/* 评论批量管理 */
.cmt-mg-item { display: flex; gap: 10px; align-items: flex-start; }
/* 圆形勾选控件（行内与「全选」共用一套图标：空心圆 / 实心圆内勾）。
   做成 button 而非原生 checkbox，原生框画不出圆形，且各浏览器样式不一致。 */
.cmt-mg-box {
  flex: none; margin-top: 2px; width: 22px; height: 22px; padding: 0;
  border: none; background: none; cursor: pointer; color: var(--text-soft);
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; transition: color .15s, transform .1s;
}
.cmt-mg-box .ico { width: 20px; height: 20px; }
.cmt-mg-box:hover { color: var(--primary-deep); }
.cmt-mg-box:active { transform: scale(.9); }
.cmt-mg-box.on { color: var(--primary-deep); }
.cmt-mg-body { flex: 1; min-width: 0; }
.cmt-mg-target { font-size: 11px; color: var(--text-soft); }
/* 「全部评论」的滚动列表：筛选栏 / 操作条固定在上方，滚动只作用在列表本身（滚到底自动取下一页，
   见 app.js cmtMgBindLazy）。内边距 + 负外边距是为了让卡片投影不被 overflow 裁掉，同时与上方内容左对齐。
   高度统一交给 syncLogScroll 实测（贴到视口底边），不再用固定 58vh —— 那样在长列表页会留一大块空白。 */
.cmt-mg-scroll {
  overflow-y: auto; overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch; padding: 2px; margin: -2px;
}
/* 懒加载哨兵：滚进滚动容器视口即取下一页 */
.cmt-mg-more { padding: 12px 0 2px; text-align: center; font-size: 12px; color: var(--text-soft); }
.cmt-inline, .cmt-host { margin-top: 10px; }
/* 列表条目内的评论区：收窄与上方正文/配图的间距（原来 cmt-inline + cmt 叠加约 40px 留白，太大） */
.list-item .cmt-inline { margin-top: 6px; }
.list-item .cmt-inline .cmt { margin-top: 0; padding-top: 0; }
.list-item .cmt-inline .cmt-form { margin-top: 6px; }
.cmt-switch { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 12px; font-size: 14px; color: var(--text); }
/* 操作条：放在筛选栏下方、评论列表上方（不是浮在内容上）。
   只有勾选了评论才出现（见 syncCmtMgSel），所以不用 sticky，也就不会挡住下面的列表。 */
.cmt-mg-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 10px 12px; margin: 10px 0 12px;
  background: var(--panel-soft); border: 1px solid var(--border); border-radius: 12px;
}
.cmt-mg-bar[hidden] { display: none; }
.cmt-mg-left { display: flex; align-items: center; gap: 12px; min-width: 0; }
/* 「全选」也是同一个圆形勾选控件；.half 表示部分选中（沿用空心圆但压暗） */
.cmt-mg-all { display: inline-flex; align-items: center; gap: 6px; flex: none; padding: 0; border: none; background: none; font-size: 13px; color: var(--text); cursor: pointer; user-select: none; }
.cmt-mg-all .ico { width: 20px; height: 20px; color: var(--text-soft); }
.cmt-mg-all:hover .ico { color: var(--primary-deep); }
.cmt-mg-all.on .ico { color: var(--primary-deep); }
.cmt-mg-all.half .ico { color: var(--primary); opacity: .55; }
/* 详情页作者行：头像 + 昵称在左，编辑按钮贴右 */
.detail-author { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
/* 作者头像（详情页 / 列表 / 评论共用）需显式约束尺寸：默认头像的 SVG 无自带宽高，不约束会溢出遮住内容。
   投影：一层很淡的环形暗影，把头像从卡片白底上"托"起来一点；不用 box-shadow 外扩，
   避免和 border-radius:50% + overflow:hidden 的裁剪打架（外扩阴影会被裁掉）。 */
.author-avatar {
  display: block; width: 32px; height: 32px; flex: none;
  border-radius: 50%; overflow: hidden; object-fit: cover; background: var(--bg);
  box-shadow: 0 1px 3px rgba(176, 53, 91, .14), 0 0 0 1px rgba(176, 53, 91, .06);
}
.author-avatar img, .author-avatar svg { width: 100%; height: 100%; display: block; object-fit: cover; }
/* 深色模式：浅色投影在暗底上会显脏，改成更淡的黑影 + 一圈浅色描边勾出轮廓 */
body.dark .author-avatar { box-shadow: 0 1px 3px rgba(0, 0, 0, .25), 0 0 0 1px rgba(255, 255, 255, .10); }
.detail-author-name { font-size: 14px; color: var(--text-soft); }
/* 操作按钮组靠右：li-head-right 是 .detail-author 的直接子元素，auto 外边距才能把它推到最右
   （若按 .btn-edit 写，它在包装层内部，选择器匹配不到） */
.detail-author .li-head-right { margin-left: auto; }

/* ===== 日常详情（对齐 docs/prototype：作者行 + 日期行 + 手写体正文，配图与徽章在正文内）===== */
.detail-card { padding: 16px 14px; }
/* 作者行右侧的「更多」：只留图标，不画框、不铺底色，靠图标本身的颜色识别 */
.opbtn {
  width: 30px; height: 30px; border-radius: 9px; border: none;
  background: none; color: var(--primary-deep); padding: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.opbtn:hover { color: var(--primary); }
.opbtn .ico { width: 16px; height: 16px; }
/* 列间距不再由 CSS 给：标题行内容之间是两个 &nbsp;（见 diaryTitleHtml），
   这里只保留换行时的行间距，避免和 &nbsp; 叠加成过宽的缝 */
.diary-title { font-size: 17px; font-weight: 700; display: flex; align-items: center; gap: 4px 0; flex-wrap: wrap; margin-bottom: 10px; }
/* 图标略大于字号：17px 粗体汉字旁边放 20px 线性图标，视觉重量才相当 */
.diary-title .ico { width: 20px; height: 20px; }
/* 公开 / 私密徽章推到作者行最右端，作者行的「更多」按钮紧随其右 */
.detail-author .privacy-badge { margin-left: auto; }
/* 天气 / 心情图标配色。天气沿用 docs/diary-ui-reference.html 的 .wico 色板，
   心情按情绪冷暖各给一色；列表（.p-title）/ 详情（.diary-title）/ 展示页（.sp-head）共用这套类名。 */
.wico.sun { color: #f6a935; }
.wico.cloud { color: #9fb4cc; }
.wico.rain { color: #5b9bd5; }
.wico.snow { color: #6fb1dd; }
.wico.wind { color: #97a6b6; }
.mico.happy { color: #f2b135; }
.mico.moved { color: #e0638f; }
.mico.miss { color: #ff5c8a; }
.mico.calm { color: #7fa8cf; }
.mico.quarrel { color: #e8823f; }
.mico.sweet { color: #ff8fab; }
.diary-body { line-height: 1.95; }
.diary-body .p-imgs { display: grid; grid-template-columns: repeat(var(--cols, 3), 1fr); gap: 6px; margin: 10px 0 0; }
.diary-body .thumb {
  position: relative; /* 实况标记 / 悬停视频的定位参照 */
  aspect-ratio: 1; border-radius: 4px; overflow: hidden;
  border: 1px solid var(--border); background: var(--panel-soft);
}
.diary-body .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; margin: 0; cursor: pointer; }
/* 详情页单图与列表卡片同口径：先按 4:3 占位，图到位后按原比例展示（宽图不裁边、不跳高度） */
.diary-body .p-imgs[data-cols="1"] .thumb { aspect-ratio: auto; width: fit-content; max-width: 100%; justify-self: center; }
.diary-body .p-imgs[data-cols="1"] .thumb img { width: auto; height: auto; max-width: 100%; max-height: min(60vh, 420px); object-fit: contain; }
.diary-body .p-imgs[data-cols="1"] .thumb:not(.is-loaded) { aspect-ratio: 4 / 3; width: 100%; }
.diary-body .p-imgs[data-cols="1"] .thumb:not(.is-loaded) img { width: 100%; height: 100%; object-fit: cover; }
.diary-body .p-badges { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.diary-body .p-badges .loc-badge { margin-left: 0; }
/* 评论区在详情卡内：紧接正文下方，不画分隔线，间距与列表页口径一致 */
.detail-card #cmtBox .cmt { margin-top: 6px; }
/* 列表条目的作者行：头像 + 昵称 */
.li-author { display: inline-flex; align-items: center; gap: 6px; }
.li-author .li-sub { font-size: 14px; }
/* 相册列表头部行：作者在左，隐私徽章与操作按钮在右 */
.li-head-right { display: inline-flex; align-items: center; gap: 8px; }
/* 照片下方一行：相对时间 + 位置徽章；详情页再追加隐私徽章，margin-left:auto 把它推到最右 */
.album-foot { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.album-foot .loc-badge { margin-left: 0; }
.album-foot .privacy-badge { margin-left: auto; }
/* 相册详情页拖拽上传遮罩：拖入图片时铺满屏幕，提示松手即上传（遮罩本身即投放框） */
.album-drag-mask {
  position: fixed; inset: 0; z-index: 60; display: none;
  align-items: center; justify-content: center;
  background: rgba(28, 20, 26, .45);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.album-drag-mask.on { display: flex; }
.album-drag-box {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  min-width: 220px; padding: 34px 40px; text-align: center;
  color: var(--primary-deep); background: var(--card);
  border: 2px dashed var(--primary); border-radius: 18px;
}
.album-drag-box .ico { width: 28px; height: 28px; }
.album-drag-box .adbm-t { font-size: 15px; font-weight: 600; }
.album-drag-box .adbm-s { font-size: 12px; color: var(--text-soft); }
/* 专辑头：元信息 pill 行 + 操作行（相册没有长篇正文，信息密度靠这两行撑） */
.album-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 11px; }
.meta-pill {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; color: var(--primary-deep);
  background: var(--panel-soft); border: 1px solid var(--border); border-radius: 999px; padding: 3px 9px;
}
/* 专辑头的操作区：按钮等宽铺满一行（设计稿 .hero .acts .btn{flex:1}） */
.album-acts { display: flex; gap: 8px; margin-top: 12px; }
.album-acts .btn { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
/* 上传按钮的文案：移动端只留「上传」（这一行还要容下分级条），PC 端显示「上传照片」 */
.ad-up-full { display: none; }
@media (min-width: 1024px) {
  .ad-up-full { display: inline; }
  .ad-up-short { display: none; }
}
/* 分级筛选条：紧挨「上传照片」右侧，点 / 按住滑过星星只看该等级，再点同一颗取消。
   外观与同排的 .btn-ghost.btn-sm 对齐（同边框色 / 同底色 / 同圆角，间距也回到行内统一 gap）；
   touch-action:none —— 按住左右滑动时别让页面跟着横向滚。 */
.album-rate-filter {
  display: inline-flex; align-items: center; gap: 5px; flex: none;
  padding: 0 10px;
  background: var(--surface);
  border: 1px solid var(--primary);
  border-radius: 10px;
  color: var(--primary-deep);
}
.album-rate-filter .arf-label { font-size: 12px; color: var(--primary-deep); }
.album-rate-filter .arf-stars { display: inline-flex; align-items: center; gap: 1px; touch-action: none; }
.album-rate-filter .rate-star { color: var(--border); }
.album-rate-filter .rate-star.on { color: var(--primary); }
.album-rate-filter .rate-star:hover { color: var(--primary-deep); }
/* 上传进度条：固定在专辑头卡正下方。照片墙里的占位格排在墙末尾，相册照片一多就被挤出视野，
   所以「正在传第几张 / 共几张」要另有一条常驻在视线里（由 uploadAlbumFiles 插入 / 移除）。 */
.album-up-bar {
  display: flex; align-items: center; gap: 10px;
  margin-top: 10px; padding: 10px 14px;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 14px; box-shadow: var(--shadow);
}
.aub-text { flex: none; font-size: 12.5px; color: var(--text-soft); font-variant-numeric: tabular-nums; }
.aub-track { flex: 1; height: 6px; border-radius: 3px; background: var(--primary-soft); overflow: hidden; }
.aub-fill { display: block; width: 0; height: 100%; border-radius: 3px; background: var(--primary-deep); transition: width .18s linear; }
/* 详情页照片墙：按「拍摄日」分组的完整照片墙。
   刻意不用列表页那套 .album-grid-wrap（PC 固定 5 列 140px + 第 6 张起隐藏），
   因为详情页要完整展示 + PC 6 列铺满（设计稿 .pw）。 */
/* 照片墙内纵向滚动照常，横向拖动整个交给滑动多选（免得被浏览器横滑手势抢走）；
   保留 pinch-zoom，别让墙区域内双指缩放页面失效。 */
.album-wall {
  touch-action: pan-y pinch-zoom;
  /* 照片墙禁掉 iOS 的长按原生 callout（「存储图像 / 拷贝」）：它会冒出来打断横向滑动选择的手势
     （Android / 桌面端由 JS 拦 contextmenu）。
     只限详情页照片墙，列表页缩略图不受影响，长按仍可存图。 */
  -webkit-touch-callout: none; -webkit-user-select: none; user-select: none;
}
/* 照片墙里的图片禁掉浏览器原生拖拽：鼠标按住照片拖动时，浏览器会先把 <img> 当原生拖放源
   （触发 dragstart 并派发 pointercancel），把正在进行的滑动选择手势打断 —— 表现就是
   「按住拖过一片照片，一张都选不上」。-webkit-user-drag 只覆盖 WebKit / Blink，Firefox
   由 JS 在绑定时设 draggable=false（见 bindAlbumWallGestures）。只限详情页照片墙，
   查看器 / 列表页拖图另存不受影响。 */
.album-wall img { -webkit-user-drag: none; }
.album-wall .vg-sec .album-grid { margin-bottom: 0; }
.album-wall .vg-sec:last-child { margin-bottom: 0; }
/* ===== 勾选标记（全站统一）=====
   两种形态，接入点只关心「要不要计数」：
   · 不需要计数 → .pick-mark 里放 .pick-ico：实心圆 + 镂空勾。勾处是挖空的，透出容器底衬色，
     所以容器必须带浅色底（默认白），勾才显成白色。
   · 需要计数   → .pick-mark.pick-mark-n：主色实心圆 + 白字序号（.pick-n）。
   尺寸由 --pick-sz 控制（默认 22px），接入点按需覆盖。 */
.pick-mark {
  width: var(--pick-sz, 22px); height: var(--pick-sz, 22px); border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  background: #fff; color: var(--primary);
}
.pick-mark.pick-mark-n { background: var(--btn-grad); }
/* 勾 / 序号是可与别处共用的两个内容物：相册容器自带圆底，只借这两样 */
.pick-ico { display: block; width: 100%; height: 100%; color: var(--primary); flex: none; }
.pick-n { color: var(--on-primary); font-size: 12px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }

/* —— 详情页照片多选（对齐 docs/album-ui-reference.html）——
   勾选组件有两处：照片格左上角一个（.album-pick）、日期组头左侧一个（.album-hdsel，点它整组全选）。
   它们是 DOM 节点而不是 ::after 伪元素 —— 「已选中」的画法是「实心圆 + 镂空勾」的 SVG，
   还要在圆里叠「第几张」的序号，伪元素塞不进子节点。
   显隐分三层，浏览态一律不显示（由基础 opacity:0 兜住）：
   ① 已选中：管理态下常显。任何设备都一样 —— 不靠悬停也要看得出选了哪几张、第几张
   ② 未选中 + 触摸设备：管理态下也常显，否则用户无从点起
   ③ 未选中 + 真鼠标：照片格上的勾选圈悬停才出现，平时不挡照片
   ⚠ 组头那个勾选圈（.album-hdsel）不压在照片上，没有遮挡问题，管理态下一律常显（见 ①b）——
   若也按悬停隐藏，就成了「看不见却点得到」，用户根本发现不了「全选这一天」这个入口。
   ⚠ 悬停规则必须同时限定 pointer:fine。触摸设备有「粘滞 hover」，点一下 :hover 就永久挂在那个
   元素上再也收不回去；而且部分安卓浏览器会把自己报成 hover:hover，只判 hover 会漏掉它们。 */
.album-pick, .album-hdsel {
  width: 22px; height: 22px; border-radius: 50%; border: 2px solid #fff;
  background: rgba(74, 59, 64, .35); box-shadow: 0 1px 3px rgba(0, 0, 0, .18);
  opacity: 0; transition: opacity .12s ease; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
}
.album-pick { position: absolute; left: 6px; top: 6px; cursor: pointer; }
.album-hdsel { position: relative; flex: none; cursor: pointer; }
/* 只在多选态里可点：浏览态它是隐形的，若还能接点击，照片左上角与日期组头左侧就成了
   「看不见、一碰却进多选」的暗坑（触摸端尤其明显 —— 点照片左上角本该打开大图）。 */
.album-manage .album-pick, .album-manage .album-hdsel { pointer-events: auto; }
/* 勾 / 序号在相册里的显隐：勾只在组头「整组已全选」时亮起，照片格一律用序号 */
.album-pick .pick-ico, .album-hdsel .pick-ico { display: none; }
.album-pick .pick-n { display: none; }
/* 照片选中：实心主色圆 + 序号 */
.album-cell.on .album-pick { border: 0; background: var(--btn-grad); box-shadow: none; }
.album-cell.on .album-pick .pick-n { display: block; }
/* 组头整组全选：底衬白圈，让镂空的勾显形成白色 */
.vg-sec-title.ap-all .album-hdsel { border: 0; background: #fff; box-shadow: none; }
.vg-sec-title.ap-all .album-hdsel .pick-ico { display: block; }
/* 选中态：主色描边压在照片上（用 ::after 才会盖在 img 之上）+ 压暗 */
.album-manage .album-cell.on::after {
  content: ""; position: absolute; inset: 0; border-radius: 8px;
  border: 3px solid var(--primary); pointer-events: none;
}
.album-manage .album-cell.on img { filter: brightness(.86); }
/* ① 已选中：管理态下常显 */
.album-manage .album-cell.on .album-pick { opacity: 1; }
/* ①b 组头「全选这一天」：管理态下一律常显。它在标题行里，不压照片，没有悬停隐藏的理由 */
.album-manage .vg-sec-title .album-hdsel { opacity: 1; }
/* ② 未选中 + 触摸设备：管理态下也常显。
      pointer:coarse 一并判上 —— 部分安卓浏览器会把自己报成 hover:hover，只判 hover 会漏掉它们 */
@media (hover: none), (pointer: coarse) {
  .album-manage .album-pick { opacity: 1; }
}
/* ③ 未选中 + 真鼠标：照片格上的勾选圈悬停才出现，平时不挡照片 */
@media (hover: hover) and (pointer: fine) {
  .album-manage .album-cell:hover .album-pick { opacity: 1; }
}
/* 管理态底栏：固定在视口底部（左右与内容区对齐），只与页面底部留一点间距。
   原先用 sticky，只有滚到文档末尾才贴底，中间过程会跟着照片墙跑出屏幕。
   滚动 / 贴边自动滚屏时先收起来（别挡住照片），停手后再滑回来（.is-hidden，见 adMBarOnScroll）。 */
.album-mbar {
  position: fixed; z-index: 5;
  left: calc(var(--sidebar-w, 0px) + 16px); right: 16px;
  bottom: calc(var(--tabbar-h) + 12px);
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 10px 12px;
  background: var(--card); border: 1px solid var(--border); border-radius: 14px; box-shadow: var(--shadow);
  transition: transform .18s ease, opacity .18s ease;
}
.album-mbar.is-hidden { transform: translateY(calc(100% + 24px)); opacity: 0; pointer-events: none; }
.album-mbar .n { flex: none; font-size: 12.5px; color: var(--text-soft); }
/* 管理态底栏的六个动作按钮（移动 / 复制 / 下载 / 打包下载 / 删除 / 取消）：
   等分剩下的横向空间；窄屏一行放不下就整行折下去，不把文字挤成两行 */
.album-mbar .btn { flex: 1 1 56px; }
/* 「移动 / 复制」的目标相册选择弹窗 */
.ad-target-list { display: flex; flex-direction: column; gap: 8px; max-height: 52vh; overflow-y: auto; }
.ad-target-item {
  display: flex; align-items: center; gap: 10px; padding: 12px 14px; cursor: pointer; text-align: left;
  border: 1px solid var(--border); border-radius: 12px; background: var(--surface);
}
.ad-target-item:active { background: var(--panel-soft); }
.ad-target-item .t { font-size: 14.5px; font-weight: 600; color: var(--text); }
.ad-target-item .s { margin-left: auto; font-size: 12px; color: var(--text-soft); }
/* 底栏浮在内容之上（不在文档流里），给管理态的照片墙补出它占的高度，免得最后一行被盖住 */
.album-wall.album-manage { padding-bottom: 48px; }
/* 移动端多选态左上角有勾选圆（.album-pick），分级角标挪到顶部后会压住它；选择时也不太需要看星级。
   PC 端角标仍在底部、与勾选圆不冲突，所以这条只管移动端。 */
@media (max-width: 1023.98px) { .album-manage .rate-badge { display: none; } }
@media (min-width: 1024px) { .album-mbar { bottom: 20px; } }
/* 相册的「说明」最多两行：相册的文字是附注，不是正文（日常的正文不设限） */
.album-note { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; margin-top: 6px; }
/* 相册「列表」排版：一行（缩略图 + 标题 + 张数/地点 + 说明 + 话题）。互动只在详情页，列表不内联评论 */
.album-rows { display: flex; flex-direction: column; gap: 12px; }
.album-row {
  display: flex; align-items: center; gap: 12px; cursor: pointer;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 10px;
}
.album-row .th { width: 64px; height: 64px; flex: none; border-radius: 12px; overflow: hidden; background: var(--panel-soft); }
.album-row .th img { width: 100%; height: 100%; object-fit: cover; display: block; }
.album-row .th-empty { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--primary-soft); }
.album-row .th-empty .ico { width: 22px; height: 22px; }
.album-row .mn { min-width: 0; flex: 1; }
.album-row .t { font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.album-row .s { margin-top: 4px; font-size: 11.5px; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 行里的「说明」与「话题」：说明沿用详情页口径（附注、最多两行），但字号要压到次级文字那档
   ——基础规则只管截断，不管字号，直接用会跟标题一样大 */
.album-row .album-note { margin-top: 4px; font-size: 12px; line-height: 1.5; color: var(--text-soft); }
.album-row .topic-chips { margin-top: 6px; }
/* 右侧入口箭头：线性 chevron（对齐参考稿 .rows .arrow），不是文本字符 */
.album-row .entry-arrow { display: flex; flex: none; color: var(--text-soft); }
.album-row .entry-arrow .ico { width: 15px; height: 15px; }
.album-time { font-size: 12px; color: var(--text-soft); }

/* ===== 弹窗 ===== */
/* 弹窗打开时锁住背景滚动；--modal-sbw 由 app.js 按实际滚动条宽度写入，避免内容横向跳动 */
body.modal-open { overflow: hidden; padding-right: var(--modal-sbw, 0px); }
/* 弹窗统一为屏幕居中的浮动卡片：任意宽度（含移动端）都垂直居中，不再有底部弹层形态 */
.modal-mask {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.4);
  z-index: 100;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  overscroll-behavior: contain;
  animation: fadeIn .2s ease;
}
/* 叠层弹窗（编辑弹窗里再弹「确认 / 改名」）：整体高一层，关掉后下层表单还在。
   z-index 必须高于所有基础层：普通弹窗 100、照片查看器 200、强制弹窗（openForcedModal）300。 */
.layered-modal { position: fixed; inset: 0; z-index: 350; }
.modal {
  width: 100%;
  max-width: 520px;
  background: var(--card);
  border-radius: 22px;
  padding: 20px 18px;
  max-height: 90vh;
  overflow-y: auto;
  animation: fadeIn .2s ease;
}
/* 容器本身作为焦点落点（tabindex=-1）时不画整圈焦点框，内部控件仍保留各自焦点样式 */
.modal:focus { outline: none; }
/* 手机键盘弹起：弹窗改为顶部对齐并按可视高度限高，最后一行输入框才不会被键盘盖住。
   --vvh 由 app.js 从 visualViewport 写入；桌面端不会进入 .kb-open。 */
body.kb-open .modal-mask { align-items: flex-start; padding-top: 12px; }
body.kb-open .modal { max-height: calc(var(--vvh, 100vh) - 24px); }
.modal-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; position: relative; }
.modal-head h3 { margin: 0; font-size: 17px; }
/* 弹窗标题内的行内图标：与标题文字垂直居中、间距统一 */
.modal-head h3 .ico { width: 17px; height: 17px; vertical-align: -0.16em; margin-right: 4px; }
.modal-close { border: none; background: transparent; font-size: 22px; color: var(--text-soft); cursor: pointer; }

/* ===== Toast ===== */
#toastRoot { position: fixed; top: 60px; left: 0; right: 0; z-index: 200; display: flex; flex-direction: column; align-items: center; gap: 8px; pointer-events: none; }
/* 基础款「粉色柔光」：浅主题色渐变底 + 深色文字 + 柔光投影。
   站点的默认样式是「磨砂玻璃」，由下方 html[data-toast-style="glass"] 覆盖；这里作为基础定义保留。
   渐变色用 --primary-rgb 推导，换成柠檬黄 / 天青蓝 / 香芋紫时自动跟随，不会固定成粉色。
   左侧圆点 / 圆形状态图标由 html[data-toast-style] 二选一显示（见下）。 */
.toast {
  display: flex;
  align-items: center;
  gap: 8px;
  background: linear-gradient(180deg, rgba(var(--primary-rgb), .07), var(--primary-soft));
  color: var(--primary-deep);
  padding: 10px 16px;
  border: 1px solid rgba(var(--primary-rgb), .34);
  border-radius: 14px;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.5;
  text-align: left;
  /* 长文案（接口报错）在窄屏换行，不撑出屏幕；可点击关闭 */
  max-width: min(560px, calc(100vw - 32px));
  word-break: break-word;
  pointer-events: auto;
  cursor: pointer;
  box-shadow: 0 8px 22px rgba(var(--primary-rgb), .22);
  animation: fadeIn .2s ease;
}
/* 成功 / 失败换成同色系的浅底 + 深字，圆点跟着变色 */
.toast--success {
  background: linear-gradient(180deg, #f4fbf6, var(--ok-soft));
  color: var(--ok-ink);
  border-color: var(--ok-border);
  box-shadow: 0 8px 22px rgba(59, 165, 93, .16);
}
.toast--error {
  background: linear-gradient(180deg, #fff5f4, var(--danger-soft));
  color: var(--danger-ink);
  border-color: var(--danger-border);
  box-shadow: 0 8px 22px rgba(229, 72, 77, .16);
}
.toast-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--primary); }
.toast--success .toast-dot { background: var(--ok); }
.toast--error .toast-dot { background: var(--danger); }
/* 圆形状态图标：默认隐藏，仅在「图标卡片」样式下取代圆点 */
.toast-ico {
  display: none;
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  align-items: center;
  justify-content: center;
  background: var(--primary-soft);
  color: var(--primary-deep);
}
.toast-ico svg { width: 15px; height: 15px; }
.toast-msg { min-width: 0; }

/* 深色模式：柔光底改成低亮度主题色，保持发光质感但不刺眼 */
body.dark .toast {
  background: linear-gradient(180deg, rgba(var(--primary-rgb), .18), rgba(var(--primary-rgb), .09));
  color: var(--primary);
  border-color: rgba(var(--primary-rgb), .34);
  box-shadow: 0 8px 22px rgba(0, 0, 0, .38);
}
body.dark .toast--success {
  background: linear-gradient(180deg, rgba(var(--ok-rgb, 59, 165, 93), .2), rgba(var(--ok-rgb, 59, 165, 93), .1));
  color: var(--ok);
  border-color: var(--ok-border);
  box-shadow: 0 8px 22px rgba(0, 0, 0, .38);
}
body.dark .toast--error {
  background: linear-gradient(180deg, rgba(var(--danger-rgb, 229, 72, 77), .2), rgba(var(--danger-rgb, 229, 72, 77), .1));
  color: #ff9a9e;
  border-color: var(--danger-border);
  box-shadow: 0 8px 22px rgba(0, 0, 0, .38);
}
body.dark .toast-ico { background: rgba(var(--primary-rgb), .16); color: var(--primary); }
body.dark .toast--success .toast-ico { background: rgba(59, 165, 93, .18); color: var(--ok); }
body.dark .toast--error .toast-ico { background: rgba(229, 72, 77, .18); color: #ff9a9e; }

/* ===== 提示样式 2：磨砂玻璃 ===== */
html[data-toast-style="glass"] .toast {
  background: rgba(255, 255, 255, .72);
  color: var(--text);
  border: 1px solid rgba(var(--primary-rgb), .26);
  border-radius: 14px;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 10px 26px rgba(var(--accent-rgb), .16);
}
html[data-toast-style="glass"] .toast-dot { background: var(--primary-deep); }
html[data-toast-style="glass"] .toast--success {
  background: rgba(232, 246, 237, .8); color: var(--ok-ink);
  border-color: var(--ok-border); box-shadow: 0 10px 26px rgba(59, 165, 93, .14);
}
html[data-toast-style="glass"] .toast--error {
  background: rgba(253, 236, 234, .82); color: var(--danger-ink);
  border-color: var(--danger-border); box-shadow: 0 10px 26px rgba(229, 72, 77, .14);
}
html[data-toast-style="glass"] body.dark .toast {
  background: rgba(35, 28, 40, .72);
  color: var(--text);
  border-color: rgba(var(--primary-rgb), .26);
}
html[data-toast-style="glass"] body.dark .toast--success { background: rgba(31, 51, 40, .78); color: var(--ok); }
html[data-toast-style="glass"] body.dark .toast--error { background: rgba(56, 30, 30, .78); color: #ff9a9e; }

/* ===== 提示样式 3：图标卡片 ===== */
html[data-toast-style="icon"] .toast {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 10px 15px 10px 12px;
  box-shadow: var(--shadow-float);
}
html[data-toast-style="icon"] .toast-dot { display: none; }
html[data-toast-style="icon"] .toast-ico { display: flex; }
html[data-toast-style="icon"] .toast--success { background: var(--surface); color: var(--text); border-color: var(--ok-border); }
html[data-toast-style="icon"] .toast--error { background: var(--surface); color: var(--text); border-color: var(--danger-border); }
html[data-toast-style="icon"] .toast--success,
html[data-toast-style="icon"] .toast--error { box-shadow: var(--shadow-float); }
html[data-toast-style="icon"] .toast--success .toast-ico { background: var(--ok-soft); color: var(--ok-ink); }
html[data-toast-style="icon"] .toast--error .toast-ico { background: var(--danger-soft); color: var(--danger-ink); }

/* 空状态 */
.empty {
  text-align: center;
  color: var(--text-soft);
  padding: 40px 20px;
  font-size: 14px;
}
.empty .empty-icon { font-size: 40px; margin-bottom: 8px; }
/* 加载失败：原因 + 重试，避免用户只能切走再回来 */
.error-state { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.error-state .err-mark {
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(var(--accent-rgb), .12);
  color: var(--primary-deep);
  font-weight: 700; font-size: 18px;
}
.error-state .error-state-msg { margin: 0; max-width: 420px; line-height: 1.6; word-break: break-word; }
/* 字段级校验：红字贴在字段下方，输入后自动清除 */
.field.has-error input,
.field.has-error textarea,
.field.has-error .dd-input,
.ck-field.has-error input { border-color: var(--danger); }
.field-err { margin-top: 6px; font-size: 12px; line-height: 1.55; color: var(--danger); }

/* ===== 登录 / 注册：全屏欢迎页 ===== */
.auth-screen {
  position: relative;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end; /* 双头像与爱心靠下展示，贴近波浪 */
  padding-bottom: 17vh;      /* 让开底部波浪的高度 */
  overflow: hidden;
  text-align: center;
  /* 海报底色要压住白字：用当前主题的深色快照（--sc-auth-grad），
     每套主题最浅一段的白字对比度均 ≥4.5:1 */
  background: var(--sc-auth-grad);
}
/* 展示页顶部横幅：左侧品牌（logo+站名）+ 右侧一言 */
.showcase-topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: calc(env(safe-area-inset-top) + 14px) 20px 14px;
  background: rgba(255, 255, 255, .10);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: 0 2px 10px rgba(var(--sc-accent-rgb), .07);
}
.st-brand { display: flex; align-items: center; gap: 8px; min-width: 0; }
.st-logo { width: 26px; height: 26px; border-radius: 6px; flex: none; }
.st-name { font-size: 16px; font-weight: 800; letter-spacing: 1px; color: #3d3038; white-space: nowrap; }
.st-quote { font-size: 13px; color: rgba(0,0,0,.62); max-width: 55%; text-align: right; font-style: italic; }
@media (max-width: 639.98px) {
  .showcase-topbar { padding: calc(env(safe-area-inset-top) + 12px) 14px 12px; gap: 10px; }
  .st-name { font-size: 14px; }
  .st-quote { font-size: 12px; max-width: 58%; }
}
/* 模块公开展示页：顶部条只留左侧品牌 + 右侧返回按钮 */
.sp-back-grad { border: 1px solid rgba(0,0,0,.16); background: rgba(0,0,0,.06); color: #3d3038; font-size: 13px; cursor: pointer; padding: 6px 14px; border-radius: 999px; }
.sp-back-grad:hover { background: rgba(0,0,0,.1); }
/* 展示页头像尺寸由类控制（默认桌面 124px），不再用 inline 写死，便于手机端响应式缩小 */
.showcase-avatars .arco-avatar { width: 124px; height: 124px; font-size: 62px; }
/* 对外展示页（.showcase）：高度收缩到内容为止。
   标题已移进顶部条、波浪已移到底部，渐变区只剩头像，故留白大幅压缩 */
.auth-screen.showcase { position: sticky; top: 0; z-index: 5; overflow: visible; justify-content: flex-start; min-height: 0; padding-top: 112px; padding-bottom: 20px; }
/* 模块展示页（.showcase-module）：整页不再铺粉色渐变，只保留顶栏一层主题粉。
   - 顶部条自身是不透明的粉色渐变，故这块静态占位只负责让出固定顶栏的高度。
     原来的 sticky 情侣头像区已换成正文里的 hero 卡（见 .ab-hero），不再需要 sticky 遮罩
     （留着会用一个同色底把滚动中的内容盖住），因此改为 static。
   - 顶栏回到主题粉色（--hero-grad，与首页 hero 同一组色）：它是 .st-name /
     .sp-back-grad 这组深色文字的原始底色，去掉后顶栏就没颜色了；粉底本身不透明，故不再需要毛玻璃。 */
.auth-screen.showcase-module { position: static; background: var(--bg); padding-bottom: 0; }
.showcase-module .showcase-topbar { background: var(--hero-grad); backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none; }
/* 模块展示页 hero 卡容器：与正文同宽（.showcase-public 给宽度），但不需要它那 40px 底部内边距，
   与下方正文的间距由卡片自身的 margin 提供 */
.showcase-public.sp-hero-wrap { padding-bottom: 0; }
/* 无 hero 卡的模块页（相册 / 日常 / 清单）：正文顶部补间距，避免紧贴固定顶栏 */
.showcase-public.sp-body-nohero { padding-top: 16px; }

/* ===== 模块展示页顶部 hero 卡（版式对齐设计稿 .ab-hero） =====
   粉底 + 右上高光、情侣头像与名字、第 N 天、在一起时长、一言、三项统计 */
.ab-hero { position: relative; overflow: hidden; text-align: center; background: var(--btn-grad); border: none; color: var(--on-primary); padding: 20px 14px 18px; }
.ab-hero::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(circle at 20% 12%, rgba(255, 255, 255, .35), transparent 60%); }
.ab-couple { display: flex; align-items: center; justify-content: center; gap: 14px; position: relative; z-index: 1; }
.ab-couple .fl { display: flex; flex-direction: column; align-items: center; }
.ab-ava { width: 64px; height: 64px; border-radius: 50%; overflow: hidden; flex: none; border: 2px solid rgba(255, 255, 255, .85); background: #fff; }
.ab-ava img, .ab-ava svg { display: block; width: 100%; height: 100%; object-fit: cover; }
/* hero 卡里的爱心：与首页展示区 .heart 同一套脉动动画（不依赖 .couple-avatars 父类，
   故动画直接挂在本元素上，而不是复用 .couple-avatars .heart 的选择器） */
.ab-heart {
  width: 34px; height: 34px; flex: none;
  color: #fff; filter: drop-shadow(0 2px 8px rgba(var(--sc-primary-rgb), .28));
  animation: heartbeat 1.6s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) { .ab-heart { animation: none; } }
.ab-name { font-size: 13px; margin-top: 6px; color: #fff; font-weight: 600; }
.ab-day { font-size: 26px; font-weight: 800; letter-spacing: 1px; margin-top: 12px; position: relative; z-index: 1; }
.ab-since { font-size: 12.5px; opacity: .94; margin-top: 4px; position: relative; z-index: 1; }
.ab-motto { font-family: var(--font-hand); font-size: 14px; line-height: 1.7; margin-top: 10px; padding: 0 8px; position: relative; z-index: 1; }
.showcase .avatar-name { color: #000; text-shadow: 0 1px 6px rgba(var(--sc-primary-rgb), 0.22); }
/* 名字与爱心随头像一起放大，保持头像 / 爱心 / 名字三者的视觉比例 */
.showcase .couple-avatars .avatar-name { font-size: 16px; }
.showcase .couple-avatars .heart { width: 72px; height: 72px; margin-bottom: 42px; }
.showcase-avatars { gap: 170px; margin: 10px 0 8px; cursor: pointer; }
/* 首页展示页的波浪是同一块内的定位元素（.waves absolute 贴块底 14vh），
   定位元素排在静态的头像行之上，会用白色半透明层把头像糊住、并挡掉头像区的点击。
   故给头像自身开一层：压在波浪之上，但仍低于固定顶栏（z-index 20）。 */
.auth-screen.showcase .showcase-avatars { position: relative; z-index: 1; }
/* 恋爱计时：独立区块（渐变区之外），水平居中，深灰大字 */
.showcase-love {
  max-width: 1080px;
  margin: 0 auto;
  padding: 40px 16px 6px;
  text-align: center;
  color: #212529;
  font-family: Georgia, serif;
}
/* 字号随视口宽度平滑缩放（与首页 hero 同一套 clamp 思路）：
   min 保持平板 / 窄屏原字号不动，宽屏按比例放大并封顶，
   避免内容区被拉到 1400px 时文字仍按 640px 的尺寸显得过小。
   手机端（<640px）仍由下方媒体查询给出更小的固定值。 */
.showcase-love .couple { font-size: clamp(22px, 1.25vw + 9px, 30px); letter-spacing: 2px; color: #212529; }
.showcase-love .love-main { font-size: clamp(56px, 3vw + 26px, 84px); font-weight: 800; line-height: 1.2; color: #212529; }
.showcase-love .love-sub { font-size: clamp(20px, .6vw + 14px, 26px); color: #212529; padding-bottom: 8px; }
.showcase-love .quote { font-size: clamp(18px, .5vw + 13px, 24px); color: #212529; margin-top: 10px; }
/* 「今天… + 第X天 + 时分秒」整行不换行；水平居中以「第X天」为准——couple 靠左、love-sub 靠右、love-main 严格居中 */
.showcase-love .days {
  display: flex;
  flex-wrap: nowrap;
  align-items: baseline;
  justify-content: center;
  gap: 12px;
}
.showcase-love .days .couple { flex: 1; text-align: right; }
.showcase-love .days .love-main { flex: none; }
.showcase-love .days .love-sub { flex: 1; text-align: left; }
/* 视差波浪下方的公开模块区 */
.showcase-modules { max-width: 1080px; margin: 0 auto; padding: 34px 16px calc(44px + 14vh); }
/* PC 登录页：品牌区 + 居中登录卡片，表单直接可见 */
.auth-screen.login-pc { justify-content: center; padding-bottom: 12vh; }
.auth-form-card { width: min(420px, 92%); text-align: left; margin-bottom: 6vh; }
/* 移动端登录页：同样的渐变背景与波浪，品牌区文字反白，卡片下移让开波浪 */
.auth-screen.login-mobile { justify-content: flex-start; padding: 30px 16px 110px; }
.login-mobile .auth-title { color: #fff; text-shadow: 0 2px 10px rgba(var(--sc-primary-rgb), 0.20); }
.login-mobile .auth-sub { color: var(--on-primary); }
.login-mobile .auth-form-card { width: 100%; margin-bottom: 0; }
/* 品牌区：新图标 + 站名横向居中 */
.auth-brand { display: flex; align-items: center; justify-content: center; gap: 10px; font-size: 26px; font-weight: 800; color: #fff; letter-spacing: 2px; text-shadow: 0 2px 12px rgba(var(--sc-primary-rgb), 0.22); }
.auth-brand .ico { width: 34px; height: 34px; flex: none; filter: drop-shadow(0 2px 8px rgba(var(--sc-primary-rgb), 0.28)); }
.auth-slogan { font-size: 13px; color: var(--on-primary); margin: 8px 0 30px; }
/* 移动端旧版登录页品牌区（PC 欢迎页不用） */
.auth-hero { text-align: center; padding: 42px 0 26px; }
.auth-logo { font-size: 56px; }
.auth-title { font-size: 22px; font-weight: 800; color: var(--primary-deep); margin-top: 10px; letter-spacing: 1px; }
.auth-sub { font-size: 13px; color: var(--text-soft); margin-top: 6px; }
.auth-tip { font-size: 12px; color: var(--text-soft); margin-top: 10px; line-height: 1.6; }

/* 底部波浪动画（视差四层） */
.waves { position: absolute; left: 0; bottom: 0; width: 100%; height: 14vh; min-height: 90px; max-height: 150px; }
/* 模块展示页的底部波浪：挂在内容区之后，波浪本身固定贴窗口底部，
   页面滚动时始终可见（原来是绝对定位在正文末尾，往下滚就看不见了）。
   容器 .showcase-waves 保留 14vh 占位，保证正文末尾不会被固定波浪永久压住；
   波浪是纯装饰，pointer-events:none 避免挡住下方内容的点击。
   填充色：波浪落在浅色页面底色上，原白色（rgba(255,255,255,·) / #fff7f9）几乎看不见，
   故按主题粉色系重铺四层深浅叠加（CSS 覆盖 use 上的内联 fill）。 */
.showcase-waves { position: relative; height: 14vh; min-height: 90px; max-height: 150px; margin-top: 18px; }
.showcase-waves .waves { position: fixed; left: 0; right: 0; bottom: 0; z-index: 4; pointer-events: none; }
/* 首页展示页 / 登录页也直接用 wavesSVG（没有 .showcase-waves 包裹），
   这里统一接管前三层，避免残留 SVG 里写死的白色；底层则跟随页面底色。 */
.waves .parallax > use:nth-child(1) { fill: rgba(var(--primary-rgb), .52); }
.waves .parallax > use:nth-child(2) { fill: rgba(var(--primary-rgb), .38); }
.waves .parallax > use:nth-child(3) { fill: rgba(var(--primary-rgb), .25); }
.waves .parallax > use:nth-child(4) { fill: var(--bg); }
.parallax > use { animation: wave-move 25s cubic-bezier(.55, .5, .45, .5) infinite; }
.parallax > use:nth-child(1) { animation-delay: -2s; animation-duration: 7s; }
.parallax > use:nth-child(2) { animation-delay: -3s; animation-duration: 10s; }
.parallax > use:nth-child(3) { animation-delay: -4s; animation-duration: 13s; }
.parallax > use:nth-child(4) { animation-delay: -5s; animation-duration: 20s; }
@keyframes wave-move {
  0% { transform: translate3d(-90px, 0, 0); }
  100% { transform: translate3d(85px, 0, 0); }
}

/* 页面底部动态鱼塘：固定定位在浏览器视口底部，滚动时始终可见；颜色由 canvas 绘制（水面之上白、之下粉），不设容器背景以免露出渐变带 */
.fish-sea { position: fixed; left: 0; bottom: 0; width: 100%; height: 150px; z-index: 5; pointer-events: auto; touch-action: pan-y; }
.fish-sea canvas { display: block; width: 100%; height: 100%; }

/* ===== 设置项 ===== */
.setting-row { display: flex; justify-content: space-between; align-items: center; padding: 14px 0; border-bottom: 1px solid var(--border); }

/* 更多页入口卡片 */
.card-entry { cursor: pointer; transition: transform .12s, box-shadow .15s; display: flex; align-items: center; gap: 12px; }
.card-entry:active { transform: scale(0.98); box-shadow: var(--shadow-accent); }
.card-entry .entry-main { flex: 1; display: flex; align-items: center; justify-content: space-between; font-size: 15px; font-weight: 700; }
.card-entry .entry-arrow { font-size: 18px; font-weight: 700; color: #e0ccd3; }
.card-entry .entry-desc { font-size: 13px; color: var(--text-soft); margin-top: 6px; }
/* 更多页入口：图标只在 PC 端展示；移动端保持原有「纯文字 + ›」一列卡片，故默认隐藏 */
.more-entry-grid .entry-ico { display: none; }
/* PC 端：入口改为两列加高卡片（左侧图标、右侧箭头），移动端（<1024px）不受影响 */
@media (min-width: 1024px) {
  .more-entry-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
  }
  .more-entry-grid > .card { margin-bottom: 0; }
  .more-entry-grid .card-entry {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 20px 22px;
    border-radius: 16px;
  }
  .more-entry-grid .card-entry .entry-ico {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 40px;
    height: 40px;
  }
  .more-entry-grid .card-entry .entry-ico .ico { width: 26px; height: 26px; }
  .more-entry-grid .card-entry .entry-main { flex: 1; font-size: 16px; }
}

/* 更多页入口（移动端）：按用途分组的卡片列表（此前是一列纯文字卡、图标被 CSS 隐藏） */
.entry-group { margin-bottom: 14px; }
.entry-group-title { font-size: 12.5px; font-weight: 700; color: var(--text-soft); padding: 0 4px 8px; }
.entry-list { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; }
.entry-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-top: 1px solid var(--border); cursor: pointer; }
.entry-row:first-child { border-top: none; }
.entry-row:active { background: var(--panel-soft); }
.entry-row .entry-ico { display: flex; align-items: center; justify-content: center; flex: none; width: 32px; height: 32px; border-radius: 10px; background: var(--panel-soft); color: var(--primary-deep); }
.entry-row .entry-ico .ico { width: 18px; height: 18px; }
.entry-row .entry-main { flex: 1; min-width: 0; }
.entry-row .entry-title { font-size: 15px; font-weight: 600; }

/* 移动端子设置页入口卡（站点/公开/衣柜设置）：图标 + 文字横排，与 PC 端 .pc-pane-body 一致 */
.card-entry .entry-ico { display: flex; align-items: center; justify-content: center; flex: none; width: 26px; height: 26px; }
.card-entry .entry-ico .ico { width: 18px; height: 18px; }

/* 图标主题切换：两个可选卡片，各带一排图标预览 */
.theme-box-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.theme-box { position: relative; border: 1px solid var(--border); border-radius: 14px; padding: 14px 12px; text-align: center; cursor: pointer; background: var(--bg); transition: border-color .15s, background .15s; }
.theme-box.on { border-color: var(--primary); background: var(--panel-soft); }
.theme-box-preview { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 10px; color: var(--primary-deep); }
.theme-box-preview .ico { width: 26px; height: 26px; }
.theme-box-name { font-size: 14px; font-weight: 700; color: var(--text); }
.theme-box-desc { font-size: 11.5px; color: var(--text-soft); margin-top: 4px; }
/* 右上角选择控件：点击直接切到该主题；未选中为空心圈，选中后叠加对勾。
   圈用 inset 阴影画而非 border，保证两种状态都是 20px、不发生尺寸跳动。 */
.theme-box-check { position: absolute; top: 8px; right: 8px; width: 20px; height: 20px; padding: 0; border: 0; border-radius: 50%; background: var(--card); box-shadow: inset 0 0 0 1.5px var(--border); cursor: pointer; color: var(--primary-deep); transition: box-shadow .15s; }
.theme-box-check:hover { box-shadow: inset 0 0 0 1.5px var(--primary); }
.theme-box.on .theme-box-check { background: transparent; box-shadow: none; }
.theme-box-check .tbc-ico { width: 100%; height: 100%; display: none; }
.theme-box.on .theme-box-check .tbc-ico { display: block; }
/* 主题色卡：左浅色 / 右深色两栏色板 + 预设选择。深色栏固定深色底，不随当前模式变化 */
.tc-modes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.tc-mode { border: 1px solid var(--border); border-radius: 14px; padding: 10px; background: var(--bg); min-width: 0; }
.tc-mode-dark { background: #17131c; border-color: #3a3345; }
.tc-mode-name { font-size: 12px; font-weight: 700; color: var(--text-soft); margin-bottom: 8px; }
.tc-mode-dark .tc-mode-name { color: #a9a1b3; }
.tc-swatches { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.tc-swatch { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.tc-swatch i { height: 26px; border-radius: 8px; border: 1px solid rgba(0, 0, 0, .06); }
.tc-mode-dark .tc-swatch i { border-color: rgba(255, 255, 255, .08); }
.tc-swatch em { font-style: normal; font-size: 11px; color: var(--text-soft); }
.tc-swatch b { font-size: 10px; font-weight: 500; color: var(--text-soft); opacity: .85; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tc-mode-dark .tc-swatch em, .tc-mode-dark .tc-swatch b { color: #a9a1b3; }
.tc-picks { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.tc-pick { display: inline-flex; align-items: center; gap: 7px; padding: 7px 12px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); color: var(--text); font-size: 13px; cursor: pointer; }
.tc-pick i { width: 14px; height: 14px; border-radius: 50%; flex: none; }
.tc-pick.on { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(var(--primary-rgb), .16); font-weight: 700; }

/* 提示样式卡：名称 + 说明 + 一组真实 Toast 预览，点击即切换全站 Toast */
.ts-picks { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; margin-top: 12px; }
.ts-pick {
  display: flex; flex-direction: column; gap: 7px; min-width: 0;
  padding: 10px; border: 1px solid var(--border); border-radius: 14px;
  background: var(--bg); color: var(--text); font: inherit; text-align: left;
  cursor: pointer; transition: border-color .15s, box-shadow .15s;
}
.ts-pick:hover { border-color: var(--primary); }
.ts-pick.on { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(var(--primary-rgb), .16); }
.ts-pick b { font-size: 13px; }
.ts-pick em { font-style: normal; font-size: 11.5px; line-height: 1.5; color: var(--text-soft); }
/* 预览组：普通 / 成功 / 失败三条，结构同正式 Toast。
   统一用 .ts-pick 前缀抬高优先级，避免被当前生效的 html[data-toast-style] 与深色变量改写。 */
.ts-pick .ts-demo { display: flex; flex-direction: column; gap: 6px; }
.ts-pick .ts-demo .toast {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 9px; border-radius: 9px;
  font-size: 11px; font-weight: 600; line-height: 1.45; text-align: left;
  max-width: none; cursor: default; pointer-events: none; animation: none;
}
.ts-pick .ts-demo .toast-dot { width: 5px; height: 5px; }
.ts-pick .ts-demo .toast-ico { display: none; width: 18px; height: 18px; }
.ts-pick .ts-demo .toast-ico svg { width: 11px; height: 11px; }

/* 预览 · 粉色柔光 */
.ts-pick .ts-demo-pink .toast {
  background: linear-gradient(180deg, rgba(var(--primary-rgb), .07), var(--primary-soft));
  color: var(--primary-deep); border: 1px solid rgba(var(--primary-rgb), .34);
  box-shadow: 0 4px 10px rgba(var(--primary-rgb), .16);
}
.ts-pick .ts-demo-pink .toast-dot { background: var(--primary); }
.ts-pick .ts-demo-pink .toast--success { background: var(--ok-soft); color: var(--ok-ink); border-color: var(--ok-border); box-shadow: none; }
.ts-pick .ts-demo-pink .toast--error { background: var(--danger-soft); color: var(--danger-ink); border-color: var(--danger-border); box-shadow: none; }
.ts-pick .ts-demo-pink .toast--success .toast-dot { background: var(--ok); }
.ts-pick .ts-demo-pink .toast--error .toast-dot { background: var(--danger); }

/* 预览 · 磨砂玻璃 */
.ts-pick .ts-demo-glass .toast {
  background: rgba(255, 255, 255, .72); color: var(--text);
  border: 1px solid rgba(var(--primary-rgb), .26);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 4px 10px rgba(var(--accent-rgb), .12);
}
.ts-pick .ts-demo-glass .toast-dot { background: var(--primary-deep); }
.ts-pick .ts-demo-glass .toast--success { background: rgba(232, 246, 237, .8); color: var(--ok-ink); border-color: var(--ok-border); box-shadow: 0 4px 10px rgba(59, 165, 93, .12); }
.ts-pick .ts-demo-glass .toast--error { background: rgba(253, 236, 234, .82); color: var(--danger-ink); border-color: var(--danger-border); box-shadow: 0 4px 10px rgba(229, 72, 77, .12); }
.ts-pick .ts-demo-glass .toast--success .toast-dot { background: var(--ok); }
.ts-pick .ts-demo-glass .toast--error .toast-dot { background: var(--danger); }
body.dark .ts-pick .ts-demo-glass .toast { background: rgba(35, 28, 40, .72); color: var(--text); }
body.dark .ts-pick .ts-demo-glass .toast--success { background: rgba(31, 51, 40, .78); color: var(--ok); }
body.dark .ts-pick .ts-demo-glass .toast--error { background: rgba(56, 30, 30, .78); color: #ff9a9e; }

/* 预览 · 图标卡片 */
.ts-pick .ts-demo-icon .toast {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); box-shadow: var(--shadow-float-sm);
}
.ts-pick .ts-demo-icon .toast-dot { display: none; }
.ts-pick .ts-demo-icon .toast-ico { display: flex; background: var(--primary-soft); color: var(--primary-deep); }
.ts-pick .ts-demo-icon .toast--success { border-color: var(--ok-border); box-shadow: var(--shadow-float-sm); }
.ts-pick .ts-demo-icon .toast--error { border-color: var(--danger-border); box-shadow: var(--shadow-float-sm); }
.ts-pick .ts-demo-icon .toast--success .toast-ico { background: var(--ok-soft); color: var(--ok-ink); }
.ts-pick .ts-demo-icon .toast--error .toast-ico { background: var(--danger-soft); color: var(--danger-ink); }
@media (max-width: 560px) {
  .ts-picks { grid-template-columns: 1fr; }
}

/* 图标一览弹窗：列出该主题下每个模块的图标与取色 */
.ipv-sec-title { font-size: 12.5px; font-weight: 700; color: var(--text-soft); margin: 16px 0 8px; }
.ipv-sec-title:first-child { margin-top: 0; }
.ipv-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
.ipv-item { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 10px 6px; border: 1px solid var(--border); border-radius: 12px; background: var(--bg); }
.ipv-ico { display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; }
.ipv-ico .ico { width: 30px; height: 30px; }
.ipv-name { font-size: 11.5px; color: var(--text); text-align: center; line-height: 1.3; }
.ipv-hex { font-size: 10.5px; color: var(--text-soft); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.ipv-tip { font-size: 12px; color: var(--text-soft); line-height: 1.7; margin: 16px 0 12px; }
.setting-row:last-child { border-bottom: none; }
.setting-row .s-name { font-size: 14px; }
/* 设置行的小字说明：对应精修稿 .form-label small（12px / 浅色 / 与标签留 3px） */
.setting-row .s-tip { font-size: 12px; color: var(--text-soft); margin-top: 3px; line-height: 1.5; }
/* 定位管理：调用次数统计 */
.loc-stat-total { font-size: 12px; font-weight: 500; color: var(--text-soft); }
.setting-row .s-tip [data-loc-stat] { color: var(--primary-deep); font-weight: 700; }

/* 定位管理：定位方式优先级列表（按住把手拖动排序，开关控制是否启用） */
.loc-pri-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.loc-pri-item {
  display: flex; align-items: center; gap: 10px; padding: 12px;
  border: 1px solid var(--border); border-radius: 14px; background: var(--panel-soft);
  transition: opacity .15s ease, box-shadow .15s ease, background .15s ease;
}
.loc-pri-item.is-off .loc-pri-main { opacity: .5; }
/* 拖动占位：原行只留虚线框，内容隐藏，给副本让出位置 */
.loc-pri-item.dragging {
  background: transparent; border-style: dashed; border-color: var(--primary);
  box-shadow: none;
}
.loc-pri-item.dragging .loc-pri-main,
.loc-pri-item.dragging .loc-key-btn,
.loc-pri-item.dragging .switch { visibility: hidden; }
/* 跟手的拖拽副本：fixed 定位，脱离列表流 */
.loc-drag-ghost {
  position: fixed; z-index: 90; margin: 0; pointer-events: none;
  background: var(--card); box-shadow: var(--shadow-float);
  will-change: transform; transform-origin: center;
}
.loc-pri-drag {
  flex: none; align-self: stretch; display: flex; align-items: center; justify-content: center;
  width: 26px; color: var(--text-soft); cursor: grab; touch-action: none;
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
}
.loc-pri-drag:active { cursor: grabbing; }
.loc-pri-drag .ico { width: 16px; height: 16px; }
.loc-pri-main { flex: 1; min-width: 0; }
.loc-pri-main .s-name { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.loc-pri-main .s-tip { font-size: 12px; color: var(--text-soft); margin-top: 3px; line-height: 1.5; }
.loc-key-btn {
  flex: none; width: 26px; height: 26px; padding: 0; border: 1px solid var(--border);
  border-radius: 50%; background: var(--surface); color: var(--text-soft);
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  transition: color .15s ease, border-color .15s ease;
}
.loc-key-btn:hover { color: var(--primary-deep); border-color: var(--primary); }
.loc-key-btn .ico { width: 15px; height: 15px; }

/* 分页器：页码多时省略号折叠，始终保持一行；给列表留出更多可视高度 */
.pager-gap { align-self: center; padding: 0 4px; font-size: 12px; color: var(--text-soft); }
.blessing-pager { flex-wrap: nowrap; overflow-x: auto; }

/* 访客记录列表 */
.visit-list { display: flex; flex-direction: column; margin-top: 12px; }
.visit-row { padding: 10px 0; border-bottom: 1px dashed var(--border); }
.visit-row:last-child { border-bottom: none; }
.visit-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.visit-ip { font-size: 14px; font-weight: 700; }
.visit-time { flex: none; font-size: 12px; color: var(--text-soft); }
.visit-sub { display: flex; align-items: center; gap: 6px; margin-top: 4px; font-size: 12px; color: var(--text-soft); }
.visit-dot { opacity: .6; }
/* 访客统计：概览四项 + 归属地/设备 Top5 排行 */
.visit-ov { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-top: 12px; }
.visit-ov-item { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 12px 6px; background: var(--bg); border: 1px solid var(--border); border-radius: 10px; }
.visit-ov-num { font-size: 20px; font-weight: 700; color: var(--primary-deep); }
.visit-ov-k { font-size: 12px; color: var(--text-soft); }
.visit-ranks { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 14px; }
.visit-rank-title { font-size: 13px; color: var(--text-soft); margin-bottom: 6px; }
/* Top5 改成环形饼图：左边饼图 + 右边图例（名称 / 数量 / 占比） */
.rank-pie { display: flex; align-items: center; gap: 14px; }
.rank-pie-svg { flex: none; width: 108px; height: 108px; }
.rank-legend { flex: 1; min-width: 0; }
.rank-legend-row { display: flex; align-items: center; gap: 6px; padding: 3px 0; font-size: 12.5px; }
.rank-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; }
.rank-legend-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rank-legend-count { flex: none; color: var(--text-soft); }
@media (max-width: 560px) {
  .visit-ov { grid-template-columns: repeat(2, 1fr); }
  .visit-ranks { grid-template-columns: 1fr; }
}

/* 修改申请列表 */
.approval-list { display: flex; flex-direction: column; gap: 8px; max-height: 210px; overflow-y: auto; }
/* 每条两行：申请内容一行，状态与操作另起一行（窄栏里不再挤成一行） */
.approval-item { display: flex; flex-direction: column; gap: 9px; padding: 10px 12px; background: var(--bg); border: 1px solid var(--border); border-radius: 10px; }
.approval-item .approval-text { font-size: 13px; color: var(--text); line-height: 1.5; }
.approval-item .approval-row { display: flex; align-items: center; gap: 6px; }
.approval-item .approval-btns { margin-left: auto; display: flex; gap: 6px; }
.approval-item .approval-status { flex: none; font-size: 12px; padding: 2px 8px; border-radius: 999px; background: var(--surface); border: 1px solid var(--border); color: var(--text-soft); }
.approval-item .approval-status.approved { color: var(--ok); border-color: var(--ok); }
.approval-item .approval-status.denied { color: var(--danger); border-color: var(--danger); }
.approval-item .approval-status.pending { color: var(--warn); border-color: var(--warn); }
/* 申请详情弹窗 */
.ap-detail { display: flex; flex-direction: column; gap: 10px; }
.ap-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: 13px; }
.ap-row > span:first-child { color: var(--text-soft); flex: none; }
.ap-row b { font-weight: 500; word-break: break-all; text-align: right; }
.ap-sec-title { font-size: 13px; font-weight: 600; color: var(--text); margin-top: 4px; }
/* 申请详情小标题内的行内图标：与文字垂直居中、间距统一 */
.ap-sec-title .ico { width: 15px; height: 15px; vertical-align: -0.18em; margin-right: 2px; }
.ap-block { display: flex; flex-direction: column; gap: 6px; padding: 10px 12px; background: var(--bg); border: 1px solid var(--border); border-radius: 8px; font-size: 13px; line-height: 1.6; word-break: break-all; }
.ap-field, .ap-change .ap-label { color: var(--text-soft); }
.ap-field { display: flex; gap: 8px; }
/* 申请详情弹窗底部的操作行（仅待处理的申请出现：拒绝 / 同意） */
.ap-acts { display: flex; gap: 10px; margin-top: 16px; }
.ap-acts .btn { flex: 1; margin: 0; }

/* 情侣信息：头像 + 昵称 */
.partner-block {
  display: flex;
  align-items: center;
  justify-content: space-around;
  gap: 12px;
}
.partner-pair {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
  justify-content: center;
  padding: 6px 0;
}
.partner-avatar {
  width: 64px; height: 64px;
  border-radius: 50%;
  overflow: hidden;
  flex: none;
  background: var(--bg);
  border: 2px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  /* 头像阴影按性别着色（见下方 data-gender 规则）；未设性别时用中性柔光兜底 */
  box-shadow: 0 1px 3px rgba(var(--accent-rgb), .05), 0 6px 18px rgba(var(--accent-rgb), .10);
  transition: box-shadow .22s ease;
}
/* 男蓝 / 女粉：只改光晕颜色，不动边框，避免与主题色冲突。
   两种颜色都必须写死：女粉若取 --primary-rgb，蓝色系主题下会和男蓝撞成同一个颜色，
   改性别就看不出来了（这正是「改成女性还是蓝色」的原因）。
   光晕用 blur 过渡而不是 0 0 0 的实心环，否则贴着头像边框会形成一圈硬边。 */
.partner-avatar[data-gender="男性"] { box-shadow: 0 0 10px 2px rgba(74, 144, 226, .26), 0 8px 22px rgba(74, 144, 226, .16); }
.partner-avatar[data-gender="女性"] { box-shadow: 0 0 10px 2px rgba(255, 143, 171, .28), 0 8px 22px rgba(255, 143, 171, .16); }
.partner-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.partner-avatar .pa-plus { font-size: 26px; font-weight: 300; color: var(--primary-deep); }
.partner-name { font-size: 15px; font-weight: 600; cursor: pointer; }
.partner-name:active { opacity: 0.7; }
.partner-avatar svg { width: 100%; height: 100%; }
/* 默认头像：浅色中性灰；深色圆底用面板软底、图标用次级文字灰（对比 6.36:1）。
   宽高默认铺满容器，任何头像框都不会因为没写 svg 尺寸而露出 200px 的原图。 */
.default-avatar { display: block; width: 100%; height: 100%; color: #8a8a8a; }
/* 深色下：圆底用面板软底 #291f2c，图标用次级文字灰 #a9a1b3（对比 6.36:1） */
body.dark .default-avatar { color: var(--text-soft); }
body.dark .author-avatar,
body.dark .partner-avatar,
body.dark .couple-avatars .arco-avatar { background: var(--panel-soft); }
/* 头像预览没有独立的圆形容器，给 SVG 自己补同色底（它已经有 border-radius:50%） */
body.dark .avatar-preview svg.default-avatar { background: var(--panel-soft); }
.avatar-preview {
  display: flex;
  justify-content: center;
  margin-bottom: 18px;
}
.avatar-preview img, .avatar-preview svg {
  width: 150px;
  height: 150px;
  border-radius: 50%;
  object-fit: cover;
}
.avatar-actions { display: flex; gap: 10px; }
.avatar-actions .btn { flex: 1; }
/* 头像裁剪：拖动正方形裁剪框选择保留区域，拖四角缩放 */
.crop-stage { position: relative; margin: 0 auto; overflow: hidden; border-radius: 12px; background: #000; touch-action: none; }
.crop-stage img { display: block; max-width: none; max-height: none; user-select: none; pointer-events: none; }
.crop-box {
  position: absolute; box-sizing: border-box; cursor: move;
  border: 1px solid rgba(255, 255, 255, .9);
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, .55);
  background:
    linear-gradient(rgba(255, 255, 255, .22), rgba(255, 255, 255, .22)) center / 1px 100% no-repeat,
    linear-gradient(rgba(255, 255, 255, .22), rgba(255, 255, 255, .22)) center / 100% 1px no-repeat;
}
.crop-handle {
  position: absolute; width: 16px; height: 16px; background: #fff; border-radius: 3px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .28);
}
.crop-handle[data-dir="nw"] { left: -8px; top: -8px; cursor: nwse-resize; }
.crop-handle[data-dir="ne"] { right: -8px; top: -8px; cursor: nesw-resize; }
.crop-handle[data-dir="sw"] { left: -8px; bottom: -8px; cursor: nesw-resize; }
.crop-handle[data-dir="se"] { right: -8px; bottom: -8px; cursor: nwse-resize; }
.crop-actions { display: flex; gap: 10px; margin-top: 16px; }
.crop-actions .btn { flex: 1; }


.tool-list { display: flex; flex-direction: column; font-size: 15px; }
.tool-row { display: flex; align-items: center; gap: 14px; padding: 13px 6px; border-bottom: 1px solid var(--border); }
.tool-row:last-child { border-bottom: none; }
.tool-name { flex: 1; min-width: 0; }
.tool-go { color: var(--text-soft); flex: none; display: flex; }

/* 工具设置子入口（移动端入口卡）：补上图标后改成「图标 + 文字 + ›」一行，与「更多」页入口卡同构。
   PC 左导航（.pc-pane-nav .card-entry）与右栏列表（.pc-pane-body .card-entry）各自已有 flex 规则，这里只管移动端这张卡。 */
.tool-sec-card { display: flex; align-items: center; gap: 12px; }
.tool-sec-card .entry-ico { display: flex; align-items: center; justify-content: center; flex: none; width: 26px; height: 26px; }
.tool-sec-card .entry-ico .ico { width: 22px; height: 22px; }
.tool-sec-card .entry-main { flex: 1; }

/* 工具设置：代码编辑区（html / js） */
.code-area {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Courier New", monospace;
  font-size: 12.5px;
  line-height: 1.6;
  min-height: 130px;
  white-space: pre;
  overflow-x: auto;
}

/* AI 设置：提示词编辑区 */
.prompt-area {
  min-height: 92px;
  font-size: 13px;
  line-height: 1.6;
}

/* ===== 照片查看器（深色全屏，对齐设计稿 docs/album-ui-reference.html） =====
   顶部图标工具栏 + 照片区 + 信息面板（PC 右侧列 / 移动端底部抽屉）。
   相册上下文额外给出「添加到相册 / 设为封面 / 删除照片 / 所属相册」，其它页面自动降级。
   移动端 / PC 的分档用媒体查询（查看器是整屏 fixed 覆盖层，容器查询在这里没有意义）。 */
.vw {
  position: fixed; inset: 0; z-index: 200;
  background: #0e0e10; color: #fff;
  display: flex; flex-direction: column; overflow: hidden;
  animation: fadeIn .18s ease;
  /* 顶栏随窗口高度自适应：矮窗收紧、大屏放大，800px 高时约等于原来的 52px。
     以 vh 为基准 —— 这是水平条，视觉大小跟窗口高度走，跟宽度无关。 */
  --vw-top-h: clamp(44px, 6.5vh, 62px);
  --vw-btn: calc(var(--vw-top-h) * .65);
  --vw-ico: calc(var(--vw-btn) * .68);   /* 顶栏图标统一尺寸：圆钮图标与「原图」图标都读它，保证一样大 */
  /* 幻灯片切图动效的统一参数：四种效果共用同一时长与缓动。想调快慢只改这里 ——
     JS 也读它来算「溶解副本」的回收时刻，不会出现两处写死不同步。 */
  --vw-ss-dur: 1s;
  --vw-ss-ease: cubic-bezier(.22,.8,.24,1);
  /* PC 信息面板的宽度（含左右各 14px 内边距）—— 顶栏让位时要按它腾出右侧那条 */
  --vw-info-w: 348px;
}
.vw-top {
  height: var(--vw-top-h); flex: none; display: flex; align-items: center; padding: 0 6px; gap: 2px;
  background: none; border-bottom: 0; z-index: 5;
}
.vw-count { margin-left: 4px; font-size: 12.5px; color: rgba(255,255,255,.6); letter-spacing: .5px; }
.vw-ib {
  width: var(--vw-btn); height: var(--vw-btn); border-radius: 50%; border: 0; background: transparent; color: #fff;
  display: flex; align-items: center; justify-content: center; cursor: pointer; flex: none;
  transition: color .18s ease, background-color .18s ease;
}
.vw-ib:hover { background: rgba(255,255,255,.1); }
/* 按下只闪底色，不做缩放：顶栏图标是细描边 SVG，缩放动画会让描边每帧重新取整（收藏那颗星的
   外圈尤其明显，看着像「抖」）。不改变几何就没有重光栅化，图标一个像素都不动。 */
.vw-ib:active { background: rgba(255,255,255,.18); }
.vw-ib .ico { width: var(--vw-ico); height: var(--vw-ico); }
.vw-ib.on { color: var(--primary); }
.vw-acts { margin-left: auto; display: flex; gap: 2px; }
/* 「加载原图」：只在移动端出现（PC 端直接加载原图，见 vwShow）。方框和「原图」二字都在 SVG 里，
   按钮只给一个等比的高度，整块随顶栏缩放；字体沿用系统圆体优先栈，SVG 的 <text> 会继承 font-family。
   视觉尺寸比其它圆钮收一档（40:26 的方框整块看着比同高图标大），触控高度仍与圆钮对齐（--vw-btn）；
   宽度按 40:26 从高度推出，切到转圈图标时按钮才不会忽宽忽窄。 */
.vw-ib.vw-orig {
  --orig-h: calc(var(--vw-ico) * .82);
  width: calc(var(--orig-h) * 40 / 26); height: var(--vw-btn); padding: 0;
  border: 0; border-radius: 8px; background: transparent;
  font-family: "Yuanti SC", "YouYuan", "圆体-简", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
}
.vw-ib.vw-orig .orig-idle,
.vw-ib.vw-orig .orig-busy { display: flex; align-items: center; justify-content: center; height: 100%; }
.vw-ib.vw-orig .orig-busy { display: none; }
.vw-ib.vw-orig.busy .orig-idle { display: none; }
.vw-ib.vw-orig.busy .orig-busy { display: flex; }
.vw-ib.vw-orig .ico { width: auto; height: var(--orig-h); }
.vw-body { flex: 1; min-height: 0; display: flex; position: relative; }
.vw-main { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.vw-stage {
  /* 内边距变量化：绝对定位的「滑动换张的隔壁那张」与实况视频都要按同一圈内边距内缩，
     才能和主图落在同一个内容盒里。主图的 100% / 86% 是相对内容盒算的，而绝对定位元素的
     inset:0 是内边距盒 —— 少缩这一圈，它们的百分比就大了约 6%，滑动时会看到「放大一下再缩回去」。 */
  --vw-stage-pad: 12px;
  flex: 1; min-height: 0; min-width: 0; position: relative;
  display: flex; align-items: center; justify-content: center; padding: var(--vw-stage-pad);
  /* 照片区的触摸由查看器自己接管（滑动换张 / 单击关闭 / 双击缩放 / 拖动 / 捏合），
     必须关掉浏览器默认手势：否则点在图片外的留白上会被当成页面双击缩放或下拉刷新 */
  touch-action: none;
}
.vw-photo {
  /* 打开时按「不超出可视区域」等比缩放：宽或高任一超过照片区，就把对应边收到 100%，
     另一边按原比例跟着缩；小于照片区的图保持原尺寸，不放大。 */
  width: auto; height: auto;
  max-width: 100%; max-height: var(--ph, 100%); object-fit: contain;
  box-shadow: 0 14px 56px rgba(0,0,0,.42); user-select: none; -webkit-user-drag: none; touch-action: none;
  /* 旋转其实是两件事同时发生：转 90°（rotate）+ 宽高约束互换（.rot90）。
     两段必须同一条曲线、同一个时长才像一个整体动作；原来 max-height 那条 .3s 带回弹尾巴，
     和 .22s 的 rotate 各走各的，看起来就是「一边转一边弹一下」。统一压到 .16s 的 ease-out。 */
  transition: rotate .16s ease-out, scale .16s ease-out,
              max-height .16s ease-out, max-width .16s ease-out,
              filter .22s ease;
}
/* 预览图先上屏的模糊态（见 app.js vwShow）：大图落地后自动移除，观感是「先轮廓、后清晰」 */
.vw-photo.is-thumb { filter: blur(12px); }
/* 幻灯片切图动效（淡化 / 溶解 / 缩放 / 推移）：时长与缓动统一取 --vw-ss-dur / --vw-ss-ease，
   只有「怎么变」不同；都只动 opacity / translate / scale —— 照片的旋转用 rotate、缩放拖拽用
   transform，互不干扰。这里的时长是「切换动作」本身，每张停留多久由 JS 的定时器控制。 */
.vw-photo.ss-fade { animation: vwSsFade var(--vw-ss-dur) var(--vw-ss-ease) both; }
@keyframes vwSsFade { from { opacity: 0 } }
.vw-photo.ss-slide { animation: vwSsSlide var(--vw-ss-dur) var(--vw-ss-ease) both; }
@keyframes vwSsSlide { from { opacity: .3; translate: 8% 0 } }
/* 缩放：从略大一号收到原尺寸，顺势淡入 */
.vw-photo.ss-zoom { animation: vwSsZoom var(--vw-ss-dur) var(--vw-ss-ease) both; }
@keyframes vwSsZoom { from { opacity: .25; scale: 1.07 } }
/* 溶解：像素块消散 —— 副本上铺一层「方块孔」蒙版（8×8 瓦片，正中挖 2×2 方孔，重复平铺），
   动画里瓦片从 8px 放大到 40px（方孔 2px → 10px，块感更明显），同时整体淡出。
   观感是旧画面碎成像素块化开（新图全程不动），和「淡化」（新图从黑底淡入）完全不同。
   瓦片用内联 SVG（evenodd 挖透，走 alpha 蒙版，不依赖 mask-mode/luminance 的兼容性）；
   网格固定不漂移（mask-position 不参与动画），否则像素格会「游走」，失去像素块的稳定感。
   起始孔洞只占约 6% 面积，肉眼看不出跳变；蒙版只在 .ss-out 阶段存在，切换前的静态帧不加蒙版。 */
.vw-ss-ghost { pointer-events: none; }
.vw-ss-ghost.ss-out {
  animation: vwSsDissolve var(--vw-ss-dur) var(--vw-ss-ease) both;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%23fff' fill-rule='evenodd' d='M0 0h8v8H0zM3 3h2v2H3z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%23fff' fill-rule='evenodd' d='M0 0h8v8H0zM3 3h2v2H3z'/%3E%3C/svg%3E");
  -webkit-mask-repeat: repeat;
  mask-repeat: repeat;
  -webkit-mask-position: 0 0;
  mask-position: 0 0;
}
@keyframes vwSsDissolve {
  from {
    opacity: 1;
    -webkit-mask-size: 8px 8px; mask-size: 8px 8px;
  }
  to {
    opacity: 0;
    -webkit-mask-size: 40px 40px; mask-size: 40px 40px;
  }
}
/* 小图不放大：加 .small 后按原始尺寸显示（PC 的 max-* 本来就不会放大，这条主要管移动端的 width:100%） */
.vw-photo.small { width: auto; max-width: 100%; }
/* 旋转 90/270 时照片宽高在视觉上反转，宽高约束互换（小图不受影响） */
.vw-photo.rot90:not(.small) { width: auto; height: 100%; max-width: var(--ph, 100%); max-height: none; }
/* 滑动换张时从另一侧滑进来的「隔壁那张」的外层盒，以及实况视频的外层盒：
   先精确占住与主图相同的「内容盒」（绝对定位 + 按 --vw-stage-pad 内缩），
   里面的 img / video 再按 .vw-photo 那套约束自己适配。
   为什么必须分两层：绝对定位元素的包含块是「内边距盒」，它的 100% / 86% 也按内边距盒解析 ——
   只给媒体元素加 inset 只能挪位置、改不了百分比基准，尺寸会凭空大一圈，
   表现出来就是滑动换张时「放大再缩小」、实况播放时视频比静态图大一圈。 */
.vw-peek, .vw-livewrap {
  position: absolute; inset: var(--vw-stage-pad);
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}

/* ---- 实况图（Live Photo）---- */
/* 视频与静态图同位同尺寸：放在 .vw-livewrap 里（见上面的说明），所以这里不再自己绝对定位 ——
   百分比相对外层盒的内容盒解析，与主图完全同一口径。
   pointer-events:none 让缩放 / 拖拽 / 长按手势都落在下方 img 上（既有逻辑不动）。 */
.vw-livevideo {
  max-width: 100%; max-height: var(--ph, 100%);
  width: auto; height: auto; object-fit: contain; pointer-events: none;
}
/* 实况播放图标：悬停时 8 条放射线依次淡入（复刻 SunIcon 的交互动效） */
.vw-ib .vw-ray { opacity: 1; }
.vw-ib:hover .vw-ray { animation: vwRayIn .3s ease both; animation-delay: calc(var(--i) * .1s); }
@keyframes vwRayIn { from { opacity: 0 } to { opacity: 1 } }
/* 播放中：图标常驻不消失，8 条射线循环依次亮起，跟随播放节奏。
   用 id 选择器：播放入口并入顶栏后类名只剩 .vw-ib（已无 vw-livebadge），
   而 id 的优先级高于 .vw-ib:hover，不依赖两条规则的定义顺序。 */
#vwLiveBadge.playing .vw-ray { animation: vwRayIn .8s ease infinite; animation-delay: calc(var(--i) * .08s); }
/* hidden 属性必须压过组件自身的 display（否则 .vw-ib 的 display:flex 会让 hidden 失效） */
.vw [hidden] { display: none !important; }
.vw-livectl {
  position: absolute; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 3;
  display: flex; align-items: center; gap: 10px; padding: 6px 12px; border-radius: 999px;
  background: rgba(0,0,0,.5); backdrop-filter: blur(4px);
}
.vw-livebtn { width: 30px; height: 30px; border: 0; border-radius: 50%; background: rgba(255,255,255,.2); color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; }
.vw-livebtn .ico { width: 16px; height: 16px; }
.vw-liveprog { width: 120px; height: 3px; border-radius: 2px; background: rgba(255,255,255,.25); overflow: hidden; display: inline-block; }
/* 进度由 rAF 逐帧驱动，这里不能再挂 transition：两者叠加会互相追平，反而更顿 */
.vw-liveprog i { display: block; height: 100%; width: 0; background: #ffd60a; }
/* 放大沉浸态时控制条同样让位（与顶栏一致） */
.vw.zoomed .vw-livectl { opacity: 0; pointer-events: none; }

.vw-nav {
  position: absolute; top: 50%; transform: translateY(-50%); width: 38px; height: 38px; border-radius: 50%;
  border: 0; background: rgba(255,255,255,.14); color: #fff; display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: background-color .18s ease, opacity .25s ease, scale .18s cubic-bezier(.2,.9,.3,1);
}
/* 切图 1.5 秒后自动淡出（鼠标在照片区移动会重新出现，见 vwNavPulse） */
.vw.nav-hidden .vw-nav { opacity: 0; pointer-events: none; }
.vw-nav:hover { background: rgba(255,255,255,.26); }
.vw-nav:active { scale: .9; }
.vw-nav .ico { width: 17px; height: 17px; }
.vw-nav.l { left: 10px; }
.vw-nav.r { right: 10px; }
/* 移动端换页：点照片区左 / 右两侧（各 30%），中间留空避免误触 */
.vw-hit {
  display: none; position: absolute; top: 0; bottom: 0; width: 30%;
  border: 0; padding: 0; background: transparent; cursor: pointer; z-index: 1; -webkit-tap-highlight-color: transparent;
}
.vw-hit.l { left: 0; }
.vw-hit.r { right: 0; }
/* 信息面板 */
.vw-info {
  flex: none; width: 320px; background: #17171a; border-left: 1px solid rgba(255,255,255,.08);
  overflow-y: auto; padding: 14px; scrollbar-width: none; -ms-overflow-style: none;
  /* 必须建层：放大后的照片带 transform，会成为「定位 / 堆叠上下文」元素，
     而面板是普通流元素 —— 按绘制规则定位元素永远画在普通流之上，照片就会盖住面板。
     这里让面板也成为定位元素并抬到 z-index 2（低于顶栏 5 / 菜单 7 / 弹窗 9，只压照片）。 */
  position: relative; z-index: 2;
}
.vw-info::-webkit-scrollbar { display: none; width: 0; height: 0; }
.vw-in { width: 100%; }
/* 标题居中（× 绝对定位到右侧，不占位、不把标题挤偏） */
.vw-info h4 { margin: 0 0 12px; font-size: 15px; display: flex; align-items: center; justify-content: center; position: relative; }
.vw-info h4 .x {
  position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  color: rgba(255,255,255,.55); font-size: 18px; line-height: 1; border: 0; background: transparent; cursor: pointer;
}
.vw-sec { margin-top: 16px; }
.vw-sec h5 { margin: 0 0 9px; font-size: 12px; color: rgba(255,255,255,.55); font-weight: 600; display: flex; align-items: center; }
/* 评论标题上的真实条数（评论 2） */
.vw-sec h5 .n { margin-left: 6px; color: var(--primary); }
/* 评论区：输入框在上、列表在下（设计稿顺序） */
.vw-info .cmt-form { margin-bottom: 12px; }
.vw-row { display: flex; gap: 9px; align-items: flex-start; margin-bottom: 9px; }
.vw-row .ico { width: 15px; height: 15px; flex: none; margin-top: 2px; color: rgba(255,255,255,.6); }
.vw-row .b { min-width: 0; }
.vw-row .t { font-size: 12.5px; color: rgba(255,255,255,.92); line-height: 1.5; word-break: break-all; }
.vw-row .s { font-size: 11.5px; color: rgba(255,255,255,.5); margin-top: 2px; }
.vw-album { display: flex; gap: 9px; align-items: center; background: rgba(255,255,255,.05); border-radius: 10px; padding: 8px; }
.vw-album .cv { width: 38px; height: 38px; border-radius: 8px; overflow: hidden; flex: none; background: #2a2a30; }
.vw-album .cv img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vw-album .t { font-size: 12.5px; font-weight: 600; }
.vw-album .s { font-size: 11px; color: rgba(255,255,255,.5); margin-top: 2px; }
.vw-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.vw-chip { font-size: 11px; color: #ffd0dc; background: rgba(240,107,147,.18); border-radius: 999px; padding: 3px 9px; }
/* 评论：复用站内评论区组件（.cmt）的逻辑，这里只做一层深色配色覆盖 */
.vw-info .cmt { margin-top: 0; padding-top: 0; border-top: 0; }
.vw-info .cmt-head { display: none; }
.vw-info .cmt-body, .vw-info .cmt-text { color: rgba(255,255,255,.85); }
.vw-info .cmt-who .who { color: #fff; }
.vw-info .cmt-who { color: rgba(255,255,255,.75); }
.vw-info .cmt-meta, .vw-info .cmt-more, .vw-info .cmt-empty { color: rgba(255,255,255,.45); }
.vw-info .cmt-at { color: var(--primary); }
.vw-info .cmt-item { border-bottom: 0; }
.vw-info .cmt-input {
  background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.14); color: #fff;
}
.vw-info .cmt-input::placeholder { color: rgba(255,255,255,.4); }
/* 输入区占位入口同样换成深色底，避免在白卡片样式里亮出一块 */
.vw-info .cmt-open {
  background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.14); color: rgba(255,255,255,.4);
}
.vw-info .cmt-open:hover { border-color: var(--primary); color: #fff; }
/* 点赞 / 回复 / 更多：深色底上换成浅色文字，主题色留给点赞选中态 */
.vw-info .cmt-act { color: rgba(255,255,255,.55); }
.vw-info .cmt-act:hover { color: #fff; }
/* ⋮ 在深色底上也要比其它动作按钮亮一档（与浅色底的正文色口径一致） */
.vw-info .cmt-act[data-cmt-more] { color: rgba(255,255,255,.85); }
.vw-info .cmt-like.on { color: var(--primary); }
/* ===== 照片查看器信息面板：标题衬线化，信息沿用无衬线与小号分组标签 ===== */
.vw-info h4 { font-family: var(--font-serif); font-size: 17px; font-weight: 600; letter-spacing: .04em; }
.vw-sec h5 { font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: rgba(255,255,255,.42); }
.vw-row .t { font-size: 13px; line-height: 1.6; }
.vw-row .s { font-size: 11px; }
.vw-album .t { font-family: var(--font-serif); font-size: 14px; font-weight: 600; }
.vw-album .s { font-size: 10.5px; }
.vw-chip { font-size: 10.5px; }
.vw-rate-k, .vw-rate-v { font-size: 11px; }
/* 可交互星级（查看器「详情」的分级 / 相册的等级筛选共用）：同一颗星两态图标靠 .on 切换 */
.rate-star {
  appearance: none; background: none; border: 0; padding: 2px; margin: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; color: inherit; line-height: 0;
}
.rate-star .ico { width: 15px; height: 15px; display: block; }
.rate-star .off-i { display: block; }
.rate-star .on-i { display: none; }
.rate-star.on .off-i { display: none; }
.rate-star.on .on-i { display: block; }
/* 查看器「详情」区的分级行：标签 + 5 颗星 + 当前等级 */
.vw-rate { display: flex; align-items: center; gap: 8px; margin-bottom: 9px; }
.vw-rate-k { font-size: 12px; color: rgba(255, 255, 255, .55); flex: none; }
.vw-rate-stars { display: inline-flex; align-items: center; gap: 2px; }
.vw-rate .rate-star { color: rgba(255, 255, 255, .68); }
.vw-rate .rate-star.on { color: var(--primary); }
.vw-rate .rate-star:hover { color: #fff; }
.vw-rate-v { font-size: 11.5px; color: rgba(255, 255, 255, .5); }
/* 查看器「详情」区的摄影师 / 模特：行首图标 + 标签 + 内联输入（失焦或回车即存，见 vwSaveCredits） */
.vw-cred { display: flex; align-items: center; gap: 8px; margin-bottom: 9px; }
.vw-cred .ico { width: 15px; height: 15px; flex: none; color: rgba(255, 255, 255, .6); }
.vw-cred-k { font-size: 12px; color: rgba(255, 255, 255, .55); flex: none; }
/* 输入框用独立的 .vw-cred-in —— 别再叫 .vw-in：那个类名是 #vwIn（面板内容容器）的，
   撞名会让整块面板套上输入框的半透明底 / 边框 / 圆角，看起来像从侧栏里「分离」出来的一层盒子。 */
.vw-cred-in {
  flex: 1; min-width: 0; font-family: inherit; font-size: 12.5px; outline: none;
  padding: 4px 8px; border-radius: 7px; color: rgba(255, 255, 255, .92);
  background: rgba(255, 255, 255, .08); border: 1px solid rgba(255, 255, 255, .14);
}
.vw-cred-in::placeholder { color: rgba(255, 255, 255, .35); }
.vw-cred-in:focus { border-color: var(--primary); background: rgba(255, 255, 255, .13); }
/* 播放幻灯片：收起所有界面元素，只剩照片（点任意处或 Esc 退出） */
/* padding-right 也做过渡：面板打开时顶栏要让出右侧那条，得跟面板的挤出同步动（见 PC 媒体查询） */
.vw-top { transition: opacity .3s ease, transform .3s cubic-bezier(.22,.8,.24,1), padding-right .28s cubic-bezier(.22,.8,.24,1); }
/* 放大看细节时顶栏淡出让位；鼠标靠近屏幕顶部时重新浮现 ——
   否则放大后关闭 / 播放 / 收藏等按钮就彻底没了入口。
   热区高度直接取顶栏自身的高度（--vw-top-h）：鼠标碰到「顶栏原本所在的那片区域」就唤回，
   不必精准怼到屏幕最上沿 —— 原来只有 14px，等于要贴着边角去蹭才出得来。 */
.vw.zoomed .vw-top { opacity: 0; pointer-events: none; }
.vw.zoomed .vw-top::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: var(--vw-top-h); pointer-events: auto; }
.vw.zoomed .vw-top:hover { opacity: 1; pointer-events: auto; }
/* 放大态：左右箭头与左右点按区一并让位 —— 拖动图片时不会误触切图。
   切图仍可用键盘 ← → ，或双击 / 滚轮缩回 1× 后再点。 */
.vw.zoomed .vw-nav, .vw.zoomed .vw-hit { opacity: 0; pointer-events: none; }
.vw.slide .vw-top, .vw.slide .vw-nav, .vw.slide .vw-hit {
  opacity: 0; pointer-events: none;
}
/* ⋯ 更多菜单 */
.vw-more {
  position: absolute; right: 8px; top: 56px; width: 206px; background: #222226;
  border: 1px solid rgba(255,255,255,.1); border-radius: 12px; padding: 6px; z-index: 7;
  box-shadow: 0 16px 48px rgba(0,0,0,.42); transform-origin: top right;
  animation: vwMenuIn .24s cubic-bezier(.16,1,.3,1);
}
@keyframes vwMenuIn { from { opacity: 0; transform: translate(8px,-8px) scale(.95); } to { opacity: 1; transform: none; } }
.vw-more .it {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 8px;
  font-size: 13.5px; color: #fff; cursor: pointer; transition: background-color .16s ease;
}
.vw-more .it:hover { background: rgba(255,255,255,.08); }
.vw-more .it:active { background: rgba(255,255,255,.14); }
.vw-more .it .ico { width: 16px; height: 16px; color: rgba(255,255,255,.75); }
/* 「下载」这类有后续动作的条目，右侧给一个指引小箭头（设计稿的 .go） */
.vw-more .it .go { margin-left: auto; display: flex; align-items: center; opacity: .4; }
.vw-more .it .go .ico { width: 14px; height: 14px; color: inherit; }
.vw-more .it.dg .ico { color: #ff8a8a; }
/* 「下载」二级菜单：展开时指引箭头转 90°，子项缩进一级列出「原图 / 标清图」 */
.vw-more .it.has-sub .go { transition: transform .18s ease; }
.vw-more .it.has-sub.open { background: rgba(255,255,255,.08); }
.vw-more .it.has-sub.open .go { transform: rotate(90deg); }
.vw-more .sub { display: none; }
.vw-more .it.open + .sub { display: block; }
.vw-more .sub .it { padding-left: 36px; font-size: 13px; color: rgba(255,255,255,.85); }
.vw-more .sub .it.dis { opacity: .4; cursor: default; }
.vw-more .sub .it.dis:hover, .vw-more .sub .it.dis:active { background: none; }
.vw-more .sep { height: 1px; margin: 5px 8px; background: rgba(255,255,255,.1); }
/* 弹窗（从相册移除 / 已到最后一张 / 选相册）与轻提示 */
.vw-mask {
  position: absolute; inset: 0; background: rgba(0,0,0,.6); z-index: 9;
  display: flex; align-items: center; justify-content: center; padding: 22px;
}
/* hidden 在设了 display 的元素上会被覆盖，这里显式兜底（同 .chip-row[hidden] / .topic-sec[hidden]）。
   少了这条，弹窗层即使 hidden 也一直是 flex，那层半透明遮罩会盖住整个查看器、挡住所有操作。 */
.vw-mask[hidden] { display: none; }
.vw-dlg {
  width: 100%; max-width: 318px; background: #242428; border-radius: 16px; padding: 16px;
  box-shadow: 0 24px 72px rgba(0,0,0,.48); animation: vwDlgIn .26s cubic-bezier(.16,1,.3,1);
}
@keyframes vwDlgIn { from { opacity: 0; transform: translateY(14px) scale(.94); } to { opacity: 1; transform: none; } }
.vw-dlg h6 { margin: 0 0 7px; font-size: 15px; }
.vw-dlg p { margin: 0 0 14px; font-size: 12.5px; color: rgba(255,255,255,.7); line-height: 1.65; }
.vw-dlg .list { max-height: 38vh; overflow: auto; margin: 0 0 12px; }
.vw-dlg .li {
  display: flex; gap: 10px; align-items: center; padding: 8px; border-radius: 10px;
  font-size: 13.5px; cursor: pointer; transition: background-color .16s ease;
}
.vw-dlg .li:hover { background: rgba(255,255,255,.05); }
.vw-dlg .li .cv { width: 34px; height: 34px; border-radius: 8px; overflow: hidden; flex: none; background: #333; }
.vw-dlg .li .cv img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 行内顺序照设计稿：封面 + 名称（占满剩余）+ 张数 + 右侧勾选圈 */
.vw-dlg .li .tt { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vw-dlg .li .s { margin-left: auto; font-size: 11.5px; color: rgba(255,255,255,.45); }
.vw-dlg .li.on { background: rgba(255,255,255,.08); }
.vw-dlg .ck { width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid rgba(255,255,255,.35); flex: none; margin-left: 8px; }
.vw-dlg .li.on .ck { background: var(--btn-grad); border-color: transparent; }
.vw-dlg .foot { display: flex; gap: 8px; }
.vw-dlg .foot button {
  flex: 1; height: 36px; border-radius: 10px; border: 1px solid rgba(255,255,255,.16);
  background: transparent; color: #fff; font-size: 13.5px; cursor: pointer; font-family: inherit;
}
.vw-dlg .foot .pri { background: var(--btn-grad); border-color: transparent; font-weight: 600; }
.vw-dlg .foot .dg { background: #e5484d; border-color: transparent; font-weight: 600; }
.vw-toast {
  position: absolute; left: 50%; bottom: 100px; z-index: 8; pointer-events: none;
  transform: translateX(-50%); background: rgba(42,42,48,.94); color: #fff; font-size: 12.5px;
  padding: 7px 14px; border-radius: 999px; box-shadow: 0 8px 24px rgba(0,0,0,.36);
  animation: vwToast 1.7s ease forwards;
}
@keyframes vwToast {
  0% { opacity: 0; transform: translateX(-50%) translateY(8px); }
  12% { opacity: 1; transform: translateX(-50%) translateY(0); }
  78% { opacity: 1; }
  100% { opacity: 0; }
}
/* 移动端：信息面板做成底部抽屉（滑入滑出）+ 照片让位 + 缩略图条自动收起 */
@media (max-width: 1023.98px) {
  /* 移动端顶栏窄：只留 收藏 / 原图 / 信息 / 更多，计数和（缩放、添加到相册）都收起。
     #vwFav / #vwAdd 的 display 另有 JS 按回收站切换，非回收站时 JS 写的是空值，这里的规则才生效。 */
  .vw-count, #vwZoom, #vwAdd { display: none; }
  /* 「加载原图」脱离顶栏，悬浮到照片区右下角：单手可达，也不再挤占本就很窄的顶栏。
     绝对定位以 .vw 为参照（.vw-top / .vw-acts 都不是定位元素），bottom 让开 iPhone 底部手势条。 */
  .vw-ib.vw-orig {
    position: absolute;
    right: 14px;
    bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  }
  .vw-body { position: static; }
  .vw-info {
    position: absolute; left: 0; right: 0; bottom: 0; width: auto; height: 60%; z-index: 6;
    border-left: 0; border-radius: 16px 16px 0 0; box-shadow: 0 -14px 48px rgba(0,0,0,.42);
    transform: translateY(105%); transition: transform .3s cubic-bezier(.22,.8,.24,1);
  }
  .vw-info.open { transform: translateY(0); }
  /* 照片同步缩小并上移，让出抽屉的位置（与抽屉同一条曲线，看起来是一起动） */
  .vw-stage { transition: transform .3s cubic-bezier(.22,.8,.24,1); }
  .vw-body.has-panel .vw-stage { --ph: 36%; transform: translateY(-30%); }
  /* 移动端主图：同样按「不超出照片区」等比缩放，大图贴边、小图保持原尺寸；
     贴满屏幕就不再带圆角与投影 */
  .vw-photo { width: auto; max-width: 100%; border-radius: 0; box-shadow: none; }
  /* 实况视频跟主图同一口径（原本是 100% / 86%，主图改成自适应后视频不跟就会大小不一） */
  .vw-livevideo { width: auto; max-width: 100%; }
  .vw-nav { display: none; }
  /* 移动端不要左右点按翻页：翻页靠左右滑动，照片区任意处单击＝关闭查看器（见 vwBindTap）。
     点按区留着会先吃掉这一击（变成上一张/下一张），单击关闭也就无从触发。 */
  .vw-hit { display: none; }
}
/* PC / 横屏：面板从右侧挤出（挤压照片区，不覆盖照片）；点 ⓘ 展开、点 × 收起 */
@media (min-width: 1024px) {
  .vw-info {
    width: 0; padding: 0; border-left: 0; overflow: hidden;
    transition: width .28s cubic-bezier(.22,.8,.24,1), padding .28s cubic-bezier(.22,.8,.24,1), margin-top .28s cubic-bezier(.22,.8,.24,1);
  }
  /* 面板宽度要把左右 14px 内边距算进去（box-sizing:border-box），内容宽度才是 .vw-in 的 320px。
     少了这 28px，.vw-in 会顶出面板、右侧内容被窗口裁掉（评论输入框就被切在外面）。 */
  .vw-info.open {
    width: var(--vw-info-w); padding: 14px; border-left: 1px solid rgba(255,255,255,.08); overflow-y: auto;
    /* 往上顶一个顶栏的高度：右侧这条从页面最上沿一直贯到最底部（顶栏同时让出右边的宽度，见下一条规则） */
    margin-top: calc(-1 * var(--vw-top-h));
  }
  .vw-in { width: 320px; }
  /* 面板打开时顶栏让出右侧那条：按钮组靠 margin-left:auto 自动贴到面板左边界，关闭 / 计数留在最左 */
  .vw.info .vw-top { padding-right: calc(var(--vw-info-w) + 6px); }
}

/* 中屏（平板/小窗口）：维持手机版居中限宽形态 */
@media (min-width: 640px) and (max-width: 1023.98px) {
  #app { max-width: 640px; margin: 0 auto; }
  .modal-mask { align-items: center; padding: 20px; }
  .modal { border-radius: 22px; }
  .tabbar { left: 50%; transform: translateX(-50%); width: 100%; max-width: 640px; }
  .tabbar.is-hidden { transform: translateX(-50%) translateY(calc(100% + 40px)); }
  .fab { right: calc(50% - 302px); }
}

/* 未登录态（展示页/PC 登录欢迎页）：隐藏应用壳顶栏，内容区取消留白由全屏页铺满（移动端旧版登录卡片不打此标） */
body.is-auth .topbar { display: none; }
body.is-auth .content { padding: 0; }

/* ===== 非 PC（<1024px）：隐藏 PC 专属侧栏入口，移动端保持原 tab 布局 ===== */
@media (max-width: 1023.98px) {
  .tab-pc-only { display: none !important; }
  .home-fish { display: none !important; }
  /* 移动端返回按钮：固定在顶栏（header）左上角 */
  #backBtn {
    position: fixed;
    top: calc(env(safe-area-inset-top) + 8px);
    /* 应用列在 640~1024px 区间是 640px 居中，故左偏移要跟随应用列而非视口，
       否则按钮会脱离顶栏飘到页面背景上 */
    left: max(12px, calc(50% - 308px));
    right: auto;
    z-index: 30;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    font-size: 28px;
    line-height: 1;
    padding: 0;
  }
  #backBtn[hidden] { display: none !important; }
}

/* ===== PC 大屏：左侧边栏 + 宽幅内容区 ===== */
@media (min-width: 1024px) {
  :root { --sidebar-w: 256px; --topbar-h: 52px; }

  /* 内容区的限宽居中统一交给下方 .page 规则处理，.content 只负责避让侧栏。
     两处同时做居中会形成「双重居中」，内容被推得明显偏右。 */

  /* PC 端侧栏模块页（首页 / 衣柜 / 相册 …）靠左侧导航切换，不再重复显示返回键；
     但详情 / 编辑等子页不属于侧栏入口，进去后没有返回上一级的手段，
     故由 body.is-pc-sub 放开返回键并固定在顶栏左上角（顶栏左侧本就留空，不占内容区）。
     移动端不受影响，仍在顶栏左上角 */
  /* 隐藏限定在「非子页」上：若写成 #backBtn{display:none!important} 再想放开，
     新规则会被这条 !important 压住（!important 优先于特异性），按钮永远出不来。 */
  body:not(.is-pc-sub) #backBtn { display: none !important; }
  body.is-pc-sub #backBtn {
    display: inline-flex;
    position: fixed;
    top: calc((var(--topbar-h) - 34px) / 2);
    left: calc(var(--sidebar-w) + 12px);
    z-index: 30;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    font-size: 28px;
    line-height: 1;
    padding: 0;
  }
  body.is-pc-sub #backBtn[hidden] { display: none !important; }

  #app { max-width: none; }

  /* 首页倒计时卡片 PC 端两列并排（间隙与其它网格统一 14px） */
  .countdown-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
  }

  /* 首页模块网格 PC 端三列（与设计稿一致；移动端仍是两列） */
  .module-grid.cols-2 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  /* 首页情侣头像区只在移动端显示，PC 端隐藏 */
  .couple-avatars.no-heart { display: none; }

  /* 首页底部小鱼限定在右侧内容区（避开左侧固定边栏） */
  .home-fish { left: var(--sidebar-w); width: calc(100% - var(--sidebar-w)); }

  /* 底部 tabbar 重排为左侧固定边栏（元素与 JS 高亮逻辑完全复用），并从顶部延伸到底部 */
  .tabbar {
    left: 0; right: auto; top: 0; bottom: 0;
    width: var(--sidebar-w);
    height: auto;
    flex-direction: column;
    justify-content: flex-start;
    align-items: stretch;
    gap: 6px;
    padding: 24px 14px;
    border-top: none;
    border-right: 1px solid var(--border);
    box-shadow: 4px 0 24px rgba(var(--accent-rgb), 0.06);
    transition: transform .28s ease;
  }
  /* 手机自定义底栏专属入口：PC 侧栏不展示（与移动端的 .tab-pc-only 互为反向规则） */
  .tab-mobile-only { display: none !important; }
  /* 侧栏顶部品牌区：网页图标 + 网站标题（仅 PC 显示），点击跳转展示页 */
  .sidebar-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 6px 22px;
    color: var(--primary-deep);
    cursor: pointer;
  }
  .sidebar-brand:hover .brand-title { opacity: .85; }
  .sidebar-brand .brand-icon { width: 30px; height: 30px; border-radius: 7px; flex: none; }
  .sidebar-brand .brand-title { font-size: 18px; font-weight: 800; letter-spacing: 1px; }
  /* 子页面：侧栏整体滑出屏幕（nav 连同里面的「+」一起隐藏，不再常显） */
  .tabbar.is-hidden { transform: translateX(-100%); pointer-events: none; }
  /* 侧栏隐藏后，顶栏 / 内容区 / 返回键 / 底部浮条全部铺满；返回键回到左边缘 */
  body.nav-hidden .topbar,
  body.nav-hidden .content { margin-left: 0; }
  body.nav-hidden #backBtn { left: 12px; }
  body.nav-hidden .home-fish { left: 0; width: 100%; }
  body.nav-hidden .album-mbar { left: 16px; }
  .tab {
    flex: none;
    flex-direction: row;
    justify-content: flex-start;
    gap: 14px;
    padding: 14px 18px;
    border-radius: 14px;
    font-size: 15px;
  }
  .tab:hover { background: var(--bg); color: var(--primary-deep); }
  .tab.active { background: var(--primary-soft); }
  .tab.active .tab-icon { transform: none; }
  .tab-icon { font-size: 24px; }
  /* 中间凸起"+"变为侧栏里的整宽添加按钮，并移到侧栏最底部（仅 PC，用 order 不改 DOM，不影响移动端） */
  .tab-center { flex: none; order: 10; margin-top: auto; }
  .tab-plus {
    width: 100%; height: 50px;
    margin-top: 0;
    border-radius: 14px;
    font-size: 24px;
    box-shadow: var(--shadow-accent);
  }
  .tab-plus::after { content: " 添加"; font-size: 15px; font-weight: 600; }
  .tab-center:hover .tab-plus { filter: brightness(1.05); }

  /* 顶栏移到侧栏右侧（减去侧栏宽度），内容区仍让开侧栏宽度，内容限宽居中（未登录页无侧栏，铺满见全局 is-auth） */
  .topbar { margin-left: var(--sidebar-w); height: var(--topbar-h); }
  .content { margin-left: var(--sidebar-w); padding-bottom: 10px; }
  body.is-auth .content { margin-left: 0; }
  /* 内容区宽度跟随视口：取外层 .content 的 90%（此前是写死的 940px，宽屏下显得小） */
  .page { width: 90%; margin: 0 auto; }
  /* 地图视图：PC 上要铺满内容区，所以取消 .page 的 90% 限宽居中；
     底部负外边距对上 PC 的 .content padding-bottom（24px），而不是移动端那条 --tabbar-h + 8 */
  .page-map { width: auto; margin: 0; }
  .page-map .list { margin-bottom: -24px; }
  /* 下面还有「未标地点」时同样不能吞掉底部负边距，否则内容被拉出可视区 */
  .page-map-rest .list { margin-bottom: 0; }

  /* 爱情清单：宽屏下卡片改为单行舒展列表（完成信息并入同一行右侧，排在编辑铅笔之前） */
  .promise-item { padding: 14px 20px; gap: 14px; }
  .promise-item .promise-done-meta { flex-basis: auto; order: 1; }
  .promise-item .promise-pending { flex-basis: auto; order: 1; }

  /* 小工具：宽屏下工具行两列排布 */
  .tool-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 24px; }

  /* 恋爱日常（列表条目 / 详情）：PC 端头像放大到 44px，摘要放宽到 6 行，配图固定 120px 缩略图 */
  .post { --post-av-w: 44px; --post-gap: 14px; }
  .post .author-avatar { width: 44px; height: 44px; }
  .post .p-sum { -webkit-line-clamp: 6; font-size: 14.5px; }
  .post .p-imgs { grid-template-columns: repeat(var(--cols, 3), 120px); gap: 8px; }
  /* 单图 / 单视频：多图仍用 120px 小格，单媒体放大到 360px，避免 PC 上只有一条窄条 */
  .post .p-imgs[data-cols="1"] { grid-template-columns: minmax(0, 360px); }
  /* 列表内联评论区：不再加分隔线与额外留白，间距由 .list-item .cmt-inline 统一控制 */
  /* 详情正文里的配图：固定 120px 缩略图，与列表口径一致 */
  .diary-body .p-imgs { grid-template-columns: repeat(var(--cols, 3), 120px); gap: 8px; }

  /* 列表条目（相册 / 日记）：PC 端改为微博卡片式——头像固定在左栏并跨满整卡高度，
     昵称行 / 正文 / 配图 / 评论整体归入右栏成一列；移动端不受影响，仍是头像与昵称同排 */
  .list-item.post-item {
    grid-template-columns: 44px minmax(0, 1fr);
    grid-template-areas:
      "avatar head"
      "avatar body"
      "avatar cmt";
    column-gap: 12px;
  }
  .post-item .author-avatar { width: 44px; height: 44px; }
  .post-item .post-body { margin-top: 6px; }
  /* 配图在 PC 端改为固定尺寸缩略图（微博九宫格风格），不再铺满整宽 */
  .list-item.post-item .album-grid { max-width: none; grid-template-columns: repeat(var(--cols, 3), 120px); justify-content: start; gap: 8px; }
  .list-item.post-item .album-grid.single { grid-template-columns: 168px; }
  .list-item.post-item .album-grid.single.landscape { grid-template-columns: 300px; }
  /* 相册配图（列表 & 详情）：一行 5 张、每张 140px、间距 8px；超过 5 张仅显示前 5 张，
     第 5 格叠加剩余张数角标。移动端不受影响（仍为九宫格：3 列、最多 9 格截断） */
  .album-grid-wrap .album-grid:not(.single) { grid-template-columns: repeat(5, 140px); gap: 8px; }
  .album-grid-wrap .album-grid:not(.single) .album-cell { width: 140px; height: 140px; aspect-ratio: auto; }
  .album-grid-wrap .album-grid:not(.single) .album-cell:nth-child(n+6) { display: none; }
  .album-grid-wrap .album-grid .album-more-pc { display: flex; }
  /* 详情页照片墙：PC 6 列等宽铺满（设计稿 .pw 的 repeat(6,1fr)），不截断、不用固定像素格 */
  .album-wall .album-grid:not(.single) { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 8px; }
  /* 分级角标：PC 端仍在缩略图底部（移动端的顶部位置见 .rate-badge 基础规则） */
  .rate-badge {
    top: auto; bottom: 0;
    padding: 8px 4px 3px;
    background: linear-gradient(to top, rgba(0, 0, 0, .55), rgba(0, 0, 0, 0));
  }
  /* 相册 / 日常编辑页的照片格：PC 内容区很宽，3 列铺满会得到很大的方块，
     改成固定 140px 的缩略图（与「相册配图 PC 每张 140px」同一口径），一行能排几张排几张 */
  .photo-grid { grid-template-columns: repeat(auto-fill, 140px); justify-content: start; gap: 8px; }
  /* 专辑头动作区：PC 内容区很宽，按钮撑满整行会显得空荡，改成自然宽度靠左 */
  .album-acts .btn { flex: 0 0 auto; }

  /* 关于我们配图：PC 端内容区宽达 1080px，图片按 100% 撑满会过大，限宽并居中（限在容器上） */
  .about-photo { max-width: 480px; margin-left: auto; margin-right: auto; }

  /* 弹窗改为屏幕居中的浮动卡片 */
  .modal-mask { align-items: center; padding: 20px; }
  .modal { border-radius: 22px; max-width: 560px; animation: fadeIn .2s ease; }

  /* 悬浮按钮贴右下角 */
  .fab { right: 24px; bottom: 24px; }

  /* 衣柜条目 6 列 */
  .w-item, .opick { width: calc(16.66% - 7px); }

  /* 首页模块卡片hover反馈 */
  .module-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-hover); }
  /* 内容卡沿用同一套悬浮反馈：轻抬 + 粉色柔光，和模块卡保持一致的触感 */
  .card { transition: transform .15s, box-shadow .15s; }
  .card:hover { transform: translateY(-3px); box-shadow: var(--shadow-hover); }
  /* 账单卡（左滑容器）沿用同样的悬浮反馈：外层的 overflow:hidden 会裁掉内层阴影，所以挂在外层 */
  .swipe-item { transition: transform .15s, box-shadow .15s; }
  .swipe-item:hover { transform: translateY(-3px); box-shadow: var(--shadow-hover); }
  .card-entry:hover { transform: translateY(-2px); box-shadow: var(--shadow-hover); }
  .btn:hover { filter: brightness(1.04); }
  .btn-ghost:hover { background: var(--bg); }
  .quick-item:hover { background: var(--primary-soft); }
  .chip:hover { border-color: var(--primary); }
}

/* ===== 手机端（<640px）：展示页整体缩小，避免头像/计时行溢出或显示不全 ===== */
@media (max-width: 639.98px) {
  /* 头像区：缩小头像与间距，爱心同步缩小 */
  .showcase-avatars { gap: 26px; margin: 2vh 0 12px; }
  .showcase-avatars .arco-avatar { width: 80px; height: 80px; font-size: 38px; border-width: 2px; }
  .showcase .couple-avatars .heart { width: 28px; height: 28px; margin-bottom: 24px; }
  .showcase .couple-avatars .heart::before, .showcase .couple-avatars .heart::after { width: 28px; height: 28px; }
  .showcase .couple-avatars .heart::before { top: -14px; }
  .showcase .couple-avatars .heart::after { left: -14px; }
  .showcase .couple-avatars .heart-broken { width: 28px; height: 28px; margin-bottom: 24px; }
  /* 与桌面规则同为三类选择器，媒体查询在后，手机端覆盖生效 */
  .showcase .couple-avatars .avatar-name { font-size: 14px; }

  /* 恋爱计时：顶栏文案可换行、计时行允许换行、整体字号适度缩小 */
  .auth-screen.showcase { padding-top: 60px; padding-bottom: 16px; }
  .showcase-love { padding: 30px 8px 4px; }
  .showcase-love .couple { font-size: 16px; }
  .showcase-love .love-main { font-size: 40px; }
  .showcase-love .love-sub { font-size: 15px; }
  .showcase-love .quote { font-size: 14px; word-break: break-word; white-space: normal; }
  .showcase-love .days { flex-wrap: wrap; gap: 8px; }
  /* 移动端三行：couple 独占一行、第X天与时分秒并排一行、引号一行 */
  .showcase-love .days .couple { flex: 0 0 100%; text-align: center; }
  /* 移动端鱼塘固定高度，避免 14vh 随视口导致高度波动 */
  .fish-sea { height: 110px; }
  .page-blessing { padding-bottom: calc(var(--tabbar-h) + 24px + 110px); }
  .showcase-love .days .love-main { flex: 0 0 100%; }
  .showcase-love .days .love-sub { flex: 0 0 100%; text-align: center; }

  /* 公开模块区：3 列改 2 列，卡内间距缩小 */
  .showcase-modules { padding: 30px 12px 32px; }
  .showcase-modules .module-grid { gap: 10px; }
  .showcase-modules .module-grid.cols-3 { grid-template-columns: repeat(2, 1fr); }
}

/* ===== 公开 / 私密 ===== */
.privacy-field { margin-top: 4px; }
.privacy-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
/* 公开/私密两段式胶囊：靠右对齐，复用倒数日的 dp-cal-seg 视觉 */
.privacy-seg { margin-left: auto; }
/* 约定表单里独占一行，跟随字段左对齐 */
.ls-field .privacy-seg { margin-left: 0; }
.switch { position: relative; display: inline-block; width: 46px; height: 26px; flex: none; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch .slider { position: absolute; inset: 0; background: var(--switch-track); border-radius: 26px; cursor: pointer; transition: .2s; }
.switch .slider::before { content: ""; position: absolute; height: 20px; width: 20px; left: 3px; top: 3px; background: #fff; border-radius: 50%; transition: .2s; box-shadow: 0 1px 3px rgba(176, 53, 91, .14); }
.switch input:checked + .slider { background: var(--btn-grad); }
.switch input:checked + .slider::before { transform: translateX(20px); }

/* 列表项上的公开/私密小标识 */
.privacy-badge { display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px; font-size: 11px; font-weight: 500; vertical-align: middle; }
/* 徽章底色用半透明色叠加，天然适配深浅两种底色，无需分别写两套 */
.privacy-badge.public { background: rgba(75, 180, 120, .16); color: var(--ok-ink); }
.privacy-badge.private { background: rgba(120, 120, 140, .18); color: #5f5f72; }
body.dark .privacy-badge.public { color: #5fd39a; }
body.dark .privacy-badge.private { color: #a9a9bd; }
.privacy-badge svg { width: 14px; height: 14px; vertical-align: -2px; margin-right: 2px; }

/* 清单列表项内的徽章对齐 docs/promise-ui-reference.html（公开=浅粉底深粉字 / 私密=白底描边灰字）。
   放在全局徽章之后覆盖，仅作用于清单列表，相册 / 日常 / 账单等仍用上面的绿色 / 灰色语义。 */
.promise-item .privacy-badge {
  display: inline-flex; align-items: center; gap: 4px;
  margin-left: 0; padding: 2px 7px;
  font-size: 10.5px; font-weight: 600;
  border: 1px solid var(--border); vertical-align: baseline;
}
.promise-item .privacy-badge svg { width: 11px; height: 11px; margin-right: 0; vertical-align: middle; }
.promise-item .privacy-badge.public { background: var(--panel-soft); color: var(--primary-deep); }
.promise-item .privacy-badge.private { background: var(--card); color: var(--text-soft); }

/* ===== 定位（日记 / 相册）：内联在隐私开关那一行，无填充无边框 ===== */
.loc-trigger { display: flex; align-items: center; gap: 6px; min-width: 0; cursor: pointer; user-select: none; }
.loc-trigger .loc-icon { display: inline-flex; color: var(--text-soft); }
.loc-trigger.located .loc-icon { color: var(--primary-deep); }
.loc-trigger .loc-text { font-size: 13px; color: var(--text-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.loc-trigger.located .loc-text { color: var(--text); font-weight: 600; }
/* 定位行 + 清除按钮：整行可点（打开地图选点），✕ 只负责清掉定位 */
.privacy-loc { display: flex; align-items: center; gap: 6px; min-width: 0; }
.loc-clear {
  flex: none; width: 22px; height: 22px; padding: 0; border: none; border-radius: 50%;
  background: var(--panel-soft); color: var(--text-soft); cursor: pointer;
  font-size: 13px; line-height: 1; font-family: inherit;
  display: flex; align-items: center; justify-content: center;
}
.loc-clear:hover { background: var(--primary-soft); color: var(--primary-deep); }
.loc-map-name { font-size: 13px; font-weight: 600; margin-bottom: 8px; }
.loc-map-frame { display: block; width: 100%; height: 320px; border: 0; border-radius: 10px; }
.loc-badge { display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px; font-size: 11px; font-weight: 500; vertical-align: middle; background: rgba(90, 150, 200, .16); color: #3a6b8f; }
.loc-badge svg { width: 12px; height: 12px; vertical-align: -1px; margin-right: 2px; }
/* 可点击的位置徽章：点开地图弹窗 */
.loc-badge-btn { cursor: pointer; transition: background .15s, color .15s; }
.loc-badge-btn:hover { background: rgba(90, 150, 200, .26); color: #3a6b8f; }
body.dark .loc-badge { color: #7fb2d8; }
body.dark .loc-badge-btn:hover { color: #a8cde8; }

/* ===== 模块独立公开展示页 ===== */
.sp-page { max-width: 720px; margin: 0 auto; padding: 20px 16px 40px; }
.sp-topbar { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.sp-back { border: none; background: transparent; color: var(--primary-deep); font-size: 15px; cursor: pointer; padding: 6px 10px; border-radius: 10px; display: inline-flex; align-items: center; gap: 4px; }
.sp-back:hover { background: var(--primary-soft); }
.sp-top-title { font-size: 17px; font-weight: 800; letter-spacing: .5px; color: var(--text); }

/* ===== 展示页公开内容内联区块 ===== */
/* 模块内容区：占视口 95%（原来是固定 720px，窄屏时正文 / 大事记两栏被压得挤） */
.showcase-public { width: 95%; max-width: 1080px; margin: 0 auto; padding: 0 0 40px; }
/* 展示页的卡片浮在粉色渐变上，通用 --shadow（中性深灰）看着发脏、显重；
   换成更淡、偏粉的短投影，层次还在但不抢眼 */
.showcase-public .card { box-shadow: 0 2px 10px rgba(190, 90, 130, .10); }
.showcase-public .sp-block { margin-bottom: 16px; }
.sp-title { font-size: 15px; font-weight: 700; color: var(--text); margin-bottom: 12px; }
.sp-item { padding-bottom: 12px; margin-bottom: 12px; border-bottom: 1px dashed var(--border); }
.sp-item:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; }
.sp-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 4px; }
.sp-head b { font-size: 14px; }
.sp-text { font-size: 13px; color: var(--text-soft); white-space: pre-wrap; word-break: break-word; }
.sp-imgs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin-top: 8px; }
.sp-imgs img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 10px; display: block; }
.sp-grid { display: grid; grid-template-columns: 1fr; gap: 10px; }
.sp-album { background: var(--bg); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; cursor: pointer; }
/* 展示页相册：纵向时间线（以相册为节点），节点下九宫格平铺照片 */
.timeline { position: relative; }
.timeline::before { content: ""; position: absolute; left: 28px; top: 6px; bottom: 6px; width: 2px; background: var(--border); }
/* 每本相册一个节点：左侧预留节点栏（圆点+日期），右侧为内容区 */
.tl-item { position: relative; display: flex; align-items: flex-start; margin-bottom: 20px; }
.tl-node { position: relative; flex: 0 0 56px; text-align: center; }
.tl-dot { position: absolute; left: 50%; transform: translateX(-50%); top: 3px; width: 12px; height: 12px; border-radius: 50%; background: var(--primary, #ff6b9d); border: 2px solid var(--bg); box-shadow: 0 0 0 2px var(--border); }
.tl-date { display: block; margin-top: 22px; font-size: 12px; color: var(--text-soft); }
.tl-body { flex: 1; min-width: 0; padding-left: 14px; }
.tl-title { margin: 3px 0 0; font-size: 15px; font-weight: 700; }
.tl-summary { margin: 2px 0 8px; font-size: 12px; color: var(--text-soft); display: -webkit-box; -webkit-line-clamp: 1; line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; }
.tl-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px; }
.tl-cell { position: relative; aspect-ratio: 1; overflow: hidden; background: var(--primary-soft); border-radius: 4px; cursor: zoom-in; }
.tl-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tl-cell-empty { display: flex; align-items: center; justify-content: center; font-size: 26px; cursor: default; }
.tl-more { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(0,0,0,.45); color: #fff; font-size: 14px; font-weight: 700; }
.sp-thumbs { display: grid; gap: 2px; }
/* 只有一张(或仅占位)时限制缩略图宽度并居中，避免单张照片撑满整卡显得过大 */
.sp-thumbs:has(:only-child) { max-width: 240px; margin: 0 auto; }
.sp-thumb { position: relative; aspect-ratio: 1; overflow: hidden; background: var(--primary-soft); }
.sp-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sp-thumb-empty { display: flex; align-items: center; justify-content: center; }
.sp-thumb-empty .al-emoji { font-size: 30px; }
.sp-more { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(0,0,0,.45); color: #fff; font-size: 14px; font-weight: 700; }
.sp-cover { aspect-ratio: 1; background: var(--primary-soft); display: flex; align-items: center; justify-content: center; }
.sp-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.al-emoji { font-size: 34px; }
.sp-al-title { padding: 8px 10px 0; font-size: 13px; font-weight: 600; }
.sp-al-sub { padding: 2px 10px 10px; font-size: 12px; color: var(--text-soft); }

/* ===== 全站彩色 SVG 图标：.ico 尺寸默认跟随容器 font-size（1em） ===== */
.ico { width: 1em; height: 1em; display: inline-block; vertical-align: -0.14em; flex: none; }
/* 入口图标：站点设置沿用齿轮但着色为主题色（与公开设置的品牌图区分开） */
.ico-theme { display: inline-flex; color: var(--primary-deep); }
/* 入口图标复用网站品牌图（favicon）时收个圆角，与侧栏品牌图一致 */
.entry-ico img.ico { border-radius: 6px; }

/* 底部/侧栏 tab 图标容器 */
.tab-icon { display: inline-flex; align-items: center; justify-content: center; line-height: 1; }

/* 首页与展示页模块卡片图标（固定 30px，居中） */
/* 图标容器统一主题色：线性图标靠 currentColor 上色；彩色插画不受影响（自带 fill） */
.module-card .module-icon { display: flex; align-items: center; justify-content: center; line-height: 1; color: var(--primary-deep); }
.module-card .module-icon .ico { width: 30px; height: 30px; }

/* 卡片标题内的行内图标 */
.card-title .ico { width: 17px; height: 17px; vertical-align: -3px; margin-right: 2px; }

/* 日记标题行里的天气 / 心情图标：尺寸与所在页字号解耦，各自在容器规则里定
   （列表 .p-title 17px / 详情 .diary-title 20px / 展示页 .sp-head 17px） */
.li-title .ico, .sp-head b .ico { width: 17px; height: 17px; vertical-align: -0.22em; }

/* 底栏「+」快捷添加菜单 */
.quick-icon { display: flex; align-items: center; justify-content: center; line-height: 1; }
.quick-icon .ico { width: 30px; height: 30px; }

/* 列表搜索框放大镜 */
.list-search .ls-icon { display: flex; align-items: center; justify-content: center; }
.list-search .ls-icon .ico { width: 15px; height: 15px; }

/* 铅笔编辑 / 垃圾桶删除：行内紧凑方形图标按钮，颜色随 currentColor */
/* 图标型编辑/删除/下载按钮：无描边、无底色，仅靠颜色与 hover 背景区分
   （描边是 .btn-ghost 带来的、灰底是浏览器按钮默认样式，此处都显式去掉，
   避免同一组件在不同页面一个有框一个有底） */
.btn-edit, .btn-del, .btn-down { display: inline-flex; align-items: center; justify-content: center; padding: 6px 8px; gap: 4px; border: none; background: transparent; }
.btn-edit .ico, .btn-del .ico, .btn-down .ico { width: 16px; height: 16px; vertical-align: 0; }
.btn-edit { color: var(--primary-deep); }
.btn-del { color: #de637c; } /* 柔和玫红：与主题同色系，替换原先刺眼的正红 */
.btn-down { color: var(--primary-deep); }
.btn-edit:hover, .btn-del:hover, .btn-down:hover { background: var(--bg); }

/* 关于本站：数据备份按钮行（导出 / 恢复并排，各占一半） */
.backup-actions { display: flex; gap: 10px; margin-top: 12px; }
.backup-actions .btn { flex: 1; }

/* 编辑表单底部的危险操作按钮（与保存并排）：图标+文字、红色 */
.btn-danger { color: var(--danger, #e5484d); display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.btn-danger .ico { width: 17px; height: 17px; }
.btn-danger:hover { background: rgba(229, 72, 77, 0.08); }

/* 衣物详情页通栏编辑按钮：图标+文字并排居中 */
#wDetailEdit { display: flex; align-items: center; justify-content: center; gap: 5px; color: var(--primary-deep); }
#wDetailEdit .ico { width: 18px; height: 18px; }

/* ===== 昵称弹窗：输入框右侧的性别选择 ===== */
.nick-row { display: flex; gap: 10px; align-items: stretch; }
.nick-row input { flex: 1; min-width: 0; width: auto; }
.nick-gender { display: flex; gap: 6px; flex: none; }
.nick-gender .chip {
  display: flex; align-items: center; justify-content: center;
  padding: 0 16px; font-family: inherit; line-height: 1; white-space: nowrap;
}

/* ===== 加载动画：页面（方块 shuffle）/ 图片（环形点阵）/ 上传（圆环+数字） ===== */
.ld-svg { display: block; color: var(--primary-deep); }
/* 页面 / 列表数据加载占位 */
.ld-block {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 44px 0; color: var(--text-soft);
}
.ld-block .ld-svg { width: 34px; height: 34px; }
.ld-text { font-size: 13px; }

/* 图片加载：在图片容器内叠加环形点阵，加载完成即移除 */
.img-host { position: relative; }
/* 懒加载占位：data-src 尚未提升为 src 时，不显示破图与 alt 文本（容器尺寸由 aspect-ratio 撑住） */
img[data-src]:not([src]) { visibility: hidden; }
/* 骨架微光扫过：占位层的统一动效（图片卡片 / 视频封面共用） */
@keyframes skelSweep { from { background-position: 200% 0; } to { background-position: -200% 0; } }
.img-spin {
  position: absolute; inset: 0; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.img-spin .ld-svg { width: 30%; max-width: 34px; min-width: 18px; height: auto; aspect-ratio: 1; }

/* 上传进度环：覆盖在图片容器上，中心显示百分比数字 */
.photo-cell, .wphoto-cell, .avatar-preview, #cdImgBox, #oImgPreview { position: relative; }
.up-ring {
  position: absolute; inset: 0; z-index: 3;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .55);
  border-radius: inherit;
}
.up-ring > svg { width: 56%; max-width: 64px; aspect-ratio: 1; transform: rotate(-90deg); }
.up-ring-bg { fill: none; stroke: rgba(var(--primary-rgb), .22); stroke-width: 3; }
.up-ring-fg {
  fill: none; stroke: var(--primary-deep); stroke-width: 3; stroke-linecap: round;
  stroke-dasharray: 100; stroke-dashoffset: 100;
  transition: stroke-dashoffset .15s linear;
}
.up-ring-num { position: absolute; font-size: 12px; font-weight: 700; color: var(--primary-deep); }
/* 排队中（还没轮到上传）：中心显示「排队」两个字，缩小字号并降低对比度 */
.up-ring-num.queued { font-size: 10px; font-weight: 600; opacity: .72; }

/* ================= 经期记录 ================= */
.pd-nav { margin-bottom: 14px; }
/* PC 端：左（状态 / 日历 / 月经来了吗）· 右（用品消耗 / 记录卡 / 备注 / 保存）两栏 */
.pd-cols > div > .card:first-child, .pd-cols > div > details:first-child { margin-top: 0; }

.pd-hero { background: var(--btn-grad); color: var(--on-primary); border: none; }
.pd-hero-main { font-size: 19px; font-weight: 800; letter-spacing: .2px; }
.pd-hero-sub { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 8px; font-size: 12px; opacity: .94; }
.pd-hero-sub b { font-weight: 700; }
/* 经期概览卡：文字左、沙漏右，两者垂直居中 */
.pd-hero-iconic { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.pd-hero-text { min-width: 0; }
.pd-hero-ico { flex: none; width: 46px; height: 46px; opacity: .92; }
.pd-hero-ico .ico { width: 100%; height: 100%; display: block; }

.pd-cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.pd-cal-title { font-size: 15px; font-weight: 700; }
.pd-cal-head button {
  width: 32px; height: 32px; padding: 0; border-radius: 9px;
  border: 1px solid var(--border); background: var(--panel-soft); color: var(--primary-deep);
  display: flex; align-items: center; justify-content: center;
}
.pd-cal-head button .ico { width: 18px; height: 18px; }
.pd-flip { display: flex; transform: rotate(180deg); }
.pd-wk, .pd-grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.pd-wk span { text-align: center; font-size: 12px; color: var(--text-soft); padding: 4px 0; }
.pd-wk span.we { color: var(--primary-deep); }
.pd-d { height: 46px; display: flex; align-items: center; justify-content: center; position: relative; cursor: pointer; }
.pd-d.is-blank { cursor: default; }
.pd-d .pd-n {
  position: relative;
  width: calc(100% - 4px); height: calc(100% - 4px); border-radius: 10px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  font-size: 14px; color: var(--text);
}
/* 节日 / 法定节假日：简称排在日期数字下方，直接压在放大后的标记底色上。
   法定节假日（含调休）用主题色，普通节日用浅灰。 */
.pd-d .pd-fest-t {
  font-style: normal; font-size: 8px; line-height: 1;
}
.pd-d.pd-cal-rest .pd-fest-t { color: var(--primary-deep); font-weight: 700; }
.pd-d.pd-cal-fest .pd-fest-t { color: var(--text-soft); font-weight: 400; }
.pd-d.is-period .pd-n { background: var(--period-fill); color: var(--on-primary); font-weight: 700; }
.pd-d.is-pred .pd-n { background: var(--primary-soft); color: var(--primary-deep); font-weight: 700; }
/* 排卵期 / 排卵日走状态绿，和「预测月经期」的浅粉拉开色相；排卵日保留圆形描边圈，与方块填充的日期区分 */
.pd-d.is-fert .pd-n { background: var(--ok-soft); color: var(--ok-ink); }
.pd-d.is-ovu .pd-n { border-radius: 50%; border: 2px solid var(--ok); color: var(--ok-ink); font-weight: 700; }
/* 简称压在标记底色上：深色经期底反白，浅绿排卵期用深绿墨 */
.pd-d.is-period .pd-fest-t { color: rgba(255, 255, 255, .92); }
.pd-d.is-fert .pd-fest-t { color: var(--ok-ink); }
.pd-d.is-today .pd-n { font-weight: 800; }
.pd-d.is-sel .pd-n { box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--primary); }
.pd-d.has-rec::after {
  content: ""; position: absolute; bottom: 2px; left: 50%; transform: translateX(-50%);
  width: 5px; height: 5px; border-radius: 50%; background: var(--primary-deep);
}
.pd-legend { display: flex; flex-wrap: wrap; gap: 8px 14px; margin-top: 10px; }
.pd-legend i { display: inline-flex; align-items: center; gap: 6px; font-style: normal; font-size: 11.5px; color: var(--text-soft); }
.pd-legend i::before { content: ""; width: 11px; height: 11px; border-radius: 3px; }
.pd-legend .lg-period::before { background: var(--period-fill); }
.pd-legend .lg-pred::before { background: var(--primary-soft); }
.pd-legend .lg-fert::before { background: var(--ok-soft); box-shadow: inset 0 0 0 1px var(--ok-border); }
.pd-legend .lg-ovu::before { border-radius: 50%; border: 2px solid var(--ok); }

.pd-switchline { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.pd-switch-title { font-size: 15px; font-weight: 700; }
.seg-pd { display: inline-flex; background: var(--panel-soft); border-radius: 999px; padding: 3px; }
.seg-pd span { font-size: 13px; padding: 5px 18px; border-radius: 999px; color: var(--text-soft); cursor: pointer; user-select: none; }
.seg-pd span.active { background: var(--btn-grad); color: var(--on-primary); font-weight: 700; }

.pd-acc { padding: 0; }
.pd-acc-head {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between;
  padding: 15px 16px; font-size: 14px; font-weight: 700;
}
.pd-acc-head::-webkit-details-marker { display: none; }
.pd-acc-chev { display: flex; color: var(--text-soft); transition: transform .2s ease; }
.pd-acc[open] .pd-acc-chev { transform: rotate(90deg); color: var(--primary-deep); }
.pd-acc-body { padding: 0 16px 14px; }

.pd-sup-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.pd-sup {
  display: flex; align-items: center; gap: 6px;
  background: var(--panel-soft); border: 1px solid var(--border); border-radius: 12px; padding: 6px 8px;
}
.pd-sup-btn {
  width: 26px; height: 26px; flex: none; border-radius: 50%; cursor: pointer;
  background: var(--surface); border: 1px solid var(--border); color: var(--primary-deep);
  display: flex; align-items: center; justify-content: center;
}
.pd-sup-btn .ico { width: 14px; height: 14px; }
.pd-sup-name { flex: 1; text-align: center; font-size: 13px; font-weight: 600; }
.pd-sup-val { min-width: 14px; text-align: right; font-size: 12px; font-weight: 700; color: var(--primary-deep); }

.pd-row { display: flex; gap: 10px; padding: 10px 0; align-items: flex-start; border-bottom: 1px solid var(--border); }
.pd-row:last-child { border-bottom: none; }
.pd-label { flex: none; width: 58px; padding-top: 8px; font-size: 13.5px; }
.pd-chips { flex: 1; }
.pd-chips .chip { padding: 6px 12px; font-size: 12.5px; }

.pd-textarea {
  width: 100%; min-height: 62px; resize: vertical; font-family: inherit;
  border: 1px solid var(--border); border-radius: 13px; padding: 11px 12px;
  font-size: 13.5px; color: var(--text); background: var(--surface);
}

/* 经期模块男性只读：记录 / 打卡仅限女方，男性只能查看与改设置。
   只读态不渲染保存按钮，这里再把「月经来了吗」切换与用品加减收起，避免看着像能点。 */
.pd-ro-tip {
  display: flex; align-items: flex-start; gap: 10px;
  font-size: 12.5px; line-height: 1.7; color: var(--text-soft);
  background: var(--primary-soft); border: 1px solid var(--border);
}
.pd-ro-tip-text { flex: 1; min-width: 0; }
.pd-ro-tip-x {
  flex: none; width: 22px; height: 22px; margin-top: -2px;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%; background: transparent;
  color: var(--text-soft); font-size: 17px; line-height: 1; cursor: pointer;
}
.pd-ro-tip-x:hover { background: rgba(var(--primary-rgb), .18); color: var(--primary-deep); }
.pd-readonly .seg-pd { pointer-events: none; opacity: .8; }
.pd-readonly .pd-sup-btn { visibility: hidden; } /* 保留占位，数值仍在原来的网格位置 */
.pd-readonly .pd-textarea, .pd-readonly .pp-temp-input { pointer-events: none; }
.pd-readonly .chip:not(.chip-add) { cursor: default; } /* 记录选项 / 排卵试纸都不可选 */
.pd-readonly .chip-add, .pd-readonly .pd-del { display: none; } /* 选项的新增 / 删除也只限女方 */

.pd-hist-row { display: flex; align-items: center; gap: 10px; padding: 12px 0; border-bottom: 1px solid var(--border); }
/* 经期历史：条数随时间累积（两年就有 20+ 条），在卡片内独立滚动，别再把整页拉长。
   高度由 syncLogScroll 实测写入，这里给兜底上限。 */
.pd-hist-scroll { max-height: 60vh; overflow-y: auto; overscroll-behavior: contain; }
.pd-hist-row:last-child { border-bottom: none; }
.pd-hist-idx {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  background: var(--primary-soft); color: var(--primary-deep);
  font-size: 12px; font-weight: 700; display: flex; align-items: center; justify-content: center;
}
.pd-hist-main { flex: 1; }
.pd-hist-date { font-size: 13.5px; }
.pd-hist-meta { margin-top: 3px; font-size: 11.5px; color: var(--text-soft); }
.pd-hist-gap { flex: none; font-size: 12px; font-weight: 600; color: var(--primary-deep); }

.pd-trend-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.pd-trend-title { font-size: 15px; font-weight: 700; }
.pd-trend-refresh { display: flex; color: var(--primary-deep); cursor: pointer; }
.pd-trend-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.pd-trend-cell { display: flex; flex-direction: column; align-items: center; justify-content: center; background: var(--panel-soft); border-radius: 14px; padding: 15px 6px; text-align: center; }
.pd-trend-num { font-size: 22px; font-weight: 800; color: var(--primary-deep); }
.pd-trend-ring { line-height: 0; }
.pd-trend-cap { margin-top: 6px; font-size: 11.5px; color: var(--text-soft); }
.pd-trend-empty { margin-top: 18px; text-align: center; font-size: 12.5px; color: var(--text-soft); line-height: 1.8; }

/* ---- 分析页图表（内联 SVG，宽度由 JS 实测后写死） ---- */
.pd-ring { display: block; }
.pd-ring-num { fill: var(--primary-deep); font-size: 12px; font-weight: 700; }
.pd-chart-block { margin-top: 18px; }
.pd-chart-title { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0 2px 6px; font-size: 12.5px; font-weight: 700; color: var(--text-soft); }
.pd-chart-note { font-weight: 500; }
.pd-chart-empty { padding: 20px 0; text-align: center; font-size: 12.5px; color: var(--text-soft); line-height: 1.7; }
.pd-chart-svg { display: block; }
.pd-c-grid { stroke: var(--border); stroke-width: 1; }
.pd-c-ytick, .pd-c-xtick { fill: var(--text-soft); font-size: 10px; }
.pd-c-line { fill: none; stroke: var(--primary); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.pd-c-dot { fill: var(--primary); }
.pd-c-avg { stroke: var(--primary-deep); stroke-width: 1; stroke-dasharray: 4 4; opacity: .5; }
.pd-c-bar { fill: var(--primary); opacity: .85; }
.pd-c-val { fill: var(--primary-deep); font-size: 10px; font-weight: 600; }
.pd-dist-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 18px; }
.pd-dist-grid .pd-bar-list { margin-top: 6px; }
.pd-dist-cap { margin: 4px 2px 0; font-size: 12px; color: var(--text-soft); }
@media (max-width: 760px) {
  .pd-dist-grid { grid-template-columns: 1fr; }
  .pd-dist-cap { margin-top: 12px; }
}
.pd-bar-list { margin-top: 16px; }
.pd-bar-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; }
.pd-bar-cap { flex: none; width: 66px; font-size: 12px; color: var(--text-soft); }
.pd-bar-track { flex: 1; height: 10px; border-radius: 999px; background: var(--panel-soft); overflow: hidden; }
.pd-bar-fill { height: 100%; border-radius: 999px; background: var(--btn-grad); }
.pd-bar-val { flex: none; width: 44px; text-align: right; font-size: 12px; font-weight: 600; color: var(--primary-deep); }

/* 选项可自定义：行末「+」新增；PC 右键删除；移动端长按进入编辑态（选项右上角出 ×，「+」变「确认」） */
.pd-chips .chip { position: relative; user-select: none; -webkit-touch-callout: none; }
.pd-done { display: none; }
.pd-cols.pd-editing .pd-plus { display: none; }
.pd-cols.pd-editing .pd-done { display: inline; }
.pd-cols.pd-editing .chip-add { border-style: solid; border-color: var(--primary); color: var(--primary-deep); font-weight: 600; }
.pd-del {
  display: none; position: absolute; top: -6px; right: -6px;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--danger); color: #fff;
  font-size: 12px; line-height: 16px; text-align: center; font-style: normal; cursor: pointer;
}
.pd-cols.pd-editing .pd-del { display: block; }
.pd-opt-tip { font-size: 13px; color: var(--text-soft); margin-bottom: 10px; }
.pd-opt-input { min-height: auto; }

/* 通用浮层菜单（右键 / 长按出来的「修改 / 删除」）：层级要盖住照片查看器(.vw 是 fixed 200)，
   否则在查看器里点评论「更多」时菜单会被查看器整层挡住，看着像「点了没反应」；
   仍低于顶栏悬浮层与日期面板之外的更高层。 */
.ctx-menu {
  position: fixed; z-index: 260; min-width: 104px; padding: 4px;
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: var(--shadow-float);
}
.ctx-item { padding: 9px 14px; border-radius: 9px; font-size: 13.5px; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.ctx-item:hover { background: var(--panel-soft); color: var(--primary-deep); }
.ctx-item.on { color: var(--primary-deep); }
.ctx-check { width: 14px; height: 14px; flex: none; }
.ctx-item.danger { color: var(--danger); }
.ctx-item.danger:hover { background: rgba(229, 72, 77, .08); color: var(--danger); }

/* 未来日期不能记录：保存按钮置灰（配合 .is-locked 的降透明度，做出"禁用"观感但仍可点击出提示） */
.pd-save-future { background: var(--switch-track); color: var(--text-soft); box-shadow: none; }

/* AI 小贴士卡：标题在左、场景标签在右 */
.pd-tips-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.pd-tips-title { font-size: 15px; font-weight: 700; }
.pd-tips-kind {
  padding: 3px 10px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600; color: var(--primary-deep);
  background: var(--panel-soft); border: 1px solid var(--border);
}
.pd-tips-kind:empty { display: none; }
.pd-tips-text { font-size: 14px; line-height: 1.75; color: var(--text); }
.pd-tips-time { margin-top: 8px; font-size: 11px; color: var(--text-soft); }
.pd-tips-loading, .pd-tips-empty { font-size: 13px; color: var(--text-soft); }
.pd-tips-err { font-size: 13px; color: var(--danger-ink); line-height: 1.6; }

/* ===== 经期记录：对齐设计稿（PC 页头 / 衬线标题 / 轻底概览 / 指标化用品） ===== */
.pd-pagehead { display: block; margin-bottom: 12px; }
.pd-pagehead .t { display: none; }
.pd-pagehead .acts { display: block; }
.pd-page .pd-nav { margin-bottom: 0; }
.pd-page .pd-nav .chip {
  flex: none; height: 30px; padding: 0 12px;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--card); color: var(--text-soft);
  font-size: 12px; font-weight: 500; white-space: nowrap;
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
}
.pd-page .pd-nav .chip.active {
  background: var(--btn-grad); border-color: transparent;
  color: var(--on-primary); font-weight: 600;
}
.pd-page .pd-nav .chip.gear {
  width: 30px; padding: 0; border-radius: 50%;
  border: 1px solid var(--border); background: var(--card); color: var(--text-soft);
}
.pd-page .pd-nav .chip.gear .ico { width: 15px; height: 15px; }
.pd-page .pd-nav .chip.gear.active {
  background: var(--btn-grad); color: var(--on-primary); border-color: transparent;
}

/* 记录页专属：概览卡改成轻底 + 衬线标题 + 圆形水滴 */
.pd-record .pd-hero {
  position: relative; overflow: hidden; padding: 17px;
  background: var(--primary-soft); color: var(--text);
  border: 1px solid rgba(var(--primary-rgb), .16); border-radius: 22px;
}
.pd-record .pd-hero-main {
  font-family: var(--font-serif); font-size: 22px; font-weight: 600;
  line-height: 1.25; letter-spacing: 0;
}
.pd-record .pd-hero-sub {
  margin-top: 6px; gap: 5px 12px;
  font-size: 12px; color: var(--text-soft); opacity: 1;
}
.pd-record .pd-hero-sub b { color: var(--primary-deep); font-weight: 600; }
.pd-record .pd-hero-ico {
  position: absolute; right: 14px; top: 16px;
  width: 44px; height: 44px; border-radius: 50%; opacity: 1;
  background: rgba(255, 255, 255, .55); color: var(--primary-deep);
  display: grid; place-items: center;
}
.pd-record .pd-hero-text { padding-right: 56px; }
.pd-record .pd-hero-ico .ico { width: 22px; height: 22px; }

.pd-record .pd-grid { gap: 3px; }
.pd-record .pd-cal-title { font-size: 14px; font-weight: 600; }
.pd-record .pd-wk span { font-size: 11px; }
.pd-record .pd-d .pd-n { border-radius: 9px; font-size: 13.5px; }
.pd-record .pd-legend i { font-size: 11px; }
.pd-record .pd-d.is-pred .pd-n { border: 1px dashed rgba(var(--primary-rgb), .45); }

.pd-record .pd-switch-title { font-size: 14px; font-weight: 600; }
.pd-record .seg-pd span { font-size: 12.5px; padding: 5px 16px; }

.pd-record .pd-tips-card {
  background: rgba(191, 154, 107, .08);
  border-color: rgba(191, 154, 107, .26); border-radius: 16px;
}
.pd-record .pd-tips-title { font-size: 13.5px; font-weight: 600; }
.pd-record .pd-tips-kind {
  padding: 2px 8px; font-size: 10px; font-weight: 500;
  color: var(--primary-deep); background: var(--card);
  border-color: rgba(191, 154, 107, .26);
}
.pd-record .pd-tips-text { font-size: 13px; line-height: 1.8; }

/* 卫生用品：每个用品做成「小号步进器 + 大号衬线数字 + 名称」的指标块 */
.pd-record .pd-sup-grid { grid-template-columns: repeat(2, 1fr); gap: 8px; }
.pd-record .pd-sup {
  display: grid; grid-template-columns: 22px minmax(0, 1fr) 22px; grid-template-rows: auto auto;
  align-items: center; justify-items: center; gap: 2px 4px;
  padding: 9px 6px; border-radius: 14px;
  background: var(--panel-soft); border: 1px solid var(--border);
}
.pd-record .pd-sup-btn { width: 22px; height: 22px; }
.pd-record .pd-sup-btn .ico { width: 12px; height: 12px; }
.pd-record .pd-sup-btn[data-pd-sup-minus] { grid-column: 1; grid-row: 1; }
.pd-record .pd-sup-btn[data-pd-sup-plus] { grid-column: 3; grid-row: 1; }
.pd-record .pd-sup-name {
  grid-column: 2; grid-row: 2; font-size: 10.5px; font-weight: 500; color: var(--text-soft);
}
.pd-record .pd-sup-val {
  grid-column: 2; grid-row: 1; min-width: 0; text-align: center;
  font-family: var(--font-serif); font-size: 18px; font-weight: 600; color: var(--text);
}

.pd-record .pd-acc-head { font-size: 14px; font-weight: 600; }
.pd-record .pd-label { width: 52px; padding-top: 7px; font-size: 12px; color: var(--text-soft); }
.pd-record .pd-chips .chip { font-size: 12px; padding: 5px 11px; }
.pd-record #pdSave { height: 44px; border-radius: 14px; font-size: 13.5px; }

@media (min-width: 1024px) {
  .pd-pagehead { display: flex; align-items: flex-end; gap: 24px; margin-bottom: 16px; }
  .pd-pagehead .t { display: block; flex: none; }
  .pd-pagehead .eyebrow {
    margin: 0 0 4px; font-size: 9px; font-weight: 600;
    letter-spacing: .22em; text-transform: uppercase; color: var(--text-soft);
  }
  .pd-pagehead h2 {
    margin: 0; font-family: var(--font-serif);
    font-size: 25px; font-weight: 600; line-height: 1.15; letter-spacing: -.01em; color: var(--text);
  }
  .pd-pagehead .acts { flex: 1; min-width: 0; display: flex; justify-content: flex-end; }
  .pd-page .pd-nav { width: auto; justify-content: flex-end; }
  .pd-page .pd-nav .chip.gear {
    width: auto; padding: 0 12px; border-radius: 999px;
    position: static; margin-left: 8px;
  }
  .pd-page .pd-nav .chip.gear::after { content: "设置"; font-size: 12px; }
  .pd-record .pd-sup-grid { grid-template-columns: repeat(3, 1fr); }
  body.period-page .topbar-title { visibility: hidden; }
}


/* 首页经期提醒：经期中常驻在顶部卡片下方，点整卡进经期记录页 */
#pdHomeRemind:not(:empty) { margin-top: 14px; }
.pd-hr { display: flex; align-items: center; gap: 12px; cursor: pointer; }
.pd-hr-ico {
  width: 40px; height: 40px; border-radius: 13px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--panel-soft); color: var(--primary-deep);
}
.pd-hr-ico .ico { width: 22px; height: 22px; }
.pd-hr-main { flex: 1; min-width: 0; }
.pd-hr-title { font-size: 14.5px; font-weight: 700; }
.pd-hr-sub { font-size: 12.5px; color: var(--text-soft); margin-top: 3px; }
.pd-hr-go { flex: none; font-size: 12.5px; font-weight: 600; color: var(--primary-deep); }

/* 首页提醒区：移动端上下堆叠；PC 端并排两列 —— 左列「经期 + 生育计划」纵向堆叠，右列「打卡提醒」独占一列。
   容器由 renderHome 的 notice 区块给出（.home-remind-grid > 两个 .home-remind-col）。 */
@media (min-width: 1024px) {
  .home-remind-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
    /* 两列等高：短的一列同样撑到行高，左右两张提醒卡上下对齐（此前 start 时短的只到内容高） */
    align-items: stretch;
    margin-top: 14px;
    /* 列内单卡的 margin-bottom 已被归零，这里补回提醒区整体与下方模块区的间距 */
    margin-bottom: 14px;
  }
  /* 两列都为空时不占用首页高度 */
  .home-remind-grid:not(:has(.home-remind-col:not(:empty))) { display: none; }
  .home-remind-col { display: flex; flex-direction: column; gap: 14px; }
  .home-remind-col .card { margin-bottom: 0; }
  /* 列间距由网格 gap 提供，去掉单卡上下外边距，避免左列被挤出等高（下行同理） */
  .home-remind-grid #pdHomeRemind { margin-top: 0; margin-bottom: 0; }
  /* 右列「打卡提醒」列内只有一张卡：撑满列高，与左列整卡 #pdHomeRemind 等高 */
  .home-remind-col:not(#pdHomeRemind) > .card { height: 100%; }
}

/* 历史：整行可点开某次经期的每日明细 */
.pd-hist-row[data-pd-cy] { cursor: pointer; padding-left: 8px; padding-right: 8px; margin: 0 -8px; border-radius: 10px; }
.pd-hist-row[data-pd-cy]:hover { background: var(--panel-soft); }
.pd-hist-go { display: flex; color: var(--text-soft); }
.pd-hd-day { padding: 10px 0; border-bottom: 1px solid var(--border); }
.pd-hd-day:last-child { border-bottom: none; }
.pd-hd-date { font-size: 13.5px; font-weight: 600; margin-bottom: 7px; }
.pd-hd-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.pd-hd-tags .chip-static { font-size: 11.5px; padding: 4px 10px; }
.pd-hd-empty { font-size: 12.5px; color: var(--text-soft); }

@media (min-width: 1024px) {
  .pd-cols { display: grid; grid-template-columns: 388px minmax(0, 1fr); gap: 20px; align-items: start; }
  .pd-sup-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ================= 生育计划（备孕 / 避孕 / 吃药打卡 / 设置） =================
   复用经期模块的 .pd-hero / .pd-cols / .pd-d 等结构，仅按设计稿补配色与新增组件样式；
   新增类统一 pp- 前缀（开关用 pp-sw，避免与既有的 .hk-switch .sw / .ck-bb-sw .sw 撞样式）。 */

/* 页签排：单行横向滚动，齿轮贴最右 */
.pd-nav { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.pd-nav::-webkit-scrollbar { display: none; }
/* 收紧内边距：6 个页签（记录/历史/分析 + 备孕，或 + 避孕/吃药）在 375px 宽下也能一行放下；
   否则会横向溢出，齿轮被迫跟着一起滚，切页时看起来就是整行在左右跳 */
.pd-nav .chip { flex: none; white-space: nowrap; padding: 7px 12px; }
/* 齿轮吸在右侧：不论当前页有几个页签、有没有横向溢出，位置都固定，切页时不左右跳。
   无描边、无实心底 —— 齿轮就是一枚图标。（底色写 --bg 不是为了好看：吸住时必须挡住
   从下面滑过去的页签，而 --bg 正好等于页面底色，肉眼看不出来。） */
.pd-nav .chip.gear {
  position: sticky; right: 0; margin-left: auto; padding: 7px 10px;
  display: inline-flex; align-items: center;
  color: var(--primary-deep); border-color: transparent;
  background: var(--bg);
}
.pd-nav .chip.gear .ico { width: 16px; height: 16px; }
/* 这里不再有 .active 覆盖：既然去掉了实心粉底，选中态就没有可换的底了。
   也绝不能再写 color:#fff —— 没有底色时白图标会直接消失。 */

/* 卡片小标题 / 徽标 */
.pp-sub { display: flex; align-items: center; gap: 8px; margin: 0 2px 12px; font-size: 14px; font-weight: 700; }
.pp-sub .ico { width: 18px; height: 18px; color: var(--primary-deep); flex: none; }
.pp-badge { font-size: 10.5px; font-weight: 600; color: var(--primary-deep); background: var(--panel-soft); border: 1px solid var(--border); padding: 2px 8px; border-radius: 999px; white-space: nowrap; }
.pp-badge.gray { color: var(--text-soft); }
.pp-right { margin-left: auto; }

/* 记录页：生育计划开关卡 */
.plan-row { display: flex; align-items: center; gap: 12px; padding: 12px 2px; border-bottom: 1px solid var(--border); }
.plan-row:last-of-type { border-bottom: none; }
.plan-ico { flex: none; width: 34px; height: 34px; border-radius: 11px; background: var(--panel-soft); color: var(--primary-deep); display: flex; align-items: center; justify-content: center; }
.plan-ico .ico { width: 19px; height: 19px; }
.plan-txt { flex: 1; min-width: 0; }
.plan-name { font-size: 14px; font-weight: 700; }
.plan-desc { font-size: 11.5px; color: var(--text-soft); margin-top: 3px; line-height: 1.5; }

/* 设置页：卫生用品记录入口 + 管理弹窗列表 */
.sup-entry { cursor: pointer; }
.sup-entry:hover .plan-name { color: var(--primary-deep); }
.sup-list { display: flex; flex-direction: column; gap: 10px; }
/* 每项是一张卡片。底色用 --bg 而不是 --card：这张列表本身挂在一张 .card 里，
   同用 --card 会与父容器连成一片、看不出卡片边界（深色主题同理）。 */
/* 每项的明细直接摊在名称下方（一条一行），所以整项顶部对齐；
   右侧不再有「点进去」的箭头——点这一项是弹窗修改（见 supOpenForm）。 */
.sup-item { display: flex; align-items: flex-start; gap: 10px; padding: 12px 14px; cursor: pointer;
  background: var(--bg); border: 1px solid var(--border); border-radius: 14px;
  transition: border-color .15s; }
/* 整张卡都可点（弹窗修改），给个悬停反馈，免得看不出它是可点的 */
.sup-item:hover { border-color: var(--primary); }
.sup-item-main { flex: 1; min-width: 0; }
.sup-item-name { font-size: 14px; font-weight: 700; }
/* 明细自适应铺开（每格至少 150px）：宽屏一行就能放下 4 条，卡片高度压掉四成；
   窄屏自动退成 2 列 / 1 列，不用额外写媒体查询 */
.sup-item-info { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 4px 16px; margin-top: 6px; }
.sup-info-row { display: flex; gap: 8px; font-size: 12px; line-height: 1.6; }
.sup-info-k { flex: none; width: 5.5em; color: var(--text-soft); }
.sup-info-v { min-width: 0; color: var(--text); }
.sup-del { color: #d9536f; border-color: #ffd7e0; }

/* 开关（生育计划开关 / 测体温提醒）：自己一套样式，不依赖全站 .sw */
.pp-sw { width: 46px; height: 27px; border-radius: 999px; background: var(--switch-track); position: relative; flex: none; cursor: pointer; transition: background .2s; }
.pp-sw::after { content: ""; position: absolute; top: 3px; left: 3px; width: 21px; height: 21px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(176, 53, 91, .16); transition: left .2s; }
.pp-sw.on { background: var(--btn-grad); }
.pp-sw.on::after { left: 22px; }

/* 说明 hint（虚线小字块） */
.hint { font-size: 12px; color: var(--text-soft); line-height: 1.7; background: var(--panel-soft); border: 1px dashed var(--primary-soft); border-radius: 12px; padding: 11px 13px; margin-top: 10px; }
.hint:empty { display: none; }
.hint.warn { color: var(--overdue-ink); background: var(--overdue-soft); border-color: var(--overdue-border); }
.pp-hint-ico { display: inline-flex; vertical-align: -2px; margin-right: 3px; color: var(--overdue-ink); }
.pp-hint-ico .ico { width: 13px; height: 13px; }

/* 吃药页：hero 内的打卡控件 */
.pp-hero-ck { display: flex; align-items: center; gap: 10px; margin-top: 11px; padding-top: 11px; border-top: 1px solid rgba(255, 255, 255, .35); cursor: pointer; }
.pp-hc-ico { flex: none; width: 30px; height: 30px; border-radius: 50%; background: rgba(255, 255, 255, .24); display: flex; align-items: center; justify-content: center; }
.pp-hc-ico .ico { width: 17px; height: 17px; }
.pp-hc-txt { flex: 1; font-size: 12.5px; opacity: .95; line-height: 1.5; }
.pp-hc-badge { flex: none; font-size: 11.5px; font-weight: 700; background: #fff; color: var(--primary-deep); padding: 6px 12px; border-radius: 999px; }

/* 设置页：分组标题（卡片内 .pp-sub，图标在 app.js 里）/ 设置行 / 数字步进 */
.set-row { display: flex; align-items: center; gap: 10px; padding: 12px 2px; border-bottom: 1px solid var(--border); }
.set-row:last-child { border-bottom: none; }
.set-row .label { flex: none; width: 90px; font-size: 13.5px; }
.set-row .val { flex: 1; text-align: right; font-size: 13.5px; font-weight: 600; }
.set-row .val.soft { color: var(--text-soft); font-weight: 400; }
.set-row .val.cval { color: var(--primary-deep); font-weight: 700; }
.set-num { flex: 1; display: flex; align-items: center; justify-content: flex-end; gap: 12px; }
.set-num button { width: 27px; height: 27px; border-radius: 50%; border: 1px solid var(--border); background: var(--surface); color: var(--primary-deep); display: flex; align-items: center; justify-content: center; cursor: pointer; padding: 0; }
.set-num button .ico { width: 14px; height: 14px; }
.set-num .v { min-width: 28px; text-align: center; font-size: 15px; font-weight: 800; color: var(--primary-deep); }
.pp-unit { margin-left: -6px; font-size: 12px; color: var(--text-soft); }
.pp-input { flex: 1; min-width: 0; text-align: right; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); font-family: inherit; font-size: 13.5px; font-weight: 600; color: var(--primary-deep); padding: 7px 10px; }
.pp-input:focus { outline: none; border-color: var(--primary); }
.pp-input::placeholder { color: var(--text-soft); font-weight: 400; }
/* 数字输入框（库存卡的「当前盒剩余」）：去掉浏览器原生步进箭头，与站内自绘的步进组件观感保持一致 */
.pp-num-input::-webkit-outer-spin-button,
.pp-num-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.pp-num-input { -moz-appearance: textfield; appearance: textfield; }

/* 月历配色：安全期（men/risk/safe）与吃药打卡（take/miss/pause/off） */
/* 同房标记改为一颗心：格子里压在数字下方，图例里跟在「同房」前面（原来的小红点已弃用） */
.pd-d .pp-sex-ico { position: absolute; bottom: 1px; left: 50%; transform: translateX(-50%); display: flex; color: var(--danger); }
.pd-d .pp-sex-ico .ico { width: 9px; height: 9px; }
.pd-d.men .pd-n { background: var(--period-fill); color: var(--on-primary); font-weight: 700; }
.pd-d.risk .pd-n { background: var(--danger-soft); color: var(--danger-ink); font-weight: 700; }
.pd-d.safe .pd-n { background: var(--ok-soft); color: var(--ok-ink); }
.pd-d.take .pd-n { background: var(--btn-grad); color: var(--on-primary); font-weight: 700; }
.pd-d.miss .pd-n { background: var(--danger-soft); color: var(--danger-ink); font-weight: 700; box-shadow: inset 0 0 0 1.5px var(--danger); }
.pd-d.pause .pd-n { border: 1.5px dashed var(--primary); color: var(--primary-deep); }
.pd-d.off .pd-n { color: #d3c6cc; }
/* 节日 / 节气简称跟随格子底色自适应：深色或彩色填充底反白，
   浅色底用同色系深墨——否则「已吃」的渐变底上还压着主题色小字，基本看不清。 */
.pd-d.take .pd-fest-t,
.pd-d.men .pd-fest-t { color: rgba(255, 255, 255, .92); }
.pd-d.miss .pd-fest-t,
.pd-d.risk .pd-fest-t { color: var(--danger-ink); }
.pd-d.safe .pd-fest-t { color: var(--ok-ink); }
.pd-d.pause .pd-fest-t { color: var(--primary-deep); }
.pd-d.off .pd-fest-t { color: #d3c6cc; }
.pd-legend .lg-s::before { display: none; } /* 同房改用心形图标，不再用小圆点 */
.pd-legend .lg-s .ico { width: 11px; height: 11px; color: var(--danger); }
.pd-legend .lg-men::before { background: var(--period-fill); }
.pd-legend .lg-risk::before { background: var(--danger-soft); box-shadow: inset 0 0 0 1px var(--danger); }
.pd-legend .lg-safe::before { background: var(--ok-soft); box-shadow: inset 0 0 0 1px var(--ok-border); }
.pd-legend .lg-take::before { background: var(--btn-grad); }
.pd-legend .lg-miss::before { background: var(--danger-soft); box-shadow: inset 0 0 0 1px var(--danger); }
.pd-legend .lg-pause::before { background: var(--card); box-shadow: inset 0 0 0 1.5px var(--primary); }
.pd-legend .lg-off::before { background: var(--switch-track); }

/* 备孕页：图表宿主 / 进度指标卡 / 今日体温输入 */
/* 图表宿主：宽度由 JS 按内容盒实测，所以内边距写在这里而不是让 SVG 去凑 */
.pp-chart-wrap { background: var(--panel-soft); border-radius: 14px; padding: 10px 10px 6px; }
/* 备孕进度指标卡 */
.pp-metric-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.pp-metric { background: var(--panel-soft); border-radius: 12px; padding: 11px 4px; text-align: center; }
.pp-metric-num { font-size: 19px; font-weight: 800; color: var(--primary-deep); }
.pp-metric-cap { margin-top: 4px; font-size: 10.5px; color: var(--text-soft); }
/* 备孕页图表元素：易孕期底纹 / 排卵日竖线 / 体温折线 / 试纸折线 */
.pd-c-band { fill: var(--ok); opacity: .10; }
.pd-c-ovu { stroke: var(--ok-ink); stroke-width: 1.4; stroke-dasharray: 4 3; }
.pd-c-ovutag { fill: var(--ok-ink); font-size: 10px; font-weight: 700; }
.pd-c-temp { fill: none; stroke: var(--primary-deep); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.pd-c-tdot { fill: #fff; stroke: var(--primary-deep); stroke-width: 1.6; }
.pd-c-lh { fill: none; stroke: var(--primary); stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; }
.pd-c-lhdot { fill: #fff; stroke: var(--primary); stroke-width: 1.6; }
.pd-c-lhdot.strong { fill: var(--primary-deep); stroke: var(--primary-deep); }
@media (max-width: 760px) {
  .pp-metric-grid { grid-template-columns: repeat(2, 1fr); }
}
.pp-temp-empty { font-size: 12.5px; color: var(--text-soft); text-align: center; padding: 18px 6px; }
.pp-metric-row { display: flex; align-items: center; gap: 10px; padding: 11px 2px; border-top: 1px solid var(--border); }
.pp-metric-label { flex: none; font-size: 13px; font-weight: 600; }
.pp-metric-unit { font-size: 11.5px; color: var(--text-soft); }
.pp-temp-input { flex: 1; min-width: 0; text-align: right; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); font-family: inherit; font-size: 15px; font-weight: 800; color: var(--primary-deep); padding: 6px 10px; }
.pp-temp-input:focus { outline: none; border-color: var(--primary); }
.pp-chips-tight { flex-wrap: wrap; gap: 6px; }
/* 记录页「备孕记录」折叠块：首行紧贴标题，去掉多余的上分隔线与上内边距（标题本身已是分隔） */
.pd-acc-body .pp-metric-row:first-child { border-top: none; padding-top: 0; }

/* 列表条目（同房记录 / 紧急避孕 / 吃药打卡入口） */
.pp-row { display: flex; align-items: center; gap: 10px; padding: 11px 2px; border-bottom: 1px solid var(--border); }
.pp-row:last-child { border-bottom: none; }
.pp-row-main { flex: 1; min-width: 0; }
.pp-row-t { font-size: 13.5px; font-weight: 600; }
.pp-row-s { font-size: 11.5px; color: var(--text-soft); margin-top: 3px; }
.pp-row-empty { font-size: 12.5px; color: var(--text-soft); padding: 4px 0; }
.pp-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--primary-deep); flex: none; }
.pp-dot.fert { background: var(--primary-soft); box-shadow: inset 0 0 0 1px var(--primary); }
.pp-dot.sex { background: var(--danger); }
.pp-dot.gray { background: #ddd2d7; }

/* AI 建议卡 */
.pp-ai { border-radius: 14px; padding: 13px 14px; font-size: 13px; line-height: 1.85; background: var(--panel-soft); border: 1px solid var(--primary-soft); color: var(--text); }
.pp-ai-head { display: flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 700; color: var(--primary-deep); margin-bottom: 7px; }
.pp-ai-head .ico { width: 15px; height: 15px; }
.pp-ai-empty { font-size: 13px; color: var(--text-soft); line-height: 1.7; }

/* 避孕方式：有效性数字 + 进度条 */
.pp-eff { margin-top: 12px; }
.pp-eff-top { display: flex; align-items: baseline; gap: 6px; }
.pp-eff-num { font-size: 26px; font-weight: 800; color: var(--primary-deep); }
.pp-eff-cap { font-size: 11.5px; color: var(--text-soft); }
.pp-eff-cap b { color: var(--primary-deep); }
.pp-eff-bar { height: 9px; border-radius: 999px; background: var(--panel-soft); overflow: hidden; margin-top: 9px; }
.pp-eff-fill { height: 100%; border-radius: 999px; background: var(--btn-grad); }
.pp-eff-legend { display: flex; flex-wrap: wrap; gap: 10px 16px; margin-top: 10px; font-size: 11.5px; color: var(--text-soft); }
.pp-eff-legend b { color: var(--primary-deep); }

/* 卡片标题右侧的展开箭头（默认朝下，展开时旋转） */
.pp-chev { display: flex; color: var(--text-soft); flex: none; }
.pp-chev .ico { width: 16px; height: 16px; }

/* ---- 设置行里的「占满右侧」容器（日期 / 时间 / 下拉都放进来，统一右对齐） ---- */
.pp-grow { flex: 1; min-width: 0; display: flex; justify-content: flex-end; align-items: center; }
.pp-time-pick { justify-content: flex-end; }

/* ---- 站内下拉：仿日期选择器做「只读输入框 + 弹出面板」，不用原生 select ---- */
.pp-dd { position: relative; z-index: var(--z-dropdown); width: 100%; display: flex; justify-content: flex-end; }
/* 与 .dd 同理：展开时抬 1 级 */
.pp-dd.pp-dd-open { z-index: calc(var(--z-dropdown) + 1); }
.pp-dd-input {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
  font-size: 13.5px; font-weight: 600; color: var(--primary-deep);
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
  padding: 7px 10px; cursor: pointer;
}
.pp-dd-input span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pp-dd-input .ico { width: 15px; height: 15px; flex: none; color: var(--text-soft); }
/* 面板宽度取整行：避免比输入框宽而在两栏布局里被裁掉 */
.pp-dd-panel {
  position: absolute; top: calc(100% + 6px); right: 0; width: 100%; z-index: var(--z-dropdown);
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: var(--shadow-float); padding: 5px;
}
.pp-dd-opt { font-size: 13.5px; padding: 9px 12px; border-radius: 9px; cursor: pointer; }
.pp-dd-opt:hover { background: var(--panel-soft); }
.pp-dd-opt.on { color: var(--primary-deep); font-weight: 700; background: var(--panel-soft); }

/* ---- 设置行里的站内日期选择器 ----
   日期选择器自带「100% 宽 + 12/14px 大内边距 + 15px 字」，直接塞进设置行会比同行控件高一大截；
   而且它的日历面板是 left:0 right:0（跟着输入框宽度），在设置行里被压到只剩文字宽 → 日历挤成一团。
   这里把输入框收成与下拉/时间选择器一致，并给面板一个够用的固定宽度。 */
.set-row .dp { flex: 1; min-width: 0; display: flex; justify-content: flex-end; }
.set-row .dp-input {
  width: auto; max-width: 100%; padding: 7px 10px; border-radius: 10px;
  font-size: 13.5px; font-weight: 600; color: var(--primary-deep); text-align: right;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.set-row .dp-panel { left: auto; right: 0; width: 264px; }

/* ================= 打卡计划 =================
   逾期 / 不可用两态沿用设计稿语义色：逾期=警示橙，待开始 / 暂停=中性灰；
   完成态复用主色，保持「单一强调色」。 */

/* ---- 页面骨架：可滚动正文 + 底部固定操作条（移动端贴底，PC 回落内容流） ---- */
.ck-body { padding-bottom: 12px; }
.ck-bottombar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px));
  background: var(--tabbar-bg, rgba(255, 255, 255, .96));
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--border);
}
.ck-bb-main {
  flex: 1; min-height: 50px; border: none; border-radius: 15px;
  background: var(--btn-grad); color: var(--on-primary); font-size: 15.5px; font-weight: 700;
  font-family: inherit; cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  box-shadow: var(--shadow-accent);
}
.ck-bb-main .ico { width: 18px; height: 18px; }
.ck-bb-main[disabled] { background: var(--panel-soft); color: var(--text-soft); box-shadow: none; cursor: default; }
.ck-bb-side {
  flex: none; min-height: 50px; padding: 0 18px; border-radius: 15px;
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
  font-size: 14.5px; font-family: inherit; cursor: pointer;
}
.ck-bb-round {
  flex: none; width: 64px; height: 64px; border-radius: 50%; border: none;
  background: var(--btn-grad); color: #fff; font-size: 12px; font-weight: 700;
  font-family: inherit; cursor: pointer; line-height: 1.15;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  box-shadow: var(--shadow-accent-strong);
}
.ck-bb-round .ico { width: 20px; height: 20px; }
.ck-bb-sw { display: flex; align-items: center; gap: 7px; flex: none; }
.ck-bb-sw .sw { width: 42px; height: 25px; }
.ck-bb-sw .sw::after { width: 19px; height: 19px; }
.ck-bb-sw .sw.on::after { left: 20px; }
.ck-bb-sw-t { font-size: 11px; color: var(--text-soft); line-height: 1.3; text-align: center; }

/* ---- 步骤胶囊（导航右侧 / 正文顶部） ---- */
.ck-pill {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; color: var(--primary-deep);
  background: var(--panel-soft); border: 1px solid var(--border);
  padding: 4px 9px; border-radius: 999px;
}
.ck-topline { display: flex; justify-content: flex-end; align-items: center; margin-bottom: 12px; }

/* ---- 胶囊分段（全部 / 进行中 / 已完成 / 已逾期） ---- */
.ck-seg { display: inline-flex; gap: 4px; background: var(--panel-soft); border-radius: 999px; padding: 3px; max-width: 100%; overflow-x: auto; }
.ck-seg::-webkit-scrollbar { display: none; }
.ck-seg span { flex: none; font-size: 12px; padding: 6px 12px; border-radius: 999px; color: var(--text-soft); white-space: nowrap; cursor: pointer; }
.ck-seg span.on { background: var(--btn-grad); color: var(--on-primary); font-weight: 700; }

/* ---- 卡片内的小按钮（列表「去打卡」/「查看」） ---- */
.ck-mini {
  height: 40px; padding: 0 16px; border-radius: 12px; border: none;
  background: var(--btn-grad); color: #fff; font-size: 13px; font-weight: 700;
  font-family: inherit; cursor: pointer;
  box-shadow: var(--shadow-accent);
}
.ck-mini.ghost { background: var(--surface); color: var(--primary-deep); border: 1px solid var(--primary); box-shadow: none; }
.ck-mini.grey { background: var(--switch-track); color: var(--text-soft); box-shadow: none; cursor: default; }

/* ---- 顶部：状态卡 + 正方形新建按钮 ---- */
.ck-top { display: flex; gap: 12px; align-items: stretch; }
.ck-top .ck-hero { flex: 1; min-width: 0; }
.ck-new-sq {
  flex: none; align-self: stretch; aspect-ratio: 1 / 1; min-width: 76px;
  border: none; border-radius: var(--radius, 18px);
  background: var(--btn-grad); color: #fff;
  font-family: inherit; cursor: pointer; text-align: center;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  padding: 8px; box-shadow: var(--shadow-accent);
}
.ck-new-sq .ico { width: 26px; height: 26px; flex: none; }

.ck-hero {
  position: relative;
  background: linear-gradient(135deg, var(--primary), #ffb3c6 55%, #ffc9d5);
  color: #fff; border-radius: var(--radius, 18px); padding: 16px;
  box-shadow: var(--shadow-accent);
}
.ck-hero-main { font-size: 19px; font-weight: 800; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* 白底卡片右上角的浮按钮（如编辑计划页的删除）：卡面要成为定位参照 */
.card.ck-card-corner { position: relative; }
.ck-card-del {
  position: absolute; top: 10px; right: 10px; z-index: 2;
  width: 32px; height: 32px; padding: 0; border: none; border-radius: 50%;
  background: var(--panel-soft); color: var(--danger); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.ck-card-del:hover { background: rgba(229, 72, 77, .14); }
.ck-card-del .ico { width: 18px; height: 18px; }
/* 弹窗里的操作菜单（由列表卡片长按 / 右键唤出） */
.ck-menu { display: flex; flex-direction: column; gap: 6px; }
.ck-menu-i {
  display: flex; align-items: center; gap: 10px; width: 100%;
  min-height: 48px; padding: 0 14px; border: none; border-radius: 12px;
  background: var(--panel-soft); color: var(--text); font-size: 14.5px;
  font-family: inherit; text-align: left; cursor: pointer;
}
.ck-menu-i .ico { width: 18px; height: 18px; color: var(--primary-deep); flex: none; }
/* 相册选择项：左侧显示相册封面（无封面时回退为通用图片图标） */
.ck-menu-thumb {
  width: 34px; height: 34px; flex: none; overflow: hidden;
  border-radius: 8px; background: var(--bg);
}
.ck-menu-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ck-menu-i.ck-danger { color: #e8734a; }
.ck-menu-i.ck-danger .ico { color: #e8734a; }
.ck-hero-sub { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 14px; font-size: 12px; opacity: .94; }
.ck-hero-sub b { font-weight: 700; }
/* 粉色状态卡里的徽章：白底 + 语义色文字。
   必须逐个状态写：.ck-hero .ck-badge 的特异性高于 .ck-b-done，
   只写前者会把「今日已完成」压成白底白字（看不见）。 */
/* 粉底 hero 里的徽章：底是固定的白色，所以墨色也必须用「白底上可读」的值——
   不能跟着主题换（深色主题的 --primary-deep 是亮粉，压在白底上只有 1.7:1） */
.ck-hero .ck-badge { border-color: transparent; }
.ck-hero .ck-b-todo,
.ck-hero .ck-b-done { background: #fff; color: var(--btn-grad); }
.ck-hero .ck-b-over { background: #fff; color: #a8441c; }
.ck-hero .ck-b-wait { background: rgba(255, 255, 255, .88); color: #6b5a60; }

.ck-toolbar { margin-top: 14px; margin-bottom: 16px; }
/* 状态卡与紧随其后的卡片之间补间距：.card 只有 margin-bottom，紧贴会挤在一起 */
.ck-hero + .card { margin-top: 14px; }

.ck-list { display: grid; gap: 8px; }
.ck-card { display: flex; gap: 12px; align-items: center; padding: 13px 12px; cursor: pointer; }
.ck-list .ck-card { margin-top: 0; }
.ck-card.ck-over { border-color: var(--overdue-border); }
.ck-card.ck-done { opacity: .88; }
.ck-card-ico {
  width: 44px; height: 44px; border-radius: 14px; flex: none;
  background: var(--panel-soft); color: var(--primary-deep);
  display: flex; align-items: center; justify-content: center;
}
.ck-card.ck-over .ck-card-ico { background: var(--overdue-soft); color: var(--overdue-ink); }
.ck-card-main { flex: 1; min-width: 0; }
.ck-card-title { font-size: 15px; font-weight: 700; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.ck-card-sub { font-size: 12px; color: var(--text-soft); margin-top: 5px; line-height: 1.6; }
.ck-card-act { flex: none; }
.ck-card-act .btn { min-height: 40px; padding: 9px 14px; }

.ck-badge {
  font-size: 11px; font-weight: 600; padding: 3px 9px; border-radius: 999px;
  border: 1px solid transparent; white-space: nowrap;
}
.ck-b-todo { color: var(--primary-deep); background: var(--surface); border-color: var(--primary); }
.ck-b-done { color: var(--on-primary); background: var(--btn-grad); border-color: var(--btn-grad); }
.ck-b-over { color: var(--overdue-ink); background: var(--overdue-soft); border-color: var(--overdue-border); }
.ck-b-wait { color: var(--text-soft); background: var(--panel-soft); border-color: var(--border); }

.ck-bar { height: 8px; border-radius: 999px; background: var(--panel-soft); overflow: hidden; margin-top: 8px; }
.ck-bar i { display: block; height: 100%; border-radius: 999px; background: linear-gradient(135deg, var(--primary), var(--primary-deep)); }
.ck-bar-hero { background: rgba(255, 255, 255, .38); margin-top: 12px; }
.ck-bar-hero i { background: #fff; }

.ck-empty { padding-top: 32px; }
.ck-empty-t { font-size: 16px; font-weight: 700; color: var(--text); margin-top: 12px; }
.ck-empty-d { font-size: 12.5px; line-height: 1.8; margin: 8px auto 0; max-width: 260px; }
.ck-new { margin-top: 14px; display: flex; align-items: center; justify-content: center; gap: 6px; }

/* 键值卡 */
.ck-kv { padding: 4px 12px; }
.ck-kv-title { font-size: 14px; font-weight: 700; padding: 12px 2px 6px; }
.ck-kv-row { display: flex; align-items: center; gap: 10px; padding: 12px 2px; border-bottom: 1px solid var(--border); min-height: 48px; }
.ck-kv-row:last-child { border-bottom: none; }
.ck-kv-ico { width: 20px; height: 20px; color: var(--primary-deep); flex: none; display: flex; }
.ck-kv-ico .ico { width: 20px; height: 20px; }
.ck-kv-label { flex: 1; font-size: 14px; }
.ck-kv-value { font-size: 13px; color: var(--text-soft); text-align: right; }
.ck-kv-chev { color: #d3c4ca; flex: none; display: flex; }
.ck-kv-chev .ico { width: 16px; height: 16px; }
.ck-kv-row.ck-danger .ck-kv-ico, .ck-kv-row.ck-danger .ck-kv-label { color: var(--overdue-ink); }
.ck-sec-title { font-size: 14px; font-weight: 700; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ck-sec-title .ico { width: 16px; height: 16px; color: var(--primary-deep); flex: none; }

/* ===== 打卡详情页 =====
   移动端单列：hero → 今日打卡 → 关键信息 → 日历热力图 → 打卡记录 → 计划操作；
   PC（≥1024px）改为左右两栏（见本区块末尾的媒体查询）。 */
/* 今日打卡大圆：可打卡时是入口（点击进打卡流程），已打卡换成实线圆 */
.dash[data-ck-run] { cursor: pointer; }
.dash.done { border-style: solid; border-color: var(--primary); background: #fff; }
/* 关键信息卡里的操作行（编辑 / 提醒与同步 / 暂停 / 删除） */
.ck-kv-link { cursor: pointer; }
.ck-kv-link:hover { background: var(--panel-soft); }

/* 今日打卡 / 记录 */
.ck-today-c { font-size: 13px; line-height: 1.7; margin-top: 10px; color: var(--text); }
.ck-rec-sub-c { justify-content: center; }
.ck-rec-time { font-size: 12px; color: var(--text-soft); flex: none; margin-left: 8px; }
.ck-rec-link { cursor: pointer; }
/* 打卡列表页：移动端只显示计划列表；PC 才把「全部打卡记录」放到计划列表右侧（见 PC 媒体查询） */
.ck-main { display: block; }
#ckRecBox { display: none; }

/* 近 30 天打卡日历（7 列网格） */
.ck-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
.ck-cell {
  aspect-ratio: 1; border-radius: 9px; background: var(--panel-soft); border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center; font-size: 11px; color: var(--text-soft);
}
.ck-cell.on { background: var(--btn-grad); border-color: var(--btn-grad); color: var(--on-primary); font-weight: 700; }
.ck-cell.today { outline: 2px solid var(--primary); outline-offset: 1px; }
.ck-legend { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 12px; font-size: 11.5px; color: var(--text-soft); }
.ck-legend i { display: inline-block; width: 12px; height: 12px; border-radius: 4px; margin-right: 5px; vertical-align: -1px; background: var(--panel-soft); border: 1px solid var(--border); }
.ck-legend i.on { background: var(--btn-grad); border-color: var(--btn-grad); }
.ck-legend i.today { outline: 2px solid var(--primary); outline-offset: 1px; }

/* 连续 / 累计统计 */
.ck-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 14px; }
.ck-stat { background: var(--panel-soft); border: 1px solid var(--border); border-radius: 14px; padding: 11px 8px; text-align: center; }
.ck-stat b { display: block; font-size: 19px; color: var(--primary-deep); letter-spacing: .3px; }
.ck-stat span { font-size: 11px; color: var(--text-soft); }

/* PC：左右分栏（卡片自带 14px 下间距，这里只留列间距） */
@media (min-width: 1024px) {
  .ck-detail { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); column-gap: 18px; align-items: start; }
  .ck-detail .dash { width: 132px; height: 132px; }
  .ck-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.ck-thumbs { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin-top: 10px; }
.ck-thumb { width: 64px; height: 64px; border-radius: 10px; overflow: hidden; display: block; background: var(--panel-soft); }
.ck-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

.ck-rec { display: flex; gap: 10px; padding: 12px 2px; border-bottom: 1px solid var(--border); }
.ck-rec:last-child { border-bottom: none; }
.ck-rec-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--primary); flex: none; margin-top: 6px; }
.ck-rec-dot.ck-rec-makeup { background: #e8734a; }
.ck-rec-main { flex: 1; min-width: 0; }
.ck-rec-title { font-size: 13.5px; font-weight: 600; }
.ck-rec-sub { font-size: 12px; color: var(--text-soft); margin-top: 5px; line-height: 1.6; display: flex; align-items: center; gap: 4px; }
.ck-rec-sub .ico { width: 13px; height: 13px; }
.ck-rec-main .ck-thumbs { justify-content: flex-start; }
.ck-rec-del { border: none; background: none; color: var(--text-soft); padding: 8px; flex: none; cursor: pointer; display: flex; }
.ck-rec-del .ico { width: 16px; height: 16px; }

/* ===== 打卡列表页：对齐设计稿（轻底 hero + 胶囊筛选 + 图标卡 + 右栏日历） ===== */
.ck-page .ck-pagehead { display: none; }
.ck-page .ck-main { display: block; }
.ck-page .ck-col-main { min-width: 0; }
.ck-page .ck-hero {
  display: flex; align-items: center; gap: 12px;
  margin-top: 4px; padding: 18px; border-radius: 22px; overflow: hidden;
  border: 1px solid rgba(var(--primary-rgb), .16);
  background: linear-gradient(135deg,
    rgba(var(--primary-rgb), .22) 0%,
    rgba(var(--primary-rgb), .09) 55%,
    rgba(var(--primary-rgb), .15) 100%);
  color: var(--text); box-shadow: none;
}
.ck-page .ck-hero-copy { flex: 1; min-width: 0; }
.ck-page .ck-hero-copy h2 {
  margin: 0; font-family: var(--font-serif);
  font-size: 21px; font-weight: 600; line-height: 1.25; color: var(--text);
}
.ck-page .ck-hero-copy p { margin: 6px 0 0; font-size: 11.5px; line-height: 1.6; color: var(--text-soft); }
.ck-page .ck-add {
  width: 46px; height: 46px; flex: none;
  border: 0; border-radius: 15px; background: var(--btn-grad); color: var(--on-primary);
  display: grid; place-items: center; cursor: pointer;
  box-shadow: var(--shadow-accent);
}
.ck-page .ck-add svg { width: 20px; height: 20px; }
/* 新建计划按钮：移动端用「+」，PC 端换成沙漏图标（与设计稿一致） */
.ck-page .ck-add .ck-add-ico-pc { display: none; }
@media (min-width: 1024px) {
  .ck-page .ck-add .ck-add-ico-m { display: none; }
  .ck-page .ck-add .ck-add-ico-pc { display: block; width: 24px; height: 24px; }
}

.ck-page .ck-toolbar { display: flex; gap: 6px; margin: 14px 0 10px; overflow-x: auto; }
.ck-page .ck-filter {
  flex: none; height: 32px; padding: 0 13px;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface); color: var(--text-soft);
  font: inherit; font-size: 12px; cursor: pointer;
}
.ck-page .ck-filter b { margin-left: 4px; font-size: 10.5px; font-weight: 500; opacity: .6; }
.ck-page .ck-filter.is-on { background: var(--text); border-color: var(--text); color: var(--bg); }

.ck-page .ck-list { display: block; }
.ck-page .ck-card {
  display: flex; align-items: center; gap: 12px;
  margin: 0 0 10px; padding: 14px;
  border: 1px solid var(--border); border-radius: 18px;
  background: var(--card); box-shadow: var(--shadow); cursor: pointer;
}
.ck-page .ck-card:last-child { margin-bottom: 0; }
.ck-page .ck-card.ck-over { border-color: var(--overdue-border); }
.ck-page .ck-ic {
  width: 42px; height: 42px; flex: none; border-radius: 13px;
  background: var(--panel-soft); color: var(--primary-deep);
  display: grid; place-items: center;
}
.ck-page .ck-ic.rose { background: rgba(var(--primary-rgb), .12); color: var(--primary-deep); }
.ck-page .ck-ic.blue { background: rgba(91, 118, 145, .12); color: #5b7691; }
.ck-page .ck-ic.red { background: var(--overdue-soft); color: var(--overdue-ink); }
.ck-page .ck-ic .ico { width: 20px; height: 20px; }
.ck-page .ck-body { flex: 1; min-width: 0; }
.ck-page .ck-title { display: flex; align-items: center; gap: 6px; min-width: 0; }
.ck-page .ck-title b {
  min-width: 0; font-size: 14.5px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ck-page .ck-state {
  flex: none; height: 20px; padding: 0 7px; border-radius: 999px;
  background: var(--panel-soft); color: var(--text-soft);
  font-size: 10px; display: inline-flex; align-items: center;
}
.ck-page .ck-state.green { background: var(--ok-soft); color: var(--ok-ink); }
.ck-page .ck-state.red { background: var(--overdue-soft); color: var(--overdue-ink); }
.ck-page .ck-rhythm { margin-top: 4px; font-size: 11.5px; line-height: 1.5; color: var(--text-soft); }
.ck-page .ck-prog { height: 5px; margin-top: 7px; border-radius: 999px; background: var(--panel-soft); overflow: hidden; }
.ck-page .ck-prog i { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--primary), var(--primary-deep)); }
.ck-page .ck-data { margin-top: 6px; font-size: 11.5px; line-height: 1.5; color: var(--text-soft); }
.ck-page .ck-card-act { flex: none; }
.ck-page .ck-btn {
  height: 32px; padding: 0 13px; border: 0; border-radius: 10px;
  background: var(--btn-grad); color: var(--on-primary);
  font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
}
.ck-page .ck-btn.ghost { background: var(--surface); border: 1px solid var(--border); color: var(--text-soft); }

/* 右栏面板：日历 / 统计 / 全部记录。
   列表贴底时的圆角裁剪见全局 .log-clip（由 syncLogScroll 按需挂到面板上）。 */
.ck-page .pco-panel {
  padding: 15px; border: 1px solid var(--border); border-radius: 18px;
  background: var(--card); box-shadow: var(--shadow);
}
.ck-page .pco-panel + .pco-panel { margin-top: 12px; }
/* 「全部打卡记录」在面板内独立滚动：条数一多也不再把页面撑长。
   高度由 syncLogScroll 实测写入（面板内的滚动区会扣掉卡片剩余内边距）。 */
.ck-page .ck-rec-scroll { max-height: 40vh; overflow-y: auto; overscroll-behavior: contain; }
/* 大事记列表：同理在卡片内滚动，编辑页左侧列表不会无限拉长 */
.ab-tl-scroll { max-height: 46vh; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.ck-page .pco-panel h3 {
  margin: 0 0 10px; font-size: 11px; font-weight: 600; letter-spacing: .12em;
  color: var(--text-soft); display: flex; align-items: center; justify-content: space-between;
}
.ck-page .pco-panel h3 span { letter-spacing: 0; font-size: 11px; font-weight: 400; color: var(--primary-deep); }
.ck-page .ck-cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.ck-page .ck-cal i {
  aspect-ratio: 1; border-radius: 7px; background: var(--panel-soft);
  display: grid; place-items: center; font-style: normal;
  font-size: 11px; color: var(--text-soft);
}
.ck-page .ck-cal i.on { background: rgba(59, 165, 93, .14); color: #4d6b3a; font-weight: 600; }
.ck-page .ck-cal i.today { box-shadow: inset 0 0 0 1.5px var(--primary-deep); color: var(--primary-deep); font-weight: 600; }
.ck-page .ck-cal-legend { display: flex; gap: 12px; margin-top: 9px; font-size: 10.5px; color: var(--text-soft); }
.ck-page .ck-cal-legend i {
  width: 9px; height: 9px; border-radius: 3px; margin-right: 4px; vertical-align: -1px;
  background: rgba(59, 165, 93, .14); display: inline-block;
}
.ck-page .ck-cal-legend i.gray { background: var(--panel-soft); border: 1px solid var(--border); }
.ck-page .ck-stats4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin-top: 12px; }
.ck-page .ck-stats4 div { padding: 9px 4px; border-radius: 10px; background: var(--panel-soft); text-align: center; }
.ck-page .ck-stats4 b { display: block; font-family: var(--font-serif); font-size: 17px; font-weight: 600; color: var(--text); }
.ck-page .ck-stats4 span { display: block; margin-top: 2px; font-size: 9.5px; color: var(--text-soft); }
.ck-page .ck-rec {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 0; border-bottom: 1px solid var(--border); font-size: 11.5px;
}
.ck-page .ck-rec:last-child { border-bottom: 0; }
.ck-page .ck-rec i { width: 6px; height: 6px; border-radius: 50%; flex: none; background: var(--primary); }
.ck-page .ck-rec i.is-makeup { background: var(--warn); }
.ck-page .ck-rec b { flex: none; font-weight: 600; }
.ck-page .ck-rec span { min-width: 0; color: var(--text-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ck-page .ck-rec time { margin-left: auto; flex: none; font-size: 10.5px; color: var(--text-soft); }

@media (min-width: 1024px) {
  /* 左栏 = hero + 筛选 + 计划卡；右栏 = 日历 / 全部记录（列宽对齐设计稿 pco-cols） */
  .ck-page .ck-main { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); column-gap: 16px; align-items: start; }
  .ck-page .ck-pagehead { display: flex; align-items: center; gap: 16px; margin-bottom: 14px; }
  .ck-page .ck-pagehead .eyebrow {
    margin: 0 0 4px; font-size: 9px; font-weight: 600;
    letter-spacing: .22em; text-transform: uppercase; color: var(--text-soft);
  }
  .ck-page .ck-pagehead .t h2 {
    margin: 0; font-family: var(--font-serif);
    font-size: 26px; font-weight: 600; line-height: 1.15; letter-spacing: -.01em; color: var(--text);
  }
  .ck-page .ck-pagehead .acts { margin-left: auto; display: flex; align-items: center; gap: 8px; }
  .ck-page .ck-pagehead-new {
    display: inline-flex; align-items: center; gap: 5px;
    height: 36px; padding: 0 14px; border: 0; border-radius: 10px;
    background: var(--btn-grad); color: var(--on-primary);
    font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer;
    box-shadow: var(--shadow-accent);
  }
  .ck-page .ck-pagehead-new .ico { width: 15px; height: 15px; }
  .ck-page .ck-hero { margin-top: 0; padding: 20px; }
  .ck-page .ck-hero-copy h2 { font-size: 22px; }
  .ck-page .ck-card { transition: box-shadow .2s ease, transform .2s ease; }
  .ck-page .ck-card:hover { transform: translateY(-1px); box-shadow: var(--shadow-hover); }
  body.checkin-page .topbar-title { visibility: hidden; }
}
body.dark .ck-page .ck-ic.blue { background: rgba(120, 160, 200, .16); color: #9dc3e6; }
body.dark .ck-page .ck-cal i.on { background: rgba(79, 201, 138, .16); color: #9ed3a8; }

.ck-note { font-size: 13px; line-height: 1.75; color: var(--text-soft); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.ck-note .ico { width: 16px; height: 16px; flex: none; }
.card.ck-note { padding: 12px 14px; }
.ck-note-ok { color: var(--primary-deep); }
.ck-note-warn { color: #b05a30; }
.ck-over-text { color: #e8734a; }

/* 弹窗 */
.ck-modal-text { font-size: 13.5px; line-height: 1.8; color: var(--text-soft); }
.ck-modal-btns { display: flex; gap: 10px; margin-top: 16px; }
.ck-modal-btns .btn { flex: 1; }
.ck-danger-btn { background: #e8734a !important; border-color: #e8734a !important; box-shadow: none !important; }

/* 配置页 */
.ck-steps { display: flex; gap: 8px; margin-bottom: 12px; }
.ck-steps span {
  flex: 1; text-align: center; font-size: 12.5px; color: var(--text-soft);
  background: var(--panel-soft); border-radius: 10px; padding: 8px 4px;
}
.ck-steps span.on { background: var(--btn-grad); color: var(--on-primary); font-weight: 700; }

.ck-field { display: flex; flex-direction: column; gap: 8px; padding: 12px 2px; border-bottom: 1px solid var(--border); }
.ck-field:last-child { border-bottom: none; }
.ck-field > label { font-size: 13px; color: var(--text-soft); }
.ck-field input, .ck-field select {
  width: 100%; min-height: 44px; border: 1px solid var(--border); border-radius: 12px;
  padding: 0 12px; font-size: 14px; color: var(--text); background: var(--card);
  font-family: inherit; box-sizing: border-box;
}
.ck-inline { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ck-inline input { flex: 1 1 120px; min-width: 0; }
/* 并排字段（提醒时间 + 提前提醒）：同一行展示，共用一条分隔线 */
.ck-field-row { display: flex; align-items: flex-end; gap: 12px; border-bottom: 1px solid var(--border); }
.ck-field-row .ck-field { flex: 1; min-width: 0; border-bottom: none; }
.ck-field-row .ck-picker-col { width: 54px; } /* 收窄一点，窄屏也能和右侧输入框并排 */
/* 时间选择：滚动选择器，默认只显示当前选中项（一行），上下滑动切换。
   box-sizing: content-box 让 height 只管可视区，上下 padding 让首尾项也能滚到中间。
   注意：可视高必须等于单项高——否则滚轮的几何中心与选中项位置错开，
   旁边的「:」「至」按几何中心对齐就会和数字错位。 */
.ck-picker { display: inline-flex; align-items: center; gap: 6px; }
.ck-picker-colon { font-style: normal; color: var(--text-soft); font-weight: 700; }
.ck-picker-col {
  box-sizing: content-box; flex: none; position: relative;
  width: 62px; height: 30px; padding: 7px 0;
  overflow-y: auto; scrollbar-width: none;
  -webkit-overflow-scrolling: touch; text-align: center;
  border: 1px solid var(--border); border-radius: 12px; background: var(--card);
}
.ck-picker-col::-webkit-scrollbar { display: none; }
.ck-picker-item {
  display: block; height: 30px; line-height: 30px;
  font-size: 15px; color: var(--text-soft);
  font-variant-numeric: tabular-nums;
}
.ck-picker-item.on { color: var(--primary-deep); font-weight: 700; }
/* 双击后的手动输入框：原地覆盖数字行（容器 padding box 高 44px，上下各留 7px 正好 30px） */
.ck-picker-input {
  position: absolute; top: 7px; bottom: 7px; left: 2px; right: 2px;
  box-sizing: border-box; width: auto; padding: 0;
  border: none; border-radius: 8px; background: var(--panel-soft);
  color: var(--primary-deep); font-family: inherit;
  font-size: 15px; font-weight: 700; line-height: 1;
  text-align: center; outline: none;
}
.ck-unit { font-size: 13px; color: var(--text-soft); flex: none; }
.ck-hint { font-size: 12px; color: var(--text-soft); line-height: 1.7; }
/* 日期校验错误提示（贴在日期字段下方） */
.ck-daterr { margin-top: 6px; font-size: 12px; line-height: 1.6; color: var(--danger); }
/* 禁选的日期（早于下限）：置灰、不可点，也不出悬停圆环 */
.dp-cell.dp-off { color: var(--text-soft); opacity: .35; cursor: not-allowed; }
.dp-cell.dp-off:hover { background-image: none; }
/* 「参照日」标记（如选第二次服用时标出第一次服用那天）：数字下方一个小圆点 */
.dp-cell.dp-mark { position: relative; }
.dp-cell.dp-mark::after {
  content: ""; position: absolute; left: 50%; bottom: 3px; transform: translateX(-50%);
  width: 5px; height: 5px; border-radius: 50%; background: var(--primary-deep);
}
/* 节日 / 法定节假日：日期数字下方显示两字简称（格子太窄，放不下全名）。
   法定节假日（含调休）用主题色加粗；普通节日用浅色。 */
.dp-cell.dp-has-fest { flex-direction: column; line-height: 1; }
.dp-fest-t { font-style: normal; font-size: 8px; line-height: 1; margin-top: 1px; }
.dp-cell.dp-cal-rest .dp-fest-t { color: var(--primary-deep); font-weight: 700; }
/* 显式 400：否则选中格 .dp-sel 的 font-weight:700 会继承到简称上，与未选中的普通节日不一致 */
.dp-cell.dp-cal-fest .dp-fest-t { color: var(--text-soft); font-weight: 400; }
.ck-textarea {
  width: 100%; min-height: 120px; border: 1px solid var(--border); border-radius: 12px;
  padding: 12px; font-size: 14px; line-height: 1.65; color: var(--text);
  background: var(--card); font-family: inherit; resize: none; box-sizing: border-box;
}
.ck-count { text-align: right; font-size: 12px; color: var(--text-soft); margin-top: 6px; }

.ck-picks { display: flex; flex-wrap: wrap; gap: 8px; }
.ck-pick {
  font-size: 13px; padding: 9px 15px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--card); color: var(--text); cursor: pointer;
}
.ck-pick.on { background: var(--btn-grad); border-color: var(--btn-grad); color: var(--on-primary); font-weight: 600; }

.ck-mgrid { display: flex; flex-direction: column; gap: 10px; }
.ck-mcard {
  display: flex; gap: 12px; align-items: flex-start; padding: 13px 14px;
  border: 1px solid var(--border); border-radius: 16px; background: var(--card); cursor: pointer;
}
.ck-mcard.on { border-color: var(--primary); background: var(--panel-soft); box-shadow: 0 0 0 3px rgba(var(--primary-rgb), .16); }
.ck-mcard-ico {
  width: 38px; height: 38px; border-radius: 12px; flex: none;
  background: var(--panel-soft); color: var(--primary-deep);
  display: flex; align-items: center; justify-content: center;
}
.ck-mcard-ico .ico { width: 20px; height: 20px; }
.ck-mcard.on .ck-mcard-ico { background: var(--btn-grad); color: var(--on-primary); }
.ck-mcard-main { flex: 1; min-width: 0; }
.ck-mcard-name { font-size: 14.5px; font-weight: 700; }
.ck-mcard-desc { font-size: 11.5px; color: var(--text-soft); margin-top: 4px; line-height: 1.6; }
/* 定位打卡方式在「定位管理」关闭后置灰不可选 */
.ck-mcard.is-off { opacity: .5; cursor: not-allowed; }
.ck-mcard.is-off.on { opacity: .8; border-color: var(--border); background: transparent; box-shadow: none; }
.ck-mcard.is-off .ck-radio { display: none; }
.ck-mcard-warn { margin-top: 8px; font-size: 12px; line-height: 1.6; color: var(--danger); }
.ck-radio { width: 20px; height: 20px; border-radius: 50%; border: 1.5px solid var(--border); background: var(--surface); flex: none; margin-top: 9px; }
.ck-radio.on { border: 6px solid var(--primary-deep); }
.ck-extra { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--primary-soft); }
.ck-extra-title { font-size: 13px; font-weight: 700; display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.ck-task-row { display: flex; align-items: center; gap: 8px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.ck-task-row:last-of-type { border-bottom: none; }
.ck-task-name { flex: 1; font-size: 13.5px; }
.ck-task-del { border: none; background: none; padding: 6px; color: var(--text-soft); cursor: pointer; display: flex; }
.ck-task-del .ico { width: 14px; height: 14px; }
/* 专属配置的行式键值（对齐设计稿的 krow）：点击整行进入设置 */
.ck-krow { position: relative; display: flex; align-items: center; gap: 10px; padding: 12px 2px; border-bottom: 1px solid var(--border); min-height: 48px; cursor: pointer; }
.ck-krow:last-of-type { border-bottom: none; }
.ck-krow:hover { background: var(--panel-soft); }
/* 行内下拉（最多张数）：高度固定 4 项，其余滚动 */
.ck-kdrop {
  position: absolute; top: calc(100% - 2px); left: 0; right: 0; z-index: var(--z-dropdown);
  padding: 6px; background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: var(--shadow-float);
  max-height: 172px; overflow-y: auto;
}
.ck-kopt {
  height: 40px; display: flex; align-items: center; padding: 0 12px;
  border-radius: 8px; font-size: 14px; color: var(--text); cursor: pointer;
}
.ck-kopt:hover { background: var(--bg); }
.ck-kopt.active { background: var(--primary-soft); font-weight: 600; }
.ck-kico { width: 20px; height: 20px; color: var(--primary-deep); flex: none; display: flex; }
.ck-kico .ico { width: 20px; height: 20px; }
.ck-klbl { flex: 1; font-size: 14px; }
.ck-kval { font-size: 13.5px; color: var(--text-soft); text-align: right; }
.ck-kchev { color: #d3c4ca; flex: none; display: flex; }
.ck-kchev .ico { width: 16px; height: 16px; }
/* 条件必填的报错（同设计稿 err-msg） */
.ck-err-msg { display: flex; align-items: center; gap: 4px; font-size: 12px; color: var(--warn, var(--danger)); margin-top: 6px; }
.ck-err-msg .ico { width: 13px; height: 13px; flex: none; }
/* 卡片内的全宽次要按钮（添加任务项等） */
.ck-add-btn {
  width: 100%; height: 44px; margin-top: 10px; border: 1px solid var(--primary); border-radius: 15px;
  background: var(--surface); color: var(--primary-deep); font-size: 15px; font-weight: 700; font-family: inherit;
  display: flex; align-items: center; justify-content: center; gap: 6px; cursor: pointer;
}
.ck-add-btn .ico { width: 16px; height: 16px; }
/* 打卡执行页：hero 进度条（对齐设计稿 hero-bar） */
.ck-hero-bar { height: 8px; border-radius: 999px; background: rgba(255, 255, 255, .38); overflow: hidden; margin-top: 10px; }
.ck-hero-bar i { display: block; height: 100%; background: #fff; border-radius: 999px; }
/* 今日状态卡：1:1 对齐设计稿（sub-title + dash 圆形倒计时 + hint） */
.sub-title { font-size: 14px; font-weight: 700; margin: 0 2px 12px; display: flex; align-items: center; gap: 8px; }
.sub-title .grow { flex: 1; }
.sub-title > .ico { width: 18px; height: 18px; color: var(--primary-deep); flex: none; }
/* 状态徽章（对齐设计稿 .st-*） */
.st { display: inline-flex; align-items: center; gap: 3px; font-size: 11px; font-weight: 600; padding: 3px 9px; border-radius: 999px; border: 1px solid transparent; white-space: nowrap; }
.st-todo { color: var(--primary-deep); background: var(--surface); border-color: var(--primary); }
.st-done { color: var(--on-primary); background: var(--btn-grad); border-color: var(--btn-grad); }
.st-over { color: var(--overdue-ink); background: var(--overdue-soft); border-color: var(--overdue-border); }
.st-wait { color: var(--text-soft); background: var(--panel-soft); border-color: var(--border); }
/* 卡片内的轻量徽章 / 辅助说明 / 多行输入（对齐设计稿） */
.badge { font-size: 10.5px; font-weight: 600; color: var(--primary-deep); background: var(--panel-soft); border: 1px solid var(--border); padding: 2px 8px; border-radius: 999px; white-space: nowrap; }
.muted { font-size: 12px; color: var(--text-soft); line-height: 1.7; }
.textarea {
  width: 100%; min-height: 92px; border: 1px solid var(--border); border-radius: 13px;
  padding: 12px; font-size: 14px; line-height: 1.65; color: var(--text);
  background: var(--surface); font-family: inherit; resize: none; box-sizing: border-box;
}
.textarea::placeholder { color: #c6b8be; }
.dash {
  width: 164px; height: 164px; border-radius: 50%; margin: 8px auto 0;
  border: 2px dashed var(--primary-soft); background: var(--panel-soft);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  color: var(--primary-deep);
}
.dash > .ico { width: 34px; height: 34px; }
.dash .d-t { font-size: 11.5px; color: var(--text-soft); }
.dash .d-time { font-size: 20px; font-weight: 800; letter-spacing: .4px; font-variant-numeric: tabular-nums; }
/* 底部固定操作条：通栏长方形主操作 */
.ck-runbar {
  position: sticky; bottom: 0; z-index: 20;
  display: flex; align-items: center;
  padding: 12px 0 calc(12px + env(safe-area-inset-bottom));
  background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, var(--bg) 38%);
}
.ck-runbar-main {
  flex: 1; height: 52px; border-radius: 15px; border: none; background: var(--btn-grad); color: #fff;
  font-size: 15px; font-weight: 700; font-family: inherit;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  box-shadow: var(--shadow-accent-strong); cursor: pointer;
}
.ck-runbar-main .ico { width: 20px; height: 20px; }
.ck-runbar-main:disabled { opacity: .45; box-shadow: none; cursor: not-allowed; }
.ck-btn-row { display: flex; gap: 10px; margin-top: 14px; }

/* 打卡执行页 */
.ck-task { display: flex; align-items: center; gap: 10px; padding: 12px 2px; border-bottom: 1px solid var(--border); min-height: 48px; cursor: pointer; }
.ck-task:last-child { border-bottom: none; }
/* 打卡任务勾选：圆形容器 + 统一勾（勾只在选中时亮，未选中是空圈） */
.ck-tbox {
  width: 22px; height: 22px; border-radius: 50%; border: 1.5px solid var(--border);
  background: var(--surface); flex: none;
  display: flex; align-items: center; justify-content: center;
}
.ck-tbox.on { border-color: transparent; }
.ck-tbox .pick-ico { display: none; }
.ck-tbox.on .pick-ico { display: block; }
.ck-task.on .ck-task-name { color: var(--text-soft); text-decoration: line-through; }

/* 上传照片（对齐设计稿 up-grid / up-thumb / up-add） */
.up-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.up-thumb {
  position: relative; aspect-ratio: 1; min-height: 74px; border-radius: 14px; overflow: hidden;
  background: var(--panel-soft);
  display: flex; align-items: center; justify-content: center; color: var(--primary-deep);
}
.up-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.up-x {
  position: absolute; top: 5px; right: 5px; width: 20px; height: 20px; border-radius: 50%;
  border: none; background: rgba(74, 59, 64, .55); color: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.up-x .ico { width: 12px; height: 12px; }
.up-add {
  aspect-ratio: 1; min-height: 74px; border: 1.5px dashed var(--primary-soft); border-radius: 14px;
  background: var(--panel-soft); color: var(--primary-deep); cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  font-size: 11.5px; font-family: inherit;
}
.up-add .ico { width: 22px; height: 22px; }

.ck-geo-name { font-size: 14px; font-weight: 600; display: flex; align-items: center; gap: 6px; }
.ck-geo-name .ico { width: 16px; height: 16px; color: var(--primary-deep); }
/* 目标地点真地图（高德）：高度对齐设计稿的 152px；
   加载中 / 加载失败 / 未设坐标时，容器里放一层居中说明 */
.ck-geo-map {
  position: relative; height: 152px; margin-top: 12px; border-radius: 14px;
  border: 1px solid var(--border); overflow: hidden;
  background: var(--panel-soft);
}
/* 地图右下角的「回到我的位置」：独立覆盖在地图容器上（AMap 只往 #ckGeoMap 里加图层），
   z-index 30 压住底图与标记（高德标记是 12） */
.ck-geo-mapwrap { position: relative; margin-top: 12px; }
.ck-geo-mapwrap > .ck-geo-map { margin-top: 0; }
.ck-geo-locate {
  position: absolute; right: 10px; bottom: 24px; z-index: 30;
  width: 36px; height: 36px; padding: 0; border-radius: 11px;
  border: 1px solid var(--border); background: var(--card); color: var(--primary-deep);
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-float-sm); cursor: pointer;
}
.ck-geo-locate .ico { width: 20px; height: 20px; }
.ck-geo-locate:active { transform: scale(.95); }
/* PC 内容区比手机宽一倍多，照搬 152px 会压成一条窄带（打卡范围圈和定位点都看不清），放宽到 320px。
   必须写在基础规则之后：同特异性下后者生效 */
@media (min-width: 1024px) {
  .ck-geo-map { height: 320px; }
}
.ck-geo-map-empty {
  height: 100%; display: flex; align-items: center; justify-content: center;
  padding: 0 16px; text-align: center; font-size: 12.5px; color: var(--text-soft);
}
/* 目标地点弹窗：定位后的地图 + 附近地点下拉（供挑选，替代手填） */
.ck-place-map {
  height: 168px; margin-top: 10px; border-radius: 14px;
  border: 1px solid var(--border); overflow: hidden; background: var(--panel-soft);
}
.ck-place-pois {
  margin-top: 8px; max-height: 190px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 12px; background: var(--card);
}
.ck-poi {
  display: flex; align-items: center; gap: 8px; padding: 11px 12px;
  font-size: 13.5px; cursor: pointer; border-bottom: 1px solid var(--border);
}
.ck-poi:last-child { border-bottom: none; }
.ck-poi:hover { background: var(--panel-soft); }
.ck-poi span { margin-left: auto; flex: none; max-width: 46%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11.5px; color: var(--text-soft); }
.ck-poi.on { background: var(--panel-soft); }
.ck-poi.on, .ck-poi.on span { color: var(--primary-deep); font-weight: 600; }
.ck-dist { display: flex; align-items: center; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.ck-dist-num { font-size: 20px; font-weight: 800; color: var(--primary-deep); }
.ck-dist-cap { font-size: 11.5px; color: var(--text-soft); flex: 1; }
.ck-dist-num.muted { font-size: 16px; font-weight: 700; color: var(--text-soft); }
/* 定位卡片状态（与 docs/checkin-geo-states.html 同一套方案）：
   有 GPS 说距离、只有 IP 说归属地、都没有只说原因，三种状态互斥 */
.ck-geo-refresh {
  flex: none; padding: 7px 12px; border-radius: 999px; border: 1px solid var(--primary-soft);
  background: var(--card); color: var(--primary-deep); font-family: inherit;
  font-size: 12px; font-weight: 600; cursor: pointer;
}
.ck-geo-refresh:active { transform: scale(.97); }
.ck-geo-warn { display: flex; align-items: center; gap: 6px; margin-top: 8px; font-size: 12px; color: #b05a30; }
.ck-geo-warn .ico { width: 14px; height: 14px; flex: none; }
.ck-geo-ip {
  margin-top: 12px; padding: 11px 12px; border-radius: 12px;
  background: var(--panel-soft); border: 1px dashed var(--primary-soft);
}
.ck-geo-ip-head { display: flex; align-items: center; gap: 8px; }
.ck-geo-chip {
  padding: 3px 7px; border-radius: 6px; background: var(--primary-soft);
  color: var(--primary-deep); font-size: 10.5px; font-weight: 800; letter-spacing: .02em;
}
.ck-geo-pill { margin-left: auto; padding: 3px 9px; border-radius: 999px; font-size: 11px; font-weight: 700; }
.ck-geo-pill.ok { color: var(--ok-ink); background: var(--ok-soft); }
.ck-geo-pill.bad { color: var(--danger-ink); background: var(--danger-soft); }
.ck-geo-ip-text { margin-top: 8px; font-size: 12.5px; line-height: 1.7; color: var(--text-soft); }
.ck-geo-ip-text b { color: var(--text); font-weight: 600; }
.ck-geo-ip-text i { margin: 0 5px; font-style: normal; color: #c2b3b8; }
.ck-geo-fail {
  display: flex; align-items: flex-start; gap: 10px; margin-top: 12px; padding: 11px 12px;
  border-radius: 12px; background: var(--danger-soft); border: 1px solid var(--danger-border);
}
.ck-geo-fail .ico { flex: none; width: 16px; height: 16px; color: var(--danger-ink); margin-top: 1px; }
.ck-geo-fail-title { font-size: 13px; font-weight: 700; color: var(--danger-ink); }
.ck-geo-fail-text { margin-top: 3px; font-size: 11.5px; line-height: 1.6; color: var(--text-soft); }
body.dark .ck-geo-warn { color: var(--warn); }
body.dark .ck-geo-ip-text i { color: var(--text-soft); }

/* 首页顶部卡片下方的打卡提醒 */
.ck-hr-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.ck-hr-ico { width: 30px; height: 30px; border-radius: 50%; background: var(--panel-soft); color: var(--primary-deep); display: flex; align-items: center; justify-content: center; flex: none; }
.ck-hr-ico .ico { width: 17px; height: 17px; }
.ck-hr-title { font-size: 14.5px; font-weight: 700; }
/* 每个打卡项各自一张小卡：淡粉底 + 描边 + 圆角，项与项之间靠外边距拉开
   （此前是同卡内三行、只靠顶部分隔线，改成独立卡后层次更清楚） */
.ck-hr-row { display: flex; align-items: center; gap: 10px; min-height: 48px; padding: 8px 12px; background: var(--bg); border: 1px solid var(--border); border-radius: 12px; cursor: pointer; transition: background .15s; }
.ck-hr-row + .ck-hr-row { margin-top: 8px; }
.ck-hr-row:hover { background: var(--panel-soft); }
.ck-hr-name { flex: 1; min-width: 0; font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ck-hr-time { font-size: 12px; color: var(--text-soft); flex: none; font-variant-numeric: tabular-nums; }
.ck-hr-go { font-size: 12.5px; font-weight: 700; color: var(--primary-deep); flex: none; }
/* 行首的打卡方式图标：与页头铃铛沿用同一套「淡底圆角块 + 主题色」语言 */
.ck-hr-way { flex: none; width: 26px; height: 26px; border-radius: 8px; background: var(--panel-soft); color: var(--primary-deep); display: flex; align-items: center; justify-content: center; }
.ck-hr-way .ico { width: 15px; height: 15px; }

/* 首页「消息通知」列：形态与右侧「打卡提醒」卡对齐 ——
   整列收进一张白卡容器（含内边距），内部每条提醒各自一张淡粉底小卡；
   此前是三个独立白卡平铺，两列观感不一致。 */
#pdHomeRemind {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px;
  margin-bottom: 14px;
}
#pdHomeRemind .card.pd-hr {
  margin-bottom: 0;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: none;
  padding: 10px 12px;
}
/* 没有任何提醒时（后端未派生、也不在经期）整列不显示，避免留一张空白容器卡 */
#pdHomeRemind:empty { display: none; }

/* 首页提醒区各类图标的主色：照设计稿「同色系淡底 + 主色」的做法，逐个类型区分，
   不再全部套用同一个 --primary-deep（此前所有提醒图标都是深粉，彼此没有辨识度）。 */
#pdHomeRemind .ck-hr-ico { background: rgba(154, 92, 184, .14); color: #9a5cb8; }  /* 消息提醒：紫 */
#ckHomeRemind .ck-hr-ico { background: rgba(47, 158, 143, .13); color: #2f9e8f; }  /* 打卡提醒：青 */
.pd-hr-ico { background: rgba(194, 90, 34, .13); color: #c25a22; }                 /* 经期 / 补药 / 测体温：橙 */
.ck-hr-way { background: rgba(47, 158, 143, .13); color: #2f9e8f; }                /* 打卡方式：青（与打卡同系） */
.count-item span.count-img { background: rgba(74, 127, 165, .13); color: #4a7fa5; } /* 倒计时占位时钟：蓝 */

/* 首页字号随视口缩放：PC 宽屏下此前仍沿用移动端字号（13~15px），
   内容区被拉到 1400px 左右时字显得过小、与卡片尺寸不成比例。
   clamp(移动端原值, 视口比例, 上限)：窄屏自动回到原值，宽屏按比例放大并有封顶。 */
@media (min-width: 1024px) {
  .hero .couple { font-size: clamp(18px, 1.4vw, 24px); }
  .hero .days .love-main { font-size: clamp(46px, 4.4vw, 70px); }
  .hero .days .love-sub { font-size: clamp(17px, 1.3vw, 22px); }
  .hero .quote { font-size: clamp(13px, 1.05vw, 17px); }
  .card-title { font-size: clamp(15px, 1.25vw, 18px); }
  .count-item .c { font-size: clamp(13px, 1.05vw, 16px); }
  .count-item .count-line { font-size: clamp(12px, 0.95vw, 14px); }
  .module-card .module-title { font-size: clamp(15px, 1.25vw, 18px); }
  .module-card .module-sub { font-size: clamp(11px, 0.95vw, 13px); }
  .couple-avatars .avatar-name { font-size: clamp(14px, 1.15vw, 17px); }
  .pd-hr-title { font-size: clamp(14px, 1.15vw, 17px); }
  .pd-hr-sub { font-size: clamp(12.5px, 1vw, 15px); }
  .ck-hr-title { font-size: clamp(14.5px, 1.2vw, 17px); }
  .ck-hr-name { font-size: clamp(14px, 1.15vw, 17px); }
  .ck-hr-time, .ck-hr-go { font-size: clamp(12.5px, 1vw, 15px); }
}

@media (min-width: 1024px) {
  /* 打卡列表页：左栏计划列表（单排，一行一个）+ 右栏日历 / 全部打卡记录 */
  .ck-main { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); column-gap: 18px; align-items: start; }
  #ckRecBox { display: block; }
  /* 页头留在顶部，两栏各自滚动、页面整体不滚：右栏「全部打卡记录」才能稳定贴在窗口底往上 10px。
     否则左栏 6 张计划卡会把整页撑高，页面一滚右栏列表就被带出视口（底部看起来不足 10px）。 */
  .ck-page { display: flex; flex-direction: column; height: calc(100vh - 78px); }
  .ck-page .ck-main {
    flex: 1; min-height: 0;
    grid-template-rows: minmax(0, 1fr); align-items: stretch;
  }
  .ck-page .ck-col-main, .ck-page #ckRecBox {
    min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  }
  .ck-list { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  .up-grid { grid-template-columns: repeat(4, 1fr); }
  /* PC 端侧栏常驻，固定贴底会横跨侧栏区，故回落为内容流内的按钮行 */
  .ck-bottombar { position: static; border-top: none; background: transparent; padding: 16px 0 0; }
}

/* 「更多」右栏下钻列表的行内小字：只在 PC 端显示。
   默认隐藏、宽屏断点内才放出来——万一窗口从宽屏缩到窄屏、PC 外壳标记残留在 DOM 里，
   描述也不会在移动端露出来。 */
.entry-sub { display: none; }

/* ===== PC「更多」双栏（点入口后：左栏 = 「更多」页整页内容 / 设置页的子入口；移动端不出现该结构） ===== */
@media (min-width: 1024px) {
  .pc-pane { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 20px; align-items: start; }
  /* 两栏固定等高、各自滚动：切换入口时左右栏高度与页面总高都不变，彻底不抖
     （项目已全局隐藏滚动条，出现/消失滚动条也不会改变宽度）。
     高度 = 视口 − 顶栏 52 − 内容区上内边距 16 − 底部留白 10 ⇒ 底边正好落在「窗口底往上 10px」，
     栏内最后一张卡片的底边也就贴在 10px 处，不再像原来那样空出一整条。 */
  .pc-pane-nav, .pc-pane-body { height: calc(100vh - 78px); overflow-y: auto; overscroll-behavior: contain; }
  /* 双栏内不再播入场动画：.page 的 fadeIn 带 6px 位移，切换时会被看成抖动 */
  .pc-pane .page { animation: none; }
  .pc-pane-nav { display: flex; flex-direction: column; gap: 12px; }
  /* 容器内边距与精修稿 .pane-nav 的卡片 padding 一致 */
  .pc-pane-nav .entry-list { display: flex; flex-direction: column; gap: 12px; padding: 12px; }
  .pc-pane-nav .entry-list > .card { margin-bottom: 0; }
  /* 左栏顶部返回行：对齐精修稿 .pane-nav-back（13px / primary-deep / 前置左箭头） */
  .pc-pane-nav .pc-pane-back { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; color: var(--primary-deep); padding: 4px 8px 12px; cursor: pointer; }
  .pc-pane-nav .pc-pane-back .ico { width: 16px; height: 16px; }
  /* 左栏入口：由「白卡列表」改成「无边框导航项」（对齐设计稿）——选中只靠底色，不再画卡片
     注意只作用于 .card-entry：左栏顶部的情侣信息 / 修改申请仍是正常白卡 */
  .pc-pane-nav .card-entry { display: flex; align-items: center; gap: 12px; min-height: 46px; padding: 10px 12px; border-radius: 10px; background: transparent; border-color: transparent; box-shadow: none; }
  .pc-pane-nav .card-entry:hover { background: var(--bg); }
  .pc-pane-nav .card-entry .entry-ico { display: flex; align-items: center; justify-content: center; flex: none; width: 26px; height: 26px; border-radius: 8px; }
  .pc-pane-nav .card-entry .entry-ico .ico { width: 15px; height: 15px; }
  .pc-pane-nav .card-entry .entry-main { flex: 1; font-size: 14.5px; }
  .pc-pane-nav .card-entry.pc-on { border-color: transparent; background: var(--panel-soft); }
  .pc-pane-nav .card-entry.pc-on .entry-title { color: var(--primary-deep); }
  .pc-pane-nav .pc-sec-label { font-size: 12px; font-weight: 700; color: var(--text-soft); padding: 10px 8px 6px; }
  .pc-pane-body { min-width: 0; }
  /* 右栏是独立的滚动容器：给子页留出内边距，否则卡片的左右 / 上方阴影会被 overflow 裁掉。
     内边距需 ≥ 阴影模糊半径（--shadow 环境层 16px），这里取 16 / 18px。 */
  .pc-pane-sec { padding: 18px 16px 24px; }
  .pc-pane-sec .page { width: 100%; margin: 0; }
  /* 右栏入口（站点 / 工具 / 衣柜 / 公开设置的子页）：独立卡片列表。
     容器取消整块白卡壳层，每个入口是一张可点的圆角卡，悬停浮起。 */
  .pc-pane-body .entry-list {
    display: flex; flex-direction: column; gap: 10px; padding: 0;
    background: transparent; border: none; border-radius: 0; box-shadow: none; overflow: visible;
  }
  .pc-pane-body .entry-list > .card-title { margin: 0 0 2px; }
  .pc-pane-body .entry-list > .card {
    margin-bottom: 0; background: var(--card); border: 1px solid var(--border);
    border-radius: 14px; box-shadow: var(--shadow);
  }
  .pc-pane-body .entry-list > .card-entry {
    min-height: 64px; padding: 15px 18px; border-radius: 14px; gap: 14px;
    border-top: 1px solid var(--border);
    transition: transform .15s ease, box-shadow .2s ease, border-color .15s ease, background .15s ease;
  }
  .pc-pane-body .entry-list > .card-entry:hover {
    background: var(--card); border-color: var(--primary-soft);
    transform: translateY(-2px); box-shadow: var(--shadow-hover);
  }
  .pc-pane-body .entry-list > .card-entry:active { transform: scale(.995); box-shadow: var(--shadow); }
  .pc-pane-body .entry-list .card-entry .entry-ico {
    width: 34px; height: 34px; border-radius: 10px;
    background: var(--bg); box-shadow: inset 0 0 0 1px var(--border);
  }
  .pc-pane-body .entry-list .card-entry .entry-ico .ico { width: 19px; height: 19px; }
  .pc-pane-body .entry-list .entry-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
  .pc-pane-body .entry-list .entry-title { font-size: 14.5px; font-weight: 600; }
  .pc-pane-body .entry-list .entry-sub { display: block; font-size: 12px; font-weight: 400; color: var(--text-soft); }
  .pc-pane-body .entry-list .entry-arrow {
    font-size: 16px; font-weight: 600; color: var(--text-soft); opacity: .6;
    transition: transform .15s ease, color .15s ease, opacity .15s ease;
  }
  .pc-pane-body .entry-list > .card-entry:hover .entry-arrow { color: var(--primary-deep); opacity: 1; transform: translateX(2px); }
  /* 右栏内其它位置的 .card-entry（如衣柜设置入口、通知渠道卡）保持原有卡片样式 */
  .pc-pane-body .card-entry { display: flex; align-items: center; gap: 16px; min-height: 68px; padding: 18px 22px; border-radius: 16px; }
  .pc-pane-body .card-entry .entry-main { flex: 1; font-size: 15px; }
  /* 带图标的子入口（如工具设置）：图标位尺寸与左导航同口径 */
  .pc-pane-body .card-entry .entry-ico { display: flex; align-items: center; justify-content: center; flex: none; width: 26px; height: 26px; }
  .pc-pane-body .card-entry .entry-ico .ico { width: 18px; height: 18px; }
  /* 右栏设置页：给 .field 加 form-row 后，宽屏改横向「设置行」（对齐精修稿 .form-row）——
     几何与 .setting-row 一致（14px 行距 + 底部分隔线、末行无线），同一张卡里两种行看起来是一套。
     只在 PC 外壳内生效；窄屏不加任何效果，仍是原来的「标签在上、控件在下」堆叠布局，移动端零变化 */
  .pc-pane .field.form-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 0; padding: 14px 0; border-bottom: 1px solid var(--border); }
  .pc-pane .field.form-row:last-child { border-bottom: none; }
  /* no-divider：该行不要底部分隔线（下方是块级区域、或控件自带边框，画线反而多余） */
  .pc-pane .field.form-row.no-divider { border-bottom: none; }
  .pc-pane .field.form-row > label { flex: none; margin-bottom: 0; font-size: 14px; color: var(--text); }
  .pc-pane .field.form-row > :not(label) { flex: 1; min-width: 0; }
  /* 时间选择器不跟着输入框拉满整行：保持自身宽度并靠右 */
  .pc-pane .field.form-row > .tp { flex: none; }
  .pc-pane .field.form-row > .chip-row { justify-content: flex-end; }
  /* 列表顶部的「网页标题」字段：与入口卡同一套卡片外观 */
  .pc-pane-body .entry-list > .field.form-row {
    margin: 0; padding: 14px 18px;
    background: var(--card); border: 1px solid var(--border); border-radius: 14px;
    box-shadow: var(--shadow);
  }
  .pc-pane-sec.is-hidden { display: none; }
  /* 区块内的 .page 已位于外壳中：去掉限宽与入场动画，末卡不叠加下边距 */
  .pc-pane-sec > .page { max-width: none; margin: 0; animation: none; }
  .pc-pane-sec > .page > .card:last-child,
  .pc-pane-sec > .card:last-child { margin-bottom: 0; }
}

/* ================= 消息通知（站内 / 邮箱 / 微信 ClawBot） =================
   一级页 = 三个渠道入口 + 消息记录；二级页 = 单渠道配置。
   命名统一 nt- 前缀，避免与既有类冲突。 */

/* 一级页的渠道入口卡 */
.nt-ch { display: flex; align-items: center; gap: 12px; }
.nt-ch-ico {
  width: 40px; height: 40px; flex: none; border-radius: 13px;
  display: flex; align-items: center; justify-content: center;
  background: var(--panel-soft); border: 1px solid var(--border);
}
.nt-ch-ico svg { width: 23px; height: 23px; }
.nt-ch-ico.green { background: var(--ok-soft); border-color: var(--ok-border); }
.nt-ch-ico.gray { background: var(--surface); }
.nt-ch-body { flex: 1; min-width: 0; }
.nt-ch-name { font-size: 15px; font-weight: 600; }
.nt-ch-sub { font-size: 12px; color: var(--text-soft); margin-top: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nt-ch-right { display: flex; align-items: center; gap: 6px; flex: none; }
.nt-tag {
  font-size: 11px; padding: 2px 8px; border-radius: 999px;
  border: 1px solid var(--border); color: var(--text-soft); background: var(--bg);
}
.nt-tag.on { color: var(--primary-deep); background: var(--panel-soft); border-color: var(--primary-soft); font-weight: 600; }

/* 按账号的绑定行 / 额度行 */
.nt-bind { display: flex; align-items: center; gap: 10px; padding: 11px 0; border-bottom: 1px solid var(--border); }
.nt-bind:last-child { border-bottom: none; }
.nt-avatar {
  width: 34px; height: 34px; flex: none; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--panel-soft); border: 1px solid var(--border); color: var(--primary-deep);
}
.nt-avatar svg { width: 19px; height: 19px; }
.nt-avatar.green { background: var(--ok-soft); border-color: var(--ok-border); }
.nt-bind-main { flex: 1; min-width: 0; }
.nt-bind-name { font-size: 13.5px; font-weight: 600; }
.nt-bind-sub { font-size: 12px; color: var(--text-soft); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nt-bind-sub.ok { color: var(--ok); }
/* 微信待验证：验证码单独占一行，避免被状态行的省略号截断 */
.nt-verify { margin-top: 5px; font-size: 12px; line-height: 1.6; color: var(--warn); }
.nt-verify b { font-size: 15px; letter-spacing: .12em; color: var(--primary-deep); }
.nt-quota { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.nt-quota:last-child { border-bottom: none; }
.nt-quota-who { flex: none; width: 46px; font-size: 12.5px; color: var(--text-soft); }
.nt-quota-bar { flex: 1; height: 8px; border-radius: 999px; overflow: hidden; background: var(--bg); border: 1px solid var(--border); }
.nt-quota-bar i { display: block; height: 100%; background: var(--btn-grad); }
.nt-quota-num { flex: none; font-size: 12.5px; font-weight: 700; }

/* 消息记录：搜索框 + 渠道下拉 */
.nt-search-row { display: flex; gap: 10px; align-items: center; }
.nt-search { position: relative; flex: 1; min-width: 0; }
.nt-search > svg { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--text-soft); }
.nt-search input {
  width: 100%; height: 40px; padding: 0 12px 0 34px;
  font-family: inherit; font-size: 13.5px; color: var(--text); background: var(--surface);
  border: 1px solid var(--border); border-radius: 11px; outline: none;
}
.nt-select {
  flex: none; display: flex; align-items: center; gap: 6px; height: 40px; padding: 0 12px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 11px;
  font-family: inherit; font-size: 13px; color: var(--text); cursor: pointer;
}
.nt-select.on { color: var(--primary-deep); border-color: var(--primary-soft); background: var(--panel-soft); }
.nt-select svg { width: 14px; height: 14px; }

/* 记录列表 */
.nt-stat { display: flex; gap: 8px; }
.nt-stat > div { flex: 1; background: var(--bg); border: 1px solid var(--border); border-radius: 12px; padding: 10px 8px; text-align: center; }
.nt-stat > div[data-nt-failed] { cursor: pointer; transition: border-color .2s; }
.nt-stat > div[data-nt-failed]:active { transform: scale(0.98); }
.nt-stat .n { font-size: 18px; font-weight: 800; }
.nt-stat .n.fail { color: var(--danger); }
.nt-stat .l { font-size: 11px; color: var(--text-soft); margin-top: 2px; }
/* 失败 / 待发视图：补推时间设置（点击概览卡后出现） */
.nt-retry-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.nt-retry-row label { font-size: 13.5px; font-weight: 600; color: var(--text); }
/* 记录列表：内部滚动（搜索/筛选固定在上方，滚动只作用在列表本身；滚到底自动加载更早的记录） */
/* 日志类列表（调用记录 / 操作日志 / 消息记录 / 访客记录 / 拦截记录）：max-height 由 JS 按窗口高度写入（syncLogScroll）。
   所有需要「卡片内独立滚动、页面不被内容撑长」的列表都复用它，高度一律由 JS 实测到视口底边。 */
.log-scroll { overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.nt-log { display: flex; gap: 10px; padding: 12px 0; border-bottom: 1px solid var(--border); cursor: pointer; }
.nt-log:last-child { border-bottom: none; }
.nt-log-ico {
  width: 28px; height: 28px; flex: none; margin-top: 1px; border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  background: var(--panel-soft); border: 1px solid var(--border);
}
.nt-log-ico svg { width: 16px; height: 16px; }
.nt-log-ico.green { background: var(--ok-soft); border-color: var(--ok-border); }
.nt-log-main { flex: 1; min-width: 0; }
.nt-log-ch { font-size: 12px; font-weight: 600; color: var(--primary-deep); }
.nt-log-text { font-size: 13.5px; margin-top: 3px; line-height: 1.55; }
.nt-log-meta { font-size: 11.5px; color: var(--text-soft); margin-top: 4px; display: flex; gap: 8px; flex-wrap: wrap; }
.nt-log-err { font-size: 11.5px; color: var(--danger); line-height: 1.6; margin-top: 5px; }
.nt-log-err.warn { color: var(--warn); }
.nt-log-right { flex: none; display: flex; align-items: center; gap: 6px; }
.nt-log-arrow { color: var(--text-soft); flex: none; align-self: center; }
.nt-log-arrow svg { width: 16px; height: 16px; }
.nt-st {
  display: inline-flex; align-items: center; font-size: 11px; font-weight: 600;
  padding: 3px 9px; border-radius: 999px; border: 1px solid transparent; white-space: nowrap;
}
.nt-st.ok { color: var(--ok); background: rgba(59, 165, 93, .12); border-color: rgba(59, 165, 93, .3); }
.nt-st.fail { color: var(--danger); background: rgba(229, 72, 77, .1); border-color: rgba(229, 72, 77, .28); }
.nt-st.wait { color: var(--warn); background: rgba(230, 162, 60, .13); border-color: rgba(230, 162, 60, .3); }
.nt-st.pending { color: var(--text-soft); background: var(--bg); border-color: var(--border); }
.nt-empty { text-align: center; font-size: 12.5px; color: var(--text-soft); padding: 18px 0; }
.nt-more { text-align: center; font-size: 12px; color: var(--text-soft); padding: 12px 0 2px; }
/* 一个「对话」在列表里只占一行：标题右侧标出对话内消息条数 */
.nt-conv-tag { margin-left: 6px; font-size: 11px; font-weight: 500; color: var(--text-soft); border: 1px solid var(--border); border-radius: 999px; padding: 1px 7px; }

/* 对话记录（弹窗内）：机器人靠左、我靠右 */
.nt-msg { display: flex; flex-direction: column; gap: 4px; margin-bottom: 14px; }
.nt-msg.me { align-items: flex-end; }
.nt-msg-who { display: flex; gap: 8px; font-size: 12px; color: var(--text-soft); }
.nt-bubble {
  max-width: 84%; padding: 9px 12px; border-radius: 12px; font-size: 14px; line-height: 1.55;
  background: var(--bg); border: 1px solid var(--border);
  white-space: pre-wrap; word-break: break-word;
}
.nt-msg.me .nt-bubble { background: rgba(var(--primary-rgb), .1); border-color: rgba(var(--primary-rgb), .25); }
.nt-msg-foot { display: flex; align-items: center; gap: 8px; }
.nt-msg-retry { border: none; background: none; padding: 0; font-size: 12px; color: var(--primary-deep); cursor: pointer; }

/* 记录详情（弹窗内） */
.nt-row { display: flex; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--border); font-size: 13.5px; }
.nt-row:last-child { border-bottom: none; }
.nt-row-k { flex: none; width: 74px; color: var(--text-soft); font-size: 12.5px; }
.nt-row-v { flex: 1; min-width: 0; word-break: break-all; }
.nt-body {
  margin-top: 12px; padding: 12px; border-radius: 12px;
  background: var(--bg); border: 1px solid var(--border);
  font-size: 13.5px; line-height: 1.75; white-space: pre-wrap; word-break: break-word;
}
.nt-fail {
  margin-top: 10px; padding: 10px 12px; border-radius: 12px;
  background: rgba(229, 72, 77, .08); border: 1px solid rgba(229, 72, 77, .25);
  font-size: 12.5px; line-height: 1.65; color: var(--danger);
}
.nt-btns { display: flex; gap: 10px; margin-top: 16px; }
.nt-btns .btn { margin: 0; }

/* 验证码行 / 模板变量 / 扫码二维码 */
.nt-code-row { display: flex; gap: 10px; align-items: center; }
.nt-code-row input { flex: 1; min-width: 0; }
/* 发码 / 复制等次级按钮也保证 44px 以上的触控高度 */
.nt-code-row .btn, .nt-verify-code-row .btn { min-height: 44px; }
/* 字段级错误：就近显示在输入框下方，配合 aria-describedby 给读屏 */
.nt-field-err { margin-top: 6px; font-size: 12px; line-height: 1.55; color: var(--danger); }
/* 重新验证时展示已记录的收件邮箱（打码），不再要求重复输入 */
.nt-mail-fixed {
  padding: 12px 14px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--surface); font-size: 15px; color: var(--text); word-break: break-all;
}
/* 模板编辑框：等宽字体 + 更高的可视高度（HTML / Markdown 模板通常有多行） */
.field textarea.nt-tpl-body {
  min-height: 260px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px; line-height: 1.65;
}
/* 模板正文的标题行：右侧放「预览」按钮 */
.field label.nt-tpl-label { display: flex; align-items: center; justify-content: space-between; }
/* 模板预览弹窗：邮件用 iframe 真实渲染 HTML，微信用 Markdown 渲染结果 */
.nt-pv-samples { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.nt-pv-sample {
  padding: 3px 11px; border-radius: 999px; font-size: 12.5px; cursor: pointer;
  background: var(--panel-soft); color: var(--text-soft); user-select: none;
}
.nt-pv-sample.active { background: var(--btn-grad); color: var(--on-primary); }
.nt-pv-subj { font-size: 13px; color: var(--text-soft); margin-bottom: 10px; word-break: break-word; }
.nt-pv-subj span {
  display: inline-block; margin-right: 8px; padding: 1px 7px; border-radius: 999px;
  background: var(--panel-soft); color: var(--primary-deep); font-size: 11px; font-weight: 700;
}
.nt-pv-mail { width: 100%; height: 340px; border: 1px solid var(--border); border-radius: 12px; background: #fff; }
.nt-pv-wx {
  padding: 14px 16px; border: 1px solid var(--border); border-radius: 12px;
  background: #fff; color: #1a1a1a; font-size: 14px; line-height: 1.7; word-break: break-word;
}
.nt-pv-wx p { margin: 6px 0; }
.nt-pv-wx > :first-child { margin-top: 0; }
.nt-pv-wx > :last-child { margin-bottom: 0; }
.nt-pv-wx blockquote {
  margin: 8px 0; padding: 6px 12px; border-left: 3px solid var(--primary-soft);
  background: var(--panel-soft); color: var(--text-soft); border-radius: 0 8px 8px 0;
}
.nt-pv-wx hr { border: 0; border-top: 1px solid var(--border); margin: 10px 0; }
.nt-var-row { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 9px; }
.nt-var {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
  color: var(--primary-deep); background: var(--panel-soft);
  border: 1px dashed var(--primary-soft); border-radius: 8px; padding: 4px 9px; cursor: pointer;
}
.nt-qr {
  width: 176px; height: 176px; margin: 14px auto 10px; position: relative;
  background: #fff; border: 1px solid var(--border); border-radius: 14px; padding: 12px;
  display: flex; align-items: center; justify-content: center;
}
.nt-qr img { width: 100%; height: 100%; object-fit: contain; }
.nt-qr-cap { font-size: 11.5px; color: var(--text-soft); text-align: center; word-break: break-all; }
.nt-qr-status { display: flex; justify-content: center; margin-top: 6px; }
/* 绑定步骤条：扫码授权 → 发送验证码 → 开通推送 */
.nt-steps { display: flex; align-items: center; gap: 6px; margin: 2px 0 14px; }
.nt-step { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; color: var(--text-soft); white-space: nowrap; }
.nt-step i {
  width: 19px; height: 19px; border-radius: 50%; display: grid; place-items: center;
  font-style: normal; font-size: 10.5px; font-weight: 700;
  background: var(--panel-soft); border: 1px solid var(--border); color: var(--text-soft);
}
.nt-step.on { color: var(--primary-deep); font-weight: 700; }
.nt-step.on i { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }
.nt-step.done i { background: var(--ok-soft); border-color: var(--ok-border); color: var(--ok); }
.nt-step-line { flex: 1; min-width: 8px; height: 1px; background: var(--border); }
/* 扫码成功后的验证步骤：大号验证码 + 复制按钮 + 说明 */
.nt-verify-tip { margin: 14px 0 10px; font-size: 13px; line-height: 1.7; color: var(--text-soft); text-align: center; }
.nt-verify-code-row { display: flex; align-items: center; justify-content: center; gap: 8px; margin-bottom: 12px; }
.nt-verify-code {
  width: fit-content; margin: 0 auto 12px; padding: 10px 20px;
  border: 1px dashed var(--primary); border-radius: 12px; background: var(--panel-soft);
  font-size: 26px; font-weight: 800; letter-spacing: .26em; color: var(--primary-deep);
  font-variant-numeric: tabular-nums;
}
.nt-verify-code-row .nt-verify-code { margin: 0; }

/* 渠道总开关未开启时的门禁：绑定 / 额度 / 提醒内容 / 模板入口整体不可操作 */
.nt-gate.is-locked { opacity: .5; pointer-events: none; user-select: none; }

/* 祝福的回复（站内或微信指令写入，显示在祝福正文下方） */
.msg-reply {
  margin-top: 8px; padding: 9px 12px; border-radius: 12px;
  background: var(--panel-soft); border: 1px solid var(--border);
  font-size: 13.5px; line-height: 1.7; color: var(--text);
}
.msg-reply-label {
  display: inline-block; margin-right: 8px; padding: 1px 8px;
  font-size: 11px; font-weight: 700; color: var(--primary-deep);
  background: var(--card); border: 1px solid var(--primary-soft); border-radius: 999px;
}

/* ================= 话题（相册 / 日常共用） ================= */
/* 展示用胶囊：列表 / 详情 / 话题页可点击，编辑页预览与公开展示页为只读 */
.topic-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.topic-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; line-height: 1.5; padding: 2px 9px; border-radius: 999px;
  font-family: inherit; cursor: pointer;
  color: var(--primary-deep); background: var(--panel-soft); border: 1px solid var(--border);
  transition: border-color .15s;
}
/* 只有带 data-topic 的可点击胶囊有悬停反馈 */
.topic-chip[data-topic]:hover { border-color: var(--primary); }
/* 只读胶囊：编辑页的话题预览、公开展示页 */
.topic-chip.static { cursor: default; background: var(--bg); color: var(--text-soft); }
/* 编辑页话题区：没有话题时整块被 hidden 隐藏（.field 未设 display，hidden 生效） */
#topicField .topic-chips { margin-top: 0; }
/* 编辑页话题胶囊上的删除按钮：小号 × 常驻显示，悬停变主色（只读胶囊本身没有悬停反馈） */
#topicChips .chip-x {
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px; padding: 0; border: none; border-radius: 50%;
  background: transparent; color: var(--text-soft);
  font-family: inherit; font-size: 13px; line-height: 1; cursor: pointer;
}
#topicChips .chip-x:hover { color: var(--primary-deep); background: var(--panel-soft); }

/* 话题列表页 */
.topic-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
/* 话题列表的「列表」排版：单列卡片（网格排版保持上面的多列自适应）。特异性高于媒体查询里的 .topic-grid 覆盖 */
.topic-grid.one-col { grid-template-columns: 1fr; }
.topic-card {
  display: flex; flex-direction: column; gap: 4px; text-align: left;
  padding: 12px 14px; border-radius: 14px; font-family: inherit; cursor: pointer;
  background: var(--surface); border: 1px solid var(--border);
  transition: border-color .15s, transform .12s;
}
.topic-card:hover { border-color: var(--primary); }
.topic-card:active { transform: scale(.98); }
.topic-card-name { font-size: 14.5px; font-weight: 700; color: var(--primary-deep); word-break: break-all; }
.topic-card-count { font-size: 11.5px; color: var(--text-soft); }
.topic-empty-hint { margin-top: 8px; font-size: 12px; color: var(--text-soft); line-height: 1.6; }

/* 话题聚合页 */
.topic-head { font-size: 17px; font-weight: 700; color: var(--primary-deep); margin-bottom: 12px; word-break: break-all; }
.topic-head-count { margin-left: 10px; font-size: 12px; font-weight: 400; color: var(--text-soft); }
.topic-sec-title { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 700; color: var(--text); margin: 14px 0 8px; }
.topic-sec-title::before { content: ""; width: 3px; height: 13px; border-radius: 2px; background: var(--primary); }
.topic-sec-count { font-size: 11.5px; font-weight: 500; color: var(--text-soft); }
/* 聚合页筛选（日常 / 相册 两类都有时才出现）：只切换两段的显隐，不重新请求 */
.topic-filter { margin-bottom: 12px; }
.topic-filter .chip { padding: 6px 14px; font-size: 13px; }
/* hidden 在设了 display 的元素上会被覆盖，这里显式兜底（同 .chip-row[hidden]） */
.topic-sec[hidden] { display: none; }

@media (min-width: 1024px) {
  .topic-grid { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); }
}

/* ===== 数据恢复：备份管理 + 已删数据 ===== */
/* 备份列表：一份备份一行（时间 / 文件名 / 大小 + 三个小操作） */
.bk-list { margin-top: 10px; border-top: 1px solid var(--border); }
.bk-row { display: flex; align-items: center; gap: 8px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.bk-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.bk-name { font-size: 13.5px; font-weight: 700; color: var(--text); }
.bk-sub { font-size: 11.5px; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tk-mini { padding: 5px 10px; font-size: 12px; border-radius: 9px; flex: none; white-space: nowrap; }

/* 底部两个快捷按钮：移动端钉在页面底部（子页不显示底栏，不会互相压住） */
.tk-actions { display: flex; gap: 10px; margin-top: 14px; }
.tk-actions .btn { flex: 1; }
@media (max-width: 1023px) {
  .tk-actions {
    position: fixed; left: 14px; right: 14px; bottom: 14px; z-index: 20; margin: 0;
    padding: 10px; border-radius: 16px; background: var(--surface);
    box-shadow: var(--shadow-float);
  }
  .page.tk-has-actions { padding-bottom: 84px; }
}

/* 模块入口行的条数徽标 */
.tk-count {
  flex: none; margin-right: 8px; padding: 1px 8px; border-radius: 9px;
  font-size: 12px; font-weight: 700; color: var(--primary-deep); background: var(--primary-soft);
}
.tk-count.is-zero { color: var(--text-soft); background: var(--border); }

/* 模块明细：工具栏 + 条目列表 */
.tk-toolbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 10px 0; }
.tk-allsel { display: inline-flex; align-items: center; gap: 5px; margin-right: auto; font-size: 13px; color: var(--text-soft); }
.tk-list { border-top: 1px solid var(--border); }
.tk-item { display: flex; align-items: center; gap: 8px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.tk-pick { flex: none; width: 16px; height: 16px; accent-color: var(--primary); }
.tk-thumb { flex: none; width: 40px; height: 40px; border-radius: 8px; object-fit: cover; background: var(--border); }
.tk-item-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.tk-item-title { font-size: 13.5px; font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tk-item-sub { font-size: 11.5px; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tk-act { flex: none; padding: 4px 2px; font-size: 12.5px; font-weight: 700; color: var(--primary-deep); cursor: pointer; }
.tk-act.danger { color: var(--danger, #e5484d); }
.tk-act:active { opacity: .6; }

/* ===== AI 记忆管理：条目卡片 + 添加者分段筛选 ===== */
/* 条目卡片：左侧标题 / 简介，右侧启用开关与编辑删除 */
.ai-item-card {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px; border: 1px solid var(--border); border-radius: 14px;
  background: var(--surface);
}
.ai-item-card + .ai-item-card { margin-top: 10px; }
/* 条目列表：条数多了在框内滚动（记忆可能积累很多条），避免整张卡片被拉得过长。
   padding/margin 一进一出相抵，卡片视觉位置与滚动条出现前保持一致 */
.ai-item-list { max-height: min(420px, 55vh); overflow-y: auto; overscroll-behavior: contain; padding: 2px; margin: -2px; }
.ai-item-list + .upload-hint { margin-top: 10px; }
.ai-item-main { flex: 1; min-width: 0; }
.ai-item-title { font-size: 14px; line-height: 1.55; color: var(--text); word-break: break-word; }
.ai-item-sub { font-size: 12.5px; line-height: 1.6; color: var(--text-soft); margin-top: 4px; word-break: break-word; }
.ai-item-ops { flex: none; display: flex; align-items: center; gap: 8px; }

/* 记忆按添加者筛选 / 审批管理：沿用 dp-cal-seg 外观，段宽均分、滑块由 --seg-n / --seg-i 控制。
   ai-seg 拉满整行（记忆筛选）；ap-seg 靠右紧凑（审批行右侧的三档选择：关闭 / 提醒 / 申请）。 */
.ai-seg, .ap-seg { display: flex; }
.ai-seg { flex: 1; }
.ap-seg { flex: none; }
.ai-seg .dp-cal-i, .ap-seg .dp-cal-i { flex: 1; text-align: center; }
.ap-seg .dp-cal-i { padding: 6px 12px; font-size: 13px; }
.ai-seg .dp-cal-thumb, .ap-seg .dp-cal-thumb {
  width: calc((100% - 8px) / var(--seg-n, 2));
  transform: translateX(calc(var(--seg-i, 0) * 100%));
}

/* 技能的参考资料：折叠查看（只读） */
.ai-skill-files { display: flex; flex-direction: column; gap: 8px; }
.ai-skill-file {
  border: 1px solid var(--border); border-radius: 10px;
  padding: 8px 10px; background: var(--surface);
}
.ai-skill-file summary { cursor: pointer; font-size: 13px; color: var(--text-soft); word-break: break-all; }
.ai-skill-file[open] summary { color: var(--text); }
.ai-skill-file-body {
  margin: 8px 0 0; max-height: 260px; overflow: auto;
  white-space: pre-wrap; word-break: break-word;
  font-size: 12.5px; line-height: 1.6; color: var(--text);
}

/* 查看模式（内置技能只读）：输入区整体淡掉，但不至于看不见 */
.field input[readonly][disabled], .field textarea[readonly][disabled] {
  background: var(--panel-soft); cursor: default;
}

/* ---- 向量总览（记忆卡片 →「查看向量」）：概览 / 散点 / 热力图 / 分布 / 条带 ---- */
.aiv-stat { display: flex; align-items: baseline; gap: 6px; margin-top: 2px; }
.aiv-stat-num { font-size: 30px; font-weight: 700; line-height: 1.1; color: var(--primary-deep); }
.aiv-stat-sub { font-size: 15px; font-weight: 600; color: var(--text-soft); }
.aiv-stat-label { font-size: 12.5px; color: var(--text-soft); margin-bottom: 10px; }
.aiv-bar { height: 7px; border-radius: 999px; background: var(--border); overflow: hidden; margin-bottom: 12px; }
.aiv-bar-in { height: 100%; background: var(--primary); transition: width .3s; }
.aiv-meta { display: flex; flex-wrap: wrap; gap: 6px 18px; font-size: 12.5px; color: var(--text-soft); }
.aiv-meta b { color: var(--text); font-weight: 600; }
/* 各模块向量化进度明细：每行「模块名 ｜ 进度条 ｜ 已算/总数」，行与行之间留出间距 */
.aiv-mods { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.aiv-mod { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 10px; background: var(--surface); }
.aiv-mod.off { opacity: .45; }
.aiv-mod-name { flex: none; width: 68px; font-size: 12.5px; color: var(--text-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.aiv-mod-bar { flex: 1; height: 4px; border-radius: 999px; background: var(--border); overflow: hidden; }
.aiv-mod-in { height: 100%; border-radius: 999px; background: var(--primary); }
.aiv-mod-num { flex: none; width: 52px; text-align: right; font-size: 11.5px; color: var(--text); font-weight: 600; }
/* 模块筛选：条目多时换行铺开（此前单行横向滚动，后面的模块容易被忽略） */
.aiv-chips { flex-wrap: wrap; overflow: visible; margin-top: 6px; }
.aiv-chips .chip { flex: none; }
/* 图表标签：一次只显示一个图 */
.aiv-tabs { display: flex; gap: 2px; margin-top: 14px; border-bottom: 1px solid var(--border); overflow-x: auto; }
.aiv-tab { padding: 8px 10px; font-size: 13px; color: var(--text-soft); cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px; white-space: nowrap; }
.aiv-tab.active { color: var(--primary-deep); border-bottom-color: var(--primary); font-weight: 600; }
.aiv-tab.off { opacity: .35; cursor: default; }
/* 正在向量化时的整体进度：只在处理中出现，处理完自动消失 */
.aiv-progress { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); }
.aiv-progress-top { display: flex; justify-content: space-between; font-size: 12px; color: var(--text-soft); margin-bottom: 6px; }
.aiv-progress-bar { height: 5px; border-radius: 999px; background: var(--border); overflow: hidden; }
.aiv-progress-in { height: 100%; border-radius: 999px; background: var(--primary); transition: width .4s ease; }
/* 图表一律用 viewBox 自适应容器宽度，窄屏不会被撑破 */
.aiv-svg { display: block; width: 100%; height: auto; margin-top: 4px; }
.aiv-dot { fill: var(--primary); fill-opacity: .9; stroke: var(--surface); stroke-width: 1.6; }
.aiv-dot-idx { font-size: 8px; font-weight: 700; fill: #fff; text-anchor: middle; pointer-events: none; }
/* 语义分布的连线与分组：连线在 JS 里内联描边；气泡是「聚类气泡」视图 */
.aiv-edge-lab { font-size: 9px; fill: var(--text-soft); text-anchor: middle; paint-order: stroke; stroke: var(--surface); stroke-width: 3px; stroke-linejoin: round; }
.aiv-bubble { fill-opacity: .1; stroke-width: 1.6; stroke-dasharray: 4 4; }
.aiv-bubble-lab { font-size: 11px; font-weight: 700; text-anchor: middle; }
.aiv-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 6px; font-size: 12px; color: var(--text-soft); }
.aiv-legend i { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 5px; vertical-align: middle; }
.aiv-legend .aiv-legend-line { display: inline-block; width: 16px; height: 0; border-top: 2px solid var(--primary); margin-right: 5px; vertical-align: middle; }
.aiv-heat-lab, .aiv-axis { font-size: 9px; fill: var(--text-soft); }
/* 热力图画在 canvas 上：格子多时（n²）用 SVG 会塞进上万个节点 */
.aiv-heat-canvas { display: block; }
/* 图表悬停提示：跟随鼠标，贴边自动收进来（长文本可换行，不用 <title> 的原生提示） */
.aiv-tip-wrap { position: relative; }
.aiv-tip { position: absolute; z-index: 3; max-width: 240px; padding: 6px 9px; border-radius: 8px;
  background: rgba(28,24,30,.92); color: #fff; font-size: 12px; line-height: 1.5;
  word-break: break-word; pointer-events: none; }
/* hidden 在设了 display 的元素上会被覆盖，这里显式兜底（同 .chip-row[hidden]） */
.aiv-tip[hidden], .aiv-sc-wrap svg[hidden] { display: none; }
.aiv-hist-rect { fill: var(--primary); fill-opacity: .75; }
.aiv-hist-rect.hi { fill: var(--primary-deep); fill-opacity: 1; }
.aiv-hist-num { font-size: 9px; font-weight: 700; fill: var(--text); }
.aiv-cum { fill: none; stroke: #4a7fa5; stroke-width: 1.8; }

/* 语义分布：大画布 + 拖动平移 + 滚轮缩放（内容在画布内移动，不推挤页面） */
.aiv-sc-mode { margin-top: 8px; }
.aiv-sc-wrap {
  position: relative; margin-top: 8px;
  /* 正方形画布：边长取「容器宽」与「屏高 62%」里较小的那个并居中 ——
     语义平面的两个主轴等比，不会被容器拉成竖长条 */
  width: min(100%, 62vh); aspect-ratio: 1 / 1; margin-inline: auto;
  border: 1px solid var(--border); border-radius: 12px; background: var(--surface);
  /* 光标用 move（四向箭头）而不是 grab/grabbing：抓手是「无描边的白色手形」，
     落在纯白画布上几乎看不见（各桌面主题的光标字形由系统绘制，网页改不了颜色）。
     move 在常见主题里是深色箭头，同样表达「这块能拖动」。 */
  overflow: hidden; cursor: move; touch-action: none; overscroll-behavior: contain;
}
.aiv-sc-wrap svg { width: 100%; height: 100%; margin: 0; display: block; }
.aiv-sc-tools { position: absolute; right: 8px; top: 8px; display: flex; gap: 6px; }
.aiv-sc-tools button {
  border: 1px solid var(--border); background: rgba(255, 255, 255, .94); color: var(--text-soft);
  font: inherit; font-size: 12px; padding: 4px 10px; border-radius: 999px; cursor: pointer;
}
.aiv-sc-tools button:hover { color: var(--primary-deep); border-color: var(--primary); }
.aiv-sc-zoom {
  position: absolute; left: 8px; bottom: 8px; font-size: 11.5px; color: var(--text-soft);
  background: rgba(255, 255, 255, .9); border-radius: 999px; padding: 3px 9px;
}

/* 相似度热力图：格子尺寸多档 + 框内双向滚动（放大后平移查看局部）+ 行列高亮 */
.aiv-heat-wrap {
  position: relative; margin-top: 8px; max-height: min(460px, 60vh); overflow: auto;
  overscroll-behavior: contain; border: 1px solid var(--border); border-radius: 12px; background: var(--surface);
}
.aiv-heat-stage { position: relative; }
.aiv-heat-ov { position: absolute; left: 0; top: 0; width: 100%; height: 100%; pointer-events: none; }
.aiv-heat-row, .aiv-heat-col { position: absolute; background: rgba(74, 59, 64, .16); }
.aiv-median { stroke: var(--primary-deep); stroke-width: 1.2; stroke-dasharray: 3 3; }
/* 描一圈底色描边：否则标签压在同色高柱上会被吃掉第一个字 */
.aiv-median-lab { font-size: 9px; fill: var(--primary-deep); paint-order: stroke; stroke: var(--surface); stroke-width: 3px; stroke-linejoin: round; }

/* 相似度分布：结论摘要 + 最相似的前几对 */
.aiv-sum { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.aiv-sum .kv { background: var(--panel-soft); border-radius: 10px; padding: 7px 10px; font-size: 12px; color: var(--text-soft); }
.aiv-sum .kv b { color: var(--primary-deep); font-size: 13px; }
.aiv-tops { margin-top: 12px; border-top: 1px solid var(--border); }
.aiv-tops .ti { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--border); font-size: 12.5px; }
.aiv-tops .ti:last-child { border-bottom: 0; }
.aiv-tops .pct { flex: none; width: 42px; font-weight: 700; color: var(--primary-deep); }
.aiv-tops .tx { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-soft); }
/* 逐条向量列表：条目多的模块（如衣柜 43 条）限定高度、卡片内滚动，标题与说明不随之滚走 */
.aiv-rows { max-height: 420px; overflow-y: auto; overscroll-behavior-y: contain; }
.aiv-row { display: flex; align-items: center; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--border); }
.aiv-row:last-child { border-bottom: none; }
.aiv-row-idx {
  flex: none; width: 20px; height: 20px; border-radius: 50%;
  background: var(--btn-grad); color: var(--on-primary); font-size: 11px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.aiv-row-main { flex: 1; min-width: 0; }
.aiv-row-text {
  font-size: 13px; margin-bottom: 5px; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.aiv-off { font-size: 11px; color: var(--text-soft); }
.aiv-strip { display: flex; gap: 1px; height: 12px; border-radius: 3px; overflow: hidden; }
.aiv-strip span { flex: 1; }
.aiv-row-meta { flex: none; font-size: 11px; color: var(--text-soft); text-align: right; }


/* ================= 衣柜首页重设计（w2：移动端 / PC 端） ================= */
.w2-page, .w2-outfit-page { --w2-serif: "Songti SC", "Noto Serif SC", "Source Han Serif SC", Palatino, Georgia, serif; }
.w2-eyebrow {
  margin: 0; font-size: 9.5px; letter-spacing: .24em; text-transform: uppercase;
  color: var(--primary-deep); font-weight: 700;
}
.w2-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.w2-title {
  margin: 6px 0 4px; font-family: var(--w2-serif);
  font-size: 30px; line-height: 1.12; font-weight: 600; letter-spacing: -.02em; color: var(--text);
}
.w2-sub { font-size: 11.5px; color: var(--text-soft); line-height: 1.6; }
.w2-head-actions { display: flex; gap: 8px; flex: none; }
.w2-head-actions .iconbtn.is-rose { background: var(--btn-grad); border-color: transparent; color: var(--on-primary); }
.w2-head-actions .iconbtn.is-rose .ico { width: 18px; height: 18px; }
.w2-add-btn {
  flex: none; height: 36px; padding: 0 13px; border: 0; border-radius: 12px;
  background: var(--btn-grad); color: var(--on-primary);
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 600; box-shadow: var(--shadow-accent);
}
.w2-add-btn .ico { width: 14px; height: 14px; }

.w2-search-row { display: flex; align-items: center; gap: 8px; margin-top: 16px; }
.w2-search-wrap { margin-top: 16px; }
.w2-search-row .w2-search-wrap { flex: 1; min-width: 0; margin-top: 0; }
.w2-search-row .w2-add-btn { height: 46px; padding: 0 14px; border-radius: 14px; }
.w2-search-wrap .list-search { margin: 0; }
.w2-page.is-searching .w2-hero,
.w2-page.is-searching .w2-outfit-entry { display: none; }
/* 移动端：搜索行吸在顶栏下方，滚动列表时始终可搜索 / 添加。
   负外边距 + 同色内边距让吸顶块铺满内容区宽度，上下各留 8px 遮住滚动内容；
   总占用高度与原 margin-top:16px 一致，不改变首屏排版。 */
@media (max-width: 1023.98px) {
  .w2-search-row {
    position: sticky; top: var(--topbar-h); z-index: 15;
    background: var(--bg);
    margin: 8px -16px -8px; padding: 8px 16px;
  }
}

/* 今日搭配 hero */
.w2-hero {
  position: relative; overflow: hidden; margin-top: 16px; padding: 18px;
  border: 1px solid rgba(var(--primary-rgb), .16); border-radius: 24px;
  background:
    radial-gradient(120% 120% at 100% 0%, rgba(191, 154, 107, .14), transparent 55%),
    linear-gradient(135deg, rgba(var(--primary-rgb), .22), var(--panel-soft) 52%, rgba(var(--primary-rgb), .10));
  box-shadow: var(--shadow);
}
.w2-hero::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .32;
  background-image: radial-gradient(rgba(255, 255, 255, .65) .7px, transparent .7px);
  background-size: 7px 7px;
}
.w2-hero-copy { position: relative; z-index: 2; width: 58%; }
.w2-hero-kicker { margin: 0; font-size: 8.5px; letter-spacing: .22em; text-transform: uppercase; color: var(--primary-deep); font-weight: 700; }
.w2-hero h3 {
  margin: 9px 0 7px; font-family: var(--w2-serif);
  font-size: 21px; line-height: 1.32; font-weight: 600; color: var(--text);
}
.w2-hero p { margin: 0; font-size: 10.5px; line-height: 1.65; color: var(--text-soft); }
.w2-hero-cta {
  margin-top: 13px; display: inline-flex; align-items: center; gap: 5px;
  height: 32px; padding: 0 13px; border: 0; border-radius: 999px;
  background: var(--btn-grad); color: var(--on-primary); font-size: 10.5px; font-weight: 600;
  box-shadow: var(--shadow-accent);
}
.w2-hero-cta .ico { width: 12px; height: 12px; }
.w2-hero-art {
  position: absolute; z-index: 2; right: 14px; top: 16px;
  width: 115px; height: 148px; border-radius: 18px; overflow: hidden;
  border: 4px solid rgba(255, 255, 255, .92); background: var(--panel-soft);
  box-shadow: 0 14px 28px rgba(var(--accent-rgb), .20); transform: rotate(3.5deg);
}
.w2-hero-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.w2-hero-empty { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: var(--primary-deep); }
.w2-hero-empty .ico { width: 34px; height: 34px; opacity: .55; }
.w2-hero-tape {
  position: absolute; z-index: 3; right: 86px; top: 8px; width: 44px; height: 13px;
  background: rgba(255, 255, 255, .55); transform: rotate(-8deg);
}

/* 统计 / 分类 */
.w2-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 12px; }
.w2-stat {
  padding: 10px 11px; border: 1px solid var(--border); border-radius: 16px;
  background: var(--card); box-shadow: var(--shadow-soft);
}
.w2-stat b { display: block; font-family: var(--w2-serif); font-size: 18px; line-height: 1; font-weight: 600; color: var(--text); }
.w2-stat span { display: block; margin-top: 5px; font-size: 9px; letter-spacing: .05em; color: var(--text-soft); }
.w2-stat.is-accent b { color: var(--primary-deep); }

.w2-cats { display: flex; gap: 7px; overflow-x: auto; margin: 18px -16px 0; padding: 0 16px 2px; scrollbar-width: none; }
.w2-cats::-webkit-scrollbar { display: none; }
.w2-chip {
  flex: none; height: 32px; padding: 0 13px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--card); color: var(--text-soft);
  font-size: 11px; display: inline-flex; align-items: center; gap: 5px; transition: .18s ease;
}
.w2-chip b { font-size: 9px; font-weight: 500; opacity: .65; }
.w2-chip.is-on { background: var(--text); border-color: var(--text); color: var(--card); }
.w2-chip.is-on b { opacity: .72; }

.w2-section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin: 21px 0 11px; }
.w2-section-head h3 { margin: 0; font-family: var(--w2-serif); font-size: 17px; font-weight: 600; }
.w2-section-head span { font-size: 10.5px; color: var(--text-soft); }

/* 衣物卡片 */
.w2-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 11px; }
.w2-card {
  position: relative; padding: 7px; border: 1px solid var(--border); border-radius: 18px;
  background: var(--card); box-shadow: var(--shadow-soft); cursor: pointer;
  transition: transform .18s ease, box-shadow .18s ease;
}
.w2-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-hover); }
.w2-card:active { transform: scale(.985); }
.w2-card-media {
  position: relative; aspect-ratio: 3 / 4; border-radius: 12px; overflow: hidden;
  background: var(--bg); display: flex; align-items: center; justify-content: center;
}
.w2-card-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.w2-card-empty { color: var(--text-soft); opacity: .45; }
.w2-card-empty .ico { width: 28px; height: 28px; }
.w2-badge {
  position: absolute; bottom: 6px; left: 6px; padding: 2px 6px; border-radius: 999px;
  background: rgba(30, 22, 25, .52); color: #fff; font-size: 8.5px; line-height: 1.5;
  backdrop-filter: blur(4px);
}
.w2-fav-btn {
  position: absolute; top: 6px; right: 6px; z-index: 2;
  width: 28px; height: 28px; padding: 0; border: 0; border-radius: 50%;
  background: rgba(255, 253, 250, .86); color: #b7a2a8;
  display: flex; align-items: center; justify-content: center;
  backdrop-filter: blur(6px); transition: .18s ease;
}
.w2-fav-btn .ico { width: 14px; height: 14px; }
.w2-fav-btn:hover { color: var(--primary-deep); background: #fff; }
.w2-fav-btn.is-on { color: var(--primary-deep); background: #fff; }
.w2-fav-btn.is-on .ico { fill: currentColor; }
.w2-card-body { padding: 8px 3px 3px; }
.w2-card-name { font-size: 12.5px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.w2-card-meta { margin-top: 3px; font-size: 9.5px; color: var(--text-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.w2-card-price { margin-top: 4px; font-size: 10.5px; font-weight: 600; color: var(--primary-deep); }
.w2-empty {
  grid-column: 1 / -1; padding: 34px 12px; text-align: center; color: var(--text-soft);
  border: 1px dashed var(--border); border-radius: 18px; background: var(--panel-soft);
}
.w2-empty .ico { width: 30px; height: 30px; opacity: .45; }
.w2-empty p { margin: 8px 0 0; font-size: 12px; }

/* 穿搭入口 */
.w2-outfit-entry {
  display: flex; align-items: center; gap: 12px; margin-top: 18px; padding: 10px;
  border: 1px solid rgba(var(--primary-rgb), .24); border-radius: 22px;
  background: var(--panel-soft); cursor: pointer; transition: .18s ease;
}
.w2-outfit-entry:hover { border-color: var(--primary); box-shadow: var(--shadow); }
.w2-outfit-thumb {
  width: 78px; height: 78px; flex: none; border-radius: 16px; overflow: hidden;
  background: var(--card); display: flex; align-items: center; justify-content: center; color: var(--primary-deep);
}
.w2-outfit-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.w2-outfit-thumb .ico { width: 26px; height: 26px; opacity: .6; }
.w2-outfit-main { flex: 1; min-width: 0; }
.w2-outfit-title { margin-top: 4px; font-family: var(--w2-serif); font-size: 16px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.w2-outfit-sub { margin-top: 3px; font-size: 10px; color: var(--text-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.w2-outfit-arrow {
  flex: none; width: 30px; height: 30px; border-radius: 50%;
  background: var(--card); color: var(--primary-deep);
  display: flex; align-items: center; justify-content: center;
}
.w2-outfit-arrow .ico { width: 14px; height: 14px; }

/* 移动端详情抽屉 */
.w2-sheet-mask {
  position: fixed; inset: 0; z-index: 200; display: flex; align-items: flex-end;
  background: rgba(25, 17, 20, .42); animation: w2Fade .2s ease;
}
.w2-sheet {
  position: relative; width: 100%; max-width: 640px; margin: 0 auto;
  padding: 10px 18px calc(22px + env(safe-area-inset-bottom));
  border-radius: 26px 26px 0 0; background: var(--card); box-shadow: 0 -18px 50px rgba(0, 0, 0, .22);
  animation: w2SheetUp .28s cubic-bezier(.22, .8, .28, 1);
}
.w2-sheet-grab { width: 38px; height: 4px; border-radius: 4px; background: var(--border); margin: 0 auto 14px; }
.w2-sheet-close {
  position: absolute; top: 12px; right: 14px; width: 28px; height: 28px;
  border: 0; border-radius: 50%; background: var(--bg); color: var(--text-soft);
  font-size: 18px; line-height: 1;
}
.w2-sheet-top { display: flex; gap: 14px; }
.w2-sheet-media {
  width: 112px; height: 140px; flex: none; border-radius: 16px; overflow: hidden;
  background: var(--bg); display: flex; align-items: center; justify-content: center; color: var(--text-soft);
}
.w2-sheet-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.w2-sheet-empty .ico { width: 26px; height: 26px; opacity: .45; }
.w2-sheet-info { flex: 1; min-width: 0; padding-top: 4px; }
.w2-sheet-info h3 { margin: 4px 0 6px; font-family: var(--w2-serif); font-size: 21px; line-height: 1.3; font-weight: 600; padding-right: 22px; }
.w2-sheet-price { margin-top: 8px; font-size: 14px; font-weight: 700; color: var(--primary-deep); }
.w2-sheet-note { margin: 9px 0 0; font-size: 10.5px; line-height: 1.7; color: var(--text-soft); }
.w2-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
.w2-tag {
  display: inline-flex; align-items: center; height: 21px; padding: 0 8px;
  border-radius: 999px; background: var(--bg); color: var(--text-soft); font-size: 9px;
}
.w2-sheet-actions { display: flex; gap: 8px; margin-top: 16px; }
.w2-sheet-actions .btn { flex: 1; height: 43px; }
.w2-sheet-outfit { margin-top: 8px; height: 42px; }
@keyframes w2Fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes w2SheetUp { from { transform: translateY(40px); opacity: .6; } to { transform: none; opacity: 1; } }

/* 衣柜图片放大查看（原图）：铺满视口，支持滚轮 / 双指缩放与拖动 */
.w2-zoom {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(20, 14, 16, .94); animation: w2Fade .2s ease;
  overscroll-behavior: contain;
}
.w2-zoom-stage {
  position: absolute; inset: 0; overflow: hidden; display: flex; align-items: center; justify-content: center;
  padding: 56px 24px 48px; touch-action: none;
}
.w2-zoom-img {
  display: block; max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 8px;
  cursor: zoom-in; transform-origin: center center; will-change: transform;
  user-select: none; -webkit-user-drag: none;
}
.w2-zoom-img.is-zoomed { cursor: grab; }
.w2-zoom-img.is-grabbing { cursor: grabbing; }
.w2-zoom-close {
  position: absolute; top: 14px; right: 16px; z-index: 2; width: 34px; height: 34px;
  border: 0; border-radius: 50%; background: rgba(255, 255, 255, .14); color: #fff;
  font-size: 20px; line-height: 1;
}
.w2-zoom-tip {
  position: absolute; left: 0; right: 0; bottom: 14px; margin: 0; text-align: center;
  font-size: 10px; color: rgba(255, 255, 255, .55); pointer-events: none;
}

/* ================= PC 端衣柜工作台 ================= */
@media (min-width: 1024px) {
  .w2-page.w2-pc { padding-top: 2px; }
  /* 标题在左、操作区在右上角，同一行显示；滚动时固定在顶栏下方 */
  /* 头部吸附位置 = 顶栏 + 内容区原有的 16px 上内边距 + 页面 2px 上内边距。
     与自然位置完全一致，滚动时不会先跟着走 18px 再吸住。 */
  .w2-pc-head {
    position: sticky; top: calc(var(--topbar-h) + 18px); z-index: 12;
    display: flex; align-items: flex-start; justify-content: space-between; gap: 24px;
    padding-bottom: 16px; background: var(--bg);
  }
  /* 吸住后顶栏与头部之间的 18px 用同色块补齐，避免滚动内容从这道缝里透出 */
  .w2-pc-head::before {
    content: ""; position: absolute; left: 0; right: 0; bottom: 100%;
    height: 18px; background: var(--bg); pointer-events: none;
  }
  /* 头部与下方固定栏之间留 12px 呼吸区；用同色遮罩盖住缝隙 */
  .w2-pc-head::after {
    content: ""; position: absolute; left: 0; right: 0; top: 100%;
    height: 12px; background: var(--bg); pointer-events: none;
  }
  .w2-pc-head .w2-title { font-size: 28px; margin-top: 5px; }
  .w2-pc-actions { display: flex; align-items: center; gap: 9px; flex: none; }
  .w2-pc-search { width: 238px; }
  .w2-pc-search .list-search { margin: 0; }
  .w2-pc-filter-btn {
    height: 38px; padding: 0 13px; border: 1px solid var(--border); border-radius: 11px;
    background: var(--card); color: var(--text-soft);
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 11px; font-weight: 500; flex: none;
    /* 逐个属性列出，避免 transition: all 把布局属性也带进合成动画 */
    /* 缓动统一用无回弹的 ease-out（cubic-bezier(.22,.61,.36,1)），时长放到 .26s：动作更慢、更收 */
    transition: transform .26s cubic-bezier(.22, .61, .36, 1), border-color .26s ease,
                background .26s ease, color .26s ease, box-shadow .26s ease;
  }
  .w2-pc-filter-btn .ico { width: 14px; height: 14px; transition: transform .24s ease; }
  .w2-pc-filter-btn:hover {
    border-color: var(--primary-soft); color: var(--primary-deep);
    transform: translateY(-1px); box-shadow: 0 1px 6px rgba(var(--primary-rgb), .08);
  }
  .w2-pc-filter-btn:active { transform: scale(.975); }
  .w2-pc-filter-btn.is-on { background: var(--panel-soft); border-color: var(--primary-soft); color: var(--primary-deep); }
  /* 切换筛选栏时漏斗图标轻轻一收再回弹：筛选栏是瞬间显隐的，这一下给点按一个落点反馈。
     45% 处的形变量只有 scale(.92) / -4°，且缓动不带过冲，整体是「收一下再松开」而不是弹跳。
     由 JS 每次点击摘类 + 强制重排后重新加上，连续点按也能重播。 */
  .w2-pc-filter-btn.is-bump .ico { animation: w2FilterBump .46s cubic-bezier(.4, 0, .2, 1); }
  @keyframes w2FilterBump {
    0% { transform: scale(1) rotate(0); }
    45% { transform: scale(.92) rotate(-4deg); }
    100% { transform: scale(1) rotate(0); }
  }
  .w2-pc-add-btn { height: 38px; padding: 0 13px; font-size: 11px; border-radius: 11px; flex: none; }
  .w2-pc-add-btn .ico { width: 14px; height: 14px; }

  .w2-pc-ws {
    display: grid; grid-template-columns: 248px minmax(0, 1fr) 296px;
    gap: 16px; align-items: start; margin-top: 12px;
  }
  .w2-pc-ws.is-nofilter { grid-template-columns: minmax(0, 1fr) 296px; }
  .w2-pc-ws.is-nofilter .w2-filter { display: none; }

  .w2-filter {
    padding: 20px 18px; border: 1px solid var(--border); border-radius: 20px;
    background: var(--card); box-shadow: var(--shadow);
    position: sticky; top: calc(var(--topbar-h) + var(--w2-head-h, 105px) + 30px); z-index: 13;
    max-height: calc(100vh - var(--topbar-h) - var(--w2-head-h, 105px) - 46px); overflow-y: auto;
  }
  .w2-filter-block + .w2-filter-block { margin-top: 22px; }
  .w2-filter-title {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 10px; font-size: 10px; letter-spacing: .16em; text-transform: uppercase;
    color: var(--text-soft); font-weight: 700;
  }
  .w2-filter-title button {
    border: 0; background: transparent; padding: 0; color: var(--primary);
    font-size: 9.5px; letter-spacing: 0; text-transform: none;
  }
  .w2-filter-list { display: flex; flex-direction: column; gap: 3px; }
  .w2-filter-item {
    border: 0; background: transparent; display: flex; align-items: center; gap: 9px;
    padding: 8px 10px; border-radius: 9px; font-size: 12px; color: var(--text-soft);
    text-align: left; transition: .15s ease;
  }
  .w2-filter-item i { width: 7px; height: 7px; border-radius: 50%; background: var(--border); flex: none; }
  .w2-filter-item span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .w2-filter-item b { font-size: 10px; font-weight: 500; opacity: .7; }
  .w2-filter-item:hover { background: var(--bg); }
  .w2-filter-item.is-on { background: var(--panel-soft); color: var(--primary-deep); font-weight: 600; }
  .w2-filter-item.is-on i { background: var(--primary-deep); box-shadow: 0 0 0 3px rgba(var(--primary-rgb), .16); }
  .w2-color-row { display: flex; flex-wrap: wrap; gap: 7px; }
  .w2-color-dot {
    width: 24px; height: 24px; border-radius: 50%; border: 2px solid var(--card);
    background: var(--dot, var(--border)); box-shadow: 0 0 0 1px var(--border); padding: 0;
  }
  .w2-color-dot.is-on { box-shadow: 0 0 0 2px var(--primary-deep); }
  .w2-filter-chips { display: flex; flex-wrap: wrap; gap: 6px; }
  .w2-filter-chip {
    height: 28px; padding: 0 11px; border: 1px solid var(--border); border-radius: 999px;
    background: var(--card); color: var(--text-soft); font-size: 10.5px; max-width: 100%;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .w2-filter-chip.is-on { background: var(--text); border-color: var(--text); color: var(--card); }
  .w2-filter-empty { font-size: 11px; color: var(--text-soft); opacity: .7; }

  .w2-pc-center { min-width: 0; }
  .w2-pc-toolbar {
    position: sticky; top: calc(var(--topbar-h) + var(--w2-head-h, 105px) + 30px); z-index: 11;
    display: flex; align-items: center; gap: 10px;
    padding: 4px 0 8px; margin-bottom: 6px; background: var(--bg);
  }
  .w2-pc-toolbar .w2-pc-result-title { margin: 0; font-family: var(--w2-serif); font-size: 17px; line-height: 1.2; font-weight: 600; white-space: nowrap; }
  .w2-result-count { font-size: 9.5px; line-height: 1.2; color: var(--text-soft); }
  .w2-spacer { flex: 1; }
  /* 排序：复用全局自绘下拉 .dd，只把尺寸压到工具栏高度 */
  .w2-sort { position: relative; flex: none; }
  .w2-sort .dd { position: relative; }
  .w2-sort .dd-btn {
    width: auto; min-width: 132px; height: 31px;
    padding: 0 12px; border-radius: 9px;
    background: var(--card); color: var(--text-soft);
    font-size: 11px; font-weight: 500; line-height: 1.2;
  }
  .w2-sort .dd-btn:hover { border-color: var(--primary-soft); color: var(--text); }
  .w2-sort .dd.dd-open .dd-btn { border-color: var(--primary); background: var(--panel-soft); color: var(--primary-deep); }
  .w2-sort .dd-arrow { width: 5px; height: 5px; margin-right: 2px; border-width: 1.5px; }
  .w2-sort .dd-list { top: calc(100% + 6px); min-width: 132px; padding: 5px; border-radius: 12px; }
  .w2-sort .dd-opt { padding: 8px 10px; border-radius: 7px; font-size: 12px; }
  .w2-sort .dd-opt:hover { background: var(--bg); }
  .w2-sort .dd-opt.active { background: var(--primary-soft); color: var(--primary-deep); font-weight: 600; }
  .w2-view-toggle { display: inline-flex; padding: 2px; border: 1px solid var(--border); border-radius: 9px; background: var(--card); }
  .w2-view-toggle button {
    width: 27px; height: 25px; border: 0; border-radius: 7px; background: transparent;
    color: var(--text-soft); display: flex; align-items: center; justify-content: center;
  }
  .w2-view-toggle button .ico { width: 13px; height: 13px; }
  .w2-view-toggle button.is-on { background: var(--panel-soft); color: var(--primary-deep); }

  .w2-pc-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 13px; }
  .w2-pc-card {
    position: relative;
    padding: 7px; border: 1px solid var(--border); border-radius: 16px; background: var(--card);
    cursor: pointer; box-shadow: var(--shadow-soft);
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
  }
  .w2-pc-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-hover); border-color: var(--primary-soft); }
  .w2-pc-card.is-selected { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(var(--primary-rgb), .18), var(--shadow-soft); }
  .w2-pc-card-media {
    position: relative; aspect-ratio: 3 / 4; border-radius: 11px; overflow: hidden;
    background: var(--bg); display: flex; align-items: center; justify-content: center;
  }
  .w2-pc-card-media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .3s ease; }
  .w2-pc-card:hover .w2-pc-card-media img { transform: scale(1.035); }
  .w2-pc-card .w2-fav-btn { top: 13px; right: 13px; width: 25px; height: 25px; }
  .w2-pc-card .w2-fav-btn .ico { width: 12px; height: 12px; }
  .w2-pc-card-body { padding: 8px 4px 3px; }
  .w2-pc-card-meta { margin-top: 3px; display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: 8.5px; color: var(--text-soft); }
  .w2-pc-card-meta > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .w2-pc-card-meta .w2-card-price { margin: 0; flex: none; font-size: 9.5px; }
  .w2-pc-grid.is-list { grid-template-columns: 1fr; gap: 9px; }
  /* 列表卡片横向排版：收藏按钮固定在整张卡的右上角（不是缩略图右上角），
     右侧留 40px 给它，标题不会伸到按钮底下。 */
  .w2-pc-grid.is-list .w2-pc-card { display: flex; align-items: center; gap: 12px; padding: 7px 40px 7px 7px; }
  .w2-pc-grid.is-list .w2-pc-card .w2-fav-btn { top: 8px; right: 10px; }
  .w2-pc-grid.is-list .w2-pc-card-media { width: 64px; flex: none; aspect-ratio: 3 / 4; }
  .w2-pc-grid.is-list .w2-pc-card-body { flex: 1; min-width: 0; padding: 0; }
  .w2-pc-grid.is-list .w2-pc-card-meta { justify-content: flex-start; gap: 10px; }

  .w2-detail {
    padding: 20px 18px 26px; border: 1px solid var(--border); border-radius: 20px;
    background: var(--panel-soft); box-shadow: var(--shadow);
    position: sticky; top: calc(var(--topbar-h) + var(--w2-head-h, 105px) + 30px); z-index: 13;
    max-height: calc(100vh - var(--topbar-h) - var(--w2-head-h, 105px) - 46px); overflow-y: auto;
  }
  .w2-detail-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 11px; }
  .w2-detail-head span { font-size: 9px; letter-spacing: .18em; text-transform: uppercase; color: var(--text-soft); font-weight: 700; }
  .w2-detail-body { padding-top: 13px; }
  .w2-detail-media { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; border-radius: 14px; display: block; background: var(--bg); cursor: zoom-in; }
  .w2-detail-media.is-empty { display: flex; align-items: center; justify-content: center; color: var(--text-soft); }
  .w2-detail-media.is-empty .ico { width: 30px; height: 30px; opacity: .45; }
  .w2-detail-name { margin: 0; font-family: var(--w2-serif); font-size: 21px; line-height: 1.3; font-weight: 600; }
  .w2-detail-price { margin-top: 7px; font-size: 15px; font-weight: 700; color: var(--primary-deep); }
  .w2-detail-price.is-empty { color: var(--text-soft); font-weight: 500; opacity: .7; }
  .w2-rows { margin-top: 13px; border-top: 1px solid var(--border); }
  .w2-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 10px; }
  .w2-row span { flex: none; color: var(--text-soft); }
  .w2-row b { font-weight: 600; text-align: right; word-break: break-word; }
  .w2-row b.is-missing { color: var(--text-soft); font-weight: 500; opacity: .6; }
  .w2-fav-link { border: 0; background: transparent; padding: 0; color: var(--text-soft); font-size: 10px; font-weight: 600; }
  .w2-fav-link.is-on { color: var(--primary-deep); }
  .w2-detail-actions { display: flex; gap: 7px; margin-top: 14px; }
  .w2-detail-actions .btn { flex: 1; height: 38px; font-size: 11px; border-radius: 11px; }
  .w2-detail-actions .btn-primary { flex: 1.3; }
  .w2-ai-btn {
    width: 100%; height: 36px; margin-top: 8px; border: 1px dashed rgba(var(--primary-rgb), .42);
    border-radius: 11px; background: var(--panel-soft); color: var(--primary-deep);
    font-size: 10.5px; font-weight: 600; display: flex; align-items: center; justify-content: center; gap: 6px;
  }
  .w2-ai-btn .ico { width: 13px; height: 13px; }
  .w2-detail-empty { padding: 46px 8px; text-align: center; color: var(--text-soft); }
  .w2-detail-empty .ico { width: 28px; height: 28px; opacity: .45; }
  .w2-detail-empty p { margin: 8px 0 0; font-size: 11px; }
  .w2-rec { margin-top: 18px; }
  .w2-rec h4 { margin: 0 0 8px; font-size: 9px; letter-spacing: .18em; text-transform: uppercase; color: var(--text-soft); }
  .w2-rec-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 7px; }
  .w2-rec-item { border: 0; padding: 0; background: transparent; text-align: left; min-width: 0; }
  .w2-rec-media { display: flex; width: 100%; aspect-ratio: 3 / 4; border-radius: 9px; overflow: hidden; background: var(--bg); color: var(--text-soft); align-items: center; justify-content: center; }
  .w2-rec-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .w2-rec-media .ico { width: 18px; height: 18px; opacity: .45; }
  .w2-rec-item > span:last-child { display: block; margin-top: 4px; font-size: 8.5px; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

@media (min-width: 1024px) and (max-width: 1279px) {
  .w2-pc-ws { grid-template-columns: 216px minmax(0, 1fr) 258px; gap: 12px; }
  .w2-pc-ws.is-nofilter { grid-template-columns: minmax(0, 1fr) 258px; }
  .w2-pc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1560px) {
  .w2-pc-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* 穿搭列表页 */
.w2-outfit-page .w2-title { margin-bottom: 4px; }
.w2-outfit-feature {
  position: relative; overflow: hidden; border-radius: 24px; cursor: pointer;
  box-shadow: var(--shadow); margin: 0 auto 4px; max-width: 480px;
}
/* 穿搭设定图由 AI 生成（默认 3:4 竖版，比例可在设置里改），内容本身就是一整张「穿搭设定图」。
   原来固定 16:10 横版 + cover，会把竖版海报上下裁掉近一半；改为按原始比例完整展示：
   容器以 3:4 兜底（加载中 / 空态不塌陷），图片 contain 居中 —— 换成其它比例也只留边、不裁切。 */
.w2-outfit-feature-media { aspect-ratio: 3 / 4; background: var(--bg); }
.w2-outfit-feature-media img { width: 100%; height: 100%; object-fit: contain; display: block; }
.w2-outfit-feature-media > span { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: var(--primary-deep); }
.w2-outfit-feature-media > span .ico { width: 36px; height: 36px; opacity: .55; }
.w2-outfit-feature::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(25, 17, 20, 0) 38%, rgba(25, 17, 20, .66));
}
.w2-outfit-feature-copy { position: absolute; left: 16px; right: 16px; bottom: 14px; z-index: 2; color: #fff; }
.w2-outfit-feature-copy .w2-eyebrow { color: rgba(255, 255, 255, .82); }
.w2-outfit-feature-copy h3 { margin: 5px 0 4px; font-family: var(--w2-serif); font-size: 21px; font-weight: 600; }
.w2-outfit-feature-copy p:last-child { margin: 0; font-size: 10px; opacity: .86; }

/* 搭配列表：左侧重点搭配，右侧「我的穿搭」 */
.w2-outfit-overview { display: grid; grid-template-columns: 1fr; gap: 14px; }
.w2-outfit-left { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.w2-outfit-left .w2-outfit-feature { max-width: 300px; margin: 0 auto; }
.w2-outfit-dots {
  position: absolute; top: 12px; right: 12px; z-index: 3;
  display: flex; gap: 4px; padding: 4px 6px; border-radius: 999px;
  background: rgba(30, 22, 25, .35); backdrop-filter: blur(6px); pointer-events: none;
}
.w2-outfit-dots i { width: 5px; height: 5px; border-radius: 50%; background: rgba(255, 255, 255, .55); transition: .2s ease; }
.w2-outfit-dots i.is-on { width: 12px; border-radius: 3px; background: #fff; }
.w2-outfit-leftbar {
  border: 1px solid var(--border); border-radius: 20px; padding: 14px 16px;
  background: var(--card); display: flex; flex-direction: column; gap: 12px;
}
.w2-outfit-stats { display: flex; gap: 18px; flex-wrap: wrap; }
.w2-outfit-stats b { display: block; font-family: var(--w2-serif); font-size: 20px; font-weight: 600; color: var(--text); }
.w2-outfit-stats span { font-size: 9.5px; color: var(--text-soft); }
.w2-outfit-notes-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.w2-outfit-right { min-width: 0; }
.w2-outfit-right .w2-section-head { margin-top: 0; }
.w2-outfit-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 11px; }
.w2-outfit-card .w2-tags { margin-top: 6px; }
@media (min-width: 1024px) {
  /* 左栏 2 份、右侧列表 3 份；右侧三列排布（7 套 → 三排） */
  .w2-outfit-overview { grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 18px; align-items: start; }
  .w2-outfit-leftbar { padding: 16px 18px; }
  .w2-outfit-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
  /* 左栏重点图：跟随栏宽自适应缩放；再用可视高度兜底，避免吸顶栏过高导致图片底部不可见 */
  .w2-outfit-left .w2-outfit-feature {
    max-width: 100%;
    width: min(100%, calc((100vh - 330px) * .75));
  }
  /* 穿搭页：页头与左栏固定，右侧搭配列表独立滚动 */
  .w2-outfit-page .w2-head {
    position: sticky; top: var(--topbar-h, 52px); z-index: 14;
    background: var(--bg); padding-bottom: 12px;
  }
  .w2-outfit-left {
    position: sticky;
    top: calc(var(--topbar-h, 52px) + var(--w2-head-h, 105px) + 16px);
    align-self: start;
  }
}

/* ================= 衣柜添加 / 编辑页 ================= */
.w3-page { --w3-serif: "Songti SC", "Noto Serif SC", "Source Han Serif SC", Palatino, Georgia, serif; }
.w3-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 18px; }
.w3-eyebrow { margin: 0; font-size: 9.5px; letter-spacing: .24em; text-transform: uppercase; color: var(--primary-deep); font-weight: 700; }
.w3-title { margin: 6px 0 4px; font-family: var(--w3-serif); font-size: 28px; line-height: 1.12; font-weight: 600; letter-spacing: -.02em; color: var(--text); }
.w3-sub { font-size: 11.5px; line-height: 1.65; color: var(--text-soft); }
.w3-status { flex: none; padding: 4px 10px; border-radius: 999px; background: var(--panel-soft); border: 1px solid var(--border); color: var(--primary-deep); font-size: 9.5px; letter-spacing: .08em; }
.w3-layout { display: flex; flex-direction: column; gap: 12px; }
.w3-card { padding: 16px; border: 1px solid var(--border); border-radius: 20px; background: var(--card); box-shadow: var(--shadow); }
.w3-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.w3-card-head h3 { margin: 0; font-family: var(--w3-serif); font-size: 16px; font-weight: 600; color: var(--text); }
.w3-card-head p { margin: 4px 0 0; font-size: 10px; line-height: 1.6; color: var(--text-soft); }
.w3-count { flex: none; padding: 3px 8px; border-radius: 999px; background: var(--panel-soft); border: 1px solid var(--border); color: var(--primary-deep); font-size: 9.5px; }
.w3-two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.w3-hint { margin: 10px 0 0; font-size: 10px; line-height: 1.7; color: var(--text-soft); }
.w3-exec-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 2px; }
.w3-exec-row .btn { height: 42px; padding: 0 6px; border-radius: 12px; font-size: 12px; white-space: nowrap; }
.w3-note-ai { flex: none; width: 34px; height: 34px; border-radius: 11px; background: transparent; color: var(--primary-deep); }
.w3-actions { display: flex; gap: 10px; margin-top: 2px; }
.w3-actions .btn { height: 46px; border-radius: 14px; font-size: 13.5px; }
.w3-actions #saveWardrobe { flex: 2; }
.w3-actions #delWardrobe { flex: 1; }
.w3-page .field { margin-bottom: 12px; }
.w3-page .field:last-child { margin-bottom: 0; }
.w3-page .field label { margin-bottom: 6px; font-size: 11.5px; letter-spacing: .02em; }
.w3-page .field input,
.w3-page .field textarea,
.w3-page .dd-btn { padding: 11px 13px; border-radius: 13px; font-size: 14px; }
.w3-page .field textarea { min-height: 96px; }
.w3-photo-grid { gap: 8px; }
.w3-photo-grid .wphoto-cell { border-radius: 16px; border: 1.5px dashed var(--border); background: var(--bg); }
.w3-photo-grid .wphoto-cell.active { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(var(--primary-rgb), .18); }
.w3-photo-grid .wphoto-add { font-size: 32px; color: var(--primary-deep); }
.w3-photo-grid .wphoto-label { left: 6px; right: auto; bottom: 6px; padding: 2px 7px; border-radius: 999px; background: rgba(255, 253, 250, .9); color: var(--text-soft); font-size: 9.5px; text-align: left; }
.w3-photo-grid .wphoto-cell:first-child::before {
  content: "封面"; position: absolute; top: 6px; left: 6px; z-index: 2;
  padding: 2px 7px; border-radius: 999px; background: rgba(255, 253, 250, .9);
  color: var(--primary-deep); font-size: 9px; font-weight: 600;
}
.w3-photo-grid .wphoto-del { top: 6px; right: 6px; width: 22px; height: 22px; }
@media (max-width: 1023.98px) {
  .w3-col { display: contents; }
  .w3-card--photos { order: 1; }
  .w3-card--ai { order: 2; }
  .w3-card--info { order: 3; }
  .w3-card--purchase { order: 4; }
  .w3-card--note { order: 5; }
  .w3-actions { order: 6; }
}
@media (min-width: 1024px) {
  .w3-head { margin-bottom: 20px; }
  .w3-title { font-size: 30px; }
  .w3-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
    gap: 18px;
    align-items: start;
  }
  .w3-col { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
  .w3-col--right .w3-actions { margin-top: 0; }
}
body.dark .w3-photo-grid .wphoto-label,
body.dark .w3-photo-grid .wphoto-cell:first-child::before { background: rgba(30, 24, 26, .82); }

/* 搜索框在衣柜页略微加高，贴近设计稿 */
.w2-search-wrap .list-search-input { padding-top: 13px; padding-bottom: 13px; border-radius: 15px; }
.w2-pc-search .list-search-input { height: 38px; padding: 0 40px; border-radius: 11px; font-size: 12px; }

/* 图片加载前 / 失败时的底衬图标 */
.w2-card-ph {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: var(--text-soft); opacity: .18; pointer-events: none;
}
.w2-card-ph .ico { width: 34px; height: 34px; }
.w2-card-media img, .w2-pc-card-media img { position: relative; z-index: 1; }

/* 深色模式：抽屉与色点保持可读 */
body.dark .w2-hero { background: linear-gradient(135deg, rgba(var(--primary-rgb), .22), var(--panel-soft) 55%, rgba(var(--primary-rgb), .12)); }
body.dark .w2-hero-art { border-color: rgba(0, 0, 0, .35); }
body.dark .w2-badge { background: rgba(0, 0, 0, .62); }
body.dark .w2-color-dot { border-color: var(--card); }
body.dark .w2-fav-btn { background: rgba(0, 0, 0, .52); color: #c9b8bc; }
body.dark .w2-fav-btn:hover,
body.dark .w2-fav-btn.is-on { background: #2b2325; color: var(--primary); }

/* ===== 上传来源选择（相册 / 相机） ===== */
.up-src { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.up-src-btn {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 18px 10px; border: 1px solid var(--border); border-radius: 16px;
  background: var(--surface); color: var(--text); cursor: pointer; text-align: center;
}
.up-src-btn:hover { border-color: var(--primary); background: var(--panel-soft); }
.up-src-ico { color: var(--primary-deep); }
.up-src-ico .ico { width: 30px; height: 30px; }
.up-src-btn b { font-size: 14px; }

/* ===== 相机页（拍照 + 录像）===== */
.cam-page { position: fixed; inset: 0; z-index: 400; background: #000; color: #fff; overflow: hidden; }
.cam-preview { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; background: #000; }
.cam-top {
  position: absolute; top: 0; left: 0; right: 0; z-index: 2;
  display: flex; align-items: center; justify-content: space-between;
  padding: calc(12px + env(safe-area-inset-top)) 16px 12px;
  background: linear-gradient(rgba(0, 0, 0, .55), transparent);
}
.cam-title { font-size: 15px; font-weight: 600; }
.cam-ib {
  width: 38px; height: 38px; display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%; background: rgba(0, 0, 0, .35); color: #fff; cursor: pointer;
}
.cam-ib .ico { width: 22px; height: 22px; }
.cam-bottom {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  display: flex; flex-direction: column; align-items: center; gap: 16px;
  padding: 16px 20px calc(24px + env(safe-area-inset-bottom));
  background: linear-gradient(transparent, rgba(0, 0, 0, .65));
}
.cam-modes { display: flex; gap: 8px; background: rgba(255, 255, 255, .14); border-radius: 999px; padding: 4px; }
.cam-mode { border: 0; background: transparent; color: rgba(255, 255, 255, .75); font-size: 13px; padding: 6px 16px; border-radius: 999px; cursor: pointer; }
.cam-mode.on { background: #fff; color: #111; font-weight: 600; }
.cam-shutter-row { display: flex; align-items: center; justify-content: center; gap: 18px; width: 100%; }
.cam-timer, .cam-timer-gap { width: 56px; text-align: center; font-size: 13px; color: #fff; font-variant-numeric: tabular-nums; }
.cam-shutter {
  width: 72px; height: 72px; border-radius: 50%;
  border: 4px solid rgba(255, 255, 255, .85); background: #fff; cursor: pointer;
  transition: transform .12s ease, background .12s ease, border-radius .12s ease;
}
.cam-shutter:active { transform: scale(.94); }
.cam-shutter.video { background: #ff4d4f; border-color: rgba(255, 255, 255, .9); }
.cam-shutter.recording { width: 52px; height: 52px; border-radius: 16px; transform: scale(.9); }
.cam-hint { position: absolute; inset: 0; z-index: 3; display: flex; align-items: center; justify-content: center; padding: 24px; background: rgba(0, 0, 0, .72); }
.cam-hint-box { max-width: 360px; background: var(--card); color: var(--text); border-radius: 18px; padding: 20px; text-align: center; }
.cam-hint-box p { margin: 0 0 16px; font-size: 13.5px; line-height: 1.6; }
.cam-hint-acts { display: flex; gap: 10px; }
.cam-hint-acts .btn { flex: 1; margin: 0; }
.cam-review { position: absolute; inset: 0; z-index: 3; background: #000; display: flex; flex-direction: column; }
.cam-review-body { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; background: #000; }
.cam-review-body img, .cam-review-body video { max-width: 100%; max-height: 100%; object-fit: contain; }
.cam-review-acts { display: flex; gap: 12px; padding: 16px 20px calc(24px + env(safe-area-inset-bottom)); }
.cam-review-acts .btn { flex: 1; margin: 0; }
/* hidden 会输给上面的 display:flex，显式兜底 */
.cam-hint[hidden], .cam-bottom[hidden], .cam-review[hidden] { display: none; }

/* 视频缩略：铺满宿主格子（宿主沿用 <img> 的既有尺寸规则） */
.media-thumb { width: 100%; height: 100%; object-fit: cover; display: block; background: #000; border-radius: inherit; }
/* 视频缩略的外层：承载居中播放键与右下角时长，并沿用宿主的圆角 / 裁切 */
.media-thumb-wrap {
  position: relative; display: block; width: 100%; height: 100%;
  border-radius: inherit; overflow: hidden; background: #000;
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
  /* 双击用于进全屏，关掉浏览器自己的双击缩放；单指滚动 / 双指缩放仍保留 */
  touch-action: manipulation;
}
/* 封面图（poster）或首帧到位前先铺骨架微光：视频元素自身透明，画上帧就把这层盖住 */
.media-thumb-wrap::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(100deg, #191919 30%, #2c2c2c 50%, #191919 70%);
  background-size: 200% 100%;
  animation: skelSweep 1.1s linear infinite;
}
.media-thumb-wrap > .media-thumb {
  position: relative; z-index: 1; background: transparent;
  width: 100%; height: 100%; object-fit: cover; display: block;
}
@media (prefers-reduced-motion: reduce) {
  .post .thumb::before, .diary-body .thumb::before, .media-thumb-wrap::before { animation: none; }
}
.media-thumb-wrap .mv-play {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 2;
  width: clamp(16px, 38%, 44px); aspect-ratio: 1;
  color: rgba(255,255,255,.92);
  filter: drop-shadow(0 2px 8px rgba(0,0,0,.38));
  pointer-events: none;
  transition: opacity .15s ease, transform .15s ease;
}
.media-thumb-wrap .mv-play-ico { width: 100%; height: 100%; display: block; }
.media-thumb-wrap.is-playing .mv-play { opacity: 0; transform: translate(-50%, -50%) scale(.9); }
.media-thumb-wrap .mv-dur {
  position: absolute; right: 5px; bottom: 5px; z-index: 2;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 26px; padding: 1px 6px; border-radius: 999px;
  background: rgba(0,0,0,.58); color: #fff;
  font-size: 10px; font-weight: 700; line-height: 1.55;
  font-variant-numeric: tabular-nums; text-align: center;
  pointer-events: none;
}
.media-thumb-wrap .mv-dur[hidden] { display: none; }
/* 就地播放进度条：贴底 3px；只在播过之后出现，未播放的缩略图底部不挂黑边 */
.media-thumb-wrap .mv-prog {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3; height: 3px;
  background: rgba(0, 0, 0, .32);
  opacity: 0; transition: opacity .15s ease;
  pointer-events: none;
}
.media-thumb-wrap.has-prog .mv-prog { opacity: 1; }
.media-thumb-wrap .mv-prog > i {
  display: block; height: 100%; width: 0;
  background: #fff; transition: width .12s linear;
}
/* 小尺寸缩略（定位点 / 待上传 / 同色推荐）：角标收紧一档，避免盖住画面 */
.vmap-pin-thumb .mv-dur, .up-thumb .mv-dur, .ck-thumb .mv-dur, .ck-menu-thumb .mv-dur {
  right: 3px; bottom: 3px; min-width: 20px; padding: 0 4px; font-size: 8.5px;
}
.vmap-pin-thumb .mv-play, .up-thumb .mv-play, .ck-thumb .mv-play, .ck-menu-thumb .mv-play { width: clamp(14px, 34%, 28px); }
/* 公开展示页的九宫格是直接子元素、没有固定高度的宿主：由外层给方形比例 */
.sp-imgs .media-thumb-wrap { height: auto; aspect-ratio: 1; border-radius: 10px; }
.sp-imgs .media-thumb { height: auto; aspect-ratio: 1; border-radius: 10px; }
/* 单图相册：格子高度由内容决定，外层别再写死 100% 高度 */
.album-grid.single .media-thumb-wrap { height: auto; }
/* 独立视频的角标（与 LIVE 错开位置：LIVE 在右下、视频在左下） */
.vid-mini {
  position: absolute; left: 6px; bottom: 6px; z-index: 2; padding: 1px 6px; border-radius: 999px;
  background: rgba(0, 0, 0, .55); color: #fff; font-size: 10px; font-weight: 700;
}
/* 查看器里的独立视频：与主图同尺寸约束；控制条由 JS 自绘，不再使用原生 controls */
.vw-video { background: #000; border-radius: 4px; touch-action: none; }
.vw-video[hidden] { display: none !important; }

/* 视频加载 / 失败 / 中央播放按钮 */
.vw-video-loading, .vw-video-error {
  position: absolute; inset: 0; z-index: 3;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  color: rgba(255,255,255,.82); font-size: 13px;
  pointer-events: none;
}
.vw-video-loading .ld-svg { width: 30px; height: 30px; }
.vw-video-error { pointer-events: auto; }
.vw-video-error .btn { pointer-events: auto; }
.vw-video-bigplay {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 4;
  width: 72px; height: 72px; border: 0; border-radius: 50%;
  background: rgba(0, 0, 0, .52); color: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  backdrop-filter: blur(4px);
}
.vw-video-bigplay .ico { width: 30px; height: 30px; margin-left: 3px; }
.vw-video-bigplay:active { transform: translate(-50%, -50%) scale(.94); }

/* 底部自绘控制条：播放 / 进度 / 时间 / 静音 / 全屏 */
.vw-video-ctl {
  position: absolute; left: 50%; bottom: calc(16px + env(safe-area-inset-bottom));
  transform: translateX(-50%); z-index: 4;
  width: min(86%, 560px);
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border-radius: 14px;
  background: rgba(0, 0, 0, .62); color: #fff;
  backdrop-filter: blur(8px);
  transition: opacity .2s ease, transform .2s ease;
}
.vw-video-ctl.is-hidden { opacity: 0; pointer-events: none; transform: translateX(-50%) translateY(6px); }
.vw-video-btn {
  flex: none; width: 32px; height: 32px; border: 0; border-radius: 50%;
  background: transparent; color: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.vw-video-btn:hover { background: rgba(255,255,255,.14); }
.vw-video-btn .ico { width: 20px; height: 20px; }
.vw-video-time { flex: none; font-size: 12px; font-variant-numeric: tabular-nums; color: rgba(255,255,255,.85); white-space: nowrap; }
.vw-video-progress {
  position: relative; flex: 1; min-width: 60px; height: 4px; border-radius: 2px;
  background: rgba(255,255,255,.26); cursor: pointer; touch-action: none;
}
/* 扩大进度条的触控热区，4px 高的细条用手指很难点准 */
.vw-video-progress::before { content: ""; position: absolute; inset: -12px 0; }
.vw-video-progress i { display: block; height: 100%; width: 0; background: var(--primary); border-radius: inherit; }
.vw-video-progress:focus-visible { outline: 2px solid rgba(255,255,255,.7); outline-offset: 6px; }
@media (max-width: 1023px) {
  .vw-video-ctl { width: calc(100% - 24px); bottom: calc(10px + env(safe-area-inset-bottom)); gap: 8px; }
  .vw-video-time { font-size: 11px; }
}
/* 全屏时舞台自己占满屏幕：控制条仍在舞台内，不会随 <video> 单独全屏而消失 */
.vw-stage:fullscreen, .vw-stage:-webkit-full-screen { width: 100%; height: 100%; padding: 0; background: #000; }
/* 全屏播放：视频按屏幕最大化并保持比例，左右/上下留黑边而不是被裁切 */
.vw-stage:fullscreen .vw-video, .vw-stage:-webkit-full-screen .vw-video {
  width: 100%; height: 100%; max-width: 100%; max-height: 100%;
  object-fit: contain; border-radius: 0;
}
/* 全屏下不需要翻页箭头 / 点按区，避免挡住画面与控制条 */
.vw-stage:fullscreen .vw-nav, .vw-stage:fullscreen .vw-hit,
.vw-stage:-webkit-full-screen .vw-nav, .vw-stage:-webkit-full-screen .vw-hit { display: none; }
/* 衣柜详情 / 抽屉里的视频：沿用图片层的宽度与裁切比例（高度交给 aspect-ratio / 容器） */
.w2-detail-media.media-thumb { height: auto; }
.w2-sheet-media.media-thumb { width: 100%; height: 100%; }
/* 衣柜视频播放层 */
.w2-zoom-video .w2-zoom-stage video { max-width: 100%; max-height: 100%; background: #000; border-radius: 6px; }

/* ===== PWA：离线提示 / 新版本提示 =====
   浮在顶栏下方、不参与布局流，避免挤压页面内容；层级高于顶栏(20)、低于下拉(90)与弹窗(100)。 */
.pwa-offline-bar, .pwa-update-bar {
  position: fixed; left: 50%; transform: translateX(-50%);
  top: calc(var(--topbar-h) + env(safe-area-inset-top) + 6px);
  z-index: 30;
  display: flex; align-items: center; gap: 10px;
  max-width: min(92vw, 420px);
  padding: 7px 14px; border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--card); color: var(--text);
  font-size: 12.5px; line-height: 1.4;
  box-shadow: var(--shadow-float-sm);
}
.pwa-offline-bar[hidden], .pwa-update-bar[hidden] { display: none; }
.pwa-update-bar button {
  flex: none; padding: 3px 10px; border-radius: 999px; cursor: pointer;
  border: 0; background: var(--btn-grad); color: var(--on-primary);
  font-size: 12.5px; font-weight: 600;
}

/* ===== 减少动态效果：关闭装饰性运动，保留状态与操作 =====
   系统开启「减少动态效果」时，去掉入场位移、循环动画与幻灯片转场；
   加载 / 进度类指示保留（它们是状态反馈，不是装饰）。 */
@media (prefers-reduced-motion: reduce) {
  .page,
  .modal-mask, .modal,
  .toast,
  .vw, .vw-photo.ss-fade, .vw-photo.ss-slide, .vw-photo.ss-zoom, .vw-photo.ss-dissolve,
  .vw-more, .vw-dlg, .vw-toast,
  .w2-sheet-mask, .w2-sheet, .w2-zoom,
  .w2-pc-filter-btn.is-bump .ico,
  .topbar-btn.bell.has-unread .bell-svg, .topbar-btn.bell.has-unread .bell-dot,
  .theme-btn.spinning .icon-sun, .theme-btn.spinning .icon-moon,
  .couple-avatars .heart, .couple-avatars .arco-avatar, .ab-heart,
  .dissolve-blackout-hint, .dissolve-tl-title.typing::after,
  .parallax > use,
  .thumb-live.playing .vw-ray, .vw-ib:hover .vw-ray, #vwLiveBadge.playing .vw-ray { animation: none !important; }
  .page, .tabbar, .modal, .toast, .w2-sheet, .vw-more, .vw-dlg, .ui-tip, .vw-video-ctl { transition: none !important; }
  /* 纯装饰的 canvas / SVG 层不显示，避免后台持续动画 */
  .dissolve-sakura, .fish-sea, .waves { display: none !important; }
  /* 幻灯片切换不做位移与缩放，直接呈现目标图 */
  .vw-photo.ss-slide, .vw-photo.ss-zoom { translate: none !important; scale: none !important; }
}

/* ===== 允许双指缩放后的输入框字号 =====
   iOS 会为 font-size < 16px 的输入框在聚焦时自动放大页面，导致布局跳动。
   移动端把常用输入控件统一到 16px；桌面端保持原有 15px。 */
@media (max-width: 1023px) {
  .field input, .field textarea, .field select,
  .ck-field input, .ck-field textarea,
  .list-search-input, .cmt-input { font-size: 16px; }
}

/* ===== 列表加载骨架屏 =====
   只负责「结构已知、数据未回」的列表位；整页未知结构仍用 loaderHTML。
   占位条不单独定高，而是放进真实行的文字节点里（.sk-bar 的盒高取 1.2em），
   行高继续由真实样式决定；真实文字替换后行盒高度不变，避免切换跳版。
   骨架对读屏隐藏，由 .sr-only 的 role=status 统一报「正在加载」。 */
:root {
  --sk-base: rgba(74, 59, 64, .10);
  --sk-sheen: rgba(255, 255, 255, .55);
}
body.dark:not(.is-showcase):not(.is-auth) {
  --sk-base: rgba(255, 255, 255, .10);
  --sk-sheen: rgba(255, 255, 255, .07);
}
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* 扫光覆盖层：一块区域只有一道，统一方向与节奏；内容就位时整块被替换，动画自然停止 */
.sk-sheen {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none;
  z-index: 3; border-radius: inherit;
}
.sk-sheen::before {
  content: ""; position: absolute; top: -20%; bottom: -20%; left: -35%; width: 35%;
  background: linear-gradient(100deg, transparent 0%, var(--sk-sheen) 50%, transparent 100%);
  animation: sk-sweep 1.4s ease-in-out infinite;
}
@keyframes sk-sweep {
  from { transform: translateX(0); }
  to { transform: translateX(420%); }
}
@media (prefers-reduced-motion: reduce) {
  .sk-sheen { display: none; }
}
/* 文本占位条：默认盒高 1.2em，视觉条 0.68em 居中；在 flex 行里也能撑出与文字相近的行高。
   行高特殊的行用 --sk-bar-h 单独校准，保证占位与真实文字的行盒一致。 */
.sk-bar {
  display: inline-block; width: 60px; max-width: 100%; height: var(--sk-bar-h, 1.2em);
  vertical-align: middle; flex: none;
}
.sk-bar::before {
  content: ""; display: block; width: 100%; height: .68em;
  margin-top: calc((var(--sk-bar-h, 1.2em) - .68em) / 2);
  border-radius: 999px; background: var(--sk-base);
}
/* 日常标题是 15px 粗体，实际行高约 1.4em；普通占位条 1.2em 会矮 3px，数据换上来时标题行会轻微下移 */
.post .p-title .sk-bar { --sk-bar-h: 1.4em; }
.ck-page .ck-title .sk-bar { --sk-bar-h: 1.4em; }
.pd-hist-date .sk-bar { --sk-bar-h: 1.5em; }
.pd-hist-meta .sk-bar { --sk-bar-h: 1.4em; }
.tk-item-title .sk-bar { --sk-bar-h: 1.1em; }
.tk-item-sub .sk-bar { --sk-bar-h: 1.4em; }
/* 多行摘要：显式给行高，行数与真实摘要一致，整段高度可预测 */
.sk-line { display: flex; align-items: center; height: var(--sk-lh, 1.5em); }
.sk-line > i {
  display: block; height: .68em; border-radius: 999px; background: var(--sk-base);
}
.sk-sum { display: block !important; -webkit-line-clamp: unset !important; overflow: visible !important; }
.sk-pill {
  display: inline-block; flex: none; min-width: 8px;
  border-radius: 999px; background: var(--sk-base);
}
.sk-hole { display: block; background: var(--sk-base); }
.sk-static { pointer-events: none; }
/* 具体控件的尺寸沿用真实类名，这里只覆盖底色 */
.sk-avatar { background: var(--sk-base); box-shadow: none; }
.sk-cover, .sk-media, .sk-th, .sk-icon, .sk-fill, .sk-pie { background: var(--sk-base); }
.sk-pie { width: 100%; height: 118px; border-radius: 12px; margin-top: 10px; }
.sk-box { display: inline-block; flex: none; width: 14px; height: 14px; border-radius: 4px; background: var(--sk-base); }
/* 骨架列表所在的容器需要定位，扫光层才能盖住整块区域；列表数据到达后被整体替换 */
#diaryList, #albumList, #topicList, #w2Grid, #w2PcGrid, #outfitList, #pList,
#bAccList, #bRecList, #visitList, #ipBlockList, #ckHead, #ckListBox,
#ntLogList, #cmtMgList, #taList, #taStats, #bkList, #tmList, #pdMain,
#visitStats, #ntLogStats, #bStatsBox, #billHomeList { position: relative; }
