/* ══════════════════════════════════════════════════════════════════
   设计变量
   方向没变（暖米白 · 柔和珊瑚 · 鼠尾草绿 · 纸张质感 · 克制阴影），
   变的是把它变成一个真正的系统：

   审计前的实际状况 ——
     圆角 19 种（6/7/8/9/10/11/12 全都在用）
     字号 26 种（10~27 几乎每个整数都用了一遍 → 层级失效）
     阴影 13 种（"边框"和"阴影"两套深度策略混用）
     硬编码颜色 182 种，token 只有 14 个
     padding 116 种组合，gap 里有 9px / 7px / 5px 这种不在网格上的值

   系统感就是高级感的来源。同一份界面，19 种圆角会读成"凑出来的"，
   5 档圆角会读成"设计过的" —— 差别不在好不好看，在有没有决断。
   ══════════════════════════════════════════════════════════════════ */
:root {
  /* ── 墨色：四级文字层级（skill: 只有两级说明层级太平）── */
  --ink: #3e3a37;          /* 一级：标题、数字 */
  --ink-2: #756b63;        /* 二级：正文、说明 */
  --muted: #817a74;        /* 三级：元信息、时间 */
  --ink-4: #a89c93;        /* 四级：弱提示、占位 */

  /* ── 纸面：暖色纸张，靠明度分层，不靠色相 ── */
  --paper: #fffdf9;        /* 卡片 */
  --paper-raised: #fffaf5; /* 抬起面：内嵌卡片、条目 */
  --paper-inset: #fbf6f0;  /* 下沉面：输入框（比周围暗一点 = 可以输入）*/
  --canvas: #f8f4ee;       /* 页面底 */
  --cream: #f5ede2;        /* 分区底 */

  /* ── 描边：低对比，需要时才看得见 ── */
  --line: #e9e1d8;
  --line-soft: #f1ebe4;    /* 发丝分隔线 */
  --line-strong: #d6c7ba;  /* hover / 强调边界 */

  /* ── 强调色：一个就够。珊瑚负责品牌与动作，绿负责完成，黄负责提醒 ── */
  --coral: #c96f61;
  --coral-soft: #f7dfd6;
  --coral-ink: #9e5548;    /* 珊瑚底上的文字 */
  --coral-deep: #a85a4d;   /* 逾期、警示 */
  --green: #7a9b7c;
  --green-soft: #e6eee5;
  --yellow: #d3a758;
  --yellow-soft: #f7ecd1;
  --danger: #b4553f;

  /* ── 圆角：5 档，按元素尺寸递增（skill: 小元素别用大圆角）── */
  --r-xs: 6px;    /* 标签、小徽章 */
  --r-sm: 10px;   /* 按钮、输入框 */
  --r-md: 12px;   /* 卡片、条目 */
  --r-lg: 16px;   /* 面板 */
  --r-xl: 20px;   /* 弹窗 */
  --r-pill: 999px;
  --radius: var(--r-md);   /* 兼容旧引用 */

  /* ── 间距：4px 网格。之前 gap 里有 5/7/9px 这种离网值 ── */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 20px;
  --s-6: 24px;
  --s-7: 32px;

  /* ── 字号：1.2 左右的比例，从 13 起跳。
        之前 10~27 每个整数都用过一遍，等于没有层级。
        收敛到 8 档之后，相邻两档才真的看得出差别。 ── */
  --fs-micro: 11px;   /* 徽章、极小标注 */
  --fs-meta: 12px;    /* 元信息、时间、说明 */
  --fs-body: 13px;    /* 正文 */
  --fs-lead: 14px;    /* 强调正文、列表主文 */
  --fs-h4: 16px;
  --fs-h3: 18px;
  --fs-h2: 21px;
  --fs-h1: 26px;
  --fs-display: 30px; /* 净资产这类大数字：页面的焦点，要压得住 */
  --fs-hero: clamp(28px, 3.8vw, 42px); /* 登录页这类整屏标题，流体 */
  --fs-page: clamp(26px, 3vw, 34px);   /* 模块页标题，流体 */

  /* ── 字重：靠字重和颜色做层级，别只靠字号（skill 的 Apple/Linear 手法）── */
  --fw-normal: 400;
  --fw-medium: 500;
  --fw-semi: 600;
  --fw-bold: 700;

  /* ── 深度：选定"分层阴影"，不再和边框混用。
        三层叠加 = 1px 描边环 + 两级柔和投影，比单层大阴影精细得多。 ── */
  --shadow-sm: 0 0 0 1px rgba(100, 75, 54, .05), 0 1px 2px -1px rgba(100, 75, 54, .06);
  --shadow: 0 0 0 1px rgba(100, 75, 54, .05), 0 1px 2px -1px rgba(100, 75, 54, .06), 0 2px 6px rgba(100, 75, 54, .05);
  --shadow-md: 0 0 0 1px rgba(100, 75, 54, .05), 0 2px 4px -2px rgba(100, 75, 54, .07), 0 6px 16px rgba(100, 75, 54, .07);
  --shadow-lg: 0 0 0 1px rgba(100, 75, 54, .05), 0 12px 34px rgba(100, 75, 54, .1), 0 2px 8px rgba(100, 75, 54, .05);
  --ring: 0 0 0 3px rgba(201, 111, 97, .16);

  /* ── 运动：自定义缓出曲线，内置的 ease 太弱。
        时长 < 300ms，只动 transform / opacity。 ── */
  --ease-out: cubic-bezier(.23, 1, .32, 1);
  --ease-in-out: cubic-bezier(.77, 0, .175, 1);
  --t-fast: 120ms;
  --t-base: 180ms;
  --t-slow: 260ms;

  /* 中文用系统自带的字体，**故意不下载中文字体**：
     一个中文字重动辄几十 MB，而用户设备上本来就有质量很好的中文字体。
     这是国内产品的常规做法，顺带也去掉了「打开页面先去境外拉字体」这件事。
     顺序有讲究：DM Sans 在最前，拉丁字母和数字用它；中文不在 DM Sans 里，
     自然落到后面的系统字体上。 */
  --font-cjk: "PingFang SC", "HarmonyOS Sans SC", "Microsoft YaHei",
              "Source Han Sans SC", "Noto Sans CJK SC", sans-serif;
  --font-cjk-serif: "Songti SC", "STSong", "SimSun", "Source Han Serif SC",
                    "Noto Serif CJK SC", serif;
  --font-ui: "DM Sans", var(--font-cjk);
  --font-display: var(--font-cjk-serif);
}


* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { margin: 0; background: var(--canvas); color: var(--ink); font-family: var(--font-ui); font-size: var(--fs-lead); line-height: 1.6; }
button, a { font: inherit; }
button { color: inherit; cursor: pointer; }
a { color: inherit; text-decoration: none; }
svg { width: 18px; height: 18px; stroke-width: 1.8; }

/* ── 条款 / 隐私这类纯文字页 ──
   它们要**不登录也能看**（用户在注册前就该能读到），所以不能套 app-shell。
   刻意做得朴素：一条窄栏、行高松一点 —— 这种页面的目标是「读得下去」，不是好看。 */
.doc-page { margin: 0; background: var(--canvas); color: var(--ink); font-family: var(--font-ui); font-size: var(--fs-body); line-height: 1.85; }
.doc { max-width: 720px; margin: 0 auto; padding: 44px 22px 96px; }
.doc-head { display: flex; align-items: center; gap: 11px; margin-bottom: 30px; }
.doc-head .brand-mark { width: 34px; height: 34px; font-size: var(--fs-h4); }
.doc-head strong { font-family: var(--font-display); font-size: var(--fs-h3); }
.doc-head a { margin-left: auto; color: var(--coral); font-size: var(--fs-small); }
.doc h1 { margin: 0 0 6px; font-family: var(--font-display); font-size: 30px; line-height: 1.35; }
.doc .doc-meta { margin: 0 0 34px; color: var(--muted); font-size: var(--fs-small); }
.doc h2 { margin: 38px 0 10px; font-family: var(--font-display); font-size: 19px; line-height: 1.5; }
.doc h3 { margin: 24px 0 6px; font-size: var(--fs-lead); font-weight: var(--fw-semi); }
.doc p { margin: 0 0 12px; }
.doc ul, .doc ol { margin: 0 0 14px; padding-left: 22px; }
.doc li { margin-bottom: 7px; }
.doc strong { font-weight: var(--fw-semi); }
.doc code { padding: 1px 5px; border-radius: 4px; background: var(--paper-inset); font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: .92em; }
.doc a { color: var(--coral); }
/* 需要运营者填的空，在页面上要一眼看得见 —— 别让它悄悄上线 */
.doc .todo { padding: 1px 6px; border-radius: 4px; background: var(--yellow-soft); color: #8a6520; font-weight: var(--fw-semi); }
.doc .callout { margin: 0 0 16px; padding: 15px 17px; border: 1px solid var(--line); border-left: 3px solid var(--coral); border-radius: var(--r-sm); background: var(--paper); }
.doc .callout p:last-child { margin-bottom: 0; }
.doc-foot { margin-top: 52px; padding-top: 20px; border-top: 1px solid var(--line); color: var(--muted); font-size: var(--fs-small); }
.doc-nav { display: flex; gap: 16px; margin-bottom: 26px; font-size: var(--fs-small); }
/* 登录页那行「同意条款」—— 小、不抢眼，但必须在提交前就能看到 */
.auth-legal { margin: 14px 2px 0; color: var(--muted); font-size: var(--fs-micro); line-height: 1.7; }
.auth-legal a { color: var(--coral); }

.auth-page { min-height: 100vh; display: grid; place-items: center; padding: 28px 16px; background: radial-gradient(circle at top, #fff8f1 0, var(--canvas) 58%); }
.auth-shell { width: min(1120px, 100%); display: grid; grid-template-columns: 1.05fr .95fr; gap: 24px; align-items: stretch; }
.auth-intro, .auth-panel { border: 1px solid var(--line); border-radius: var(--r-lg); background: rgba(255,253,249,.9); box-shadow: var(--shadow); }
.auth-intro { padding: 34px; display: flex; flex-direction: column; justify-content: center; }
.auth-intro h1 { margin-top: 8px; font-size: var(--fs-hero); max-width: 13ch; }
.auth-intro p:last-child { max-width: 40ch; color: var(--muted); }
.auth-panel { padding: 22px; }
.auth-tabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 18px; }
.auth-tab { min-height: 44px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper-raised); color: var(--ink-2); }
.auth-tab.active { border-color: var(--coral); background: var(--coral-soft); color: var(--coral-ink); font-weight: 700; }
/* 「加入家庭」里那排方式选择：两项。
   要**明显比上面那排主标签轻** —— 否则两排长得一模一样，
   用户会分不清「我在选做什么」和「我在选用哪种方式」。
   所以：矮一点、圆角用胶囊、去掉描边。 */
.join-mode { grid-template-columns: repeat(2, 1fr); gap: 6px; margin-bottom: 16px; }
.join-mode .auth-tab { min-height: 34px; border-color: transparent; border-radius: var(--r-pill); background: var(--paper-inset); color: var(--muted); font-size: var(--fs-meta); }
.join-mode .auth-tab.active { border-color: transparent; background: var(--coral-soft); color: var(--coral-ink); font-weight: var(--fw-semi); }
/* 字段下面那行小字（比如登录名的规则）。用最弱的一级颜色，别和标签抢注意力。 */
/* ── 订阅到期横幅 ──
   只在到期时出现，所以它可以醒目一点 —— 常驻的东西才需要克制。
   但用的是中性琥珀色而不是红色：**这不是错误，也不是警告，是一个状态。**
   用户第一眼要读到的是"数据还在"，红色会让他先慌一下。 */
.subscription-banner { display: flex; align-items: flex-start; gap: 10px; margin: 0 0 18px; padding: 14px 16px; border: 1px solid #e6d3a8; border-radius: var(--radius); background: #fdf6e6; color: #7a5c1e; }
.subscription-banner svg { width: 18px; height: 18px; flex: 0 0 auto; margin-top: 1px; }
.subscription-banner-copy { display: flex; flex-direction: column; gap: 3px; }
.subscription-banner-copy strong { font-size: var(--fs-lead); font-weight: var(--fw-semi); }
.subscription-banner-copy span { font-size: var(--fs-meta); line-height: 1.7; }

.form-hint { display: block; margin-top: 6px; color: var(--ink-4); font-size: var(--fs-micro); line-height: 1.6; }
/* 「第一次来？」—— 给新访客指一下「创建家庭」那个标签。
   他默认看到的是登录表单，而他要的登录名和密码都还不存在。 */
.auth-first-time { margin: 14px 0 0; padding: 10px 12px; border-radius: var(--r-sm); background: var(--cream); color: var(--muted); font-size: var(--fs-meta); line-height: 1.7; text-align: center; }
.auth-view h2 { margin-top: 4px; font-size: var(--fs-h1); }
.auth-helper { margin: 8px 0 18px; color: var(--muted); font-size: var(--fs-body); }
.auth-link-row { margin: -8px 0 18px; display: flex; justify-content: space-between; gap: 10px; color: #8c7f74; font-size: var(--fs-meta); }
.auth-link-row button { padding: 0; border: 0; background: none; color: var(--coral); font: inherit; cursor: pointer; }
.auth-form { display: grid; gap: 0; }
.auth-form .form-field { margin-bottom: 14px; }
.auth-reset { margin-top: 8px; padding-top: 16px; border-top: 1px solid var(--line); }
/* 一个账号属于多个家庭时的选择面板 */
.family-picker { margin-top: 8px; padding-top: 16px; border-top: 1px solid var(--line); }
.family-picker[hidden] { display: none; }
.family-picker h3 { margin: 2px 0 14px; font-size: var(--fs-h3); font-family: var(--font-display); }
.family-picker-list { display: grid; gap: 8px; margin-bottom: 16px; }
.family-picker-item { display: grid; gap: 3px; width: 100%; padding: 11px 14px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper); text-align: left; font: inherit; cursor: pointer; transition: border-color .15s, background .15s; }
.family-picker-item:hover { border-color: var(--line-strong); background: var(--paper-raised); }
.family-picker-item strong { font-size: var(--fs-lead); }
.family-picker-item small { color: var(--muted); font-size: var(--fs-micro); }
.auth-reset h3 { margin: 2px 0 14px; font-size: var(--fs-h3); font-family: var(--font-display); }
.auth-submit { width: 100%; margin-top: 6px; }
.auth-message { min-height: 22px; margin: 16px 2px 0; color: var(--green); font-size: var(--fs-body); }
.auth-message.error { color: var(--coral); }
.account-modal { width: min(100%, 460px); padding: 24px; border: 1px solid #eadbd0; border-radius: var(--r-lg); background: var(--paper); box-shadow: 0 24px 70px rgba(64, 44, 30, .2); }
.account-summary { margin-top: 18px; display: grid; gap: 12px; }
.account-summary > div { padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--paper-raised); }
.account-summary strong { display: block; margin-top: 4px; font-size: var(--fs-h4); }
.account-summary small { display: block; margin-top: 4px; color: var(--muted); }
.account-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 18px; }
/* 账号弹窗里的「数据与条款」区 */
.account-legal { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line); }
.account-legal-links { display: flex; gap: 16px; margin: 8px 0 12px; font-size: var(--fs-small); }
.account-legal-links a { color: var(--coral); }
.account-legal-note { margin: 0 0 12px; color: var(--muted); font-size: var(--fs-micro); line-height: 1.75; }
.account-legal .outline-button { width: 100%; }

.app-shell { display: flex; min-height: 100vh; }
.sidebar { width: 260px; flex: 0 0 260px; padding: 28px 18px 20px; background: #fcfaf6; border-right: 1px solid var(--line); display: flex; flex-direction: column; }
.brand { display: flex; align-items: center; gap: 11px; padding: 0 11px 30px; }
.brand-mark { width: 38px; height: 38px; border-radius: var(--r-md); display: grid; place-items: center; background: var(--coral); color: white; font-family: var(--font-display); font-size: var(--fs-h2); box-shadow: 0 5px 14px rgba(201,111,97,.24); }
.brand strong { display: block; font-size: var(--fs-lead); letter-spacing: .02em; }
.brand span, .switcher-copy small, .profile-button small { display: block; color: var(--muted); font-size: var(--fs-micro); }
.eyebrow { margin: 0; color: var(--muted); font-size: var(--fs-micro); font-weight: 700; letter-spacing: .09em; text-transform: uppercase; }
.family-switcher { padding: 0 8px 23px; border-bottom: 1px solid var(--line); }
.family-switcher-button, .profile-button { width: 100%; border: 0; background: transparent; display: flex; align-items: center; gap: 9px; padding: 10px 3px; text-align: left; }
.family-switcher-button > svg, .profile-button > svg { margin-left: auto; color: #aaa09a; width: 15px; }
.switcher-copy { min-width: 0; flex: 1; }
.switcher-copy strong { font-size: var(--fs-body); }
.avatar { width: 36px; height: 36px; border-radius: 50%; display: inline-grid; place-items: center; flex: 0 0 auto; font-size: var(--fs-body); font-weight: 700; }
.avatar-family { background: var(--coral-soft); color: var(--coral); }
.avatar-user { background: #ded8ce; color: #5b554f; }
.avatar-child { width: 52px; height: 52px; background: var(--yellow-soft); color: #ad7e2f; font-family: var(--font-display); font-size: var(--fs-h2); }
.avatar-mom { background: #f1d7ca; color: #9e5d4c; }
.avatar-small { width: 25px; height: 25px; font-size: var(--fs-micro); }
.nav-list { padding: 22px 0; display: grid; gap: 5px; }
.nav-item { min-height: 44px; padding: 0 12px; border-radius: var(--r-sm); display: flex; align-items: center; gap: 12px; color: #78716b; font-size: var(--fs-lead); transition: background .2s, color .2s, transform .2s; }
.nav-item:hover { background: #f6eee5; color: var(--ink); transform: translateX(2px); }
.sortable-main-item { cursor: grab; }
.sortable-main-item:active, .sortable-main-item.dragging { cursor: grabbing; opacity: .55; }
.nav-item.active { background: var(--coral-soft); color: var(--coral-ink); font-weight: 700; }
.nav-badge { margin-left: auto; min-width: 20px; height: 20px; padding: 0 5px; border-radius: var(--r-sm); display: grid; place-items: center; background: #dedbd5; color: #77716b; font-size: var(--fs-micro); }
.nav-badge.warm { background: var(--yellow-soft); color: #9b762e; }
.customize-nav-button { width: 100%; min-height: 42px; padding: 0 12px; border: 1px dashed #d9c9bc; border-radius: var(--r-sm); display: flex; align-items: center; gap: 10px; background: rgba(255,253,249,.45); color: #927d6e; font-size: var(--fs-meta); }
.customize-nav-button:hover { border-color: var(--coral); background: var(--coral-soft); color: var(--coral-ink); }
.customize-nav-button svg:last-child { width: 14px; margin-left: auto; }
.nav-custom-dot { width: 5px; height: 5px; margin-left: auto; border-radius: 50%; background: var(--yellow); }
.nav-private-mark { margin-left: auto; color: #a98972; font-size: var(--fs-micro); }
.custom-nav-group { margin: 9px 0 2px; padding-top: 8px; border-top: 1px solid #f0e8df; }
.custom-submenu { margin: -1px 0 3px; padding: 2px 0 4px 20px; border-top: 0; border-left: 1px solid #eaded3; }
.custom-submenu .custom-nav-item { min-height: 34px; padding-left: 14px; }
.custom-nav-group-label { min-height: 28px; padding: 0 12px; display: flex; align-items: center; gap: 8px; color: #9a8c81; font-size: var(--fs-micro); font-weight: 700; letter-spacing: .04em; }
.custom-nav-group-label svg { width: 14px; color: #b18c6e; }
.custom-nav-group-label small { margin-left: auto; min-width: 17px; height: 17px; border-radius: var(--r-sm); display: grid; place-items: center; background: #f1e9df; color: #9b8879; font-size: var(--fs-micro); font-weight: 500; }
.custom-nav-group .custom-nav-item { min-height: 38px; padding-left: 28px; font-size: var(--fs-meta); }
.sidebar-bottom { margin-top: auto; }
.privacy-note { margin: 12px 8px 10px; padding: 11px; border: 1px solid var(--line); border-radius: var(--r-sm); display: flex; align-items: center; gap: 8px; color: #978e86; font-size: var(--fs-micro); }
.privacy-note svg { width: 15px; color: var(--green); }
/* 侧栏底部的条款入口。以前这两页只在登录页有链接，
   登录进来就找不到了 —— 而那恰恰是用户会想看这两页的时候。 */
.sidebar-legal { margin: 0 8px 10px; display: flex; gap: 7px; color: #a89f97; font-size: var(--fs-micro); }
.sidebar-legal a { color: #a89f97; text-decoration: underline; text-underline-offset: 2px; }
.sidebar-legal a:hover { color: var(--coral); }

/* ── 「现在的状态」+ 点赞 / 知道了 ──
   这是这个产品里少见的**非事务性**的东西：不为办事，只为看一眼。
   所以它要比周围安静，不能抢卡片标题的注意力 ——
   状态用二级正文色、时间用三级色，只有选中的那个回应才拿到颜色。 */
.member-status { margin: var(--s-3) 0 0; padding: var(--s-3) 0 0; border-top: 1px solid var(--line-soft); }
/* 状态正文**最多两行**。上限是 40 字，在窄卡里会排到三行 ——
   一行里有它一个高出一截，卡片就对不齐了。截断的部分点开状态卡能看全。 */
.member-status-note { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; margin: 0; color: var(--ink-2); font-size: var(--fs-lead); line-height: 1.65; text-wrap: pretty; }
.member-status-foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); margin-top: var(--s-2); }
.status-time { color: var(--muted); font-size: var(--fs-meta); }
.member-status.is-empty p { margin: 0; color: var(--ink-4); font-size: var(--fs-meta); line-height: 1.65; }
/* 别人没写状态时的占位。它存在的理由是**让卡片高度对齐**，
   所以要说得很轻 —— 是一句说明，不是一句催促。 */
.member-status.is-blank p { margin: 0; color: var(--ink-4); font-size: var(--fs-meta); line-height: 1.65; }

/* 两个回应并排。**只给选中的那个上色** ——
   两个都花就分不出你选的是哪个了。 */
.react-row { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-3); }
.react-button { display: inline-flex; align-items: center; gap: var(--s-1); min-height: 30px; padding: 0 var(--s-3); border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--paper); color: var(--ink-2); font-size: var(--fs-meta); transition: border-color var(--t-fast) var(--ease-out), background var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out); }
.react-button svg { width: 14px; height: 14px; }
.react-button:hover { border-color: var(--line-strong); background: var(--paper-raised); }
.react-button:hover[data-react-kind="like"] { color: var(--coral); }
.react-button:hover[data-react-kind="ack"] { color: var(--green); }
.react-button:active { transform: scale(.985); }
.react-button:disabled { opacity: .5; cursor: default; }
/* 点赞用珊瑚（它是"表达"，是强调），知道了用鼠尾草绿（它是"收到"，是完成）——
   两个都是调色板里已有的颜色，没有引入第五个强调色。 */
.react-button.is-on { border-color: transparent; font-weight: var(--fw-medium); }
.react-button.is-on svg { fill: currentColor; }
.react-button[data-react-kind="like"].is-on { background: var(--coral-soft); color: var(--coral-ink); }
.react-button[data-react-kind="ack"].is-on { background: var(--green-soft); color: #5f7d62; }
/* 谁回应过：按种类分组，给名字 */
.react-who-row { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-top: var(--s-2); }
.react-who { color: var(--muted); font-size: var(--fs-meta); }
.react-who[data-react-who="like"]::before { content: "♥ "; color: var(--coral); }
.react-who[data-react-who="ack"]::before { content: "✓ "; color: var(--green); }

/* 快捷说法。做成胶囊片，和筛选片同一套规格 ——
   它们本质上是同一类东西：一排可以点的小选项。 */
.status-presets { display: flex; flex-wrap: wrap; gap: var(--s-2); margin: 0 0 var(--s-3); }
.status-preset { min-height: 30px; padding: 0 var(--s-3); border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--paper); color: var(--ink-2); font-size: var(--fs-meta); transition: border-color var(--t-fast) var(--ease-out), background var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out); }
.status-preset:hover { border-color: var(--line-strong); background: var(--paper-raised); color: var(--coral); }
.status-preset:active { transform: scale(.985); }
.profile-button { border-top: 1px solid var(--line); padding: 16px 4px 0; }

.main-content { min-width: 0; flex: 1; }
.topbar { height: 77px; padding: 0 5.5%; border-bottom: 1px solid var(--line); display: flex; align-items: center; justify-content: space-between; background: rgba(255,253,249,.68); }
.breadcrumb { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: var(--fs-body); }
.breadcrumb svg { width: 14px; }
.breadcrumb strong { color: var(--ink); font-weight: 600; }
.topbar-actions { display: flex; align-items: center; gap: 8px; }
.icon-button, .more-button { width: 42px; height: 42px; border: 0; border-radius: 50%; display: grid; place-items: center; background: transparent; color: #746c65; position: relative; }
.icon-button:hover, .more-button:hover { background: #f2eae1; }
.notification span { min-width: 19px; height: 19px; padding: 0 5px; border-radius: var(--r-pill); display: grid; place-items: center; background: var(--coral); color: #fff; position: absolute; top: 2px; right: 1px; border: 1px solid var(--paper); font-size: var(--fs-micro); font-weight: 700; line-height: 1; }
.notification span[hidden] { display: none; }
.user-chip { height: 42px; padding: 3px 6px 3px 3px; border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--paper); display: flex; align-items: center; gap: 8px; }
.user-chip-name { font-size: var(--fs-meta); }
.user-chip svg { width: 14px; margin-left: 2px; color: #a49b92; }
.page-content { max-width: 1480px; margin: 0 auto; padding: 42px 5.5% 70px; }
.module-page-template { width: 100%; max-width: 1280px; margin: 0 auto; }
.welcome-row { display: flex; align-items: end; justify-content: space-between; gap: 30px; margin-bottom: 28px; }
/* 首页那句问候**不该是最大的东西**。它只是打个招呼，而人打开这个应用
   是要看有没有事等他 —— 所以这里把它从 --fs-hero（最大能到 42px）
   压到 --fs-h1，把视觉分量让给下面的「等你表态」。
   这是产品判断，不是审美偏好（见定位文档 7.2）。 */
#overview-welcome h1 { font-size: var(--fs-h1); line-height: 1.4; margin: 0 0 5px; }
.welcome-expand-button { min-height: 40px; padding: 0 8px; color: #a25b4f; }
h1, h2, h3, p { margin-top: 0; }
h1, h2, h3 { font-family: var(--font-display); letter-spacing: 0; }
h1 { max-width: 740px; margin: 7px 0 9px; font-size: var(--fs-hero); line-height: 1.32; font-weight: 600; }
h2 { margin: 3px 0 0; font-size: var(--fs-h2); line-height: 1.35; font-weight: 600; }
h3 { margin: 0; font-size: var(--fs-h3); line-height: 1.35; font-weight: 600; }
.welcome-copy { color: var(--muted); margin-bottom: 0; }
.welcome-copy strong { color: var(--coral); font-size: var(--fs-h3); }
.family-command-center { margin: 0 0 28px; padding: 18px 22px; border: 1px solid #e6d7ca; border-radius: var(--radius); background: #fffaf4; display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(280px, .9fr) auto; gap: 22px; align-items: center; }
.family-command-main { display: flex; align-items: start; gap: 14px; min-width: 0; }
.family-command-icon { width: 44px; height: 44px; flex: 0 0 auto; border-radius: var(--r-md); display: grid; place-items: center; background: var(--coral-soft); color: var(--coral); }
.family-command-icon svg { width: 22px; height: 22px; }
.family-command-title-row { display: flex; align-items: center; gap: 10px; }
.family-command-date { margin: 0; color: #9a8a7d; font-size: var(--fs-micro); white-space: nowrap; }
.family-command-main h2 { margin: 4px 0 4px; font-size: var(--fs-h2); }
.family-command-main p:not(.eyebrow) { margin: 0; max-width: 560px; color: var(--muted); font-size: var(--fs-meta); }
.family-member-strip { margin-top: 13px; display: flex; align-items: center; gap: 0; }
.family-member-avatar { width: 27px; height: 27px; margin-right: -5px; border: 2px solid #fffaf4; border-radius: 50%; display: grid; place-items: center; background: var(--green-soft); color: #66806a; font-size: var(--fs-micro); font-weight: 700; }
.family-member-avatar:nth-child(2) { background: var(--coral-soft); color: var(--coral-deep); }
.family-member-avatar:nth-child(3) { background: var(--yellow-soft); color: #9b762e; }
.family-member-strip small { margin-left: 13px; color: var(--muted); font-size: var(--fs-micro); }
.family-command-status { padding-left: 22px; border-left: 1px solid #eaded4; }
.family-command-status > div:first-child span { display: block; color: var(--muted); font-size: var(--fs-micro); }
.family-command-status > div:first-child strong { display: block; margin-top: 4px; font-size: var(--fs-body); font-weight: 600; }
.family-command-metrics { display: flex; gap: 13px; margin-top: 14px; }
.family-command-metrics span { color: var(--muted); font-size: var(--fs-micro); white-space: nowrap; }
.family-command-metrics strong { margin-right: 3px; color: var(--ink); font-family: var(--font-ui); font-size: var(--fs-h3); }
.family-command-actions { display: grid; gap: 2px; align-content: center; min-width: 150px; }
.family-command-actions .text-button { min-height: 38px; padding: 0 0 0 15px; border-left: 1px solid #eaded4; white-space: nowrap; }
.family-announcements-panel { margin: -10px 0 28px; padding: 19px 22px 14px; border: 1px solid #e6c9b8; border-left: 4px solid var(--coral); border-radius: var(--radius); background: #fff9f3; box-shadow: var(--shadow); }
.family-announcements-heading { display: flex; align-items: center; gap: 12px; }
.family-announcements-heading-icon { width: 38px; height: 38px; flex: 0 0 auto; border-radius: var(--r-sm); display: grid; place-items: center; background: var(--coral-soft); color: var(--coral); }
.family-announcements-heading > div:nth-child(2) { min-width: 0; }
.family-announcements-heading h2 { margin-top: 2px; font-size: var(--fs-h2); }
.family-announcements-heading .outline-button { width: auto; min-height: 38px; margin-left: auto; padding: 0 12px; }

/* ── 等你表态（首页第一块）──
   比周围重一点（珊瑚左描边 + 稍强的阴影），因为它是"要动手"的那一块；
   但每一条本身要克制 —— 它不是公告，是一份待办。
   和公告面板同一套骨架，让它一眼看出"这是家里的事"而不是系统弹窗。 */
.awaiting-panel { margin: -10px 0 28px; padding: 19px 22px 16px; border: 1px solid #e6c9b8; border-left: 4px solid var(--coral); border-radius: var(--radius); background: #fff9f3; box-shadow: var(--shadow); }
.awaiting-heading { display: flex; align-items: center; gap: 12px; }
.awaiting-heading-icon { width: 38px; height: 38px; flex: 0 0 auto; border-radius: var(--r-sm); display: grid; place-items: center; background: var(--coral-soft); color: var(--coral); }
.awaiting-heading h2 { margin-top: 2px; font-size: var(--fs-h2); }
.awaiting-list { margin-top: 14px; display: grid; gap: var(--s-2); }
.awaiting-item { display: flex; align-items: center; gap: var(--s-3); padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper); color: inherit; transition: border-color var(--t-fast) var(--ease-out), background var(--t-fast) var(--ease-out); }
.awaiting-item:hover { border-color: var(--line-strong); background: #fffdfa; }
.awaiting-item:active { transform: scale(.995); }
.awaiting-kind { flex: 0 0 auto; padding: 3px 9px; border-radius: var(--r-pill); background: var(--coral-soft); color: var(--coral-ink); font-size: var(--fs-micro); font-weight: var(--fw-semi); }
.awaiting-body { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.awaiting-body strong { font-size: var(--fs-lead); font-weight: var(--fw-semi); overflow-wrap: anywhere; }
.awaiting-body small { color: var(--muted); font-size: var(--fs-meta); }
.awaiting-go { margin-left: auto; flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px; color: var(--coral); font-size: var(--fs-meta); }
.awaiting-go svg { width: 14px; height: 14px; }

/* ── 「开始使用」清单 ──
   给刚建好家庭的人一条最短路径。它和上面两块（等你表态 / 家庭工作台）的区别是
   **它是临时的** —— 做完就消失。所以视觉上要轻一点：
   用中性底、不占珊瑚（珊瑚留给"要动手"的等你表态），
   只有"已完成"的勾用鼠尾草绿。 */
.onboarding-panel { margin: -10px 0 28px; padding: 19px 22px 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper-raised); box-shadow: var(--shadow); }
.onboarding-head { display: flex; align-items: flex-start; gap: 12px; }
.onboarding-icon { width: 38px; height: 38px; flex: 0 0 auto; border-radius: var(--r-sm); display: grid; place-items: center; background: var(--cream); color: #8a7a6b; }
.onboarding-intro { min-width: 0; flex: 1; }
.onboarding-intro h2 { margin-top: 2px; font-size: var(--fs-h2); }
.onboarding-note { margin: 4px 0 0; color: var(--muted); font-size: var(--fs-meta); }
.onboarding-dismiss { width: auto; min-height: 34px; padding: 0 10px; flex: 0 0 auto; color: var(--muted); font-size: var(--fs-meta); }
.onboarding-dismiss svg { width: 14px; height: 14px; }
.onboarding-steps { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: var(--s-2); }
.onboarding-step { display: flex; align-items: center; gap: var(--s-3); padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper); }
.onboarding-check { width: 22px; height: 22px; flex: 0 0 auto; display: grid; place-items: center; border-radius: 50%; background: var(--paper-inset); color: var(--ink-4); }
.onboarding-check svg { width: 14px; height: 14px; }
.onboarding-copy { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 2px; }
.onboarding-copy strong { font-size: var(--fs-lead); font-weight: var(--fw-semi); }
.onboarding-copy small { color: var(--muted); font-size: var(--fs-meta); line-height: 1.6; }
/* 「去邀请」这类动作按钮。
   **选择器要多带一层**：`.outline-button` 那条基础规则里有 `width: 100%` 和
   `margin-top: 20px`（它是为表单里上下堆叠设计的），而那条规则在文件里
   比这里更靠后 —— 同等特异性下**后写的赢**，所以只写 `.onboarding-go { width: auto }`
   是压不住的（第一版就是这样：按钮吃掉整行宽，标题被挤成一行一个字）。
   system.md 里"横向容器里用 .outline-button 必须同时清掉 width 和 margin-top"
   说的就是这个坑，只是这次还多了一层顺序问题。 */
.onboarding-step .onboarding-go { width: auto; min-height: 34px; margin-top: 0; padding: 0 14px; flex: 0 0 auto; font-size: var(--fs-meta); }
/* 已完成：整行退到后面去，勾变绿 —— 一眼能看出还剩哪几步 */
.onboarding-step.is-done { background: var(--paper-raised); border-color: var(--line-soft); }
.onboarding-step.is-done .onboarding-check { background: var(--green-soft); color: #5f7d62; }
.onboarding-step.is-done .onboarding-copy strong { color: var(--muted); font-weight: var(--fw-medium); }
.onboarding-done-tag { flex: 0 0 auto; color: var(--green); font-size: var(--fs-meta); }
.family-announcement-list { margin-top: 12px; }
.family-announcement-item { min-width: 0; padding: 12px 2px; border-top: 1px solid #f0e3d9; display: flex; align-items: start; gap: 12px; }
.family-announcement-item > i { margin-top: 2px; flex: 0 0 auto; color: var(--coral); width: 17px; }
.family-announcement-copy { min-width: 0; flex: 1; }
.family-announcement-copy strong { display: block; font-size: var(--fs-body); overflow-wrap: anywhere; }
.family-announcement-copy p { margin: 4px 0 0; color: var(--ink-2); font-size: var(--fs-meta); line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; }
.family-announcement-copy small { display: block; margin-top: 5px; color: #a09286; font-size: var(--fs-micro); }
.family-announcement-archive { flex: 0 0 auto; padding: 5px 7px; border: 0; border-radius: var(--r-xs); background: transparent; color: #9b887a; font-size: var(--fs-micro); }
.family-announcement-archive:hover { background: var(--coral-soft); color: var(--coral-ink); }
/* 已归档分组：默认收起，避免和当前事项抢注意力 */
.family-announcement-archived { margin-top: 10px; border-top: 1px dashed var(--line); padding-top: 8px; }
.family-announcement-archived summary { cursor: pointer; color: var(--muted); font-size: var(--fs-micro); list-style: none; }
.family-announcement-archived summary::-webkit-details-marker { display: none; }
.family-announcement-archived summary::before { content: "▸ "; }
.family-announcement-archived[open] summary::before { content: "▾ "; }
.family-announcement-archived summary:hover { color: var(--ink); }
.family-announcement-archived summary span { font-variant-numeric: tabular-nums; }
.family-announcement-item.is-archived { opacity: .72; }
.family-announcement-item.is-archived strong { font-weight: 600; }
.family-assets-panel { margin: 0 0 28px; }
.family-assets-heading { display: flex; align-items: center; gap: 12px; }
.family-assets-heading-icon { width: 38px; height: 38px; flex: 0 0 auto; border-radius: var(--r-sm); display: grid; place-items: center; background: var(--coral-soft); color: var(--coral); }
.family-assets-heading > div:nth-child(2) { min-width: 0; }
.family-assets-heading h2 { margin-top: 2px; font-size: var(--fs-h2); }
.family-assets-heading .outline-button { width: auto; min-height: 38px; margin-left: auto; padding: 0 12px; }
.family-assets-content { min-height: 78px; margin-top: 10px; display: flex; align-items: center; }
.family-assets-summary { width: 100%; display: flex; align-items: end; gap: 18px; }
.family-assets-amount { font-family: var(--font-ui); font-size: var(--fs-display); line-height: 1.15; font-weight: 700; color: var(--ink); }
.family-assets-amount small { margin-left: 5px; color: var(--muted); font-size: var(--fs-meta); font-weight: 500; }
.family-assets-meta { color: var(--muted); font-size: var(--fs-micro); }
.family-assets-private { width: 100%; padding: 13px 15px; border-radius: var(--r-sm); background: #f5f0e9; color: #887b70; font-size: var(--fs-meta); }
/* ── 家庭资产模块页 ── */
.assets-summary-panel { margin-bottom: 16px; }
.assets-split { display: flex; flex-wrap: wrap; gap: 8px 24px; margin-top: 10px; }
.assets-split span { color: var(--muted); font-size: var(--fs-meta); }
.assets-split strong { margin-left: 7px; color: var(--ink); font-family: var(--font-ui); font-size: var(--fs-lead); font-variant-numeric: tabular-nums; }
.assets-other-currencies { margin: 8px 0 0; color: #9a9087; font-size: var(--fs-micro); }
.assets-updated { margin: 8px 0 0; color: var(--muted); font-size: var(--fs-micro); }
.assets-visibility { display: flex; align-items: center; gap: 8px; }
.assets-visibility > span { color: var(--muted); font-size: var(--fs-micro); }
.assets-visibility select { min-height: 32px; padding: 0 8px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper); color: var(--ink); font: inherit; font-size: var(--fs-meta); }
.assets-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; align-items: start; }
.assets-column { padding-top: 18px; }
.asset-group { margin-top: 14px; }
.asset-group:first-of-type { margin-top: 6px; }
.asset-group-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding-bottom: 6px; border-bottom: 1px solid var(--line); }
.asset-group-head h3 { font-family: var(--font-display); font-size: var(--fs-lead); }
.asset-group-head span { color: var(--muted); font-size: var(--fs-meta); font-variant-numeric: tabular-nums; }
.asset-row { display: flex; align-items: center; gap: 10px; padding: 9px 0; border-bottom: 1px solid #f5f0e9; }
.asset-row:last-child { border-bottom: 0; }
.asset-row-name { flex: 1; min-width: 0; }
.asset-row-name strong { display: block; font-size: var(--fs-body); font-weight: 600; }
.asset-row-name small { display: block; margin-top: 2px; color: var(--muted); font-size: var(--fs-micro); }
.asset-row-amount { color: var(--ink); font-family: var(--font-ui); font-size: var(--fs-lead); font-variant-numeric: tabular-nums; white-space: nowrap; }
.asset-row-actions { display: flex; gap: 2px; opacity: 0; transition: opacity .2s; }
.asset-row:hover .asset-row-actions, .asset-row:focus-within .asset-row-actions { opacity: 1; }
.asset-row-actions .icon-button { width: 30px; height: 30px; }
.asset-row-actions .icon-button svg { width: 14px; height: 14px; }
.asset-column-total { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-top: 12px; padding-top: 10px; border-top: 2px solid var(--line); }
.asset-column-total span { color: var(--muted); font-size: var(--fs-meta); }
.asset-column-total strong { font-family: var(--font-ui); font-size: var(--fs-h4); font-variant-numeric: tabular-nums; }
.family-space-link { display: flex; flex-direction: column; align-items: start; min-height: 205px; transition: border-color .2s, transform .2s; }
.family-space-link:hover { border-color: #d9c3b4; transform: translateY(-2px); }
.family-space-link .eyebrow { margin: 18px 0 5px; }
.family-space-link h3 { font-size: var(--fs-h3); }
.family-space-link p:not(.eyebrow) { margin: 8px 0 20px; color: var(--muted); font-size: var(--fs-meta); }
.family-space-link .small-link { margin-top: auto; margin-left: 0; display: flex; align-items: center; gap: 6px; color: var(--coral); font-size: var(--fs-micro); }
/* align-items 用默认的 stretch，**不要用 start**。
   首页这几张卡是一行一行排的：谁写了状态谁的卡就高，谁没写就矮 ——
   用 start 的话一行里会并排出现一张高卡和一张矮卡，看起来像坏了。
   拉齐之后，没写状态的那张下面会空一块，所以 statusMarkup 在首页
   会补一句很轻的「还没写现在的状态」把那一块填得像是**有意留的**。
   （成员页是管理页，那里不补 —— 免得变成一张「谁还没写」的名单。） */
.family-people-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 12px; }
/* 首页的人物卡。整张卡是**一个**动作（点开这个人的状态卡），
   所以不再有第二个悬浮图标 —— 那是"点哪儿去哪不一样"的典型。 */
.family-person-card { padding: 16px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--paper); box-shadow: var(--shadow); cursor: pointer; transition: border-color var(--t-base) var(--ease-out), box-shadow var(--t-base) var(--ease-out); }
.family-person-card:hover { border-color: var(--line-strong); box-shadow: var(--shadow-md); }
/* 头像 + 名字 + 箭头 = 一个按钮。
   箭头在**按钮里面**（不是旁边另一个链接），只表示"这一行能点开"；
   悬停时一起变珊瑚，让人知道整张卡是活的。 */
.family-person-open { width: 100%; display: flex; align-items: center; gap: var(--s-3); padding: 0; border: 0; background: transparent; text-align: left; }
.family-person-chevron { margin-left: auto; flex: 0 0 auto; width: 16px; height: 16px; color: var(--ink-4); transition: color var(--t-fast) var(--ease-out), transform var(--t-fast) var(--ease-out); }
.family-person-card:hover .family-person-chevron { color: var(--coral); transform: translateX(2px); }
.family-person-avatar { width: 42px; height: 42px; flex: 0 0 auto; border-radius: 50%; display: grid; place-items: center; background: #e9e4dd; color: #615b54; font-size: var(--fs-lead); font-weight: 700; }
.family-person-card.parent .family-person-avatar { background: var(--coral-soft); color: var(--coral-deep); }
.family-person-card.child .family-person-avatar { background: var(--green-soft); color: #66806a; }
.family-person-card.other .family-person-avatar { background: var(--yellow-soft); color: #9b762e; }
.family-person-copy { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.family-person-copy strong { font-size: var(--fs-h4); font-weight: var(--fw-semi); letter-spacing: -.01em; overflow-wrap: anywhere; }
.family-person-copy small { color: var(--muted); font-size: var(--fs-micro); }
/* 账号异常才显示的小标记 */
.family-person-state { align-self: flex-start; margin-top: var(--s-1); padding: 2px 7px; border-radius: var(--r-xs); background: var(--yellow-soft); color: #8a6520; }

/* ── 状态卡（点首页人物卡打开）──
   首页那张卡地方小，状态只能挤一行；这里把状态放大、把谁回应过列全。 */
.status-card { width: min(100%, 420px); padding: var(--s-6); border: 1px solid #eadbd0; border-radius: var(--r-xl); background: var(--paper); box-shadow: var(--shadow-lg); }
.status-card-head { display: flex; align-items: center; gap: var(--s-3); }
.status-card-title { min-width: 0; flex: 1; }
.status-card-title h2 { margin: 2px 0 0; font-size: var(--fs-h3); }
.status-card-role { margin: 3px 0 0; color: var(--muted); font-size: var(--fs-meta); }
.status-card-empty { margin: var(--s-3) 0 0; color: var(--ink-4); font-size: var(--fs-meta); line-height: 1.65; }
/* 状态块在卡片里带一条上分隔线，在弹窗里不需要 —— 上面已经有头像那一段了 */
.status-card .member-status { border-top: 0; padding-top: 0; }
.status-card .member-status-note { font-size: var(--fs-h3); line-height: 1.55; }
.home-summary-section { margin: 0 0 34px; }
.home-summary-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.home-summary-card { min-height: 118px; padding: 17px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper); box-shadow: var(--shadow); display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 12px; align-items: start; transition: transform .2s, border-color .2s, box-shadow .2s; }
.home-summary-card:hover { transform: translateY(-2px); border-color: #d9c3b4; box-shadow: 0 15px 36px rgba(100, 75, 54, .11); }
.home-summary-icon { width: 35px; height: 35px; border-radius: var(--r-sm); display: grid; place-items: center; }
.summary-task .home-summary-icon { background: var(--green-soft); color: var(--green); }
.summary-approval .home-summary-icon { background: var(--coral-soft); color: var(--coral); }
.summary-result .home-summary-icon { background: var(--yellow-soft); color: #ab8134; }
.summary-message .home-summary-icon { background: #e9e3ef; color: #82729a; }
.home-summary-card span, .home-summary-card small, .home-summary-card strong { display: block; }
.home-summary-card span { color: var(--muted); font-size: var(--fs-micro); }
.home-summary-card strong { margin-top: 2px; font-family: var(--font-ui); font-size: var(--fs-h1); line-height: 1.2; font-weight: 700; }
.home-summary-card small { margin-top: 4px; color: #9a9087; font-size: var(--fs-micro); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.summary-arrow { width: 15px; color: #b4aaa2; }
.home-live-grid { display: grid; grid-template-columns: 1.15fr .85fr; gap: 14px; margin-top: 14px; }
.home-live-panel { min-height: 220px; padding: 20px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper); box-shadow: var(--shadow); }
.home-live-panel .section-heading { margin-bottom: 9px; }
.overview-live-list { display: grid; gap: 0; }
.overview-live-item { min-height: 54px; padding: 10px 0; border-bottom: 1px solid var(--line-soft); display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 10px; align-items: center; }
.overview-live-item:last-child { border-bottom: 0; }
.overview-live-item > div:nth-child(2) { min-width: 0; }
.overview-live-item strong, .overview-live-item small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.overview-live-item strong { font-size: var(--fs-meta); }
.overview-live-item small { margin-top: 2px; color: var(--muted); font-size: var(--fs-micro); }
.overview-live-status { padding: 4px 7px; border-radius: var(--r-xs); background: #f6efe8; color: #9b887a; font-size: var(--fs-micro); white-space: nowrap; }
.overview-live-status.urgent { background: var(--coral-soft); color: var(--coral-deep); }
.overview-live-status.done { background: var(--green-soft); color: #66806a; }
.overview-live-status.unread { background: var(--yellow-soft); color: #9b762e; }
.overview-live-icon { width: 28px; height: 28px; border-radius: var(--r-sm); display: grid; place-items: center; background: #f5eee7; color: #9a8778; }
.overview-live-icon svg { width: 15px; }
.overview-empty { padding: 28px 8px; color: var(--muted); font-size: var(--fs-meta); text-align: center; }
.overview-empty-cluster { margin: 0 0 28px; padding: 18px 22px; border: 1px dashed #dccabd; border-radius: var(--radius); background: rgba(255,253,249,.72); display: flex; align-items: center; gap: 14px; color: var(--muted); }
.overview-empty-cluster[hidden] { display: none; }
.overview-empty-cluster-icon { width: 38px; height: 38px; flex: 0 0 auto; border-radius: var(--r-sm); display: grid; place-items: center; background: var(--yellow-soft); color: #ad812f; }
.overview-empty-cluster-icon svg { width: 18px; }
.overview-empty-cluster strong { display: block; color: var(--ink); font-size: var(--fs-lead); }
.overview-empty-cluster p { margin: 3px 0 0; font-size: var(--fs-meta); line-height: 1.55; }
.overview-empty-cluster .outline-button { width: auto; min-width: 150px; margin: 0 0 0 auto; flex: 0 0 auto; }
.family-timeline-panel { margin: 0 0 28px; }
.family-timeline-heading { display: flex; align-items: center; gap: 12px; }
.family-timeline-heading > div:nth-child(2) { min-width: 0; }
.family-timeline-heading h2 { margin-top: 2px; font-size: var(--fs-h2); }
.family-timeline-heading .outline-button { width: auto; min-height: 38px; margin-left: auto; padding: 0 12px; }
/* 首页时间线只放最近 3 条，完整记录在时间线模块 */
.family-timeline-more { margin-left: auto; white-space: nowrap; }
.family-timeline-more + .outline-button { margin-left: 0; }
.family-timeline-list { display: grid; gap: 0; margin-top: 14px; }
.family-timeline-item { display: grid; grid-template-columns: 92px 16px minmax(0, 1fr); gap: 12px; min-height: 78px; padding: 12px 0; border-bottom: 1px solid var(--line-soft); }
.family-timeline-item:last-child { border-bottom: 0; }
.family-timeline-date strong, .family-timeline-date span { display: block; }
.family-timeline-date strong { color: var(--ink); font-size: var(--fs-meta); }
.family-timeline-date span { margin-top: 4px; color: var(--muted); font-size: var(--fs-micro); }
.family-timeline-dot { position: relative; width: 12px; height: 12px; margin-top: 3px; border: 3px solid var(--coral); border-radius: 50%; background: #fff9f3; }
.family-timeline-item:not(:last-child) .family-timeline-dot::after { content: ""; position: absolute; top: 9px; left: 2px; width: 2px; height: 66px; background: #efd9ca; }
.family-timeline-copy { min-width: 0; }
.family-timeline-copy h3 { font-size: var(--fs-lead); font-weight: 700; }
.family-timeline-copy p { margin: 5px 0 0; color: var(--muted); font-size: var(--fs-meta); line-height: 1.6; }
.family-timeline-copy small { display: block; margin-top: 6px; color: #a99484; font-size: var(--fs-micro); }
/* 家庭时间线模块（独立页面；首页只放最近 3 条） */
.timeline-filter-bar { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }
.timeline-filter-chip { min-height: 32px; padding: 0 12px; border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--paper); color: var(--muted); font: inherit; font-size: var(--fs-meta); display: inline-flex; align-items: center; gap: 6px; cursor: pointer; transition: background .2s, border-color .2s, color .2s; }
.timeline-filter-chip:hover { border-color: var(--line-strong); color: var(--ink); }
.timeline-filter-chip.active { border-color: var(--coral); background: var(--coral-soft); color: var(--coral-ink); font-weight: 700; }
.timeline-filter-chip span { font-variant-numeric: tabular-nums; opacity: .75; }
.timeline-month-stack { display: grid; gap: 24px; }
.timeline-month-heading { display: flex; align-items: baseline; gap: 10px; padding-bottom: 6px; border-bottom: 1px solid var(--line); }
.timeline-month-heading h2 { font-family: var(--font-display); font-size: var(--fs-h4); }
.timeline-month-heading span { color: var(--muted); font-size: var(--fs-micro); }
.timeline-month-group .family-timeline-list { margin-top: 0; }
.primary-button, .quiet-button, .outline-button { min-height: 44px; border-radius: var(--r-sm); border: 1px solid transparent; display: inline-flex; align-items: center; justify-content: center; gap: 8px; transition: transform .2s, box-shadow .2s, background .2s; white-space: nowrap; }
.primary-button:disabled, .quiet-button:disabled, .outline-button:disabled, button:disabled { opacity: .55; cursor: not-allowed; transform: none; box-shadow: none; }
.primary-button:active:not(:disabled), .quiet-button:active:not(:disabled), .outline-button:active:not(:disabled) { transform: translateY(1px); }
.primary-button { padding: 0 16px; background: var(--coral); color: white; box-shadow: 0 7px 16px rgba(201,111,97,.2); }
.primary-button:hover { transform: translateY(-2px); box-shadow: 0 10px 20px rgba(201,111,97,.25); }
.quiet-button { padding: 0 12px; color: #887b71; background: transparent; font-size: var(--fs-body); }
.quiet-button:hover { background: #f3ebe2; color: var(--ink); }
.outline-button { width: 100%; margin-top: 20px; padding: 0 16px; border-color: var(--line); background: rgba(255,255,255,.5); color: #746b64; font-size: var(--fs-body); }
.outline-button:hover { background: white; border-color: var(--line-strong); }
.phase-banner { padding: 22px 24px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: linear-gradient(102deg, #f7e8dc, #fbf3e9 68%, #f2eadf); display: flex; align-items: center; gap: 18px; box-shadow: var(--shadow); }
.phase-icon, .panel-icon { width: 39px; height: 39px; border-radius: var(--r-md); display: grid; place-items: center; flex: 0 0 auto; }
.phase-icon { background: rgba(255,255,255,.65); color: var(--coral); }
.phase-copy { min-width: 220px; flex: 1; }
.phase-copy h2 { font-size: var(--fs-h2); }
.phase-copy p { margin: 3px 0 0; color: #82766d; font-size: var(--fs-body); }
.phase-progress { width: 210px; }
.progress-label { display: flex; justify-content: space-between; color: #887970; font-size: var(--fs-micro); margin-bottom: 7px; }
.progress-label strong { color: var(--coral); }
.progress-track { height: 7px; overflow: hidden; border-radius: var(--r-sm); background: rgba(255,255,255,.7); }
.progress-track span { display: block; height: 100%; border-radius: inherit; background: var(--coral); }
.phase-progress small { display: block; margin-top: 7px; color: #9b8d82; font-size: var(--fs-micro); }
.text-button, .small-link { border: 0; background: transparent; color: #a25b4f; display: inline-flex; align-items: center; gap: 5px; font-size: var(--fs-meta); white-space: nowrap; }
.text-button { padding: 8px 0 8px 15px; border-left: 1px solid rgba(150,113,90,.2); }
.text-button svg, .small-link svg { width: 14px; }
.section-block { margin-top: 42px; }
.module-page-section { max-width: 1060px; margin-top: 10px; }
.module-page-section .section-heading { padding-bottom: 8px; border-bottom: 1px solid var(--line); }
.module-hero { margin-bottom: 28px; padding: 25px 28px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: linear-gradient(102deg, #f7e8dc, #fbf3e9 68%, #f2eadf); display: flex; align-items: end; justify-content: space-between; gap: 24px; box-shadow: var(--shadow); }
.module-hero h1 { margin-bottom: 7px; font-size: var(--fs-page); }
.module-hero p:last-child { max-width: 650px; margin-bottom: 0; color: #82766d; }
.approval-type-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.approval-type-card { min-height: 182px; padding: 18px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper); box-shadow: var(--shadow); display: grid; grid-template-columns: auto 1fr auto; gap: 10px 12px; align-items: start; text-align: left; }
.approval-type-card:hover { border-color: #d7b9a8; transform: translateY(-1px); }
.approval-type-card strong { align-self: center; font-size: var(--fs-h4); }
.approval-type-card p { grid-column: 1 / -1; margin: 0; color: var(--muted); font-size: var(--fs-meta); }
.approval-type-card small { grid-column: 1 / -1; color: #9e8f84; font-size: var(--fs-micro); }
.approval-type-card > svg { width: 16px; color: #af8c72; margin-top: 4px; }
.approval-type-icon { width: 38px; height: 38px; border-radius: var(--r-sm); display: grid; place-items: center; background: var(--coral-soft); color: var(--coral); }
.approval-type-icon svg { width: 18px; }
.approval-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.approval-card { padding: 16px; border: 1px solid var(--line); border-radius: var(--r-md); background: #fffdf9; box-shadow: var(--shadow); }
.approval-card-head { display: flex; align-items: start; justify-content: space-between; gap: 14px; }
.approval-card-title { min-width: 0; }
.approval-card h3 { font-size: var(--fs-h4); line-height: 1.45; overflow-wrap: anywhere; }
.approval-card-head p { margin-top: 4px; line-height: 1.45; overflow-wrap: anywhere; }
.approval-card-desc { margin: 10px 0 0; color: var(--muted); font-size: var(--fs-meta); white-space: pre-wrap; }
.approval-actions { margin-top: 12px; display: flex; gap: 8px; }
.approval-actions .outline-button, .approval-actions .quiet-button { width: auto; margin-top: 0; }
.approval-empty { padding: 18px 0; color: var(--muted); font-size: var(--fs-body); text-align: center; }
.approval-page-shell { display: grid; gap: 22px; }
.approval-page-intro { padding-top: 18px; }
.approval-page-intro .module-panel-heading { margin-bottom: 12px; align-items: start; }
.approval-page-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.approval-history-link { margin-left: 0; }
.approval-page-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.approval-page-stats span { padding: 11px 13px; border-radius: var(--r-sm); border: 1px solid #e9ddd0; background: var(--paper-raised); color: #72665d; font-size: var(--fs-meta); display: grid; gap: 4px; }
.approval-page-stats strong { color: var(--ink); font-size: var(--fs-h4); }
.approval-summary-grid { display: grid; grid-template-columns: minmax(0, 1.45fr) repeat(2, minmax(220px, .85fr)); gap: 14px; align-items: start; }
.approval-summary-panel { min-width: 0; }
.approval-summary-panel-primary { border-color: #e6c8bb; background: #fffaf4; }
.approval-summary-panel-primary .section-heading h2 { font-size: var(--fs-h2); }
.approval-summary-panel-primary .approval-summary-list { background: #fffdf9; }
.approval-summary-panel-primary.is-empty { padding-bottom: 14px; }
.approval-summary-panel-primary.is-empty .section-heading { margin-bottom: 8px; }
.approval-summary-panel-primary.is-empty .section-heading > div > p:not(.eyebrow) { display: none; }
.approval-summary-panel-primary.is-empty .approval-summary-list { min-height: 0; padding: 8px 10px; }
.approval-summary-panel-primary.is-empty .approval-empty { padding: 10px 0; }
.approval-summary-panel-primary.is-empty .approval-summary-foot { display: none; }
.approval-summary-panel-secondary { box-shadow: none; background: rgba(255,253,249,.72); }
.approval-summary-panel-secondary .section-heading h2 { font-size: var(--fs-h3); }
.approval-summary-block { display: grid; gap: 14px; }
.approval-summary-list { min-height: 142px; padding: 10px; border: 1px solid #efe3d7; border-radius: var(--r-md); background: var(--cream); box-shadow: none; display: grid; gap: 8px; align-content: start; }
.approval-empty.compact { min-height: 92px; padding: 14px 0; }
.approval-summary-panel { padding-top: 18px; }
.approval-summary-panel .section-heading { margin-bottom: 10px; align-items: center; }
.approval-summary-panel .count-badge { margin-left: auto; }
.approval-summary-foot { display: flex; justify-content: flex-end; padding-top: 2px; }
.approval-card.compact { padding: 10px 12px; border-radius: var(--r-sm); }
.approval-card.compact .approval-card-desc { display: none; }
.approval-card.compact .approval-card-meta { margin-top: 6px; }
.approval-card.compact .approval-card-foot { margin-top: 6px; gap: 8px; }
.approval-card.compact .approval-card-head { gap: 10px; }
.approval-card.compact h3 { font-size: var(--fs-h4); line-height: 1.35; }
.approval-card.compact .approval-card-head p { margin-top: 2px; line-height: 1.3; }
.approval-card.compact .approval-created-at { line-height: 1.25; }
.approval-card.compact .approval-card-controls .outline-button,
.approval-card.compact .approval-card-controls .quiet-button { min-height: 40px; }
.approval-history-nav { display: flex; gap: 8px; flex-wrap: wrap; }
.approval-history-chip { display: inline-flex; align-items: center; gap: 8px; padding: 8px 12px; border: 1px solid #eadccd; border-radius: var(--r-pill); background: var(--paper-raised); color: #7b6f66; font-size: var(--fs-meta); }
.approval-history-chip strong { min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--r-pill); background: var(--coral-soft); color: var(--coral-ink); display: grid; place-items: center; font-size: var(--fs-micro); }
.approval-history-stack { display: grid; gap: 12px; }
.approval-history-panel .approval-summary-list { min-height: 160px; padding: 10px; gap: 8px; }
.approval-history-panel .approval-card { max-width: 860px; padding: 12px; border-radius: var(--r-sm); }
.approval-history-panel .approval-card h3 { font-size: var(--fs-h4); line-height: 1.35; }
.approval-history-panel .approval-card-head { gap: 10px; }
.approval-history-panel .approval-card-head p { margin-top: 2px; line-height: 1.35; }
.approval-history-panel .approval-card-desc { margin-top: 8px; }
.approval-history-panel .approval-card-meta { margin-top: 7px; }
.approval-history-panel .approval-card-foot { margin-top: 8px; gap: 8px; }
/* 申请页原来是「表单 + 右侧 340px 说明栏」两栏。
   那栏叫「家庭视角」，内容是写死的三张卡片（父母/成员本人/长辈），
   和选的类型毫无关系，标题问「这个分类覆盖哪些人」却根本没回答 ——
   删掉之后表单占满，字段终于有地方站了。 */
.approval-detail-layout { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; align-items: start; }
.approval-detail-form { min-width: 0; }
.approval-detail-note { margin-top: 6px; padding: 12px 14px; border-radius: var(--r-sm); background: #faf4ec; display: flex; align-items: start; gap: 8px; color: #7f7269; font-size: var(--fs-meta); }
.approval-detail-note svg { width: 15px; color: var(--yellow); flex: 0 0 auto; }

.approval-chain-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: 12px; margin-top: 10px; }
.approval-user-pool { display: grid; gap: 8px; padding: 12px; border: 1px dashed #dbcbbd; border-radius: var(--r-md); background: var(--paper-raised); min-height: 180px; }
.approval-user-chip { padding: 10px 11px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper); display: grid; gap: 2px; text-align: left; }
.approval-user-chip:hover { border-color: #d7b9a8; background: #fff7f2; }
.approval-user-chip span { font-size: var(--fs-body); font-weight: 700; }
.approval-user-chip small { color: var(--muted); font-size: var(--fs-micro); }
.approval-chain-target { display: grid; gap: 10px; }
.approval-chain-list { min-height: 180px; margin: 0; padding: 12px; border: 1px solid var(--line-strong); border-radius: var(--r-md); background: #fffdf9; list-style: none; display: flex; gap: 10px; overflow-x: auto; align-items: stretch; }
.approval-chain-empty { min-width: 180px; min-height: 155px; display: grid; place-items: center; color: var(--muted); font-size: var(--fs-meta); border: 1px dashed #e1d1c3; border-radius: var(--r-sm); background: var(--paper-raised); }
.approval-chain-step { min-width: 168px; padding: 10px 11px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper); display: flex; align-items: center; gap: 10px; }
.approval-chain-step.active { border-color: var(--coral); background: var(--coral-soft); }
.approval-step-index { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; background: #fff; color: var(--coral); font-size: var(--fs-meta); font-weight: 700; flex: 0 0 auto; }
.approval-chain-step > div { min-width: 0; display: grid; gap: 2px; }
.approval-chain-step span { font-weight: 700; font-size: var(--fs-body); }
.approval-chain-step small { color: var(--muted); font-size: var(--fs-micro); }
.approval-chain-step .icon-button { margin-left: auto; width: 30px; height: 30px; flex: 0 0 auto; }
.approval-chain-hint { padding: 12px 14px; border-radius: var(--r-sm); background: #faf4ec; display: grid; gap: 3px; }
.approval-chain-hint strong { font-size: var(--fs-meta); }
.approval-chain-hint span { color: var(--muted); font-size: var(--fs-meta); }
.approval-chain-progress { padding: 10px 12px; border-radius: var(--r-sm); background: #fff7ef; color: #8f665b; font-size: var(--fs-meta); border: 1px solid #eadbcc; }
.approval-card-meta { margin-top: 10px; display: grid; gap: 4px; color: #8b7f75; font-size: var(--fs-micro); }
.approval-card-meta span { color: var(--coral); font-weight: 700; }
.approval-card-meta small { line-height: 1.45; overflow-wrap: anywhere; }
.approval-card-foot { display: flex; align-items: end; justify-content: space-between; gap: 12px; margin-top: 12px; }
.approval-created-at { color: #8b7f75; font-size: var(--fs-micro); line-height: 1.4; overflow-wrap: anywhere; }
.approval-card-controls { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; min-width: 0; }
.approval-card-controls .outline-button,
.approval-card-controls .quiet-button { width: auto; min-width: 76px; flex: 0 0 auto; margin-top: 0; padding: 0 12px; white-space: nowrap; }
.approval-flow-strip { margin-top: 12px; display: flex; gap: 8px; align-items: center; overflow-x: auto; padding-bottom: 4px; }
.approval-flow-node { min-width: 118px; padding: 9px 10px; border: 1px solid #e7d9cc; border-radius: var(--r-sm); background: #fffdf9; display: grid; gap: 3px; text-align: left; }
.approval-flow-node strong { color: #9a887b; font-size: var(--fs-lead); }
.approval-flow-node small { color: var(--muted); font-size: var(--fs-micro); line-height: 1.35; overflow-wrap: anywhere; }
.approval-flow-node em { color: #8b7f75; font-size: var(--fs-micro); font-style: normal; }
.approval-flow-node.current { border-color: var(--coral); background: var(--coral-soft); }
.approval-flow-node.approved { border-color: #cfe0cf; background: var(--green-soft); }
.approval-flow-node.approved strong, .approval-flow-node.approved em { color: #4f6b52; }
.approval-flow-node.rejected { border-color: #ecc9c3; background: #f6e0dc; }
.approval-flow-node.rejected strong, .approval-flow-node.rejected em { color: #b4544a; }
.approval-flow-node.pending em { color: #8a6a1f; }
.approval-status { display: inline-flex; align-items: center; gap: 4px; min-height: 24px; padding: 0 10px; border-radius: var(--r-pill); font-size: var(--fs-meta); font-weight: 600; white-space: nowrap; flex: none; background: #f1e9df; color: #6f6459; }
.approval-status.approval-pending { background: var(--yellow-soft); color: #8a6a1f; }
.approval-status.approval-approved { background: var(--green-soft); color: #4f6b52; }
.approval-status.approval-rejected { background: #f6e0dc; color: #b4544a; }
.approval-page-stats strong, .approval-status, .approval-history-chip strong, .approval-flow-node strong, .count-badge { font-variant-numeric: tabular-nums; }
.approval-timeline-added { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); font-size: var(--fs-body); }
.approval-timeline-added::before { content: "✓"; color: var(--green); font-weight: 700; }
.approval-flow-arrow { width: 14px; flex: 0 0 auto; color: #b39b8a; }
.approval-waiting-note { margin-top: 12px; padding: 10px 12px; border-radius: var(--r-sm); background: #faf4ec; color: #8f665b; font-size: var(--fs-meta); }
.approval-decision-modal { width: min(100%, 520px); }
/* ── 站内信：一个收件箱 ──
   原来的做法是三个等权面板并排（写私信 / 系统提醒 / 家庭私信），
   外加一个 0-0-13 的三连统计格。没有焦点，12 张同规格卡片叠成一长条。
   现在收成一个收件箱：私信保持卡片（人的消息，值得读），
   系统提醒压成回执行（机器消息，一屏扫十几条）。 */
.inbox-header { display: flex; align-items: start; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.inbox-header h1 { margin: 3px 0 0; font-size: var(--fs-h1); letter-spacing: -0.01em; }
.inbox-summary { margin: 7px 0 0; color: var(--muted); font-size: var(--fs-meta); }
.inbox-summary strong { color: var(--coral); font-size: var(--fs-lead); font-variant-numeric: tabular-nums; }
.inbox-actions { display: flex; gap: 8px; align-items: center; min-height: 44px; }
/* 写私信是低频操作，收进原生 <details>，默认不占版面 */
.compose-drawer { margin: 18px 0 0; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper-raised); }
.compose-drawer > summary { display: flex; align-items: center; gap: 8px; min-height: 42px; padding: 0 14px; color: #8b6f5f; font-size: var(--fs-body); font-weight: 600; cursor: pointer; list-style: none; }
.compose-drawer > summary::-webkit-details-marker { display: none; }
.compose-drawer > summary::after { content: "▾"; margin-left: auto; color: var(--muted); transition: transform .18s cubic-bezier(.23, 1, .32, 1); }
.compose-drawer[open] > summary::after { transform: rotate(180deg); }
.compose-drawer > summary:hover { color: var(--ink); }
.compose-form { padding: 2px 14px 14px; }
.inbox-stream { margin-top: 24px; display: grid; gap: 26px; }
.inbox-group-head { display: flex; align-items: baseline; gap: 8px; padding-bottom: 8px; }
.inbox-group-head h2 { font-size: var(--fs-h4); }
.inbox-group-head span { color: var(--muted); font-size: var(--fs-meta); font-variant-numeric: tabular-nums; }
.inbox-group-head em { margin-left: auto; color: #a49a91; font-size: var(--fs-micro); font-style: normal; }
.inbox-empty { margin: 0; padding: 13px 0; color: var(--muted); font-size: var(--fs-meta); }
/* 私信：卡片，保留呼吸 */
.message-list { display: grid; gap: 10px; }
.message-card { display: flex; gap: 12px; padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--paper); }
.message-card.unread { border-color: var(--line-strong); background: #fff8f3; }
.message-card-main { flex: 1; min-width: 0; display: grid; gap: 6px; }
.message-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.message-card-head h3 { font-size: var(--fs-lead); }
.message-card-head time { flex: 0 0 auto; color: #a49a91; font-size: var(--fs-micro); font-variant-numeric: tabular-nums; }
.message-body { margin: 0; color: #6f665f; font-size: var(--fs-body); line-height: 1.65; white-space: pre-wrap; overflow-wrap: anywhere; }
.message-card-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.message-card-foot small { color: var(--muted); font-size: var(--fs-micro); }
.message-card-foot .outline-button { width: auto; min-height: 30px; margin-top: 0; padding: 0 10px; font-size: var(--fs-micro); }
/* 系统提醒：回执行，靠分界线而不是卡片 */
.receipt-list { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--line); }
.receipt-row { display: flex; align-items: center; gap: 10px; padding: 10px 2px; border-bottom: 1px solid #f5f0e9; font-size: var(--fs-body); }
.receipt-row.is-unread { background: #fffaf6; }
.receipt-dot { width: 5px; height: 5px; flex: 0 0 auto; border-radius: 50%; }
.receipt-row.is-unread .receipt-dot { background: var(--coral); }
.receipt-result { flex: 0 0 auto; min-width: 42px; padding: 2px 8px; border-radius: var(--r-xs); text-align: center; font-size: var(--fs-micro); font-weight: 600; }
.receipt-result.is-approved { background: var(--green-soft); color: #4f6f52; }
.receipt-result.is-rejected { background: var(--coral-soft); color: var(--coral-ink); }
.receipt-result.is-plain { background: #f2e8de; color: #8b6f5f; }
.receipt-subject { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink); }
.receipt-row.is-unread .receipt-subject { font-weight: 600; }
.receipt-note { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: var(--fs-meta); }
.receipt-row time { flex: 0 0 auto; margin-left: auto; color: #a49a91; font-size: var(--fs-micro); font-variant-numeric: tabular-nums; }
.receipt-read { flex: 0 0 auto; border: 0; background: transparent; color: var(--coral); font: inherit; font-size: var(--fs-micro); cursor: pointer; opacity: 0; transition: opacity .15s; }
.receipt-row:hover .receipt-read, .receipt-read:focus-visible { opacity: 1; }
.module-grid { display: grid; gap: 14px; margin-bottom: 14px; }
.module-grid.three { grid-template-columns: repeat(3, 1fr); }
.module-panel { padding: 21px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper); box-shadow: var(--shadow); }
.module-panel > .panel-icon { margin-bottom: 19px; }
.module-panel h3 { margin: 5px 0 5px; font-size: var(--fs-h3); }
.module-panel p:not(.eyebrow) { min-height: 43px; margin-bottom: 17px; color: var(--muted); font-size: var(--fs-meta); }
.module-panel .small-link { margin-left: 0; }
.module-lower { display: grid; grid-template-columns: 1.55fr 1fr; gap: 14px; }
.module-panel.wide { min-width: 0; }
.module-panel-heading { display: flex; align-items: start; justify-content: space-between; gap: 14px; }
.module-panel-heading h2 { margin: 0; font-size: var(--fs-h2); }
.agreement-list { margin-top: 19px; display: grid; gap: 13px; }
.agreement-list div { display: flex; align-items: start; gap: 10px; padding: 11px 12px; border-radius: var(--r-sm); background: #faf5ef; color: #716860; font-size: var(--fs-body); }
.agreement-list svg { width: 16px; flex: 0 0 auto; color: var(--green); }
.shortcut-list { margin-top: 16px; display: grid; gap: 6px; }
.shortcut-list button { padding: 11px 9px; border: 0; border-radius: var(--r-sm); background: transparent; display: flex; align-items: center; gap: 10px; text-align: left; color: var(--ink-2); font-size: var(--fs-body); }
.shortcut-list button:hover { background: #faf1e8; color: var(--coral); }
.shortcut-list svg { width: 17px; color: var(--coral); }
.child-profile-large { margin-bottom: 14px; padding: 22px; border: 1px solid #e6c8bb; border-radius: var(--radius); background: linear-gradient(145deg, #fffdf9, #fff8f2); display: flex; align-items: center; gap: 16px; }
.child-profile-large h2 { margin: 4px 0; font-size: var(--fs-h2); }
.child-profile-large p:not(.eyebrow) { margin: 0; color: var(--muted); font-size: var(--fs-meta); }
.profile-progress { margin-left: auto; display: grid; grid-template-columns: auto auto; gap: 0 9px; color: var(--muted); font-size: var(--fs-micro); }
.profile-progress strong { color: var(--coral); font-size: var(--fs-h3); }
.child-profile-large .outline-button { width: auto; margin: 0 0 0 10px; padding: 0 14px; }
.module-lower .module-panel { min-height: 200px; }
.module-stat-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin: 18px 0 14px; }
.file-stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.file-summary-grid { grid-template-columns: 1fr; }
.module-stat-grid > div { min-height: 104px; padding: 17px 19px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper); box-shadow: var(--shadow); }
.module-stat-grid span, .module-stat-grid strong, .module-stat-grid small { display: block; }
.module-stat-grid span { color: var(--muted); font-size: var(--fs-micro); }
.module-stat-grid strong { margin-top: 3px; font-family: var(--font-ui); font-size: var(--fs-h1); line-height: 1.2; }
.module-stat-grid small { margin-top: 4px; color: #9a9087; font-size: var(--fs-micro); }
.task-board { display: grid; grid-template-columns: 1.2fr 1fr 1fr; gap: 14px; }
.task-board-main { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.task-lower-grid { display: grid; grid-template-columns: 1.35fr 1fr; gap: 14px; margin-top: 14px; }
.task-empty-state { max-width: 760px; padding: 34px; text-align: center; }
.task-empty-state .panel-icon { margin: 0 auto 14px; }
.task-empty-state h2 { margin: 4px 0 8px; font-size: var(--fs-h2); }
.task-empty-state p:not(.eyebrow) { max-width: 460px; margin: 0 auto; color: var(--muted); font-size: var(--fs-body); }
.task-empty-state .outline-button { width: auto; min-width: 180px; margin: 20px auto 0; }
.task-column h2 { font-family: var(--font-display); font-size: var(--fs-h3); }
.task-column h2 span { color: var(--coral); font-family: "DM Sans", sans-serif; font-size: var(--fs-body); }
.board-task { margin-top: 14px; padding: 14px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper-raised); display: grid; gap: 3px; }
.board-task strong { font-size: var(--fs-body); font-weight: 600; }
.board-task small { color: var(--muted); font-size: var(--fs-micro); }
.board-task .task-complete-button { width: auto; min-height: 32px; margin-top: 7px; padding: 0 9px; border: 1px solid #dbe7da; border-radius: var(--r-sm); background: var(--green-soft); color: #66806a; display: inline-flex; align-items: center; justify-content: center; gap: 5px; font-size: var(--fs-micro); }
.board-task .task-complete-button:hover { border-color: #b8d0b9; background: #dce9db; }
.task-complete-button svg { width: 14px; }
.task-priority { color: var(--coral); font-size: var(--fs-micro); font-weight: 700; }
.task-priority.urgent { color: var(--coral-deep); }
.task-priority.done { color: #66806a; }
/* 「重要」标记：优先级字段此前只写不读，这里补上显示。
   用中性描边而不是强调色 —— 珊瑚色已经同时承担品牌、"当前轮到"、逾期三件事，不再加第四件。 */
.task-priority-mark { display: inline-block; margin-left: 7px; padding: 1px 7px; border: 1px solid var(--line); border-radius: var(--r-pill); background: #fff; color: var(--ink); font-size: var(--fs-micro); font-weight: 700; vertical-align: 1px; }
/* 一行摘要：取代原先把三个列标题各说一遍的统计格 */
.task-summary-line { margin: 14px 0 4px; color: var(--muted); font-size: var(--fs-body); }
.task-summary-line strong { color: var(--ink); font-family: var(--font-ui); font-size: var(--fs-h4); font-variant-numeric: tabular-nums; }
.task-summary-line em.urgent { font-style: normal; color: var(--coral-deep); }
/* 看板固定 3 列：列数随数据增减会让整块宽度跳变，观感上很不稳 */
.task-lower-single { grid-template-columns: minmax(0, 1fr); }
.task-all-done .outline-button { width: auto; min-width: 160px; margin: 20px auto 0; }
.completed-task { display: flex; align-items: center; gap: 9px; }
.completed-task svg { width: 17px; color: var(--green); }
.completed-task .task-restore-button { margin-left: auto; padding: 4px 8px; border: 1px solid var(--line); border-radius: var(--r-sm); background: transparent; color: var(--muted); font-size: var(--fs-micro); }
.completed-task .task-restore-button:hover { border-color: var(--line-strong); color: var(--ink); background: #fff; }
.member-task { margin-top: 10px; padding: 10px 0; border-bottom: 1px solid var(--line-soft); display: flex; align-items: center; gap: 9px; }
.member-task span:nth-child(2) { flex: 1; }
.member-task strong, .member-task small { display: block; }
.member-task strong { font-size: var(--fs-meta); }
.member-task small { color: var(--muted); font-size: var(--fs-micro); }
.member-task > svg { width: 15px; color: #b4aaa2; }

/* ── 任务页：筛选片 + 单列列表 ──
   原来这里是三列看板（我的 / 家庭共同 / 其他成员）。对家庭规模不合适：
   只有 1 件待办时两个桶是空的，唯一那件事被挤到第三列，打开页面的人
   看到一屏「暂无」+ 一件不是自己的事。改成单列列表后不再有空桶，
   归属用筛选片收窄，任务本身按紧急度排在一起。 */
.task-filter-bar { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }
.task-filter-chip { min-height: 44px; padding: 0 13px; border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--paper-raised); color: var(--ink-2); font-size: var(--fs-body); transition: border-color .15s, background .15s; }
.task-filter-chip:hover { border-color: var(--line-strong); color: var(--ink); }
.task-filter-chip.active { border-color: var(--coral); background: var(--coral-soft); color: var(--coral-ink); font-weight: 700; }
.task-filter-chip span { margin-left: 5px; font-variant-numeric: tabular-nums; opacity: .75; }
.task-list-panel { padding: 20px 22px 6px; }
.task-rows { display: grid; }
.task-row { display: flex; align-items: center; gap: 12px; padding: 13px 0; border-bottom: 1px solid var(--line-soft); }
.task-row:last-child { border-bottom: 0; }
/* 状态标签占固定宽度，标题才会在左侧对齐成一列 —— 一排长短不一的标签
   会让整个列表看起来是歪的。 */
.task-row > .task-priority { flex: 0 0 54px; font-size: var(--fs-meta); }
.task-row-body { flex: 1; min-width: 0; }
.task-row-body strong { font-size: var(--fs-lead); font-weight: 600; overflow-wrap: anywhere; }
.task-row-body small { display: block; margin-top: 3px; color: var(--muted); font-size: var(--fs-meta); }
.task-row .task-complete-button { flex: 0 0 auto; width: auto; min-height: 44px; margin: 0; padding: 0 13px; border: 1px solid #cfe0cf; border-radius: var(--r-sm); background: #e6f0e5; color: #3f6b46; font-size: var(--fs-meta); font-weight: 600; display: inline-flex; align-items: center; gap: 5px; }
.task-row .task-complete-button:hover { border-color: #b8d0b9; background: #dce9db; }

/* ── 任务详情：点开一行做处理 ──
   派给别人的任务要对方先接受，所以行必须能点。 */
.task-row { cursor: pointer; transition: background .15s; }
.task-row:hover { background: var(--paper-raised); }
/* 派给我、还没接受：这条需要我做决定，给一点底色让它从列表里跳出来 */
.task-row.is-awaiting { background: #fff6ef; }
.task-row.is-awaiting:hover { background: #fdeee8; }
.task-awaiting { flex: 0 0 auto; padding: 5px 11px; border: 1px dashed #dfa08e; border-radius: var(--r-pill); background: #fdeee8; color: var(--coral-deep); font-size: var(--fs-meta); font-weight: 700; white-space: nowrap; }
.task-detail-card { width: min(100%, 520px); }
.task-detail-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); margin: 18px 0 20px; border-top: 1px solid var(--line-soft); }
.task-detail-facts > div { display: grid; gap: 2px; padding: 11px 0; border-bottom: 1px solid var(--line-soft); }
.task-detail-facts > div:nth-child(odd) { padding-right: 14px; }
.task-detail-facts dt { color: var(--muted); font-size: var(--fs-meta); }
.task-detail-facts dd { margin: 0; font-size: var(--fs-body); overflow-wrap: anywhere; }
.task-detail-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.task-detail-actions .primary-button, .task-detail-actions .outline-button { width: auto; min-height: 44px; }
.task-detail-note { margin: 10px 0 0; color: var(--muted); font-size: var(--fs-meta); line-height: 1.65; }
.task-detail-reassign { margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line-soft); display: flex; align-items: end; gap: 10px; }
.task-detail-reassign .form-field { flex: 1; min-width: 0; }
.task-detail-reassign .outline-button { flex: 0 0 auto; width: auto; min-height: 44px; }

@media (max-width: 560px) {
  .task-detail-facts { grid-template-columns: 1fr; }
  .task-detail-facts > div:nth-child(odd) { padding-right: 0; }
  .task-detail-actions { flex-direction: column; }
  .task-detail-actions .primary-button, .task-detail-actions .outline-button { width: 100%; }
  .task-detail-reassign { flex-direction: column; align-items: stretch; }
}
.file-summary { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-bottom: 14px; }
.file-summary > div { padding: 17px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper); display: grid; grid-template-columns: auto 1fr; gap: 1px 11px; align-items: center; box-shadow: var(--shadow); }
.file-summary .panel-icon { grid-row: span 2; }
.file-summary strong, .file-summary small { display: block; }
.file-summary strong { font-size: var(--fs-body); }
.file-summary small { color: var(--muted); font-size: var(--fs-micro); }
.file-list, .health-list { margin-top: 16px; }
.file-list > div, .health-list > div { min-height: 61px; padding: 9px 0; border-bottom: 1px solid var(--line-soft); display: flex; align-items: center; gap: 11px; }
.file-icon { width: 34px; height: 34px; border-radius: var(--r-sm); display: grid; place-items: center; }
.file-icon svg { width: 17px; }
.file-icon.doc { background: var(--coral-soft); color: var(--coral); }
.file-icon.image { background: var(--green-soft); color: var(--green); }
.file-icon.report { background: var(--yellow-soft); color: #a17b34; }
.file-list > div > span:nth-child(2), .health-list > div > span:nth-child(2) { flex: 1; }
.file-list strong, .file-list small, .health-list strong, .health-list small { display: block; }
.file-list strong, .health-list strong { font-size: var(--fs-meta); }
.file-list small, .health-list small { color: var(--muted); font-size: var(--fs-micro); }
.file-list em, .health-list em { color: #9d9289; font-size: var(--fs-micro); font-style: normal; }
.file-row-actions { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.file-row-actions .icon-button { width: 28px; height: 28px; }
.file-toolbar { display: flex; align-items: center; gap: 8px; }
.file-toolbar input, .file-toolbar select { min-height: 32px; padding: 0 9px; border: 1px solid var(--line); border-radius: var(--r-sm); background: #fff; color: var(--ink); font: inherit; font-size: var(--fs-meta); }
.file-toolbar input { width: 180px; }
.file-category-tabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin: 14px 0; }
.file-category-tab { min-height: 46px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper); color: var(--muted); font: inherit; font-size: var(--fs-lead); cursor: pointer; transition: border-color .18s ease, background .18s ease, color .18s ease; }
.file-category-tab:hover { border-color: var(--line-strong); color: var(--ink); }
.file-category-tab.active { border-color: var(--coral); background: var(--coral-soft); color: var(--ink); font-weight: 600; }
.file-toolbar input:focus, .file-toolbar select:focus { outline: 2px solid var(--coral-soft); border-color: var(--line-strong); }
.form-hint { display: block; margin-top: 5px; color: var(--muted); font-size: var(--fs-micro); line-height: 1.5; }
.modal-subtitle { margin: 5px 0 0; color: var(--muted); font-size: var(--fs-meta); }
.file-status-field { display: block; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper-raised); }
.file-status-field > span:first-child { display: block; margin-bottom: 9px; color: var(--ink); font-weight: 600; }
.checkbox-line { display: inline-flex; align-items: center; gap: 8px; color: var(--ink); font-size: var(--fs-body); cursor: pointer; }
.checkbox-line input { width: 17px; height: 17px; margin: 0; accent-color: var(--coral); }
.file-status-field .form-hint { margin: 8px 0 0 25px; }
.task-assignment-note { margin: -4px 0 14px; padding: 10px 12px; border-left: 3px solid var(--coral); background: var(--coral-soft); color: var(--muted); font-size: var(--fs-meta); line-height: 1.5; }
.task-readonly { color: var(--muted); font-size: var(--fs-micro); white-space: nowrap; }
.task-member-status { margin: 16px 0; padding: 13px 15px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper-raised); }
.task-member-status h3 { margin: 0 0 9px; font-size: var(--fs-body); }
.task-member-status > div { display: flex; justify-content: space-between; padding: 7px 0; border-top: 1px solid #f0e8df; font-size: var(--fs-meta); }
.task-member-status > div > span { display: grid; gap: 3px; }
.task-member-status small { color: var(--muted); font-size: var(--fs-micro); line-height: 1.4; }
.task-member-status strong { font-weight: 500; color: var(--muted); }
.task-member-accepted { color: var(--green) !important; }
.task-member-completed { color: #547b5a !important; }
.task-member-declined { color: var(--coral) !important; }
.file-preview-modal { width: min(900px, 94vw); max-height: 92vh; }
.file-preview-body { min-height: 180px; max-height: 62vh; margin: 14px 0; padding: 14px; border: 1px solid var(--line); border-radius: var(--radius); background: #faf7f2; display: grid; place-items: center; overflow: auto; }
.file-preview-image { display: block; max-width: 100%; max-height: 58vh; object-fit: contain; }
.file-preview-frame { width: 100%; height: 58vh; border: 0; background: #fff; }
.file-preview-text { width: 100%; margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; color: var(--ink); font: 12px/1.65 ui-monospace, SFMono-Regular, Consolas, monospace; }
.file-preview-unsupported { display: grid; justify-items: center; gap: 9px; color: var(--muted); text-align: center; }
.file-preview-unsupported svg { width: 30px; height: 30px; color: var(--coral); }
.date-tag { width: 48px; color: var(--coral); font-size: var(--fs-micro); font-weight: 700; }
.section-heading { margin-bottom: 16px; display: flex; align-items: end; justify-content: space-between; gap: 16px; }
.section-heading-note { margin: 5px 0 0; color: var(--muted); font-size: var(--fs-meta); }
.overview-grid { display: grid; grid-template-columns: 1.15fr 1.25fr 1fr; gap: 14px; }
.panel, .child-card, .add-child-card, .timeline-card { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); }
.panel { min-height: 215px; padding: 20px; }
.panel-topline, .panel-heading { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.panel-heading > div { display: flex; align-items: center; gap: 10px; }
.panel-icon.coral { background: var(--coral-soft); color: var(--coral); }
.panel-icon.green { background: var(--green-soft); color: var(--green); }
.panel-icon.yellow { background: var(--yellow-soft); color: #b48735; }
.status-pill, .selected-label, .timeline-type { color: var(--coral); font-size: var(--fs-micro); font-weight: 700; }
.focus-panel h3 { margin-top: 27px; font-size: var(--fs-h2); }
.focus-panel p { margin: 6px 0 30px; color: var(--muted); font-size: var(--fs-body); }
.panel-footer, .announcement-byline, .timeline-meta { display: flex; align-items: center; gap: 7px; color: #9a918a; font-size: var(--fs-micro); }
.panel-footer > span { display: flex; align-items: center; gap: 5px; }
.panel-footer svg { width: 14px; }
.small-link { margin-left: auto; }
.count-badge { min-width: 25px; height: 25px; border-radius: var(--r-sm); display: grid; place-items: center; background: var(--green-soft); color: #678269; font-size: var(--fs-meta); font-weight: 700; }
.task-list { list-style: none; margin: 18px 0 9px; padding: 0; }
.task-list li { display: flex; align-items: center; gap: 8px; padding: 7px 0; border-bottom: 1px solid var(--line-soft); font-size: var(--fs-meta); }
.task-list li:last-child { border-bottom: 0; }
.overview-task-panel-item { width: 100%; display: flex; align-items: center; gap: 8px; color: inherit; }
.overview-task-panel-item > span:nth-child(2) { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.overview-task-panel-item small { margin-left: auto; color: #b1a79e; font-size: var(--fs-micro); white-space: nowrap; }
.overview-task-panel-item:hover { color: var(--coral); }
.task-list li small { margin-left: auto; color: #b1a79e; font-size: var(--fs-micro); }
.check-button { width: 24px; height: 24px; padding: 0; border: 0; background: transparent; color: #b5c3b5; display: grid; place-items: center; }
.check-button:hover { color: var(--green); }
.check-button svg { width: 18px; }
.list-link { margin-top: 0; }
.announcement { min-height: 72px; margin: 22px 0 12px; color: #766d66; font-size: var(--fs-body); line-height: 1.75; }
.more-button { width: 28px; height: 28px; margin-left: auto; }
.more-button svg { width: 17px; }
.children-grid { display: grid; grid-template-columns: minmax(260px, 370px) minmax(260px, 370px); gap: 14px; }
.child-card { padding: 20px; border-color: #e6c8bb; background: linear-gradient(145deg, #fffdf9, #fff8f2); }
.child-card-top { display: flex; align-items: start; justify-content: space-between; }
.selected-label { display: flex; align-items: center; gap: 4px; padding: 5px 7px; border-radius: var(--r-xs); background: var(--coral-soft); font-size: var(--fs-micro); }
.selected-label svg { width: 13px; }
.child-card h3 { margin: 18px 0 5px; font-size: var(--fs-h2); }
.child-card p { color: var(--muted); font-size: var(--fs-meta); }
.child-stats { display: flex; gap: 18px; margin-top: 19px; color: var(--muted); font-size: var(--fs-micro); }
.child-stats strong { color: var(--ink); font-size: var(--fs-h3); margin-right: 3px; }
.add-child-card { min-height: 245px; padding: 30px; border-style: dashed; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; background: rgba(255,253,249,.42); }
.add-child-card:hover { background: var(--paper); border-color: var(--line-strong); }
.add-child-card > span { width: 43px; height: 43px; margin-bottom: 12px; border-radius: 50%; display: grid; place-items: center; background: var(--cream); color: var(--coral); }
.add-child-card strong { font-size: var(--fs-lead); }
.add-child-card small { max-width: 200px; margin-top: 5px; color: var(--muted); font-size: var(--fs-micro); }
.timeline-section { padding-bottom: 20px; }
.timeline { position: relative; padding: 5px 0 0 128px; }
.timeline::before { content: ""; position: absolute; left: 10px; top: 15px; bottom: 28px; width: 1px; background: #ded3c9; }
.timeline-item { position: relative; min-height: 148px; display: grid; grid-template-columns: 110px minmax(0, 650px); gap: 24px; align-items: start; }
.timeline-dot { position: absolute; left: -123px; top: 12px; width: 11px; height: 11px; border: 3px solid var(--canvas); border-radius: 50%; box-sizing: content-box; }
.coral-dot { background: var(--coral); box-shadow: 0 0 0 1px #d79a8e; }
.green-dot { background: var(--green); box-shadow: 0 0 0 1px #aac3ac; }
.timeline-date { padding-top: 10px; color: #988d84; font-size: var(--fs-micro); }
.timeline-card { padding: 18px 20px; }
.timeline-card h3 { margin: 6px 0 5px; font-size: var(--fs-h4); }
.timeline-card p { margin-bottom: 14px; color: var(--muted); font-size: var(--fs-meta); }
.green-type { color: #6e936f; }
.timeline-meta .more-button { margin-left: auto; }
.custom-section[hidden] { display: none; }
.custom-section-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; }
.custom-content-card { min-height: 156px; padding: 20px; border: 1px dashed #dccabd; border-radius: var(--radius); background: rgba(255,253,249,.68); display: grid; grid-template-columns: auto 1fr; gap: 13px; align-items: start; }
.custom-content-icon { width: 38px; height: 38px; border-radius: var(--r-sm); display: grid; place-items: center; background: var(--yellow-soft); color: #ad812f; }
.custom-content-card h3 { margin: 5px 0 3px; font-size: var(--fs-h4); }
.custom-content-card p { grid-column: 1 / -1; margin: 0; color: var(--muted); font-size: var(--fs-meta); }
.custom-content-card .small-link { grid-column: 1 / -1; justify-self: start; margin-left: 0; }
.custom-module-empty { max-width: 680px; min-height: 310px; padding: 45px 34px; border: 1px dashed #dccabd; border-radius: var(--radius); background: rgba(255,253,249,.68); text-align: center; box-shadow: var(--shadow); }
.custom-empty-icon { width: 57px; height: 57px; margin: 0 auto 18px; border-radius: var(--r-lg); display: grid; place-items: center; background: var(--yellow-soft); color: #ad812f; }
.custom-empty-icon svg { width: 25px; height: 25px; }
.custom-module-empty h2 { margin: 6px 0 8px; font-size: var(--fs-h2); }
.custom-module-empty > p:not(.eyebrow) { margin: 0 auto 21px; max-width: 420px; color: var(--muted); font-size: var(--fs-body); }
.custom-module-empty .outline-button { width: auto; padding: 0 16px; margin: 0; }
.module-hero-actions, .designer-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.family-id-chip { min-width: 190px; padding: 12px 15px; border: 1px solid var(--line-strong); border-radius: var(--r-sm); background: rgba(255,255,255,.58); }
.family-id-chip span, .family-id-chip strong { display: block; }
.family-id-chip span { color: var(--muted); font-size: var(--fs-micro); }
.family-id-chip strong { margin-top: 3px; color: var(--coral); font-size: var(--fs-body); word-break: break-all; }
.family-settings-panel { margin-top: 16px; padding: 20px; }
.family-settings-form { display: grid; gap: 12px; margin-top: 14px; }
.section-heading { display: flex; align-items: start; justify-content: space-between; gap: 12px; }
.section-heading h2 { margin: 3px 0 0; font-size: var(--fs-h3); }
.section-heading p { margin: 5px 0 0; color: var(--muted); font-size: var(--fs-meta); }
.section-heading svg { width: 22px; color: var(--coral); }
.members-heading { margin-top: 18px; }
.members-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
/* ── 成员卡（成员页）──
   旧版把「家庭管理员 · 可登录」和「身份：家庭所有者 / 账号状态：正常」说了两遍，
   登录名还孤零零占一行。现在：身份只说一次，正常状态不显示，登录名和邮箱并成一行。 */
.member-card { padding: var(--s-5); }
.member-card.is-self { border: 1px solid var(--coral-soft); }
.member-card-head { display: flex; align-items: center; gap: var(--s-3); }
.member-card-id { min-width: 0; }
.member-card-id h3 { display: flex; align-items: center; gap: var(--s-2); margin: 0; font-size: var(--fs-h4); font-weight: var(--fw-semi); letter-spacing: -.01em; }
.member-card-head p { margin: 3px 0 0; color: var(--muted); font-size: var(--fs-meta); }
.admin-badge { padding: 3px 8px; border-radius: var(--r-pill); background: var(--coral-soft); color: var(--coral-ink); font-size: var(--fs-micro); font-weight: 700; white-space: nowrap; }
/* 徽章跟着名字走，不再 margin-left:auto 推到最右边 ——
   推到右边之后它和名字之间的关系就断了，像是另一个东西的标签。 */
.member-card-id .admin-badge { margin-left: 0; }
.self-badge { padding: 2px 7px; border-radius: var(--r-pill); background: var(--paper-inset); color: var(--ink-4); font-size: var(--fs-micro); font-weight: var(--fw-medium); }
/* 账号状态正常就不显示，异常才挂标记 */
.account-flag { margin-left: auto; padding: 4px 9px; border-radius: var(--r-pill); background: var(--yellow-soft); color: #8a6520; font-size: var(--fs-micro); font-weight: var(--fw-medium); }
/* 登录名 + 邮箱：一行能查到的信息，取代原来那排和卡片头重复的 chips */
.member-card-facts { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); margin-top: var(--s-3); color: var(--muted); font-size: var(--fs-meta); }
.member-card-facts span { display: inline-flex; align-items: center; gap: 5px; min-width: 0; overflow-wrap: anywhere; }
.member-card-facts svg { width: 13px; height: 13px; color: var(--ink-4); }
/* 头像按角色着色。颜色和首页的人物卡**用同一套** —— 以前两处各是一套。 */
.avatar-parent { background: var(--coral-soft); color: var(--coral-deep); }
.avatar-child { background: var(--green-soft); color: #66806a; }
.avatar-other { background: var(--yellow-soft); color: #9b762e; }
.member-reset-button { width: auto; margin-top: 12px; }
.member-permission-list { margin-top: 14px; display: grid; gap: 7px; }
.member-permission-list > div { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 10px; border-radius: var(--r-sm); background: var(--paper-raised); color: var(--ink-2); font-size: var(--fs-meta); }
.member-permission-list small { color: var(--green); font-size: var(--fs-micro); white-space: nowrap; }
.designer-topbar { margin-bottom: 25px; padding: 25px 28px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: linear-gradient(102deg, #f7e8dc, #fbf3e9 68%, #f2eadf); display: flex; align-items: end; justify-content: space-between; gap: 24px; box-shadow: var(--shadow); }
.designer-topbar h1 { margin-bottom: 7px; font-size: var(--fs-page); }
.designer-topbar p:last-child { margin-bottom: 0; color: #82766d; }
.designer-layout { display: block; }
.designer-palette, .designer-canvas { padding: 18px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper); box-shadow: var(--shadow); }
.designer-palette { margin-bottom: 14px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.designer-panel-heading, .designer-canvas-heading { display: flex; align-items: end; justify-content: space-between; gap: 12px; margin-bottom: 13px; }
.designer-panel-heading { margin: 0 6px 0 0; display: block; }
.designer-panel-heading span { color: var(--muted); font-size: var(--fs-micro); }
.designer-palette-item { width: auto; min-height: 40px; padding: 0 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper-raised); display: flex; align-items: center; gap: 9px; color: var(--ink-2); font-size: var(--fs-meta); text-align: left; }
.designer-palette-item + .designer-palette-item { margin-top: 0; }
.designer-palette-item:hover { border-color: var(--line-strong); background: var(--coral-soft); color: var(--coral-ink); }
.designer-palette-item svg:last-child { width: 14px; margin-left: auto; color: #b4a195; }
.designer-tip { margin: 0 0 0 auto; padding: 9px 11px; border-radius: var(--r-sm); background: #faf5ef; display: flex; align-items: start; gap: 8px; color: #9a8d83; font-size: var(--fs-micro); }
.designer-tip svg { width: 15px; flex: 0 0 auto; color: var(--yellow); }
/* 设计器画布改成网格流式：高度由内容决定，不用手工拉。
   原来是绝对定位 + 固定像素高度，内容一长就得回来拉 ——
   而记录、回复、相册只会越用越多，等于每次加内容都要重拉一遍。 */
.designer-canvas { min-height: 480px; padding: 16px; background: #fcfaf6; }
.designer-canvas-heading { grid-column: 1 / -1; }
.designer-preview-grid .designer-live-block { margin-top: 0; }
.designer-live-block { min-height: 150px; padding: 20px; border: 1px solid var(--line); border-top: 3px solid var(--coral); border-radius: var(--radius); background: var(--paper); box-shadow: var(--shadow); }
.designer-preview-grid.tone-green .designer-live-block { border-top-color: var(--green); }
.designer-preview-grid.tone-yellow .designer-live-block { border-top-color: var(--yellow); }
.designer-canvas-heading { padding-bottom: 13px; border-bottom: 1px solid var(--line); }
.designer-canvas-heading h2 { margin: 3px 0 0; font-size: var(--fs-h3); }
.designer-status { padding: 5px 8px; border-radius: var(--r-xs); background: var(--yellow-soft); color: #97732e; font-size: var(--fs-micro); font-weight: 700; }
.designer-edit-block { position: relative; margin: 0; padding: 16px; border: 1px solid #e5d9cf; border-radius: var(--r-sm); background: var(--paper); }
.designer-edit-block:hover { border-color: var(--line-strong); }
.designer-edit-block.dragging { opacity: .55; }
/* 换顺序时的落点提示：拖动过程中不重绘，靠这个告诉用户"会插到这儿" */
.designer-edit-block.is-drop-target { box-shadow: 0 0 0 2px var(--coral); }
.designer-edit-heading { display: flex; align-items: center; gap: 8px; margin-bottom: 13px; }
.designer-live-block > .designer-edit-heading { margin-bottom: 13px; }
.designer-drag-handle { width: 28px; height: 28px; display: grid; place-items: center; color: #b3a69c; cursor: grab; }
.designer-drag-handle svg { width: 17px; }
.designer-drag-handle:active { cursor: grabbing; }
.designer-block-type { display: flex; align-items: center; gap: 6px; color: #8f665b; font-size: var(--fs-micro); font-weight: 700; }
.designer-block-type svg { width: 15px; }
.designer-delete { width: 32px; height: 32px; margin-left: auto; color: var(--ink-4); }
.designer-delete:hover { color: var(--coral); background: var(--coral-soft); }
.designer-field { display: grid; gap: 6px; margin-top: 10px; }
.designer-field > span { color: var(--ink-2); font-size: var(--fs-micro); font-weight: 700; }
.designer-field input, .designer-field textarea { width: 100%; padding: 9px 10px; border: 1px solid var(--line); border-radius: var(--r-sm); outline: 0; background: var(--paper-raised); color: var(--ink); font: inherit; font-size: var(--fs-meta); resize: vertical; }
.designer-field input { min-height: 40px; }
.designer-field input:focus, .designer-field textarea:focus { border-color: var(--coral); box-shadow: 0 0 0 3px rgba(201,111,97,.13); }
.designer-order { display: block; margin-top: 10px; color: #b0a39a; font-size: var(--fs-micro); }
.designer-dropzone { min-height: 300px; border: 1px dashed #d9c9bc; border-radius: var(--r-sm); display: grid; place-content: center; justify-items: center; gap: 7px; color: #9a8b80; text-align: center; }
.designer-dropzone svg { width: 25px; color: var(--coral); }
.designer-dropzone strong { color: var(--ink-2); font-size: var(--fs-body); }
.designer-dropzone span { font-size: var(--fs-micro); }
/* ── 两种设计模式 ──
   flow   流式：网格，块按顺序排，高度跟着内容走
   canvas 自由画布：绝对定位，位置和大小都由你摆（PPT 那种）
   容器和块都按 data-mode 分叉，两套坐标互不影响。 */
.designer-preview-grid[data-mode="flow"] {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--s-4);
  align-items: start;   /* 每块按自己的内容排，不互相拉伸 */
}
.designer-preview-grid[data-mode="canvas"] { display: block; position: relative; }
.designer-preview-grid[data-mode="flow"] > .designer-preview-block,
.designer-preview-grid[data-mode="flow"] > .designer-edit-block { position: relative; }
.designer-preview-grid[data-mode="canvas"] > .designer-preview-block,
.designer-preview-grid[data-mode="canvas"] > .designer-edit-block { position: absolute; }

/* 顶栏里的模式切换 */
.designer-mode { display: inline-flex; padding: 3px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper-inset); }
.designer-mode-button { min-height: 34px; padding: 0 12px; border: 0; border-radius: var(--r-xs); background: none; color: var(--muted); font: inherit; font-size: var(--fs-meta); cursor: pointer; transition: background-color var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out); }
.designer-mode-button:hover { color: var(--ink); }
.designer-mode-button.active { background: var(--paper); color: var(--coral-ink); font-weight: var(--fw-semi); box-shadow: var(--shadow-sm); }
.designer-preview-block { position: relative; border-top: 3px solid var(--coral); }
.designer-preview-grid.tone-green .designer-preview-block { border-top-color: var(--green); }
.designer-preview-grid.tone-yellow .designer-preview-block { border-top-color: var(--yellow); }
.designer-preview-block { min-height: 120px; padding: 20px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper); box-shadow: var(--shadow); }
.record-preview-block { display: grid; gap: 12px; }
.record-summary { margin: 0; color: var(--muted); font-size: var(--fs-body); }
.record-entries { display: grid; gap: 10px; }
.record-entry { position: relative; padding: 12px 12px 12px 22px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--paper-raised); display: grid; gap: 8px; }
.record-entry-dot { position: absolute; left: 8px; top: 16px; width: 8px; height: 8px; border-radius: 50%; background: var(--coral); box-shadow: 0 0 0 3px rgba(201,111,97,.12); }
.record-entry-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; color: var(--muted); font-size: var(--fs-micro); }
.record-entry-meta strong { color: var(--ink); font-size: var(--fs-meta); }
.record-entry p { margin: 0; color: var(--muted); font-size: var(--fs-meta); }
.record-entry-edit { padding-right: 44px; }
.record-field { width: 100%; min-height: 38px; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--r-sm); outline: 0; background: var(--paper); color: var(--ink); font: inherit; font-size: var(--fs-meta); }
.record-field:focus { border-color: var(--coral); box-shadow: 0 0 0 3px rgba(201,111,97,.13); }
.record-content { min-height: 78px; resize: vertical; }
.record-add-button { width: auto; margin-top: 10px; padding: 0 14px; }
.record-delete { position: absolute; right: 10px; top: 10px; width: 30px; height: 30px; color: var(--ink-4); }
.record-delete:hover { color: var(--coral); background: var(--coral-soft); }

/* ── 模块内容条目（module_items）──
   记录不再存在页面设计里，改成一条一个条目。这些是配套的展示样式。 */
.record-empty { margin: 0; padding: 14px 0; color: var(--muted); font-size: var(--fs-meta); }
.record-legacy-hint { margin: 8px 0 0; color: #9a8f86; font-size: var(--fs-micro); line-height: 1.6; }
.record-entry { padding-right: 74px; }
.record-entry-credit { display: block; margin-top: 6px; color: var(--ink-4); font-size: var(--fs-micro); }
/* owner（这条属于谁）和 creator（谁写的）不一样时才出现 —— 珊瑚色太抢，
   用中性描边区分「记给谁」 */
.record-owner { padding: 1px 7px; border: 1px solid var(--line); border-radius: var(--r-pill); background: #fff; font-size: var(--fs-micro); }
.record-item-actions { position: absolute; right: 10px; top: 10px; display: flex; gap: 2px; }
.record-item-actions .icon-button { width: 30px; height: 30px; color: var(--ink-4); }
.record-item-actions .icon-button:hover { color: var(--coral); background: var(--coral-soft); }
.record-item-modal { width: min(100%, 560px); }
.record-item-modal .form-hint { margin: 2px 0 6px; }

/* ── 清单 / 日期 / 图片 / 文件四种块 ── */
.module-checklist { display: grid; gap: 2px; }
.module-checklist label { display: flex; align-items: center; gap: 9px; padding: 8px 0; border-bottom: 1px solid #f4ede6; font-size: var(--fs-body); cursor: pointer; }
.module-checklist label:last-child { border-bottom: 0; }
.module-checklist input { flex: 0 0 auto; width: 17px; height: 17px; accent-color: var(--coral); }
.module-checklist label:has(input:disabled) { cursor: default; }
.module-checklist .is-done { color: var(--muted); text-decoration: line-through; }
.module-dates { display: grid; gap: 2px; }
.module-date-row { display: flex; align-items: baseline; gap: 10px; padding: 9px 0; border-bottom: 1px solid #f4ede6; font-size: var(--fs-body); }
.module-date-row:last-child { border-bottom: 0; }
.module-date-row strong { flex: 0 0 auto; font-variant-numeric: tabular-nums; }
.module-date-row span { flex: 1; min-width: 0; color: var(--ink-2); }
.module-date-yearly { flex: 0 0 auto; padding: 1px 7px; border: 1px solid var(--line); border-radius: var(--r-pill); color: var(--muted); font-size: var(--fs-micro); font-style: normal; }
/* 相册用两列；窄屏一列（在移动端块里覆盖） */
.module-media { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.module-media-item { position: relative; margin: 0; border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; background: var(--paper-raised); }
.module-media-item img { display: block; width: 100%; height: 170px; object-fit: cover; background: #f2e9e1; }
.module-media-item figcaption { display: grid; gap: 2px; padding: 10px 12px; }
.module-media-item figcaption strong { font-size: var(--fs-body); overflow-wrap: anywhere; }
.module-media-item figcaption span { color: var(--muted); font-size: var(--fs-meta); }
.module-media-item figcaption small { color: var(--ink-4); font-size: var(--fs-micro); }
.module-media-file { position: relative; display: flex; align-items: center; gap: 11px; padding: 11px 12px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--paper-raised); }
.module-media-file > svg { flex: 0 0 auto; color: var(--coral); }
.module-media-file > div { flex: 1; min-width: 0; display: grid; gap: 2px; }
.module-media-file strong { font-size: var(--fs-body); overflow-wrap: anywhere; }
.module-media-file small { color: var(--muted); font-size: var(--fs-meta); }
.module-media-file .small-link { flex: 0 0 auto; }

/* ── 投票 ──
   选项做成整条可点，背后一条按百分比填充的底 —— 一眼看出倾向，
   比单纯数字列表直观。 */
.poll-option { position: relative; display: flex; align-items: center; gap: 10px; width: 100%; margin-bottom: 7px; padding: 11px 13px; border: 1px solid #e8dcd1; border-radius: var(--r-sm); background: #fff; text-align: left; font: inherit; font-size: var(--fs-body); cursor: pointer; overflow: hidden; transition: border-color .15s; }
.poll-option:hover { border-color: var(--line-strong); }
.poll-option.is-mine { border-color: var(--coral); }
.poll-option-fill { position: absolute; left: 0; top: 0; bottom: 0; background: var(--coral-soft); transition: width .25s; }
.poll-option.is-mine .poll-option-fill { background: #f6ddd6; }
.poll-option-text, .poll-option-count, .poll-option-names { position: relative; }
.poll-option-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.poll-mine-mark { margin-left: 7px; padding: 1px 7px; border-radius: var(--r-pill); background: var(--coral); color: #fff; font-size: var(--fs-micro); font-style: normal; }
.poll-option-count { flex: 0 0 auto; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.poll-option-count em { margin-left: 5px; color: var(--muted); font-style: normal; }
.poll-option-names { position: absolute; left: 13px; right: 13px; bottom: 2px; color: var(--ink-4); font-size: var(--fs-micro); }
.poll-footer { display: flex; align-items: center; justify-content: space-between; margin-top: 4px; color: var(--muted); font-size: var(--fs-meta); }

/* ── 主题讨论 ──
   话题和回复都是条目，回复按时间正序（聊天顺序），话题按时间倒序（新的在上）。 */
.topic-threads { display: grid; gap: 14px; }
.topic-thread { padding: 13px 14px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--paper-raised); }
.topic-head { display: flex; align-items: start; justify-content: space-between; gap: 10px; }
.topic-head strong { display: block; font-size: var(--fs-lead); overflow-wrap: anywhere; }
.topic-head small { display: block; margin-top: 2px; color: var(--muted); font-size: var(--fs-micro); }
.topic-head-actions { display: flex; gap: 2px; flex: 0 0 auto; }
.topic-head-actions .icon-button { width: 28px; height: 28px; color: var(--ink-4); }
.topic-head-actions .icon-button:hover { color: var(--coral); background: var(--coral-soft); }
.topic-body { margin: 8px 0 0; color: var(--ink-2); font-size: var(--fs-body); line-height: 1.65; }
.topic-no-reply { margin: 10px 0 6px; color: var(--muted); font-size: var(--fs-meta); }
.topic-replies { display: grid; gap: 8px; margin: 10px 0 4px; }
.topic-reply { padding: 9px 11px; border-left: 2px solid #edddd2; background: #fff; border-radius: 0 var(--r-sm) var(--r-sm) 0; }
.topic-reply-head { display: flex; align-items: center; gap: 8px; margin-bottom: 3px; }
.topic-reply-head strong { font-size: var(--fs-meta); }
.topic-reply-head time { flex: 1; color: var(--ink-4); font-size: var(--fs-micro); }
.topic-reply-head .icon-button { width: 26px; height: 26px; color: #c0b5ac; }
.topic-reply-head .icon-button:hover { color: var(--coral); background: var(--coral-soft); }
.topic-reply p { margin: 0; color: var(--ink-2); font-size: var(--fs-meta); line-height: 1.6; }
.designer-settings { display: flex; align-items: center; gap: 8px; }
.designer-settings label { display: flex; align-items: center; gap: 5px; color: #8f8177; font-size: var(--fs-micro); }
.designer-settings select { min-height: 30px; padding: 0 7px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper-raised); color: var(--ink); font: inherit; }
.designer-preview-block h3 { margin: 6px 0 9px; font-size: var(--fs-h3); }
.designer-preview-block > p:last-child { margin: 0; color: var(--muted); font-size: var(--fs-body); white-space: pre-wrap; }
.designer-live-content { min-height: 42px; padding: 5px; border-radius: var(--r-xs); outline: 0; }
.designer-live-content:focus, .designer-live-block h3:focus { background: var(--paper-raised); box-shadow: 0 0 0 3px rgba(201,111,97,.13); }
.designer-live-block h3 { margin: 6px 0 9px; font-size: var(--fs-h3); }
.designer-resize-handle { position: absolute; right: 4px; bottom: 4px; width: 14px; height: 14px; border-right: 2px solid #c5a99a; border-bottom: 2px solid #c5a99a; cursor: nwse-resize; }
.designer-live-block .designer-checklist, .designer-live-block .designer-date-value, .designer-live-block .designer-media-placeholder, .designer-live-block .designer-file-placeholder { margin-top: 12px; }
.designer-checklist { display: grid; gap: 8px; color: var(--ink-2); font-size: var(--fs-meta); }
.designer-checklist label { display: flex; align-items: start; gap: 7px; }
.designer-checklist input { margin-top: 4px; accent-color: var(--coral); }
.designer-date-value { display: block; margin-top: 15px; color: var(--coral); font-size: var(--fs-h1); font-family: "DM Sans", sans-serif; }
.designer-media-placeholder, .designer-file-placeholder { min-height: 72px; padding: 14px; border: 1px dashed #d9c9bc; border-radius: var(--r-sm); display: flex; align-items: center; gap: 8px; color: #9a8b80; font-size: var(--fs-micro); }
.designer-media-placeholder svg, .designer-file-placeholder svg { width: 20px; color: var(--yellow); }
.modal-backdrop { position: fixed; inset: 0; z-index: 50; padding: 24px; display: grid; place-items: center; background: rgba(61, 48, 38, .28); backdrop-filter: blur(3px); }
.modal-backdrop[hidden] { display: none; }
label[hidden], div[hidden] { display: none !important; }
.customize-modal { width: min(100%, 520px); max-height: min(720px, calc(100vh - 48px)); overflow: auto; padding: 26px; border: 1px solid #eadbd0; border-radius: var(--r-lg); background: var(--paper); box-shadow: 0 24px 70px rgba(64, 44, 30, .2); }
.modal-header { display: flex; align-items: start; justify-content: space-between; gap: 20px; }
.modal-header h2 { margin-top: 5px; font-size: var(--fs-h2); }
.modal-intro { margin: 16px 0 22px; color: var(--muted); font-size: var(--fs-body); line-height: 1.7; }
.form-field { display: grid; gap: 7px; margin-bottom: 16px; }
.form-field > span { color: #6d625b; font-size: var(--fs-meta); font-weight: 700; }
.form-field input, .form-field select, .form-field textarea { width: 100%; min-height: 44px; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--r-sm); outline: 0; background: var(--paper-raised); color: var(--ink); font: inherit; resize: vertical; }
.form-field input:focus, .form-field select:focus, .form-field textarea:focus { border-color: var(--coral); box-shadow: 0 0 0 3px rgba(201,111,97,.13); }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
/* 三字段一行（任务弹窗的 截止日期 / 优先级 / 重复） */
.form-row-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.access-control-field { margin-top: 2px; }
.member-options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 7px; margin: -6px 0 15px; padding: 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper-raised); }
.member-options[hidden] { display: none; }
.member-option { display: flex; align-items: center; gap: 7px; color: var(--ink-2); font-size: var(--fs-meta); }
.member-option input { accent-color: var(--coral); }
.modal-actions { display: flex; align-items: center; justify-content: end; gap: 8px; margin-top: 22px; }
.existing-tabs { margin-top: 27px; padding-top: 20px; border-top: 1px solid var(--line); }
.existing-tabs-heading { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; font-size: var(--fs-body); }
.existing-tabs-heading span { min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--r-sm); display: grid; place-items: center; background: var(--cream); color: #947c6d; font-size: var(--fs-micro); }
.custom-tab-list { display: grid; gap: 6px; }
.custom-tab-row { min-height: 45px; padding: 6px 4px; display: flex; align-items: center; gap: 9px; border-bottom: 1px solid var(--line-soft); }
.custom-row-icon { width: 29px; height: 29px; border-radius: var(--r-sm); display: grid; place-items: center; background: var(--cream); color: #a37b47; }
.custom-row-icon svg { width: 15px; }
.custom-tab-row strong, .custom-tab-row small { display: block; }
.custom-tab-row strong { font-size: var(--fs-meta); }
.custom-tab-row small { color: var(--muted); font-size: var(--fs-micro); }
.custom-remove { margin-left: auto; color: var(--ink-4); }
.custom-remove:hover { color: var(--coral); background: var(--coral-soft); }
.toast { position: fixed; right: 24px; bottom: 24px; padding: 12px 16px; border: 1px solid #d9c8ba; border-radius: var(--r-sm); background: #fffdf9; box-shadow: 0 10px 30px rgba(70,45,30,.15); color: #6c5e54; font-size: var(--fs-body); opacity: 0; transform: translateY(10px); pointer-events: none; transition: opacity .25s, transform .25s; }
.toast.show { opacity: 1; transform: translateY(0); }

:focus-visible { outline: 3px solid rgba(201,111,97,.38); outline-offset: 3px; }
@media (max-width: 1050px) {
  .sidebar { width: 220px; flex-basis: 220px; }
  .overview-grid { grid-template-columns: 1fr 1fr; }
  .family-panel { grid-column: span 2; min-height: 160px; }
  .announcement { min-height: auto; }
  .home-summary-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .family-command-center { grid-template-columns: 1fr 1fr; }
  .overview-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .family-command-actions { grid-column: 1 / -1; grid-template-columns: minmax(0, 220px); justify-content: end; }
  .family-command-actions .text-button { justify-content: center; border-left: 0; border-top: 1px solid #eaded4; }
}
@media (max-width: 760px) {
  .app-shell { display: block; }
  .sidebar { width: 100%; padding: 14px 16px 10px; border-right: 0; border-bottom: 1px solid var(--line); }
  .brand { padding: 0 2px 13px; }
  .family-switcher, .sidebar-bottom { display: none; }
  .nav-list { padding: 5px 0 0; display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none; }
  .nav-list::-webkit-scrollbar { display: none; }
  .nav-item { min-width: max-content; min-height: 40px; padding: 0 11px; gap: 7px; font-size: var(--fs-meta); }
  .nav-item svg { width: 16px; }
  .nav-badge { display: none; }
  .customize-nav-button { width: auto; min-width: 150px; margin-top: 5px; }
  .custom-nav-group { min-width: max-content; margin: 5px 0 0; padding: 0; border-top: 0; display: flex; align-items: center; gap: 3px; }
  .custom-nav-group-label { min-height: 38px; padding: 0 8px; border-radius: var(--r-sm); background: #f8f0e8; }
  .custom-nav-group .custom-nav-item { min-height: 38px; padding: 0 10px; }
  .topbar { height: 61px; padding: 0 16px; }
  .user-chip-name, .user-chip > svg { display: none; }
  .user-chip { border: 0; padding: 3px; }
  .page-content { padding: 28px 16px 60px; }
  .welcome-row { align-items: start; flex-direction: column; gap: 16px; margin-bottom: 23px; }
  .primary-button { width: 100%; }
  h1 { font-size: var(--fs-h1); }
  .phase-banner { align-items: start; flex-wrap: wrap; padding: 17px; gap: 12px; }
  .phase-copy { min-width: 0; flex-basis: calc(100% - 55px); }
  .phase-progress { width: 100%; padding-left: 0; }
  .text-button { width: 100%; padding: 8px 0 0; border-left: 0; border-top: 1px solid rgba(150,113,90,.2); justify-content: space-between; }
  .section-block { margin-top: 32px; }
  .section-heading { align-items: start; flex-direction: column; }
  .section-heading .quiet-button { padding-left: 0; }
  .overview-grid, .children-grid { grid-template-columns: 1fr; }
  .family-panel { grid-column: auto; }
  .home-live-grid { grid-template-columns: 1fr; }
  .family-announcements-panel { margin: -5px 0 24px; padding: 16px 15px 10px; }
  .family-announcements-heading { gap: 9px; }
  .family-announcements-heading-icon { width: 34px; height: 34px; }
  .family-announcements-heading h2 { font-size: var(--fs-h3); }
  .family-announcements-heading .outline-button { min-height: 36px; padding: 0 8px; font-size: var(--fs-micro); }
  .family-timeline-heading { gap: 9px; }
  .family-timeline-heading h2 { font-size: var(--fs-h3); }
  .family-timeline-heading .outline-button { min-height: 36px; padding: 0 8px; font-size: var(--fs-micro); }
  .family-timeline-item { grid-template-columns: 72px 14px minmax(0, 1fr); gap: 8px; }
  .family-announcement-item { gap: 8px; }
  .family-announcement-archive { padding: 4px; font-size: var(--fs-micro); }
  .family-assets-panel { padding: 16px 15px 10px; }
  .family-assets-heading { gap: 9px; }
  .family-assets-heading-icon { width: 34px; height: 34px; }
  .family-assets-heading h2 { font-size: var(--fs-h3); }
  .family-assets-heading .outline-button { min-height: 36px; padding: 0 8px; font-size: var(--fs-micro); }
  .family-assets-summary { align-items: start; flex-direction: column; gap: 4px; }
  .overview-empty-cluster { align-items: start; flex-wrap: wrap; padding: 16px 15px; }
  .overview-empty-cluster .outline-button { width: 100%; margin-left: 0; }
  .module-stat-grid { grid-template-columns: 1fr; }
  .family-command-center { grid-template-columns: 1fr; gap: 16px; padding: 18px; }
  .family-command-status { padding: 15px 0 0; border-left: 0; border-top: 1px solid #eaded4; }
  .family-command-actions { grid-column: auto; min-width: 0; }
  .family-command-actions .text-button { justify-content: space-between; }
  .welcome-expand-button { width: 100%; justify-content: flex-start; padding-left: 0; }
  .overview-grid { grid-template-columns: 1fr; }
  .timeline { padding-left: 24px; }
  .timeline::before { left: 3px; }
  .timeline-item { display: block; min-height: 0; padding-bottom: 24px; }
  .timeline-dot { left: -26px; top: 11px; }
  .timeline-date { padding: 0 0 8px; }
  .timeline-card { padding: 16px; }
  .form-row { grid-template-columns: 1fr; gap: 0; }
  .inbox-header h1 { font-size: var(--fs-h2); }
  .receipt-row { flex-wrap: wrap; gap: 6px 8px; }
  .receipt-note { display: none; }
  .receipt-row time { margin-left: auto; }
  .receipt-read { opacity: 1; }
  .customize-modal { padding: 20px; }
  .module-hero { align-items: start; flex-direction: column; padding: 20px; }
  .module-hero .primary-button { width: 100%; }
  .module-grid.three, .module-lower, .task-board, .task-lower-grid, .file-summary, .assets-columns { grid-template-columns: 1fr; }
  .asset-row-actions { opacity: 1; }
  .approval-type-grid, .approval-grid, .approval-detail-layout, .approval-summary-grid { grid-template-columns: 1fr; }
  .approval-chain-layout { grid-template-columns: 1fr; }
  .members-grid { grid-template-columns: 1fr; }
  .designer-topbar { align-items: start; flex-direction: column; padding: 20px; }
  .designer-actions { width: 100%; }
  .designer-actions > button { flex: 1; }
  .designer-settings { flex-wrap: wrap; }
  .designer-canvas-heading { align-items: start; flex-direction: column; }
  .designer-palette { align-items: stretch; }
  .designer-panel-heading { width: 100%; }
  .designer-palette-item { flex: 1 1 calc(50% - 7px); }
  .designer-tip { width: 100%; margin-left: 0; }
  .child-profile-large { align-items: start; flex-wrap: wrap; }
  .profile-progress { margin-left: 0; }
  .child-profile-large .outline-button { width: 100%; margin-left: 0; }
  .file-list em, .health-list em { display: none; }
  .file-toolbar { width: 100%; }
  .file-toolbar input { flex: 1; width: auto; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; transition-duration: .01ms !important; animation-duration: .01ms !important; }
}
@media (max-width: 760px) {
  .approval-page-stats { grid-template-columns: 1fr; }
  .approval-type-modal-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .approval-type-card { min-height: 120px; padding: 14px; }
  .approval-card-head { gap: 10px; }
  .approval-status { padding: 0 8px; font-size: var(--fs-micro); }
  .approval-card-foot { align-items: stretch; flex-direction: column; gap: 8px; }
  .approval-card-controls { justify-content: flex-start; }
  .approval-card-controls .approval-actions { margin-top: 0; }
}
.approval-type-modal { width: min(100%, 980px); }
.approval-type-modal-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 6px; }
.approval-print-page { padding: 18px; }
.approval-print-toolbar { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 14px; }
.approval-print-sheet { max-width: 820px; margin: 0 auto; padding: 28px; border: 1px solid var(--line); border-radius: var(--radius); background: #fffdf9; box-shadow: var(--shadow); }
.approval-print-header { display: flex; justify-content: space-between; gap: 20px; padding-bottom: 16px; border-bottom: 1px solid var(--line-strong); margin-bottom: 18px; }
.approval-print-header h1 { margin: 6px 0 8px; font-size: var(--fs-h1); }
.approval-print-meta { display: grid; gap: 6px; min-width: 240px; color: var(--ink-2); font-size: var(--fs-meta); }
.approval-print-block { margin-top: 18px; }
.approval-print-block h2 { margin-bottom: 10px; font-size: var(--fs-h3); }
.approval-participation-note { padding: 14px 16px; border: 1px solid #eadccd; border-radius: var(--r-sm); background: var(--paper-raised); }
.approval-participation-note p { margin: 6px 0 0; color: var(--ink-2); font-size: var(--fs-body); line-height: 1.65; overflow-wrap: anywhere; }
.approval-participation-note p strong { color: var(--ink); }
.approval-excluded-members { padding-bottom: 8px; border-bottom: 1px solid #eee4da; }
.approval-print-table { width: 100%; border-collapse: collapse; font-size: var(--fs-meta); }
.approval-print-table th, .approval-print-table td { border: 1px solid #e6dbcf; padding: 8px 9px; vertical-align: top; text-align: left; }
.approval-note-grid { display: grid; gap: 10px; }
.approval-note-card { padding: 12px 13px; border: 1px solid #e6dbcf; border-radius: var(--r-sm); background: var(--paper-raised); }
.approval-note-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.approval-note-head strong { font-size: var(--fs-body); }
.approval-note-head span { color: var(--coral); font-size: var(--fs-meta); font-weight: 700; }
.approval-view-button { margin-top: 0; width: fit-content; white-space: nowrap; }
.approval-review-actions { display: flex; gap: 8px; margin-top: 18px; }
.approval-review-actions .outline-button, .approval-review-actions .quiet-button { width: auto; }

@media print {
  body { background: #fff; }
  .sidebar, .topbar, .toast, .approval-print-toolbar, .no-print { display: none !important; }
  .app-shell, .main-content, .page-content { display: block; padding: 0; margin: 0; max-width: none; }
  .module-slot { padding: 0; }
  .approval-print-page { padding: 0; }
  .approval-print-sheet { max-width: none; margin: 0; padding: 16mm; border: 0; border-radius: 0; box-shadow: none; background: #fff; }
  .approval-print-header, .approval-print-block, .approval-note-card, .approval-print-table { break-inside: avoid; }
  .module-panel, .approval-card { box-shadow: none !important; }
  @page { size: A4 portrait; margin: 14mm; }
}

/* ══════════════════════════════════════════════════════════════════
   移动端适配
   放在文件最后，保证层叠上覆盖前面分散的 760px 规则。
   针对五个可以量出来的问题（都是用无头 Chrome 在 320/375/414px
   真实渲染量到的，不是凭感觉）：

     1. 320px 小屏横向溢出 —— 登录页最严重（auth-shell 是两列网格，
        整个媒体查询里没有一条把它塌成单列，390px 勉强挤下，320 就溢出）
     2. 输入框字号 < 16px —— iOS Safari 聚焦时会放大整页（files 页只有 12px）
     3. 可点目标 < 44px —— WCAG 下限；实测 icon-button 只有 28×28、
        small-link 19px 高、任务完成按钮 32px 高
     4. 正文 < 12px —— eyebrow 11px、small 10px、时间 11px
     5. 顶部吃掉 231px（侧栏 170 + 顶栏 61），是 800px 屏幕的 29%
   ══════════════════════════════════════════════════════════════════ */

@media (max-width: 760px) {
  /* ── 问题 2：输入框一律 16px。这是 iOS 不自动缩放的下限，
       比它小的话用户一点输入框整页就被放大，非常难受。 ── */
  /* iOS Safari 对字号 < 16px 的输入框会在聚焦时自动放大整页。
     这是平台行为要求而不是样式偏好，逐个追特异性的成本不值得，所以用 !important
     兜底。只作用于 760px 以下。 */
  input, select, textarea { font-size: var(--fs-h4) !important; }

  /* ── 问题 3：可点目标抬到 44px ── */
  button, a { -webkit-tap-highlight-color: transparent; }
  .icon-button { min-width: 44px; min-height: 44px; }
  .small-link { display: inline-flex; align-items: center; min-height: 44px; }
  .task-complete-button, .task-restore-button { min-height: 44px; }
  .timeline-filter-chip { min-height: 44px; }
  .family-announcement-archive { min-height: 44px; padding: 0 10px; font-size: var(--fs-meta); }
  .asset-row-actions .icon-button { min-width: 44px; min-height: 44px; }
  .receipt-read { min-height: 44px; padding: 0 10px; font-size: var(--fs-meta); }
  .outline-button, .quiet-button { min-height: 44px; }

  /* 可点目标下限 44px（WCAG）。这 11 个选择器在基础样式里
     写的是 30-42px，手机上是真实的手指误触来源。同选择器写在末尾即可覆盖。 */
  .customize-nav-button,
  .welcome-expand-button,
  .family-command-actions .text-button,
  .family-announcements-heading .outline-button,
  .family-assets-heading .outline-button,
  .family-timeline-heading .outline-button,
  .timeline-filter-chip,
  .approval-card.compact .approval-card-controls .outline-button,
  .approval-card.compact .approval-card-controls .quiet-button,
  .message-card-foot .outline-button,
  .board-task .task-complete-button { min-height: 44px; }
  .auth-tab { min-height: 44px; }

  /* ── 问题 4：正文下限 12px ── */
  /* 手机上正文下限 12px。这 97 个选择器原来写的是 10-11px
     （桌面端能接受，手机上看不清）。同一选择器写在文件末尾自然覆盖。 */
  .family-picker-item small,
  .brand span,
  .switcher-copy small,
  .profile-button small,
  .eyebrow,
  .avatar-small,
  .nav-badge,
  .nav-private-mark,
  .custom-nav-group-label,
  .privacy-note,
  .notification span,
  .family-command-date,
  .family-member-avatar,
  .family-member-strip small,
  .family-command-status > div:first-child span,
  .family-command-metrics span,
  .family-announcement-copy small,
  .family-announcement-archive,
  .family-announcement-archived summary,
  .family-assets-meta,
  .assets-other-currencies,
  .assets-updated,
  .assets-visibility > span,
  .asset-row-name small,
  .family-space-link .small-link,
  .family-person-copy p,
  .family-person-copy small,
  .home-summary-card span,
  .home-summary-card small,
  .overview-live-item small,
  .overview-live-status,
  .family-timeline-date span,
  .family-timeline-copy small,
  .timeline-month-heading span,
  .progress-label,
  .phase-progress small,
  .approval-type-card small,
  .approval-history-chip strong,
  .approval-user-chip small,
  .approval-chain-step small,
  .approval-card-meta,
  .approval-created-at,
  .approval-flow-node small,
  .approval-flow-node em,
  .inbox-group-head em,
  .message-card-head time,
  .message-card-foot small,
  .message-card-foot .outline-button,
  .receipt-result,
  .receipt-row time,
  .receipt-read,
  .profile-progress,
  .module-stat-grid span,
  .module-stat-grid small,
  .board-task small,
  .board-task .task-complete-button,
  .task-priority,
  .completed-task .task-restore-button,
  .member-task small,
  .file-summary small,
  .file-list small,
  .health-list small,
  .file-list em,
  .health-list em,
  .form-hint,
  .date-tag,
  .status-pill,
  .selected-label,
  .timeline-type,
  .panel-footer,
  .announcement-byline,
  .timeline-meta,
  .overview-task-panel-item small,
  .task-list li small,
  .child-stats,
  .add-child-card small,
  .timeline-date,
  .family-id-chip span,
  .admin-badge,
  .member-permission-list small,
  .designer-panel-heading span,
  .designer-tip,
  .designer-status,
  .designer-block-type,
  .designer-field > span,
  .designer-order,
  .designer-dropzone span,
  .record-entry-meta,
  .designer-settings label,
  .designer-media-placeholder,
  .designer-file-placeholder,
  .existing-tabs-heading span,
  .custom-tab-row small,
  .family-announcements-heading .outline-button,
  .family-timeline-heading .outline-button,
  .family-assets-heading .outline-button,
  .approval-status { font-size: var(--fs-meta); }

  /* ── 问题 5：顶部收窄 ──
     原来是「侧栏整条 + 顶栏面包屑」，两排加起来 231px。
     手机上侧栏的横滑导航已经说明了当前在哪一页，面包屑是重复信息，隐藏；
     同时把顶栏压到 48px、侧栏内边距收紧。 ── */
  .topbar { height: 48px; padding: 0 12px; }
  .breadcrumb { display: none; }
  .topbar-actions { margin-left: auto; }
  .sidebar { padding: 10px 14px 6px; }
  .brand { padding: 0 2px 8px; }
  .brand-mark { width: 30px; height: 30px; border-radius: var(--r-sm); }
  .nav-item { min-height: 44px; }
  .customize-nav-button { min-height: 44px; margin-top: 2px; }

  /* 页面内边距略收，把宽度让给内容 */
  .page-content { padding: 20px 14px 52px; }
}

/* ── 登录页：手机上单列 ──
   这是一页单独的布局（不走 app-shell），所以单独处理。 ── */
@media (max-width: 760px) {
  .auth-page { padding: 16px 12px; place-items: start center; }
  .auth-shell { grid-template-columns: 1fr; gap: 12px; width: 100%; }
  /* 左栏在手机上只留「品牌行 + 那句短的」；大标题和说明与品牌重复，
     隐藏后登录表单能直接出现在首屏。 */
  .auth-intro { padding: 16px; }
  .auth-intro h1 { display: none; }
  .auth-intro > p:last-child { display: none; }
  .auth-intro .eyebrow { margin: 8px 0 0; font-size: var(--fs-body); }
  .auth-intro .brand { padding-bottom: 0; }
  .auth-panel { padding: 18px 16px; }
  .auth-tabs { margin-bottom: 14px; }
  .auth-view h2 { font-size: var(--fs-h2); }
}

/* ── 小屏（320–420）再压一档 ──
   320px 是常见最窄宽度（iPhone SE 一代 / 折叠机外屏），
   登录页最初就是在这里横向溢出的。 ── */
@media (max-width: 420px) {
  .auth-page { padding: 12px 10px; }
  .auth-panel { padding: 16px 14px; }
  .auth-shell, .auth-intro, .auth-panel { border-radius: var(--r-md); }
  .auth-tabs { gap: 5px; }
  .auth-tab { padding: 0 6px; font-size: var(--fs-body); }
  .auth-intro { padding: 14px; }

  h1 { font-size: var(--fs-h2); }
  .module-hero { padding: 16px; }
  .module-hero h1 { font-size: var(--fs-h2); }
  .module-panel { padding: 16px 14px; }
  .family-assets-amount { font-size: var(--fs-display); }
  .page-content { padding: 16px 12px 48px; }
  .task-board, .assets-columns, .module-grid.three, .task-lower-grid,
  .home-live-grid, .overview-grid { gap: 12px; }
  .form-row-3 { grid-template-columns: 1fr; }
  .receipt-result { min-width: 36px; }
  .timeline-filter-chip { padding: 0 10px; }
}

/* ── 文件工具栏：窄屏必须换行 ──
   输入框 + 下拉 + 按钮挤在一行时，实测在 320px 下会顶出视口 57px
   （select 右边界到 362，而视口只有 305）。让它换行、输入框独占一行。 ── */
@media (max-width: 760px) {
  .file-toolbar { flex-wrap: wrap; width: 100%; }
  .file-toolbar input { flex: 1 1 100%; width: 100%; }
  .file-toolbar select, .file-toolbar button, .file-toolbar .quiet-button,
  .file-toolbar .outline-button { flex: 1 1 auto; }
  .file-toolbar input, .file-toolbar select,
  .file-toolbar .quiet-button, .file-toolbar .outline-button { min-height: 44px; }

  /* 兜底：<small> 一律 12px。上面按选择器列了 97 条，
     但页面上还有不带 class 的 <small>，这条负责收尾。 */
  small { font-size: var(--fs-meta); }
  /* 生成那份清单时，这条选择器把前面的注释一起粘了进来，
     结果规则没生效（任务页和首页的「重要」标记实测仍是 10px）。
     这里显式补一条，不依赖生成结果。 */
  .task-priority-mark { font-size: var(--fs-meta); }
  /* 后加的选择器不在那份清单里，漏进来就是 11px。 */
  .task-readonly, .task-member-status small { font-size: var(--fs-meta); }
  /* 相册窄屏改单列，两列在手机上每张只有 150px 宽，看不清 */
  .module-media { grid-template-columns: 1fr; }
  .module-date-yearly, .module-media-item figcaption small { font-size: var(--fs-meta); }
  /* 投票和讨论里后加的小字，不在之前生成的那份清单里 */
  .poll-option-names, .poll-mine-mark, .topic-head small,
  .topic-reply-head time, .topic-body, .topic-reply p { font-size: var(--fs-meta); }
  .poll-option { min-height: 44px; }
  .topic-head-actions .icon-button, .topic-reply-head .icon-button { min-width: 44px; min-height: 44px; }

  /* 头像 / 文字链接的可点区域也要够大。
     原来是 .family-person-link（那个悬浮图标），现在它是 family-person-open
     —— 整个头部就是一个按钮，所以直接把高度给这个按钮。 */
  .family-person-open { min-height: 44px; }
  .auth-link-row { align-items: center; margin-bottom: 10px; }
  .auth-link-row button { min-height: 44px; padding: 0 4px; }
}

/* ── 文件行：320px 上操作按钮换行 ──
   一行里要塞下「图标 + 文件名 + 4 个 44px 的按钮」，实测在 320px 顶出 13px。
   按钮抬到 44px 是可点性要求，不能缩回去，所以让它们换到下一行，
   把宽度让给文件名（文件管理页里文件名截断比按钮小更难受）。 ── */
@media (max-width: 420px) {
  .file-list > div, .health-list > div { flex-wrap: wrap; }
  .file-list > div > span:nth-child(2), .health-list > div > span:nth-child(2) { min-width: 0; flex: 1 1 auto; }
  .file-row-actions { width: 100%; margin-left: 0; justify-content: flex-end; }
  .file-list strong, .health-list strong { overflow-wrap: anywhere; }
}

/* ── 平板区间的内容留白 ── */
@media (min-width: 761px) and (max-width: 1050px) {
  .page-content { padding: 26px 20px 60px; }
}


/* ══════════════════════════════════════════════════════════════════
   全局精细度
   单看每一条都很小，但"感觉高级"就是靠这些堆出来的 ——
   它们不会让界面变好看，只会让它不再有"没做完"的地方。
   ══════════════════════════════════════════════════════════════════ */

/* ── 字体渲染 ──
   macOS 上不写这一条，中文会渲染得偏粗、发糊。 */
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ── 等宽数字 ──
   任何会变的数字都要 tabular-nums，否则数字一变整行就左右抖。 */
.family-assets-amount, .asset-column-total strong, .module-stat-grid strong,
.task-summary-line strong, .count-badge, .poll-option-count, .nav-badge,
.receipt-row time, time, .task-priority, .approval-created-at,
.module-date-row strong, .family-timeline-date, .asset-row-name small,
.overview-live-item strong, .home-summary-card strong, .poll-option-count em {
  font-variant-numeric: tabular-nums;
}

/* ── 焦点环 ──
   键盘用户必须看得见焦点。之前全站只有两三处有 :focus，
   鼠标用户不受影响，键盘用户等于在盲操作。 */
:focus-visible {
  outline: 2px solid var(--coral);
  outline-offset: 2px;
}
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: none;
  border-color: var(--coral);
  box-shadow: var(--ring);
}

/* ── 换行 ──
   balance 让标题不会只剩一个字在第二行；pretty 让正文不出现孤字。 */
h1, h2, h3, .family-assets-amount { text-wrap: balance; }
p, li, figcaption, dd, small, .topic-body { text-wrap: pretty; }

/* ── 大字号收字距 ──
   字号越大，默认字距越显得松。收紧一点才像"排过版的"。
   正文相反，行高要放宽。 */
h1, .family-assets-amount, .auth-intro h1, .approval-print-header h1 { letter-spacing: -.015em; }
h2, h3 { letter-spacing: -.01em; }
p { line-height: 1.65; }

/* ── 按压反馈 ──
   让界面"听见"点击。只动 transform，不动布局属性。 */
button:not(:disabled):active,
.nav-item:active, .task-row:active, .poll-option:active,
.timeline-filter-chip:active, .task-filter-chip:active,
.module-media-item:active, .topic-thread:active {
  transform: scale(.985);
}

/* ── 统一过渡 ──
   命名具体属性，绝不写「过渡所有」那种写法 —— 那会把 width/height/margin
   也带上，触发重排掉帧。曲线用自定义缓出，内置的 ease 太弱。 */
button, a, .nav-item, .task-row, .poll-option, .timeline-filter-chip,
.task-filter-chip, .module-media-item, .topic-thread, .record-entry,
.module-checklist label, .menu-item, .user-chip, .family-switcher {
  transition:
    background-color var(--t-base) var(--ease-out),
    border-color var(--t-base) var(--ease-out),
    color var(--t-fast) var(--ease-out),
    box-shadow var(--t-base) var(--ease-out),
    transform var(--t-fast) var(--ease-out);
}

/* ── 图片描边 ──
   用中性 rgba，不要带色的近黑 —— 那会在边缘显出一圈"脏"。 */
.module-media-item img,
.designer-preview-block img {
  outline: 1px solid rgba(0, 0, 0, .08);
  outline-offset: -1px;
}

/* ══════════════════════════════════════════════════════════════════
   审批详情
   改前它看起来像「打印预览」：整页包在 A4 纸张样式里（限宽 820 + 阴影 + 边框），
   四个 h2 平级（申请说明 / 审批链路 / 未参与本次审批 / 每一步说明），
   而「审批单」最重要的一件事 —— 过没过 —— 只是 meta 里一行 12px 普通文字。
   而且「审批链路」表格和「每一步说明」是同一件事说了两遍。

   重排：
     结论条        全页唯一的焦点，大字号 + 语义色
     说明 / 链路    正文层级
     未参与 / 原因  降到脚注，不再占 h2
   ══════════════════════════════════════════════════════════════════ */
.approval-doc { max-width: 760px; margin: 0 auto; padding: 0 0 20px; border: 0; background: none; box-shadow: none; }

/* 工具栏：返回在左（次要），动作在右 —— 原来正好反着 */
.approval-doc-toolbar { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); margin-bottom: var(--s-5); }
.approval-doc-toolbar .outline-button { width: auto; margin-top: 0; }
.approval-doc-toolbar-actions { display: flex; align-items: center; gap: var(--s-2); }

/* 抬头：只有类型 / 标题 / 一行出处，不再重复申请人和时间 */
.approval-doc-head { padding-bottom: var(--s-5); border-bottom: 1px solid var(--line); }
.approval-doc-head h1 { margin: var(--s-2) 0 var(--s-3); font-size: var(--fs-h1); line-height: 1.25; }
.approval-doc-by { margin: 0; color: var(--muted); font-size: var(--fs-meta); }
.approval-doc-by time { font-variant-numeric: tabular-nums; }

/* ── 结论条：全页唯一的焦点 ── */
.approval-verdict { display: flex; align-items: center; gap: var(--s-3); margin: var(--s-6) 0; padding: 18px 22px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--paper-raised); }
.approval-verdict svg { width: 26px; height: 26px; flex: 0 0 auto; }
.approval-verdict strong { font-size: var(--fs-h3); font-weight: var(--fw-semi); letter-spacing: -.01em; }
.approval-verdict span { margin-left: auto; color: var(--muted); font-size: var(--fs-meta); }
.approval-verdict.is-approved { border-color: #cfe0cf; background: var(--green-soft); color: #3f6b46; }
.approval-verdict.is-rejected { border-color: #eccfc7; background: var(--coral-soft); color: var(--coral-ink); }
.approval-verdict.is-pending { border-color: #e8dcb8; background: var(--yellow-soft); color: #8a6a24; }

/* ── 区块：标题压小，靠字重和颜色分层，不再四个 h2 平铺 ── */
.approval-doc-section { margin-top: var(--s-6); }
.approval-doc-section h2 { margin: 0 0 var(--s-3); font-family: var(--font-ui); font-size: var(--fs-lead); font-weight: var(--fw-semi); letter-spacing: 0; }
.approval-doc-body { margin: 0; padding: 14px 16px; border-radius: var(--r-md); background: var(--paper-raised); color: var(--ink-2); font-size: var(--fs-body); line-height: 1.7; white-space: pre-wrap; }

/* ── 链路：一条一行 ── */
.approval-steps { display: grid; gap: var(--s-2); margin: 0; padding: 0; list-style: none; }
.approval-step { display: flex; gap: var(--s-3); padding: 13px 15px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--paper); }
.approval-step-index { flex: 0 0 auto; width: 22px; height: 22px; display: grid; place-items: center; border-radius: 50%; background: var(--cream); color: var(--muted); font-size: var(--fs-micro); font-variant-numeric: tabular-nums; }
.approval-step.is-approved .approval-step-index { background: var(--green-soft); color: #3f6b46; }
.approval-step.is-rejected .approval-step-index { background: var(--coral-soft); color: var(--coral-ink); }
.approval-step-body { flex: 1; min-width: 0; }
.approval-step-head { display: flex; align-items: baseline; gap: var(--s-2); flex-wrap: wrap; }
.approval-step-head strong { font-size: var(--fs-body); font-weight: var(--fw-semi); }
.approval-step-head time { margin-left: auto; color: var(--ink-4); font-size: var(--fs-micro); font-variant-numeric: tabular-nums; }
.approval-step-status { padding: 1px 8px; border-radius: var(--r-pill); background: var(--cream); color: var(--muted); font-size: var(--fs-micro); font-weight: var(--fw-semi); }
.approval-step.is-approved .approval-step-status { background: var(--green-soft); color: #3f6b46; }
.approval-step.is-rejected .approval-step-status { background: var(--coral-soft); color: var(--coral-ink); }
.approval-step-note { margin: 7px 0 0; color: var(--ink-2); font-size: var(--fs-meta); line-height: 1.65; white-space: pre-wrap; }

/* ── 附注：次要信息降到脚注 ── */
.approval-doc-footnote { padding: 14px 16px; border: 1px dashed var(--line); border-radius: var(--r-md); background: var(--paper-inset); }
.approval-doc-footnote h3 { margin: 0 0 6px; color: var(--muted); font-size: var(--fs-meta); font-weight: var(--fw-medium); }
.approval-doc-footnote p { margin: 0; color: var(--ink-2); font-size: var(--fs-meta); line-height: 1.65; }
.approval-doc-footnote-line { margin: var(--s-5) 0 0; color: var(--ink-4); font-size: var(--fs-meta); }
.approval-doc .approval-review-actions { margin-top: var(--s-6); padding-top: var(--s-5); border-top: 1px solid var(--line); }

@media print {
  .approval-doc { max-width: none; }
  .approval-verdict, .approval-step, .approval-doc-footnote { break-inside: avoid; }
}

/* ══════════════════════════════════════════════════════════════════
   家庭成员页
   改前的问题（都是量出来的，不是感觉）：
     - 页面 3590px，其中 1031px 是两个管理表单挡在成员列表前面 ——
       来看「家里有谁」得先滚过两个表单
     - 11 个 h2 全是 18px/600，**包括每个成员的人名**，
       所以「郑工」和「家庭信息」一样重
     - 按钮宽度失控：「添加成员」574px，「保存邮箱」「重置密码」各 396px，
       5 张卡里重复 12 个按钮
   ══════════════════════════════════════════════════════════════════ */

/* 「添加成员」不该撑满半个页面（.outline-button 默认 width:100%） */
.members-heading .outline-button { width: auto; margin-top: 0; }

/* 人名是 h3，不是 h2 —— 和区块标题拉开层级 */
.member-card-head h3 { margin: 0; font-size: var(--fs-h4); font-weight: var(--fw-semi); letter-spacing: -.01em; }

/* 成员卡的操作默认收起。5 张卡原来摊着 12 个按钮，把「谁是谁」淹了。 */
.member-manage { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line-soft); }
.member-manage > summary { display: flex; align-items: center; gap: 6px; min-height: 44px; color: var(--muted); font-size: var(--fs-meta); cursor: pointer; list-style: none; }
.member-manage > summary::-webkit-details-marker { display: none; }
.member-manage > summary svg { width: 14px; height: 14px; }
.member-manage > summary:hover { color: var(--ink); }
.member-manage[open] > summary { color: var(--ink); font-weight: var(--fw-medium); }
.member-manage .member-email-form { margin-top: 12px; }
.member-manage .member-actions { margin-top: 10px; }
/* 卡内按钮都按内容宽，不要撑满 */
.member-manage .member-email-form .outline-button,
.member-manage .member-actions .outline-button,
.member-manage .member-actions .quiet-button { width: auto; margin-top: 0; }

/* 我的账号 / 家庭设置：默认收起。
   这些是「偶尔设置一次」的东西，不该占在首页位置。 */
.member-settings { margin-top: var(--s-6); }
.member-settings-group { border: 1px solid var(--line); border-radius: var(--r-md); background: var(--paper); box-shadow: var(--shadow-sm); }
.member-settings-group > summary { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; min-height: 44px; padding: 16px 20px; cursor: pointer; list-style: none; }
.member-settings-group > summary::-webkit-details-marker { display: none; }
.member-settings-group > summary:hover .member-settings-title { color: var(--coral-ink); }
.member-settings-title { font-size: var(--fs-lead); font-weight: var(--fw-semi); }
.member-settings-group > summary small { color: var(--muted); font-size: var(--fs-meta); }
.member-settings-group[open] > summary { border-bottom: 1px solid var(--line); }
/* 内层面板不再自己画框，避免「盒子套盒子」 */
.member-settings-body { display: grid; gap: var(--s-5); padding: 20px; }
.member-settings-body .module-panel { padding: 0; border: 0; background: none; box-shadow: none; }
.member-settings-body .member-admin-tools { display: grid; gap: var(--s-5); }

/* 家庭 ID：从「可编辑的输入框」改成「只读 + 复制」。
   它同时是唯一标识和加入凭证，可读就可猜 —— 不该让人改。 */
.chip-copy { display: grid; place-items: center; width: 44px; height: 44px; flex: 0 0 auto; margin-left: auto; border: 0; border-radius: var(--r-xs); background: rgba(255, 255, 255, .55); color: var(--muted); cursor: pointer; transition: background-color var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out); }
.chip-copy:hover { background: var(--paper); color: var(--coral-ink); }
.chip-copy svg { width: 16px; height: 16px; }
.family-code-readonly { display: flex; align-items: center; gap: var(--s-2); }
.family-code-readonly code { flex: 1; min-width: 0; padding: 11px 13px; border: 1px dashed var(--line-strong); border-radius: var(--r-sm); background: var(--paper-inset); color: var(--ink); font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: var(--fs-body); letter-spacing: .04em; overflow-x: auto; white-space: nowrap; }
.family-code-readonly .outline-button { width: auto; margin-top: 0; flex: 0 0 auto; }

/* 这个说明框只在「链路没覆盖全部成员」时才出现，所以它旁边的解释
   也要跟着出现 —— 不然用户不知道这个框为什么在这。 */
.approval-note-field { margin-top: 12px; padding: 13px 15px; border: 1px solid #e8dcb8; border-radius: var(--r-sm); background: var(--yellow-soft); }
.approval-note-field > span { color: #8a6a24; font-weight: var(--fw-semi); }
.approval-note-why { margin: 5px 0 9px; color: var(--ink-2); font-size: var(--fs-meta); line-height: 1.6; }
.approval-note-why strong { color: var(--ink); font-weight: var(--fw-semi); }

/* 「待你接受」以前是 span（看着像标签），现在是按钮，要点得动。
   这条路径原先断了：全家任务下除发起人外的所有人都被渲染成 disabled 按钮，
   而禁用元素吞掉点击，连整行都点不开。 */
.task-awaiting { appearance: none; border: 1px solid transparent; border-radius: var(--r-pill); background: var(--coral-soft); color: var(--coral-ink); font: inherit; font-size: var(--fs-meta); font-weight: var(--fw-semi); padding: 5px 12px; cursor: pointer; white-space: nowrap; transition: background-color var(--t-fast) var(--ease-out), transform var(--t-fast) var(--ease-out); }
.task-awaiting:hover { background: var(--coral); color: white; }
.task-awaiting:active { transform: scale(.97); }
.task-done-mark { padding: 5px 12px; border-radius: var(--r-pill); background: var(--green-soft); color: #3f6b46; font-size: var(--fs-meta); font-weight: var(--fw-semi); white-space: nowrap; }

/* 完成备注：填了就该看得见。
   详情弹窗里是一个独立小节，列表行里是标题下面一行弱化的小字。 */
.task-completion-summary { margin-top: 16px; padding: 13px 15px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--paper-raised); }
.task-completion-summary strong { display: block; margin-bottom: 6px; color: var(--muted); font-size: var(--fs-meta); font-weight: var(--fw-medium); }
.task-completion-summary p { margin: 0; color: var(--ink-2); font-size: var(--fs-body); line-height: 1.7; white-space: pre-wrap; }
.task-row-note { display: block; margin-top: 4px; color: var(--ink-4); }
.task-row-note::before { content: ""; }

/* 已完成的任务卡片：现在要放下完成备注，并且整张卡可点开详情。
   布局从「图标 + 文字 + 按钮」一行，改成文字部分能换行的小块。 */
.completed-task { cursor: pointer; align-items: flex-start; }
.completed-task-body { flex: 1; min-width: 0; }
.completed-task-body strong { display: block; }
.completed-task-note { margin: 5px 0 0; color: var(--ink-2); font-size: var(--fs-meta); line-height: 1.6; white-space: pre-wrap; }
.completed-task .task-restore-button { flex: 0 0 auto; }
