/* ============ 基础变量 ============ */
:root{
  /* 底色偏亮、卡片纯白：东西浮在纸面上，而不是又叠一张纸。
     原来是米纸压米纸，看久了发闷 */
  --paper:#fdfaf3;
  --paper-2:#ffffff;
  --ink:#1f1c18;
  --ink-2:#4c453b;
  --ink-3:#8b8175;
  --line:#eee5d6;
  --line-2:#dccbb2;
  /* 朱红：比原来那档暗红亮一档，是这套配色的主张 */
  --red:#d8382a;
  --red-soft:#ee6a56;
  --red-deep:#a82318;
  /* 金：亮到能当强调色用，不再是灰扑扑的黄铜 */
  --gold:#e2a11c;
  --gold-soft:#f8dc94;
  --gold-deep:#a8761a;
  --green:#2b9d63;
  --blue:#2b7fd4;
  --male:#2b7fd4;
  --female:#d8382a;
  --radius:14px;
  --radius-lg:18px;
  --shadow:0 1px 2px rgba(80,55,25,.05), 0 10px 26px -14px rgba(90,60,25,.24);
  --shadow-lg:0 14px 44px -14px rgba(90,60,25,.34);
  --shadow-hi:0 2px 5px rgba(80,55,25,.06), 0 18px 38px -20px rgba(90,60,25,.42);
  --font-serif:"Songti SC","STSong","Noto Serif SC","Source Han Serif SC",Georgia,serif;
  --font-sans:"PingFang SC","Hiragino Sans GB","Microsoft YaHei","Helvetica Neue",Arial,sans-serif;
}

*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;
  /* 三处极淡的色晕：右上朱红、左上金、底部一点绿。
     淡到几乎看不出，但整页不再是死白一片 */
  background:
    radial-gradient(1100px 560px at 100% -8%, rgba(216,56,42,.10) 0%, rgba(255,255,255,0) 62%),
    radial-gradient(900px 520px at -8% 12%, rgba(226,161,28,.14) 0%, rgba(255,255,255,0) 58%),
    radial-gradient(760px 460px at 50% 106%, rgba(43,157,99,.075) 0%, rgba(255,255,255,0) 60%),
    var(--paper);
  color:var(--ink);
  font-family:var(--font-sans);
  font-size:15px;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
}
a{color:inherit;text-decoration:none}
button,input,select,textarea{font-family:inherit;font-size:inherit;color:inherit}
h1,h2,h3,h4{font-family:var(--font-serif);font-weight:600;margin:0;letter-spacing:.02em}
.muted{color:var(--ink-3)}
.small{font-size:13px}

/* ============ 布局 ============ */
.app-shell{display:flex;flex-direction:column;min-height:100%}
.topbar{
  position:sticky;top:0;z-index:40;
  display:flex;align-items:center;gap:18px;
  padding:0 28px;height:64px;
  background:rgba(253,250,243,.86);
  backdrop-filter:saturate(160%) blur(12px);
  border-bottom:1px solid var(--line);
}
.brand{display:flex;align-items:center;gap:10px;font-family:var(--font-serif);font-size:20px;font-weight:700;letter-spacing:.08em}
.brand .seal{
  width:32px;height:32px;border-radius:8px;
  background:linear-gradient(145deg,var(--red-soft),var(--red) 45%,var(--red-deep));
  color:#fff;display:grid;place-items:center;font-size:17px;
  box-shadow:0 6px 16px -6px rgba(216,56,42,.75)
}
.nav{display:flex;gap:4px;margin-left:12px}
.nav a{
  padding:7px 13px;border-radius:999px;color:var(--ink-2);font-size:14px;
  transition:.18s;
}
.nav a:hover{background:#f6eddd;color:var(--red-deep)}
/* 当前板块用朱红实心，一眼知道自己在哪 */
.nav a.active{background:linear-gradient(145deg,var(--red),var(--red-deep));color:#fff;
  box-shadow:0 6px 16px -10px rgba(216,56,42,.95)}
.nav a.active:hover{color:#fff}

/* 板块内子导航：只有一管好几项的板块（来往、家庭）才出现 */
.subbar{display:none;position:sticky;top:64px;z-index:39;
  background:rgba(253,250,243,.94);backdrop-filter:saturate(160%) blur(12px);
  border-bottom:1px solid var(--line)}
.subbar.show{display:block}
.subnav{display:flex;gap:6px;padding:8px 28px;overflow-x:auto}
.subnav a{padding:5px 12px;border-radius:999px;font-size:13px;
  color:var(--ink-2);white-space:nowrap;transition:.18s}
.subnav a:hover{background:#f0e8da}
.subnav a.active{background:var(--gold-soft);color:#5a4218;font-weight:600}

/* 导航未读角标 */
.nav-dot{display:inline-grid;place-items:center;min-width:17px;height:17px;
  margin-left:5px;padding:0 4px;border-radius:999px;
  background:var(--red);color:#fff;font-size:11px;font-style:normal;
  line-height:1;vertical-align:1px}
.tab-ico{position:relative}
.mtabs .nav-dot{position:absolute;top:-3px;right:-9px;margin:0}

/* ---------- 消息中心 ---------- */
.msg-tabs{display:flex;gap:8px;flex-wrap:wrap;margin:12px 0 2px}
.msg-tab{padding:6px 14px;border-radius:999px;font-size:14px;
  background:var(--paper-2);border:1px solid var(--line);
  color:var(--ink-2);transition:.18s}
.msg-tab:hover{border-color:var(--gold-soft)}
.msg-tab.on{background:var(--ink);border-color:var(--ink);color:#fff}
.msg-tab i{display:inline-grid;place-items:center;min-width:16px;height:16px;
  margin-left:6px;padding:0 4px;border-radius:999px;
  background:var(--red);color:#fff;font-size:11px;font-style:normal}

.msg-list{display:flex;flex-direction:column}
/* 一行消息分三格：圆点 / 正文 / 按钮。
   按钮独占右侧并贯穿两行，正文就有完整宽度可用——
   按钮和文字挤在同一行，窄屏下文字会被压成一字一行的竖条 */
.msg-row{display:grid;
  grid-template-columns:10px minmax(0,1fr) auto;
  grid-template-areas:
    "dot main act"
    "dot meta act";
  gap:5px 12px;align-items:start;padding:14px 12px;
  border-top:1px solid var(--line)}
.msg-row:first-child{border-top:0}
.msg-row.unread{background:linear-gradient(90deg,rgba(216,56,42,.06),transparent 60%)}
.msg-dot{grid-area:dot;width:8px;height:8px;border-radius:50%;
  margin-top:8px;background:var(--line-2)}
.msg-row[data-hue="todo"] .msg-dot{background:var(--red)}
.msg-row[data-hue="invite"] .msg-dot{background:var(--gold)}
.msg-row.unread .msg-dot{box-shadow:0 0 0 3px rgba(216,56,42,.16)}
.msg-main{grid-area:main;min-width:0;display:flex;flex-direction:column;gap:3px}
.msg-main b{font-weight:600;line-height:1.45}
.msg-main em{line-height:1.5}
/* 标签、时间、状态徽标同处一行；挤不下就换行，绝不去抢正文的宽度 */
.msg-meta{grid-area:meta;min-width:0;display:flex;align-items:center;
  gap:8px;flex-wrap:wrap}
.msg-tag{flex:0 0 auto;padding:2px 9px;border-radius:999px;font-size:12px;
  background:#f2ece0;color:var(--ink-2)}
.msg-time{flex:0 0 auto;font-size:12px;color:var(--ink-3);
  display:flex;gap:6px;align-items:baseline;line-height:1.3}
.msg-time em{font-style:normal;font-size:11px;opacity:.75}
.msg-act{grid-area:act;align-self:center;display:flex;gap:6px;align-items:center}

/* 消息弹窗里的详情：标签列定宽，值与值对齐，长文本自动折行不溢出 */
.msg-fields{margin:0;display:flex;flex-direction:column;gap:9px}
.msg-fields>div{display:grid;grid-template-columns:74px minmax(0,1fr);
  gap:12px;align-items:baseline}
.msg-fields dt{font-size:13px;color:var(--ink-3)}
.msg-fields dd{margin:0;font-size:14px;color:var(--ink);word-break:break-word}

/* 首页的消息入口 */
.msg-entry{display:flex;align-items:center;gap:12px;padding:14px 18px;
  border-radius:var(--radius);border:1px solid var(--line);
  background:var(--paper-2);transition:.18s}
.msg-entry:hover{border-color:var(--gold-soft);box-shadow:var(--shadow)}
.msg-entry.has-un{border-color:rgba(192,86,79,.35);
  background:linear-gradient(90deg,rgba(192,86,79,.05),var(--paper-2) 60%)}
.me-ico{width:34px;height:34px;border-radius:10px;display:grid;place-items:center;
  background:var(--gold-soft);color:#5a4218;font-size:16px;
  position:relative;flex:0 0 34px}
.me-ico i{position:absolute;top:-5px;right:-6px;min-width:17px;height:17px;
  padding:0 4px;border-radius:999px;background:var(--red);color:#fff;
  font-size:11px;font-style:normal;display:grid;place-items:center}
.me-tx{flex:1;display:flex;flex-direction:column}
.me-tx b{font-family:var(--font-serif);font-size:15px}
.me-tx em{font-style:normal;font-size:12px;color:var(--ink-3)}
.me-go{font-size:13px;color:var(--ink-3)}

/* 板块卡片里列出它管着哪几项 */
.app-keys{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}
.app-key{padding:2px 9px;border-radius:999px;font-size:12px;
  background:#f2ece0;color:var(--ink-2)}

/* 窄屏：正文能用的宽度更紧，让标签与时间整行挪到正文下面，
   按钮留在第一行右侧，两者不再互相挤 */
@media (max-width:560px){
  .msg-row{grid-template-areas:
      "dot main act"
      "dot meta meta";
    gap:7px 10px;padding:13px 6px}
  .msg-act{align-self:end}
  .msg-fields>div{grid-template-columns:minmax(0,1fr);gap:2px}
  .msg-fields dt{font-size:12px}
}
.topbar .spacer{flex:1}
.topbar-actions{display:flex;gap:8px;align-items:center}

.main{flex:1;width:100%;max-width:1240px;margin:0 auto;padding:28px 28px 56px}
@media (max-width:900px){
  .topbar{height:auto;min-height:58px;padding:10px 16px;flex-wrap:wrap;gap:10px}
  .topbar .spacer{display:none}
  .topbar-actions{margin-left:auto}
}
@media (max-width:560px){
  .brand span:last-child{display:none}
  .nav a{padding:6px 10px;font-size:13px}
}
.footer{
  border-top:1px solid var(--line);
  padding:18px 28px;display:flex;justify-content:space-between;
  font-size:13px;color:var(--ink-3);background:rgba(255,253,248,.6)
}

/* ============ 通用组件 ============ */
.btn{
  display:inline-flex;align-items:center;gap:6px;
  padding:8px 15px;border-radius:10px;border:1px solid var(--line-2);
  background:var(--paper-2);color:var(--ink-2);cursor:pointer;
  transition:.18s;font-size:14px;white-space:nowrap;
}
.btn:hover{background:#fff;border-color:var(--gold);color:var(--ink);transform:translateY(-1px)}
.btn:active{transform:none}
.btn.primary{background:linear-gradient(145deg,var(--red),var(--red-deep));color:#fff;border-color:transparent;box-shadow:0 8px 20px -10px rgba(216,56,42,.95)}
.btn.primary:hover{filter:brightness(1.06);color:#fff}
.btn.ghost{background:transparent;border-color:transparent;color:var(--ink-3)}
.btn.ghost:hover{background:#f0e8da;color:var(--ink)}
.btn.danger{color:var(--red);border-color:#e4c3c1}
.btn.danger:hover{background:#fbeeee;border-color:var(--red)}
.btn.sm{padding:5px 10px;font-size:13px;border-radius:8px}
.btn:disabled{opacity:.5;cursor:not-allowed;transform:none}

.card{
  background:var(--paper-2);border:1px solid var(--line);
  border-radius:var(--radius);box-shadow:var(--shadow);
}
.card.pad{padding:22px}
.card + .card{margin-top:18px}

.section-title{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin:0 0 14px;
}
.section-title h2{font-size:19px}
.section-title .desc{font-size:13px;color:var(--ink-3);margin-top:2px}

.page-head{margin-bottom:22px}
.page-head h1{font-size:28px;line-height:1.3}
.page-head .sub{color:var(--ink-3);font-size:14px;margin-top:6px}

.grid{display:grid;gap:18px}
.grid.cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}
.grid.cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}
.grid.cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:900px){
  .grid.cols-3,.grid.cols-4{grid-template-columns:repeat(2,minmax(0,1fr))}
  .grid.cols-2{grid-template-columns:minmax(0,1fr)}
}
@media (max-width:560px){
  .grid.cols-3,.grid.cols-4{grid-template-columns:minmax(0,1fr)}
  .main{padding:18px 14px 40px}
  .topbar{padding:0 14px;gap:10px}
  .nav{margin-left:0}
}

/* ============ 表单 ============ */
.field{margin-bottom:16px}
.field label{display:block;font-size:13px;color:var(--ink-2);margin-bottom:6px;font-weight:500}
.field .hint{font-size:12px;color:var(--ink-3);margin-top:5px}
.input,.select,.textarea{
  width:100%;padding:9px 12px;border-radius:10px;
  border:1px solid var(--line-2);background:#fff;outline:none;transition:.15s;
}
.input:focus,.select:focus,.textarea:focus{border-color:var(--gold);box-shadow:0 0 0 3px rgba(226,161,28,.14)}
.textarea{min-height:90px;resize:vertical;line-height:1.6}
.row{display:flex;gap:14px}
.row > *{flex:1;min-width:0}
@media (max-width:640px){.row{flex-direction:column;gap:0}}

.checkline{display:flex;flex-wrap:wrap;gap:10px}
.chip{
  display:inline-flex;align-items:center;gap:6px;padding:6px 12px;
  border:1px solid var(--line-2);border-radius:999px;background:#fff;cursor:pointer;font-size:13px;
}
.chip input{accent-color:var(--red)}
.chip.checked{border-color:var(--red);background:#fdf3f2;color:var(--red)}

/* ============ 统计卡 ============ */
.stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px}
@media (max-width:800px){.stats{grid-template-columns:repeat(2,minmax(0,1fr))}}
.stat{
  padding:16px 18px;border-radius:var(--radius);
  background:var(--paper-2);border:1px solid var(--line);box-shadow:var(--shadow);
}
.stat .num{font-family:var(--font-serif);font-size:30px;font-weight:700;line-height:1.1}
.stat .label{font-size:13px;color:var(--ink-3);margin-top:2px}

/* ============ 族谱卡片 ============ */
.tree-card{
  position:relative;overflow:hidden;
  padding:22px;border-radius:var(--radius);
  background:var(--paper-2);border:1px solid var(--line);box-shadow:var(--shadow);
  transition:.2s;display:flex;flex-direction:column;min-height:180px;
}
.tree-card:hover{transform:translateY(-3px);box-shadow:var(--shadow-lg);border-color:var(--line-2)}
.tree-card .orn{
  position:absolute;right:-30px;top:-30px;width:112px;height:112px;border-radius:50%;
  border:1px solid rgba(226,161,28,.28);
  box-shadow:inset 0 0 0 12px rgba(243,233,214,.35);
  transition:.3s;pointer-events:none;
}
.tree-card:hover .orn{transform:scale(1.08)}
.tree-card .tname{font-family:var(--font-serif);font-size:22px;font-weight:700;letter-spacing:.04em}
.tree-card .tmeta{font-size:13px;color:var(--ink-3);margin-top:4px}
.tree-card .tdesc{
  margin-top:10px;font-size:14px;color:var(--ink-2);line-height:1.6;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.tree-card .tfoot{margin-top:auto;padding-top:14px;display:flex;gap:14px;font-size:13px;color:var(--ink-3)}
.tree-card .tag{
  display:inline-block;padding:2px 9px;border-radius:999px;font-size:12px;
  background:#f3ead8;color:var(--gold);border:1px solid #eadfc6
}
.empty{
  padding:56px 20px;text-align:center;color:var(--ink-3);
  border:1px dashed var(--line-2);border-radius:var(--radius);background:rgba(255,253,248,.5)
}
.empty h3{font-size:18px;color:var(--ink-2);margin-bottom:6px}

.dashed-add{
  display:grid;place-items:center;gap:8px;min-height:180px;cursor:pointer;
  border:1.5px dashed var(--line-2);border-radius:var(--radius);
  color:var(--ink-3);background:rgba(255,253,248,.4);transition:.2s
}
.dashed-add:hover{border-color:var(--gold);color:var(--red);background:#fffdf6}
.dashed-add .plus{font-size:30px;font-family:var(--font-serif)}

/* ============ 表格 ============ */
.table-wrap{overflow:auto;border-radius:var(--radius);border:1px solid var(--line);background:var(--paper-2)}
table.data{width:100%;border-collapse:collapse;font-size:14px}
table.data th,table.data td{padding:11px 14px;text-align:left;border-bottom:1px solid var(--line);white-space:nowrap}
table.data th{background:#f6efe2;font-weight:600;font-size:13px;color:var(--ink-2);position:sticky;top:0}
table.data tbody tr:hover{background:#fdf8ee}
table.data td.name a{font-weight:600}
table.data td.name a:hover{color:var(--red)}

/* ============ 徽标 ============ */
.badge{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:6px;font-size:12px;border:1px solid transparent}
.badge.gen{background:#f2f0e8;color:var(--ink-2);border-color:var(--line-2)}
.badge.m{background:#eaf1f7;color:var(--blue);border-color:#d3e2ee}
.badge.f{background:#fbeceb;color:var(--red);border-color:#f0d5d3}
.badge.live{background:#ecf4ee;color:var(--green);border-color:#d8e8dc}
.badge.rank{background:#fbf4e2;color:var(--gold);border-color:#e8d9ae}

/* 动态编辑行 */
.dyn-row{display:flex;gap:8px;align-items:center;margin-bottom:10px;flex-wrap:wrap}
.dyn-card{
  border:1px solid var(--line);border-radius:12px;padding:12px 14px;margin-bottom:12px;background:#fffdf7
}
.dyn-card .field{margin-bottom:8px}
.sub-title{
  font-family:var(--font-serif);font-size:15px;font-weight:600;color:var(--ink-2);
  margin:14px 0 8px;padding-left:10px;border-left:3px solid var(--gold)
}
.badge.dead{background:#f4f1ec;color:var(--ink-3);border-color:var(--line-2)}

.tabbar{display:flex;gap:6px;border-bottom:1px solid var(--line);margin-bottom:20px;overflow:auto}
.tabbar a{
  padding:9px 16px;border-radius:10px 10px 0 0;font-size:14px;color:var(--ink-3);
  position:relative;white-space:nowrap;
}
.tabbar a:hover{color:var(--ink)}
.tabbar a.active{color:var(--red);font-weight:600}
.tabbar a.active::after{
  content:"";position:absolute;left:12px;right:12px;bottom:-1px;height:2px;background:var(--red);border-radius:2px
}

/* ============ 成员详情 ============ */
.member-hero{display:flex;gap:22px;align-items:flex-start}
.avatar{
  width:118px;height:118px;border-radius:16px;flex:none;overflow:hidden;
  border:1px solid var(--line-2);background:#f3ead8;display:grid;place-items:center;
  font-family:var(--font-serif);font-size:42px;color:#a08a5f
}
.avatar img{width:100%;height:100%;object-fit:cover;display:block}
.member-hero .info{flex:1;min-width:0}
.member-hero h1{font-size:32px}
.member-hero .rel{margin-top:8px;display:flex;flex-wrap:wrap;gap:8px}
@media (max-width:640px){
  .member-hero{flex-direction:column}
  .member-hero h1{font-size:25px}
}

.kv{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 26px}
@media (max-width:640px){.kv{grid-template-columns:minmax(0,1fr)}}
.kv .item{display:flex;gap:10px;font-size:14px;border-bottom:1px dashed var(--line);padding-bottom:9px}
.kv .k{color:var(--ink-3);flex:none;width:66px}
.kv .v{flex:1;word-break:break-word}

/* ============ 字辈 / 族史 ============ */
.rank-row{display:flex;flex-wrap:wrap;gap:12px}
.rank-item{
  width:104px;padding:14px 8px;text-align:center;border-radius:12px;
  background:linear-gradient(160deg,#fffdf7,#f5ecd9);border:1px solid var(--line-2);
  box-shadow:0 2px 8px -6px rgba(80,55,25,.5)
}
.rank-item .rank-char{
  font-family:var(--font-serif);font-size:30px;font-weight:700;color:var(--red);line-height:1.2
}
.rank-item .rank-meta{font-size:12px;color:var(--ink-3);margin-top:2px}
.rank-item .rank-note{font-size:11px;color:var(--ink-3);margin-top:6px;line-height:1.4}
td.rank-cell{font-family:var(--font-serif);font-size:19px;color:var(--red);font-weight:700}

.motto{
  font-family:var(--font-serif);font-size:19px;color:var(--red);letter-spacing:.08em;
  padding:10px 14px;margin-bottom:12px;border-left:3px solid var(--red);background:#fdf6ef;border-radius:0 8px 8px 0
}
.rules{font-size:14px;line-height:2;color:var(--ink-2);white-space:normal}
.prose p{margin:0 0 14px}
.prose{
  font-size:15px;line-height:1.95;color:var(--ink-2);
  padding:18px 20px;background:#fffdf7;border:1px solid var(--line);border-radius:12px
}
.branch-box{padding:14px 16px;border:1px solid var(--line);border-radius:12px;background:#fffdf7}
.branch-head{font-family:var(--font-serif);font-size:17px;font-weight:600}

.timeline{position:relative;padding-left:22px}
.timeline::before{content:"";position:absolute;left:6px;top:6px;bottom:6px;width:1px;background:var(--line-2)}
.tl-item{position:relative;padding-bottom:20px}
.tl-item::before{
  content:"";position:absolute;left:-19px;top:7px;width:9px;height:9px;border-radius:50%;
  background:var(--paper-2);border:2px solid var(--gold)
}
.tl-item .t{font-weight:600}
.tl-item .d{font-size:13px;color:var(--ink-3)}

.rel-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px 24px}
@media (max-width:640px){.rel-grid{grid-template-columns:minmax(0,1fr)}}
.rel-row{display:flex;gap:10px;font-size:14px;align-items:baseline}
.rel-row .k{color:var(--ink-3);width:56px;flex:none}
.rel-row .v{display:flex;flex-wrap:wrap;gap:6px}
.pill{
  padding:3px 10px;border-radius:999px;background:#f6efe2;border:1px solid var(--line);
  font-size:13px;transition:.15s
}
.pill:hover{background:#f0e3cd;border-color:var(--gold);color:var(--red)}

.gallery{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(140px,100%),1fr));gap:12px}
.gallery figure{margin:0;border:1px solid var(--line);border-radius:10px;overflow:hidden;background:#fff}
.gallery img{width:100%;height:120px;object-fit:cover;display:block}
.gallery figcaption{padding:6px 9px;font-size:12px;color:var(--ink-3)}

/* ============ 树图 ============ */
.chart-toolbar{display:flex;align-items:center;gap:8px;margin-bottom:14px;flex-wrap:wrap}
.chart-viewport{
  position:relative;height:min(72vh,720px);min-height:420px;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--radius);
  background:
    linear-gradient(rgba(0,0,0,.035) 1px, transparent 1px) 0 0/24px 24px,
    linear-gradient(90deg, rgba(0,0,0,.035) 1px, transparent 1px) 0 0/24px 24px,
    var(--paper-2);
  cursor:grab;
}
.chart-viewport.dragging{cursor:grabbing}
.chart-viewport svg{display:block;width:100%;height:100%}
.node-box{cursor:pointer}
.node-box rect{transition:.15s}
.node-box:hover rect{filter:drop-shadow(0 4px 10px rgba(80,55,25,.25))}
.node-box .nm{font-family:var(--font-serif);font-size:14px;font-weight:600;fill:#22201d}
.node-box .sub{font-size:10px;fill:#8a8279}
.legend{display:flex;gap:16px;flex-wrap:wrap;font-size:13px;color:var(--ink-3);align-items:center}
.legend i{display:inline-block;width:12px;height:12px;border-radius:3px;margin-right:5px;vertical-align:-1px}

/* ============ 提示 / 弹窗 ============ */
.toast{
  position:fixed;left:50%;bottom:40px;transform:translate(-50%,20px);
  background:var(--ink);color:#fff;padding:10px 20px;border-radius:10px;
  font-size:14px;opacity:0;pointer-events:none;transition:.25s;z-index:200;box-shadow:var(--shadow-lg)
}
.toast.show{opacity:1;transform:translate(-50%,0)}

.modal-root:empty{display:none}
.mask{
  position:fixed;inset:0;background:rgba(30,25,18,.45);backdrop-filter:blur(2px);
  display:grid;place-items:center;z-index:150;padding:20px
}
.modal{
  width:min(520px,100%);background:var(--paper-2);border-radius:16px;padding:24px;
  box-shadow:var(--shadow-lg);max-height:86vh;
  /* 按钮固定在底部，只让正文滚。
     整个弹窗一起滚的话，字段一多按钮就被卷到下面去了——
     记账表单十九个字段，手机上得滚一屏才够得着「记下」 */
  display:flex;flex-direction:column;overflow:hidden
}
.modal h3{font-size:19px;margin-bottom:10px;flex:0 0 auto}
.modal .modal-actions{display:flex;justify-content:flex-end;gap:10px;
  margin-top:20px;flex:0 0 auto}
/* min-height:0 是必需的：flex 子项默认不肯缩到内容高度以下，
   不写它正文就不会滚，弹窗照样顶破视口——跟 grid 那边 minmax(0,1fr) 一个道理 */
.modal-body{font-size:13.5px;line-height:1.8;
  overflow:auto;flex:1 1 auto;min-height:0;-webkit-overflow-scrolling:touch}
.modal-body .dup-list{margin:12px 0 0;padding:0;list-style:none;display:grid;gap:7px}
.modal-body .dup-list li{
  padding:8px 11px;border-radius:10px;font-size:12.5px;line-height:1.6;
  background:#f8f0e0;border:1px solid var(--line);color:var(--ink-2);
}
.modal-body .dup-list li b{font-family:var(--font-serif);color:var(--ink);font-weight:600}
.modal-body .dup-list li span{color:var(--ink-3)}
.file-drop{
  border:1.5px dashed var(--line-2);border-radius:14px;padding:30px 20px;text-align:center;
  color:var(--ink-3);cursor:pointer;transition:.2s;
  background:linear-gradient(180deg,#fffdf7,#fdf8ee);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
  font-size:14px;letter-spacing:.02em;
}
.file-drop::before{
  content:"";width:42px;height:49px;margin-bottom:4px;opacity:.9;
  background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0OCA1NiIgZmlsbD0ibm9uZSI+PHBhdGggZD0iTTggMmgyMmwxMiAxMnY0MGEyIDIgMCAwIDEtMiAySDhhMiAyIDAgMCAxLTItMlY0YTIgMiAwIDAgMSAyLTJ6IiBmaWxsPSIjZmZmZGY3IiBzdHJva2U9IiNjOWI4OTQiIHN0cm9rZS13aWR0aD0iMiIvPjxwYXRoIGQ9Ik0zMCAybDEyIDEySDMwVjJ6IiBmaWxsPSIjZjJlN2QwIiBzdHJva2U9IiNjOWI4OTQiIHN0cm9rZS13aWR0aD0iMiIvPjxwYXRoIGQ9Ik0xMyAyNmgyMk0xMyAzNGgyMk0xMyA0MmgxNCIgc3Ryb2tlPSIjZDhjNmEyIiBzdHJva2Utd2lkdGg9IjIuNCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PC9zdmc+") no-repeat center/contain;
  transition:.2s;
}
.file-drop:hover{border-color:var(--gold);color:var(--red);background:linear-gradient(180deg,#fffef9,#fbf4e4)}
.file-drop:hover::before{transform:translateY(-2px)}
.file-drop.over{border-color:var(--red);background:#fdf6ef;box-shadow:0 0 0 4px rgba(216,56,42,.06)}

/* =========================================================
   视觉增强：纸张质感、中式装饰与层次
   ========================================================= */

/* 宣纸纹理（纯 CSS，不额外请求资源） */
body::before{
  content:"";position:fixed;inset:0;z-index:0;pointer-events:none;
  opacity:.5;mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.32'/%3E%3C/svg%3E");
}
.app-shell{position:relative;z-index:1}

/* ---------- 顶栏 ---------- */
.topbar{
  background:linear-gradient(180deg,rgba(252,249,242,.95),rgba(250,246,239,.88));
  box-shadow:0 1px 0 rgba(230,222,208,.95), 0 14px 30px -26px rgba(80,55,25,.5);
}
.brand{letter-spacing:.14em}
.brand .seal{
  width:34px;height:34px;border-radius:10px;font-size:18px;letter-spacing:0;
  background:linear-gradient(145deg,#b53731,#a82318);
  box-shadow:0 6px 14px -6px rgba(216,56,42,.75), inset 0 1px 0 rgba(255,255,255,.28), inset 0 -2px 6px rgba(0,0,0,.18);
}
.nav a{border:1px solid transparent}
.nav a:hover{background:#f5ecdc;border-color:#eadfc6;color:var(--ink)}
.nav a.active{
  background:linear-gradient(145deg,var(--ink),#3a3630);
  border-color:var(--ink);color:#fff;
  box-shadow:0 6px 14px -8px rgba(34,32,29,.8);
}
.topbar .top-search{
  width:176px;border-radius:999px;padding:6px 12px 6px 32px;
  background:#fff url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYTg5ZThjIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCI+PGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iNyIvPjxwYXRoIGQ9Ik0yMCAyMGwtMy42LTMuNiIvPjwvc3ZnPg==") no-repeat 10px center/14px 14px;
}

/* ---------- 标题 ---------- */
.page-head h1{position:relative;display:inline-block;font-size:30px;letter-spacing:.05em}
.page-head h1::after{
  content:"";position:absolute;left:4px;bottom:-11px;width:48px;height:3px;border-radius:3px;
  background:linear-gradient(90deg,var(--red),rgba(226,161,28,.15));opacity:.9;
}
.page-head .sub{margin-top:17px}
.section-title h2{position:relative;padding-left:13px}
.section-title h2::before{
  content:"";position:absolute;left:0;top:.28em;bottom:.28em;width:3px;border-radius:3px;
  background:linear-gradient(180deg,var(--red),var(--gold));opacity:.9;
}
.sub-title{border-left-width:3px}

/* ---------- 卡片 / 按钮 ---------- */
.card{
  background:linear-gradient(180deg,#fffdf8,#fffefa);
  border-radius:var(--radius-lg);
}
.card.pad{padding:24px}
.btn{border-radius:11px;letter-spacing:.02em;box-shadow:0 1px 2px rgba(80,55,25,.04)}
.btn:hover{box-shadow:0 8px 18px -12px rgba(80,55,25,.55)}
.btn.primary{
  background:linear-gradient(145deg,var(--red-soft),var(--red) 42%,var(--red-deep));
  box-shadow:0 10px 24px -12px rgba(216,56,42,.95), inset 0 1px 0 rgba(255,255,255,.26);
}
.btn.ghost{border-color:transparent}

/* ---------- 表单 ---------- */
.input,.select,.textarea{
  border-radius:11px;background:linear-gradient(180deg,#fff,#fffdf8);
  box-shadow:inset 0 1px 2px rgba(80,55,25,.03);
}
.input:focus,.select:focus,.textarea:focus{
  border-color:var(--gold);box-shadow:0 0 0 3px rgba(226,161,28,.16), inset 0 1px 2px rgba(80,55,25,.03);
}

/* ---------- 统计卡 ---------- */
.stat{
  position:relative;overflow:hidden;border-radius:var(--radius-lg);
  background:linear-gradient(165deg,#fffdf7,#f9f3e6);
}
.stat::after{
  content:"";position:absolute;right:16px;top:15px;width:26px;height:1.5px;border-radius:2px;
  background:linear-gradient(90deg,rgba(226,161,28,0),rgba(226,161,28,.6));
  pointer-events:none;
}
.stat .num{
  font-size:32px;letter-spacing:.02em;
  background:linear-gradient(180deg,#6d5115,#a4792b);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
.stat .label{letter-spacing:.06em}

/* ---------- 族谱卡 ---------- */
.tree-card{
  background:linear-gradient(165deg,#fffdf7 0%,#fbf4e8 100%);
  border-radius:var(--radius-lg);
}
.tree-card::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:5px;
  background:linear-gradient(180deg,#d8382a,#b8443f 55%,rgba(226,161,28,.55));
}
.tree-card::after{
  content:"";position:absolute;inset:0;border:1px solid rgba(255,255,255,.5);
  border-radius:var(--radius-lg);pointer-events:none;
}
.tree-card:hover{border-color:var(--gold-soft);box-shadow:var(--shadow-hi)}
.tree-card .tname{letter-spacing:.06em}
.tree-card .tdesc{color:#5b544a}

/* ---------- 表格 ---------- */
table.data th{
  font-family:var(--font-serif);letter-spacing:.05em;
  background:linear-gradient(180deg,#f8f1e4,#f2e9d8);
}
table.data td,table.data th{border-bottom:1px solid #f1ead9}
table.data tbody tr:nth-child(even){background:rgba(250,246,238,.5)}
table.data tbody tr:hover{background:#fdf6e9}
table.data tbody tr:last-child td{border-bottom:none}

/* ---------- 徽标 / 标签 ---------- */
.badge{letter-spacing:.03em;padding:3px 9px}
.badge.gen{background:linear-gradient(180deg,#f9f6ef,#f1eee3)}
.badge.rank{background:linear-gradient(180deg,#fdf7e6,#f8efd6)}
.pill{
  border-radius:999px;background:linear-gradient(180deg,#f9f4ea,#f4ede0);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.7);
}
.pill:hover{background:#f2e6cd;border-color:var(--gold-soft);color:var(--red);transform:translateY(-1px)}

/* ---------- 选项卡 ---------- */
.tabbar{gap:2px;scrollbar-width:none}
@media (max-width:700px){
  .tabbar{-webkit-mask-image:linear-gradient(90deg,#000 88%,rgba(0,0,0,.2));mask-image:linear-gradient(90deg,#000 88%,rgba(0,0,0,.2))}
}
.tabbar::-webkit-scrollbar{display:none}
.tabbar a{border-radius:11px 11px 0 0;transition:.18s}
.tabbar a:hover{background:#f6efe1;color:var(--ink-2)}
.tabbar a.active::after{height:3px;border-radius:3px;background:linear-gradient(90deg,var(--red),var(--gold))}

/* ---------- 时间轴 ---------- */
.timeline::before{background:linear-gradient(180deg,rgba(226,161,28,.65),rgba(226,161,28,.12))}
.tl-item::before{box-shadow:0 0 0 3px rgba(226,161,28,.16)}

/* ---------- 字辈派字：印章风 ---------- */
.rank-item{
  position:relative;border-radius:14px;border:1px solid #e7dabe;
  background:linear-gradient(160deg,#fffdf7,#f6eeda);
}
.rank-item::after{
  content:"";position:absolute;inset:5px;border:1px solid rgba(216,56,42,.18);
  border-radius:9px;pointer-events:none;
}
.rank-item .rank-char{text-shadow:0 1px 0 rgba(255,255,255,.55)}

/* ---------- 家训 / 影像 ---------- */
.motto{border-radius:0 10px 10px 0;box-shadow:0 2px 12px -10px rgba(216,56,42,.9)}
.gallery figure{transition:.22s}
.gallery figure:hover{transform:translateY(-2px);border-color:var(--line-2);box-shadow:var(--shadow)}
.gallery img{transition:.35s}
.gallery figure:hover img{transform:scale(1.04)}

/* ---------- 空状态 ---------- */
.empty{
  position:relative;overflow:hidden;
  background:linear-gradient(180deg,#fffdf8,rgba(250,246,238,.55));
  border-radius:var(--radius-lg);
}
.empty::after{
  content:"";position:absolute;right:-62px;bottom:-62px;width:200px;height:200px;border-radius:50%;
  border:1px solid rgba(226,161,28,.18);
  box-shadow:inset 0 0 0 22px rgba(226,161,28,.035);
  pointer-events:none;
}
.dashed-add{border-radius:var(--radius-lg);background:rgba(255,253,248,.55)}

/* ---------- 提示与弹窗 ---------- */
.toast{
  border-radius:12px;background:rgba(34,32,29,.94);backdrop-filter:blur(6px);
  box-shadow:0 16px 36px -16px rgba(0,0,0,.55);letter-spacing:.04em;
}
.modal{border-radius:18px;border:1px solid var(--line);box-shadow:0 28px 60px -22px rgba(80,55,25,.45)}
.footer{background:linear-gradient(180deg,rgba(255,253,248,.55),rgba(246,239,226,.75))}

/* ---------- 树图节点 ---------- */
.node-box rect{filter:drop-shadow(0 1px 1px rgba(80,55,25,.07))}
.node-box:hover rect{stroke:var(--gold);stroke-width:1.8;filter:drop-shadow(0 5px 12px rgba(80,55,25,.24))}
.chart-viewport{border-radius:var(--radius-lg)}

/* ---------- 姓名与文字排印 ---------- */
table.data td.name{font-family:var(--font-serif);letter-spacing:.04em;font-size:15px}
.pill{font-family:var(--font-serif);letter-spacing:.03em}
.tl-item .t{font-family:var(--font-serif);letter-spacing:.03em}
.tree-card .tfoot{border-top:1px dashed rgba(214,204,186,.85);margin-top:14px}

/* ---------- 步骤说明 ---------- */
.steps{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;
  margin-top:20px;padding-top:20px;border-top:1px dashed var(--line);
}
.step{display:flex;gap:10px;align-items:flex-start}
.step .n{
  flex:none;width:27px;height:27px;border-radius:50%;display:grid;place-items:center;
  font-family:var(--font-serif);font-size:15px;font-weight:600;line-height:1;color:#fff;
  background:linear-gradient(145deg,#b53731,#8a2624);
  box-shadow:0 5px 12px -7px rgba(216,56,42,.95);
}
.step b{display:block;font-family:var(--font-serif);font-size:15px;letter-spacing:.06em;margin-bottom:2px}
@media (max-width:760px){.steps{grid-template-columns:minmax(0,1fr);gap:12px}}

/* ---------- 头像相框与入场动效 ---------- */
.avatar{
  border-radius:20px;
  box-shadow:0 3px 12px -6px rgba(80,55,25,.5), inset 0 0 0 4px rgba(255,255,255,.55);
}
@keyframes fadeUp{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
#view.fade{animation:fadeUp .34s cubic-bezier(.22,.7,.3,1)}
.grid > *{animation:fadeUp .4s ease both}
.grid > *:nth-child(2){animation-delay:.05s}
.grid > *:nth-child(3){animation-delay:.1s}
.grid > *:nth-child(4){animation-delay:.15s}
.grid > *:nth-child(n+5){animation-delay:.2s}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
}

/* ---------- 滚动条 ---------- */
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{
  background:#d8cdb6;border-radius:10px;border:3px solid transparent;background-clip:padding-box;
}
::-webkit-scrollbar-thumb:hover{background:#c9bda3;background-clip:padding-box}

/* =========================================================
   贴片式展示 · 多彩配色系统
   ========================================================= */
:root{
  --c-red:#d8382a;--c-gold:#e2a11c;--c-jade:#2b9d63;--c-indigo:#2b7fd4;--c-plum:#7b5294;
}

/* ---------- 统计贴片（彩色图标 + 数字） ---------- */
.stat{display:flex;align-items:center;gap:14px;padding:18px 20px}
/* 正文区必须能收缩：金额那种数字串不会自动断行，
   不给 min-width:0 就会把卡片撑出几像素，再被 overflow:hidden 裁掉 */
.stat>div{flex:1;min-width:0}
.stat .ico{
  flex:none;width:42px;height:42px;border-radius:13px;display:grid;place-items:center;
  font-family:var(--font-serif);font-size:19px;font-weight:700;color:#fff;letter-spacing:0;
}
.stat .num{font-size:26px;line-height:1.15;margin:0;overflow-wrap:anywhere}
.stat .label{margin-top:1px}
.stat.c1{background:linear-gradient(150deg,#fdf5f1,#f8eee6)}
.stat.c1 .ico{background:linear-gradient(145deg,#ee6a56,#d8382a);box-shadow:0 7px 14px -8px rgba(216,56,42,.85)}
.stat.c1 .num{background:linear-gradient(180deg,#b24540,#8a2a26);-webkit-background-clip:text;background-clip:text;color:transparent}
.stat.c2{background:linear-gradient(150deg,#fdf9ef,#f7efdc)}
.stat.c2 .ico{background:linear-gradient(145deg,#c9a25a,#a97f2f);box-shadow:0 7px 14px -8px rgba(226,161,28,.85)}
.stat.c2 .num{background:linear-gradient(180deg,#a4792b,#7c5a1c);-webkit-background-clip:text;background-clip:text;color:transparent}
.stat.c3{background:linear-gradient(150deg,#f2f8f4,#e9f2ec)}
.stat.c3 .ico{background:linear-gradient(145deg,#5a9a75,#2b9d63);box-shadow:0 7px 14px -8px rgba(43,157,99,.85)}
.stat.c3 .num{background:linear-gradient(180deg,#2b9d63,#1c7a4a);-webkit-background-clip:text;background-clip:text;color:transparent}
.stat.c4{background:linear-gradient(150deg,#f1f5f9,#e8eff5)}
.stat.c4 .ico{background:linear-gradient(145deg,#5aa3e8,#2b7fd4);box-shadow:0 7px 14px -8px rgba(43,127,212,.85)}
.stat.c4 .num{background:linear-gradient(180deg,#2b7fd4,#1a5a9e);-webkit-background-clip:text;background-clip:text;color:transparent}
.stat.c5{background:linear-gradient(150deg,#f8f4fa,#f0e9f5)}
.stat.c5 .ico{background:linear-gradient(145deg,#9a76b3,#7b5294);box-shadow:0 7px 14px -8px rgba(123,82,148,.85)}
.stat.c5 .num{background:linear-gradient(180deg,#7b5294,#5c3c70);-webkit-background-clip:text;background-clip:text;color:transparent}

/* ---------- 族谱卡多彩轮换（data-hue 0-4） ---------- */
.tree-card[data-hue="1"]{background:linear-gradient(165deg,#fefaf2,#f7eeda)}
.tree-card[data-hue="1"]::before{background:linear-gradient(180deg,#e2a11c,#f3c25c 55%,rgba(216,56,42,.4))}
.tree-card[data-hue="1"] .orn{border-color:rgba(226,161,28,.34)}
.tree-card[data-hue="2"]{background:linear-gradient(165deg,#f9fdfa,#eef5f0)}
.tree-card[data-hue="2"]::before{background:linear-gradient(180deg,#2b9d63,#4dbb87 55%,rgba(226,161,28,.4))}
.tree-card[data-hue="2"] .orn{border-color:rgba(43,157,99,.3)}
.tree-card[data-hue="3"]{background:linear-gradient(165deg,#f9fbfd,#eef3f7)}
.tree-card[data-hue="3"]::before{background:linear-gradient(180deg,#2b7fd4,#5aa3e8 55%,rgba(226,161,28,.4))}
.tree-card[data-hue="3"] .orn{border-color:rgba(43,127,212,.3)}
.tree-card[data-hue="4"]{background:linear-gradient(165deg,#fbf9fc,#f3eef7)}
.tree-card[data-hue="4"]::before{background:linear-gradient(180deg,#7b5294,#9a76b3 55%,rgba(226,161,28,.4))}
.tree-card[data-hue="4"] .orn{border-color:rgba(123,82,148,.3)}

/* ---------- 标签多彩 ---------- */
.tag.h0{background:#faecea;color:#d8382a;border-color:#eed2cf}
.tag.h1{background:#faf3e2;color:#96712c;border-color:#eadfc6}
.tag.h2{background:#ecf3ee;color:#2b9d63;border-color:#d3e5d9}
.tag.h3{background:#ecf2f7;color:#2b7fd4;border-color:#d3e2ee}
.tag.h4{background:#f4eff8;color:#7b5294;border-color:#e4d9ee}

/* ---------- 族人贴片 ---------- */
.member-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(236px,100%),1fr));gap:14px}
.member-tile{
  position:relative;display:flex;gap:13px;padding:15px 16px 14px 19px;border-radius:16px;
  background:linear-gradient(165deg,#fffdf8,#fbf6ec);border:1px solid var(--line);
  box-shadow:var(--shadow);transition:.2s;overflow:hidden;
}
.member-tile::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:4px;
  background:var(--tc,var(--c-gold));
}
.member-tile:hover{transform:translateY(-3px);box-shadow:var(--shadow-hi);border-color:var(--tc,var(--gold-soft))}
.member-tile .mt-ava{
  flex:none;width:46px;height:46px;border-radius:14px;display:grid;place-items:center;
  font-family:var(--font-serif);font-size:21px;font-weight:700;color:#fff;letter-spacing:0;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.25);
}
.member-tile.gm{--tc:var(--c-indigo)}
.member-tile.gm .mt-ava{background:linear-gradient(145deg,#5aa3e8,#33607f)}
.member-tile.gf{--tc:var(--c-red)}
.member-tile.gf .mt-ava{background:linear-gradient(145deg,#ee6a56,#d8382a)}
.member-tile.gu{--tc:#8a8279}
.member-tile.gu .mt-ava{background:linear-gradient(145deg,#b0a898,#8a8279)}
.member-tile .mt-name{font-family:var(--font-serif);font-size:17px;font-weight:700;letter-spacing:.03em;line-height:1.3}
.member-tile .mt-alias{font-family:var(--font-sans);font-size:12px;font-weight:400;color:var(--ink-3)}
.member-tile .mt-tags{display:flex;gap:5px;flex-wrap:wrap;margin-top:6px}
.member-tile .mt-line{font-size:12.5px;color:var(--ink-3);margin-top:5px;line-height:1.5}
.member-tile .mt-line:first-of-type{color:var(--ink-2)}
@media (max-width:560px){.member-grid{grid-template-columns:repeat(auto-fill,minmax(min(150px,100%),1fr));gap:10px}}

/* =========================================================
   会员账号：登录页 / 用户菜单 / 账号中心
   ========================================================= */
/* ---------- 登录外壳 ---------- */
.is-auth-page .footer{display:none}
.is-auth-page .main{display:flex;align-items:center;justify-content:center;min-height:calc(100vh - 64px);padding:40px 20px 56px}
.auth-wrap{width:100%;max-width:428px}
.auth-card{
  position:relative;overflow:hidden;
  padding:30px 30px 26px;border-radius:22px;
  background:linear-gradient(170deg,#fffdf8,#fbf3e5);
  border:1px solid var(--line);
  box-shadow:0 2px 4px rgba(80,55,25,.04), 0 26px 54px -28px rgba(80,55,25,.5);
}
.auth-card::before{
  content:"";position:absolute;left:0;top:0;right:0;height:4px;
  background:linear-gradient(90deg,var(--c-red),var(--c-gold) 55%,var(--c-jade));
}
.auth-card::after{
  content:"";position:absolute;right:-56px;bottom:-56px;width:180px;height:180px;border-radius:50%;
  border:1px solid rgba(226,161,28,.18);box-shadow:inset 0 0 0 20px rgba(226,161,28,.04);
  pointer-events:none;
}
.auth-brand{display:flex;align-items:center;gap:12px;margin-bottom:20px;position:relative}
.auth-brand .seal{
  width:44px;height:44px;border-radius:13px;display:grid;place-items:center;
  font-family:var(--font-serif);font-size:22px;color:#fff;letter-spacing:0;
  background:linear-gradient(145deg,#b53731,#a82318);
  box-shadow:0 8px 18px -9px rgba(216,56,42,.95), inset 0 1px 0 rgba(255,255,255,.25);
}
.auth-brand h1{font-size:23px;letter-spacing:.14em;line-height:1.2}
.auth-sub{font-size:12px;color:var(--ink-3);letter-spacing:.16em;margin-top:2px}
.auth-tabs{display:flex;gap:4px;padding:4px;margin-bottom:18px;background:#f3ebdb;border-radius:12px;position:relative}
.auth-tabs a{
  flex:1;text-align:center;padding:8px 0;border-radius:9px;font-size:14px;color:var(--ink-2);transition:.18s;
}
.auth-tabs a.on{
  background:linear-gradient(180deg,#fff,#fffaf0);color:var(--red);font-weight:600;
  box-shadow:0 3px 10px -6px rgba(80,55,25,.55);
}
.auth-msg{
  display:none;margin-bottom:14px;padding:9px 12px;border-radius:10px;font-size:13px;
  background:#fbeceb;border:1px solid #f0d5d3;color:#d8382a;
}
.auth-msg.show{display:block;animation:fadeUp .22s ease}
.auth-msg.ok{background:#eef5ee;border-color:#d8e8dc;color:#2f6b41}
.auth-card .field label{font-size:13px}
.auth-card .input{padding:10px 12px}
.pw-wrap{position:relative}
.pw-wrap .input{padding-right:38px}
.pw-eye{
  position:absolute;right:6px;top:50%;transform:translateY(-50%);
  height:28px;padding:0 8px;border:none;background:transparent;color:var(--ink-3);
  cursor:pointer;font-size:12px;border-radius:8px;letter-spacing:.04em;
}
.pw-eye:hover{background:#f3ebdb;color:var(--ink-2)}
.pw-eye.on{color:var(--red)}
.acct-meta{display:grid;gap:9px;margin-top:18px}
.acct-meta > div{
  display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  font-size:13px;padding-bottom:8px;border-bottom:1px dashed var(--line);
}
.acct-meta > div:last-child{border-bottom:none;padding-bottom:0}
.acct-meta span{color:var(--ink-3);flex:none}
.acct-meta b{font-weight:500;color:var(--ink-2);text-align:right}
.remember{display:flex;align-items:center;gap:7px;font-size:13px;color:var(--ink-2);margin:2px 0 16px;cursor:pointer}
.remember input{accent-color:var(--red)}
.btn.block{width:100%;justify-content:center;padding:11px 16px;font-size:15px;letter-spacing:.18em}
.auth-links{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:16px;font-size:13px;color:var(--ink-3);flex-wrap:wrap}
.auth-links a{color:var(--red)}
.auth-links a:hover{text-decoration:underline}
.auth-hint{
  margin-top:18px;padding-top:14px;border-top:1px dashed var(--line);
  font-size:12px;color:var(--ink-3);line-height:1.7;
}
.auth-foot{text-align:center;font-size:12px;color:var(--ink-3);margin-top:18px;letter-spacing:.04em}

.strength{display:flex;align-items:center;gap:5px;margin:-4px 0 16px}
.strength i{width:26px;height:4px;border-radius:3px;background:#e9e1d1;transition:.2s}
.strength i.lv1{background:#ee6a56}
.strength i.lv2{background:#e2a11c}
.strength i.lv3{background:#2b9d63}
.strength i.lv4{background:#2b7fd4}
.strength span{margin-left:6px}

/* ---------- 顶栏用户菜单 ---------- */
.user-menu{position:relative}
.user-chip{
  display:inline-flex;align-items:center;gap:7px;padding:4px 11px 4px 5px;cursor:pointer;
  border-radius:999px;border:1px solid var(--line-2);background:linear-gradient(180deg,#fff,#fdf8ee);
  font-size:13px;color:var(--ink-2);transition:.18s;
}
.user-chip:hover{border-color:var(--gold-soft);box-shadow:0 6px 14px -10px rgba(80,55,25,.6)}
.user-chip .ava{
  width:24px;height:24px;border-radius:50%;display:grid;place-items:center;
  font-family:var(--font-serif);font-size:11px;color:#fff;letter-spacing:0;
  background:linear-gradient(145deg,#b53731,#a82318);
}
.user-chip .nm{max-width:88px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.user-chip .caret{font-size:9px;color:var(--ink-3);margin-left:-1px}
.user-chip:hover .caret{color:var(--ink-2)}
.user-drop{
  position:absolute;right:0;top:calc(100% + 10px);width:198px;z-index:60;
  padding:8px;border-radius:14px;border:1px solid var(--line);
  background:linear-gradient(180deg,#fffdf8,#fffaf1);
  box-shadow:0 18px 38px -18px rgba(80,55,25,.45);
  opacity:0;visibility:hidden;transform:translateY(-6px);transition:.18s;
}
.user-drop.open{opacity:1;visibility:visible;transform:none}
.user-drop .ud-head{padding:8px 10px 10px;border-bottom:1px dashed var(--line);margin-bottom:6px}
.user-drop .ud-head b{font-family:var(--font-serif);font-size:15px}
.user-drop a,.user-drop button{
  display:block;width:100%;text-align:left;padding:8px 10px;border-radius:9px;border:none;
  background:transparent;font-size:13px;color:var(--ink-2);cursor:pointer;
}
.user-drop a:hover,.user-drop button:hover{background:#f5ecdc;color:var(--ink)}
.user-drop button[data-act="logout"]{color:var(--red)}
.user-drop button[data-act="logout"]:hover{background:#fbeceb}
@media (max-width:700px){
  .user-chip .nm{display:none}
  .user-chip{padding:4px}
  .user-chip .ava{width:26px;height:26px;font-size:12px}
}

/* ---------- 账号中心 ---------- */
.acct-hero{display:flex;align-items:center;gap:14px}
.acct-ava{
  width:62px;height:62px;flex:none;border-radius:18px;display:grid;place-items:center;
  font-family:var(--font-serif);font-size:23px;color:#fff;letter-spacing:0;
  background:linear-gradient(145deg,#b53731,#a82318);
  box-shadow:0 10px 22px -12px rgba(216,56,42,.9), inset 0 1px 0 rgba(255,255,255,.25);
}
.acct-hero h2{letter-spacing:.04em}

/* =========================================================
   后台管理
   ========================================================= */
.adm-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap}
.adm-head-actions{display:flex;gap:8px;flex-wrap:wrap;padding-bottom:4px}

/* 后台专属外壳 */
.adm-tag{
  font-size:11px;letter-spacing:.08em;color:#7a5c2a;background:#fbf1dc;border:1px solid var(--gold-soft);
  padding:3px 8px;border-radius:999px;white-space:nowrap;
}
.adm-who{display:flex;align-items:center;gap:7px;padding:0 4px}
.adm-who .ava{
  width:26px;height:26px;border-radius:50%;display:grid;place-items:center;font-size:11px;
  background:linear-gradient(160deg,#8f2b22,#6d1d16);color:#f7e7c4;flex:none;
}
.adm-who .nm{font-size:13px;color:var(--ink);max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.adm-entry{font-size:12px;color:#8a6a3a}
.adm-entry:hover{color:var(--red)}

/* 权限勾选 */
.perm-grid{display:grid;gap:8px;margin-top:8px}
@media (min-width:640px){.perm-grid{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
.perm-item{
  display:flex;gap:9px;align-items:flex-start;padding:9px 11px;border-radius:10px;
  border:1px solid var(--line);background:#fffdf8;cursor:pointer;transition:.16s;
}
.perm-item:hover{border-color:var(--gold-soft);background:#fdf6e8}
.perm-item input{accent-color:var(--red);margin-top:2px;flex:none}
.perm-item b{display:block;font-size:13px;color:var(--ink)}
.perm-item em{display:block;font-style:normal;font-size:11px;color:var(--ink-3);line-height:1.5;margin-top:2px}
.perm-item input:checked ~ span b{color:var(--red)}

/* 权限级别：无 / 查看 / 编辑 */
.perm-levels{display:grid;gap:8px;margin-top:8px}
.perm-row{
  display:flex;gap:12px;align-items:center;justify-content:space-between;flex-wrap:wrap;
  padding:10px 12px;border:1px solid var(--line);border-radius:10px;background:#fffdf8;
}
.perm-info{min-width:180px;flex:1}
.perm-info b{display:block;font-size:13px;color:var(--ink)}
.perm-info em{display:block;font-style:normal;font-size:11px;color:var(--ink-3);line-height:1.55}
.perm-row:has(input[value="view"]:checked) .perm-info b,
.perm-row:has(input[value="edit"]:checked) .perm-info b{color:var(--red)}
.seg{display:inline-flex;border:1px solid var(--line-2);border-radius:999px;overflow:hidden;background:#fff;flex:none}
.seg label{position:relative;font-size:12px;padding:5px 13px;cursor:pointer;color:var(--ink-2);border-left:1px solid var(--line)}
.seg label:first-child{border-left:0}
.seg label input{position:absolute;opacity:0;pointer-events:none}
.seg label.on{background:linear-gradient(180deg,#d8382a,#8f2b22);color:#fff}

/* 族谱管理员 */
.mgr-list{display:grid;gap:6px;margin-top:4px}
.mgr-row{
  display:flex;align-items:center;gap:10px;padding:8px 10px;
  border:1px solid var(--line);border-radius:10px;background:#fffdf8;
}
.mgr-ava{
  width:26px;height:26px;border-radius:50%;display:grid;place-items:center;
  background:#f3ead9;color:#8a6a3a;font-size:12px;flex:none;
}
.mgr-nm{display:flex;flex-direction:column;font-size:13px;flex:1;min-width:0}
.mgr-nm em{font-style:normal;font-size:11px;color:var(--ink-3)}
.mgr-add{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap}
.mgr-add .input{flex:1;min-width:180px}

/* 族谱编码展示 */
.tree-code{
  font-family:var(--font-mono,ui-monospace,SFMono-Regular,Menlo,monospace);
  font-size:12px;letter-spacing:.08em;color:var(--ink-2);
  background:#f6f1e6;border:1px solid var(--line);border-radius:4px;padding:1px 6px;white-space:nowrap;
}

/* 会员表：可建谱数的行内编辑入口 */
.lim-edit{
  color:var(--red);text-decoration:none;border-bottom:1px dashed rgba(216,56,42,.45);
  padding-bottom:1px;cursor:pointer;white-space:nowrap;
}
.lim-edit:hover{border-bottom-color:var(--red)}
.lim-edit::after{content:' ✎';font-size:10px;opacity:.7}

/* 族谱家庭账号的账号口令展示 */
.fam-cred{
  margin-top:14px;border:1px solid var(--line-2);border-radius:12px;overflow:hidden;
  background:linear-gradient(180deg,#fffdf7,#f8f2e4);
}
.fc-row{
  display:flex;align-items:center;gap:12px;padding:10px 14px;
  border-bottom:1px solid var(--line);
}
.fc-row:last-child{border-bottom:0}
.fc-row span{width:76px;flex:none;font-size:13px;color:var(--ink-3)}
.fc-row code{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:14px;
  color:var(--red);letter-spacing:.06em;user-select:all;word-break:break-all;
}

.adm-login-card{max-width:430px}
@media (max-width:560px){
  .adm-tag{display:none}
  .adm-who .nm{display:none}
  .adm-login-card{padding:26px 20px 22px}
  .is-auth-page .auth-wrap{max-width:100%}
  .is-auth-page .main{padding:24px 14px 36px}
}
.adm-notice{
  padding:10px 14px;border-radius:12px;font-size:13px;line-height:1.7;
  background:linear-gradient(170deg,#fffdf3,#f9f1dc);
  border:1px solid var(--gold-soft);color:#7a5e2a;
}
.adm-kv{display:grid;gap:9px;margin-top:4px}
.adm-kv > div{
  display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  font-size:13px;padding-bottom:8px;border-bottom:1px dashed var(--line);
}
.adm-kv > div:last-child{border-bottom:none;padding-bottom:0}
.adm-kv span{color:var(--ink-3);flex:none}
.adm-kv b{font-weight:500;color:var(--ink-2);text-align:right}

.adm-list{display:grid;gap:4px;margin-top:4px}
.adm-row{display:flex;align-items:baseline;gap:10px;padding:9px 10px;border-radius:10px;border:1px solid transparent;transition:.16s;flex-wrap:wrap}
.adm-row:hover{background:#fdf6e8;border-color:var(--line)}
.adm-row b{font-family:var(--font-serif);font-size:14.5px;flex:none;max-width:44%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 中间那段（操作对象、账号名）可能很长，得允许它收缩并自己折行，
   否则一行三截挤不开，整行就被顶出容器 */
.adm-row span{min-width:0;overflow-wrap:anywhere}
.adm-row span:last-child{margin-left:auto;flex:none}

.adm-chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:4px}
.adm-chip{display:flex;align-items:baseline;gap:7px;padding:7px 11px;border-radius:10px;background:#faf4e8;border:1px solid var(--line)}
.adm-chip b{font-family:var(--font-serif);font-size:13.5px}

.adm-filter{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.adm-filter .input{max-width:250px}

.adm-switch{display:grid;gap:8px;margin-top:4px}
@media (min-width:780px){.adm-switch{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
.sw{
  display:flex;gap:10px;align-items:flex-start;padding:11px 13px;border-radius:12px;
  border:1px solid var(--line);background:#fffdf7;cursor:pointer;transition:.16s;
}
.sw:hover{border-color:var(--gold-soft);background:#fffaf0}
.sw input{margin-top:3px;accent-color:var(--red);flex:none;width:15px;height:15px}
.sw b{display:block;font-size:13.5px;font-weight:600;color:var(--ink)}
.sw em{display:block;font-style:normal;font-size:12px;color:var(--ink-3);margin-top:2px;line-height:1.55}

.adm-bulk{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:12px;
  padding:10px 12px;border-radius:12px;font-size:13px;
  background:linear-gradient(170deg,#fffdf5,#f9f0da);border:1px solid var(--gold-soft);color:#6f5322;
}
.adm-bulk[hidden]{display:none}
.adm-bulk b{color:var(--red);margin:0 2px}
.bulk-all{display:inline-flex;align-items:center;gap:6px;cursor:pointer;user-select:none}
.bulk-all input{width:15px;height:15px;accent-color:var(--red);cursor:pointer}
.bulk-sep{width:1px;height:16px;background:var(--gold-soft);margin:0 2px}
th.bulk-col,td.bulk-col{width:38px;text-align:center;padding-left:6px;padding-right:6px}
td.bulk-col input{width:15px;height:15px;accent-color:var(--red);cursor:pointer}
.data tr.picked > td{background:#fff8e9}

.pager{
  display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
  margin-top:12px;padding-top:12px;border-top:1px dashed var(--line);
}
.pager-btns{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.pager-num,.pager-cur{
  min-width:32px;height:32px;padding:0 8px;border-radius:8px;
  display:inline-flex;align-items:center;justify-content:center;
  font-size:13px;line-height:1;
}
.pager-num{
  border:1px solid var(--line);background:#fff;color:var(--ink);text-decoration:none;
}
.pager-num:hover{border-color:var(--red);color:var(--red);background:#fff6f2}
.pager-cur{
  background:linear-gradient(160deg,#b8362a,#93261c);color:#fff;
  border:1px solid transparent;font-weight:600;
}
.pager-gap{color:var(--ink-3);padding:0 2px}
.badge.sup{background:linear-gradient(180deg,#fdf3dd,#f6e2b6);color:#8a5a12;border-color:#e6cb92}

/* 会员状态：待审核 / 已拒绝 */
.badge.warn{background:linear-gradient(180deg,#fdf6e3,#f8ecc8);color:#8a6212;border-color:#e7d29a}
.badge.danger{background:linear-gradient(180deg,#fbe9e7,#f6dcd9);color:#8f2b22;border-color:#eec7c2}
.sw.warn{background:#fffaf1;border-color:#eed9b3}
.sw.warn b{color:#8a5a12}
.req{color:var(--red);font-weight:600}
.auth-hint.warn{background:#fdf4e6;border-color:var(--gold-soft);color:#7a5e2a}

.adm-choose{display:grid;gap:6px;margin-top:12px;max-height:260px;overflow:auto}
.adm-choose label{
  display:flex;gap:9px;align-items:center;padding:9px 11px;border-radius:10px;
  border:1px solid var(--line);cursor:pointer;font-size:13px;transition:.16s;
}
.adm-choose label:hover{background:#fdf6e8;border-color:var(--gold-soft)}
.adm-choose input{accent-color:var(--red);flex:none}
.nowrap{white-space:nowrap}

/* ---------- 详情页头像按性别染色 ---------- */
.avatar.am{background:linear-gradient(160deg,#eef4f9,#dce8f1);color:#2b7fd4;border-color:#cfe0ec}
.avatar.af{background:linear-gradient(160deg,#fdf0ee,#f7dedb);color:#d8382a;border-color:#eed2cf}
.avatar.au{background:linear-gradient(160deg,#f7f4ed,#ede8dd);color:#8a8279}

/* ---------- 始祖胶囊（多彩轮换） ---------- */
.pill-row{display:flex;flex-wrap:wrap;gap:10px}
.pill-row .pill:nth-child(5n+1){background:#faecea;border-color:#eed2cf;color:var(--c-red)}
.pill-row .pill:nth-child(5n+2){background:#faf3e2;border-color:#eadfc6;color:#96712c}
.pill-row .pill:nth-child(5n+3){background:#ecf3ee;border-color:#d3e5d9;color:var(--c-jade)}
.pill-row .pill:nth-child(5n+4){background:#ecf2f7;border-color:#d3e2ee;color:var(--c-indigo)}
.pill-row .pill:nth-child(5n){background:#f4eff8;border-color:#e4d9ee;color:var(--c-plum)}
.pill-row .pill .small{color:inherit;opacity:.7}

/* ---------- 房支贴片（多彩左边条） ---------- */
.branch-tile{
  border:1px solid var(--line);border-left:3px solid var(--c-red);border-radius:12px;
  padding:13px 15px;background:linear-gradient(165deg,#fffdf8,#faf5ec);
}
.branch-tile:nth-child(5n+2){border-left-color:var(--c-gold)}
.branch-tile:nth-child(5n+3){border-left-color:var(--c-jade)}
.branch-tile:nth-child(5n+4){border-left-color:var(--c-indigo)}
.branch-tile:nth-child(5n){border-left-color:var(--c-plum)}
.branch-box{border-left:3px solid var(--c-red)}
.branch-box:nth-child(5n+2){border-left-color:var(--c-gold)}
.branch-box:nth-child(5n+3){border-left-color:var(--c-jade)}
.branch-box:nth-child(5n+4){border-left-color:var(--c-indigo)}
.branch-box:nth-child(5n){border-left-color:var(--c-plum)}

/* ---------- 字辈派字多彩轮换 ---------- */
.rank-row .rank-item:nth-child(5n+2){background:linear-gradient(160deg,#fefaf2,#f5edda);border-color:#e5d8b8}
.rank-row .rank-item:nth-child(5n+2) .rank-char{color:var(--c-gold)}
.rank-row .rank-item:nth-child(5n+2)::after{border-color:rgba(226,161,28,.22)}
.rank-row .rank-item:nth-child(5n+3){background:linear-gradient(160deg,#f9fcfa,#eaf3ee);border-color:#d3e5d9}
.rank-row .rank-item:nth-child(5n+3) .rank-char{color:var(--c-jade)}
.rank-row .rank-item:nth-child(5n+3)::after{border-color:rgba(43,157,99,.2)}
.rank-row .rank-item:nth-child(5n+4){background:linear-gradient(160deg,#f9fbfd,#ecf2f7);border-color:#d3e2ee}
.rank-row .rank-item:nth-child(5n+4) .rank-char{color:var(--c-indigo)}
.rank-row .rank-item:nth-child(5n+4)::after{border-color:rgba(43,127,212,.2)}
.rank-row .rank-item:nth-child(5n){background:linear-gradient(160deg,#fbf9fc,#f3edf8);border-color:#e4d9ee}
.rank-row .rank-item:nth-child(5n) .rank-char{color:var(--c-plum)}
.rank-row .rank-item:nth-child(5n)::after{border-color:rgba(123,82,148,.2)}

/* ---------- 世代分布条多彩 ---------- */
.gen-bar{height:10px;border-radius:6px;overflow:hidden;background:#f2ece0;display:block}

/* ---------- 打印微调 ---------- */
@media print{.member-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}

/* ============ 打印（可将族谱另存为 PDF） ============ */
@media print{
  *{animation:none!important;transition:none!important}
  .topbar,.footer,.toast,.modal-root,.chart-toolbar,.topbar-actions{display:none!important}
  body{background:#fff}
  body::before{display:none}
  .main{max-width:none;padding:0}
  .card,.stat,.tree-card{box-shadow:none;break-inside:avoid}
  .tabbar{display:none}
  .chart-viewport{height:auto;min-height:0;overflow:visible;border:none}
  a{color:#000}
  .btn{display:none}
}

/* ============ 平台首页：最新事件 + 数据概览 ============ */
.portal{max-width:1080px;margin:0 auto;padding:0 4px}
.wrap-narrow{max-width:860px;margin-left:auto;margin-right:auto}
.portal-head{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;padding:6px 0 2px}
.portal-head h1{font-family:var(--font-serif);font-size:27px;font-weight:700;letter-spacing:.05em;margin:0}
.portal-tag{font-size:14px;color:var(--gold);border-left:1px solid var(--line-2);padding-left:12px}
.portal-hi{width:100%;margin:4px 0 0;font-size:13px;color:var(--ink-3)}

.sec{margin-top:26px}
.sec-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin:0 0 12px}
.sec-head h2{position:relative;margin:0;padding-left:12px;font-family:var(--font-serif);
  font-size:18px;font-weight:700;letter-spacing:.04em}
.sec-head h2:before{content:"";position:absolute;left:0;top:.42em;bottom:.42em;width:3px;
  border-radius:2px;background:linear-gradient(180deg,var(--gold),var(--gold-soft))}
.sec-head .small{color:var(--ink-3)}
.empty-lite{padding:26px 18px;text-align:center;color:var(--ink-3);font-size:14px}

/* 事件列表 */
.ev-list{padding:6px 18px}
.ev-row{display:flex;align-items:center;gap:12px;padding:13px 0;border-bottom:1px solid var(--line)}
.ev-row:last-child{border-bottom:none}
.ev-row.is-top .ev-title{font-weight:700}
.ev-dot{width:8px;height:8px;border-radius:50%;background:var(--line-2);flex:0 0 auto}
.ev-dot.soon{background:var(--red);box-shadow:0 0 0 3px rgba(216,56,42,.14)}
.ev-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.ev-title{font-size:14.5px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ev-sub{font-size:12.5px;color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ev-tag{flex:0 0 auto;padding:2px 9px;border-radius:999px;font-size:12px;
  background:#f4eddd;color:var(--gold);border:1px solid #ece0c8}
.ev-time{flex:0 0 auto;text-align:right;font-size:13px;color:var(--ink-2);min-width:64px}
.ev-time em{display:block;font-style:normal;font-size:11.5px;color:var(--ink-3)}

/* 板块统计卡片 */
.app-grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(min(268px,100%),1fr))}
.app-card{position:relative;overflow:hidden;display:flex;flex-direction:column;
  padding:18px 20px 16px;border-radius:var(--radius);text-decoration:none;color:inherit;
  background:var(--paper-2);border:1px solid var(--line);box-shadow:var(--shadow);transition:.2s}
.app-card:hover{transform:translateY(-3px);box-shadow:var(--shadow-lg);border-color:var(--line-2)}
.app-card .orn{position:absolute;right:-28px;top:-28px;width:104px;height:104px;border-radius:50%;
  border:1px solid rgba(226,161,28,.24);box-shadow:inset 0 0 0 11px rgba(243,233,214,.35);
  transition:.3s;pointer-events:none}
.app-card:hover .orn{transform:scale(1.08)}
.app-card.is-off{background:#f7f4ee;border-style:dashed;box-shadow:none}
.app-card.is-off:hover{transform:none;box-shadow:none}
.app-head{display:flex;align-items:center;gap:9px;position:relative}
/* 图标用实心渐变，不用淡彩：淡彩在白卡上几乎看不出颜色，
   整页就剩一片米白。实心才立得住 */
.app-ico{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;
  border-radius:10px;background:linear-gradient(145deg,var(--gold),var(--gold-deep));
  color:#fff;border:1px solid transparent;flex:0 0 auto;
  box-shadow:0 8px 18px -10px rgba(226,161,28,.95)}
.app-card[data-hue="1"] .app-ico{background:linear-gradient(145deg,var(--blue),#1a5a9e);
  color:#fff;box-shadow:0 8px 18px -10px rgba(43,127,212,.95)}
.app-card[data-hue="2"] .app-ico{background:linear-gradient(145deg,var(--green),#1c7a4a);
  color:#fff;box-shadow:0 8px 18px -10px rgba(43,157,99,.95)}
.app-card[data-hue="3"] .app-ico{background:linear-gradient(145deg,var(--red-soft),var(--red) 45%,var(--red-deep));
  color:#fff;box-shadow:0 8px 18px -10px rgba(216,56,42,.95)}
.app-name{font-family:var(--font-serif);font-size:18px;font-weight:700;letter-spacing:.04em}
.app-desc{margin-top:8px;font-size:13px;color:var(--ink-3);line-height:1.6;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.app-stats{margin-top:14px;display:flex;gap:18px;flex-wrap:wrap}
.app-stats .stat{display:flex;flex-direction:column;line-height:1.25}
.app-stats b{font-family:var(--font-serif);font-size:20px;color:var(--ink)}
.app-stats span{font-size:12px;color:var(--ink-3)}
.app-foot{margin-top:14px;font-size:12.5px;color:var(--ink-3)}

@media (max-width:640px){
  .portal-head h1{font-size:22px}
  .app-grid{grid-template-columns:minmax(0,1fr)}
  .ev-time{min-width:52px}
  .ev-sub{display:none}
}

/* ============ 礼簿 ============ */
.gwrap{max-width:1080px;margin:0 auto}
.ghead{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;flex-wrap:wrap}
.ghead h1{margin:0 0 4px}
.ghead p{margin:0}
.ghead-act{display:flex;gap:8px;flex-wrap:wrap}

/* 收礼 / 送礼 标签 */
.gtag{display:inline-block;padding:2px 9px;border-radius:999px;font-size:12px;
  border:1px solid #d8e3d6;background:#eaf0e9;color:var(--green);vertical-align:middle}
.gtag.out{border-color:#eed8d6;background:#f5e9e8;color:var(--red)}
.gtag.in{border-color:#d8e3d6;background:#eaf0e9;color:var(--green)}

/* 统计条 */
.gov{display:grid;gap:12px;grid-template-columns:repeat(4,minmax(0,1fr));margin:16px 0 0}
.gov .gov-item{display:flex;flex-direction:column;gap:2px;padding:14px 16px;border-radius:var(--radius);
  background:var(--paper-2);border:1px solid var(--line);box-shadow:var(--shadow)}
.gov .gov-lab{font-size:12px;color:var(--ink-3)}
.gov .gov-item b{font-family:var(--font-serif);font-size:22px;line-height:1.2}
.gov .gov-item em{font-style:normal;font-size:12px;color:var(--ink-3)}
.gov.sm{grid-template-columns:repeat(3,minmax(0,1fr))}
.gov.sm .gov-item b{font-size:19px}
.gov .in{color:var(--green)}
.gov .out{color:var(--red)}

/* 标签页 */
.gtabs{display:flex;gap:6px;margin:22px 0 14px;border-bottom:1px solid var(--line)}
.gtab{padding:8px 16px;font-size:14px;color:var(--ink-2);text-decoration:none;
  border-bottom:2px solid transparent;margin-bottom:-1px}
.gtab:hover{color:var(--ink)}
.gtab.on{color:var(--gold);border-bottom-color:var(--gold);font-weight:600}

/* 宴事卡片 */
.gcard-list{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(min(290px,100%),1fr))}
.gcard{display:flex;flex-direction:column;padding:16px 18px;border-radius:var(--radius);
  background:var(--paper-2);border:1px solid var(--line);box-shadow:var(--shadow);
  text-decoration:none;color:inherit;transition:.2s}
.gcard:hover{transform:translateY(-2px);box-shadow:var(--shadow-lg);border-color:var(--line-2)}
.gcard-hd{display:flex;align-items:center;gap:8px}
.gcard-nm{font-family:var(--font-serif);font-size:18px;font-weight:700;letter-spacing:.03em}
.gcard-sub{margin-top:6px;font-size:13px;color:var(--ink-3)}
.gcard-ft{margin-top:12px;display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.gcard-ft b{font-size:19px;color:#8a6d3b}
.gcard-ft span{font-size:12.5px;color:var(--ink-3)}

/* 表格 */
.gtable{width:100%;border-collapse:collapse;font-size:14px}
.gtable th{text-align:left;font-weight:600;font-size:12.5px;color:var(--ink-3);
  padding:8px 10px;border-bottom:1px solid var(--line-2);white-space:nowrap}
/* 单元格不换行。表头和内容都允许折行的话，浏览器会把名字、
   日期这些短字段压成一条竖线去迁就长地址——一行字叠成一个字一行的竖条 */
.gtable td{padding:11px 10px;border-bottom:1px solid var(--line);vertical-align:middle;
  white-space:nowrap}
/* 副说明（地址、微信、备注）本来就是长文本，允许它折行 */
.gtable td em{white-space:normal}
/* 表格比容器宽时横滑，不硬挤 */
.gtable-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}

/* 后台的表格用 .tbl，此前 CSS 里压根没给它写过样式——没有 nowrap，
   也没有横滑容器。窄屏上短字段被压成一字一行的竖条，整张表还撑破容器 */
.tbl{width:100%;border-collapse:collapse;font-size:13.5px}
.tbl th{text-align:left;font-weight:600;font-size:12.5px;color:var(--ink-3);
  padding:8px 10px;border-bottom:1px solid var(--line-2);white-space:nowrap}
.tbl td{padding:9px 10px;border-bottom:1px solid var(--line);
  vertical-align:middle;white-space:nowrap}
.tbl td em{white-space:normal}
/* 装修页：页面 / 端的挑选按钮组 */
.decor-pick{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
/* 已隐藏的区块整行淡掉，一眼能看出哪些不显示 */
.tbl tr.is-off td{opacity:.45}
.tbl tr.is-off td .btn{opacity:1}

/* 列多的表格（≥5 列，渲染时由 JS 打上 .tbl-card，
   并把表头文字分发到每一格）在窄屏一律拆成一条一张卡：字段名在左、值在右。
   竖排的表格再怎么横滑，短字段也免不了被压成一字一行的竖条——
   与其让地址去挤名字、让备注去挤金额，不如干脆不摆表格 */
@media (max-width:900px){
  .tbl-card,.tbl-card tbody,.tbl-card tr,.tbl-card td{display:block;width:auto}
  .tbl-card thead{display:none}
  .tbl-card tr{border:1px solid var(--line);border-radius:12px;
    padding:12px 14px;margin-bottom:10px;background:var(--paper-2)}
  .tbl-card td{border:0;padding:5px 0;white-space:normal;
    display:flex;flex-wrap:wrap;gap:4px 10px;align-items:baseline}
  .tbl-card td::before{content:attr(data-label);flex:0 0 auto;min-width:62px;
    font-size:12px;color:var(--ink-3)}
  /* 首列是主字段（姓名 / 日期 / 金额），放大占一行，不必再重复标签 */
  .tbl-card td:first-child{font-size:15px;padding-bottom:7px;
    align-items:center;gap:6px}
  .tbl-card td:first-child::before{display:none}
  /* 末列通常是按钮，整行右对齐，上边留条分隔线 */
  .tbl-card td:last-child{justify-content:flex-end;gap:8px;
    border-top:1px solid var(--line);margin-top:8px;padding-top:10px}
  .tbl-card td:last-child::before{display:none}
  /* 装按钮的那一列表头是空的，没名字就别占位置 */
  .tbl-card td[data-label=""]::before{display:none}
}
.gtable tr:last-child td{border-bottom:none}
.gtable td em{font-style:normal;font-size:12px;margin-left:3px}
.gtable .amt{font-variant-numeric:tabular-nums;white-space:nowrap}
.gtable .amt em{display:block;margin-left:0}
.gtable .amt.in{color:var(--green)}
.gtable .amt.out{color:var(--red)}
.gdone{font-size:12px;color:var(--green)}
.gpending{font-size:12px;color:var(--red)}

/* 筛选条 */
.gfilter{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin-bottom:12px}
/* 筛选栏里的输入框与下拉不定宽就会各占一整行，挤成竖排 */
.gfilter .input{width:auto;flex:0 1 172px;min-width:132px}
.gfilter input.input{flex:1 1 220px}
.gseg{display:inline-flex;border:1px solid var(--line-2);border-radius:999px;overflow:hidden;background:var(--paper-2)}
.gseg label{padding:6px 16px;font-size:13px;color:var(--ink-2);cursor:pointer}
.gseg label input{display:none}
.gseg label.on{background:var(--gold);color:#fff}
.gadd{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin:16px 0}

/* 日常账本：月度对比条 */
.xcmp{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.xcmp-i{display:flex;flex-direction:column;gap:2px;min-width:106px}
.xcmp-lab{font-size:12px;color:var(--ink-2)}
.xcmp-i b{font-size:17px;color:var(--ink)}
.xcmp-i b.big{font-size:23px;color:var(--red)}
.xcmp-i em{font-size:12px;color:var(--ink-2);font-style:normal}
.xcmp-d{padding:5px 12px;border-radius:999px;font-size:13px;font-weight:600;
  white-space:nowrap}
.xcmp-d.up{background:rgba(190,60,45,.1);color:var(--red)}
.xcmp-d.down{background:rgba(47,107,69,.12);color:#2f6b45}

/* 可见范围标记：标了「仅自己」的记录，本人这边看得见记号，家庭账号那边根本不会出现 */
.vtag{display:inline-block;margin-left:5px;padding:1px 7px;border-radius:999px;
  font-size:11px;line-height:1.5;white-space:nowrap;
  background:rgba(74,74,74,.1);color:#5a5a5a;border:1px solid #e2e2e2}
.vtag.private{background:rgba(190,60,45,.1);color:var(--red);border-color:#f0d5d0}

/* 家庭日历：月历网格 */
.gcal{border:1px solid var(--line);border-radius:10px;overflow:hidden;
  background:var(--paper)}
.gcal-hd{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));
  background:var(--paper-2);border-bottom:1px solid var(--line)}
.gcal-hd span{padding:8px 0;text-align:center;font-size:12px;color:var(--ink-2)}
.gcal-grid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr))}
.gcal-cell{min-height:76px;border-right:1px solid var(--line);
  border-bottom:1px solid var(--line);padding:6px 5px;vertical-align:top}
.gcal-cell:nth-child(7n){border-right:0}
.gcal-cell.out{background:var(--paper-2);opacity:.5}
.gcal-d{display:inline-block;font-size:13px;font-weight:600;color:var(--ink-2);
  font-variant-numeric:tabular-nums}
.gcal-cell.today .gcal-d{width:22px;height:22px;line-height:22px;text-align:center;
  border-radius:50%;background:var(--red);color:#fff}
.gcal-ev{display:flex;flex-direction:column;gap:2px;margin-top:4px}
.gcal-e{font-size:11px;line-height:1.4;padding:1px 5px;border-radius:3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--ink)}
/* 生日是红事、忌辰是白事，颜色分开：一眼能分出该贺还是该祭 */
.gcal-e.birth{background:rgba(190,60,45,.12);color:var(--red)}
.gcal-e.death{background:rgba(74,74,74,.13);color:#4a4a4a}
.gcal-e.affair{background:rgba(226,161,28,.15);color:#8a6d2f}
.gcal-e.term{background:rgba(47,107,69,.13);color:#2f6b45}
.gcal-e.more{background:none;color:var(--ink-2);font-size:10px;padding:0 2px}

/* 日子类别标签，配色与月历格子保持一致 */
.ctag.birth{background:rgba(190,60,45,.12);color:var(--red);border-color:#f0d5d0}
.ctag.death{background:rgba(74,74,74,.12);color:#4a4a4a;border-color:#e2e2e2}
.ctag.affair{background:rgba(226,161,28,.14);color:#8a6d2f;border-color:#ece0c8}
.ctag.term{background:rgba(47,107,69,.12);color:#2f6b45;border-color:#d6e5da}

/* 窄屏放不下文字，日子缩成小圆点，详情仍在下方清单里 */
@media (max-width:560px){
  .gcal-cell{min-height:52px;padding:4px 2px}
  .gcal-d{font-size:12px}
  .gcal-ev{flex-direction:row;gap:3px;margin-top:3px}
  .gcal-e{flex:0 0 7px;width:7px;height:7px;border-radius:50%;
    font-size:0;padding:0}
  .gcal-e.more{flex:0 0 auto;width:auto;height:auto;border-radius:3px;
    font-size:9px;padding:0 3px}
}

/* 往来明细弹窗 */
.llist{margin-top:14px;max-height:300px;overflow:auto}
.lrow{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:10px 0;border-bottom:1px solid var(--line)}
.lrow:last-child{border-bottom:none}
.lmain{display:flex;flex-direction:column;min-width:0}
.lmain em{font-style:normal;font-size:12px;color:var(--ink-3)}
.lamt{font-variant-numeric:tabular-nums;white-space:nowrap}
.lamt.in{color:var(--green)}
.lamt.out{color:var(--red)}

@media (max-width:760px){
  .gov{grid-template-columns:repeat(2,minmax(0,1fr))}
  .gov.sm{grid-template-columns:repeat(2,minmax(0,1fr))}
  .gcard-list{grid-template-columns:minmax(0,1fr)}
  .gtable th:nth-child(4),.gtable td:nth-child(4){display:none}
}

/* ============ 礼簿：统计 ============ */
.gstats{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(min(320px,100%),1fr))}
.gpanel{padding:16px 18px;border-radius:var(--radius);background:var(--paper-2);
  border:1px solid var(--line);box-shadow:var(--shadow)}
.gpanel-hd{font-family:var(--font-serif);font-size:15px;font-weight:700;letter-spacing:.03em;
  margin-bottom:12px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.gpanel-hd .small{font-weight:400}

/* 收送对比 */
.cmp-row{display:flex;align-items:center;gap:10px;margin-bottom:9px}
.cmp-lab{flex:0 0 42px;font-size:13px;color:var(--ink-3)}
.cmp-track{flex:1;height:14px;border-radius:999px;background:#f0ece4;overflow:hidden}
.cmp-fill{height:100%;border-radius:999px;transition:width .35s}
.cmp-fill.in{background:linear-gradient(90deg,#7a9a70,var(--green))}
.cmp-fill.out{background:linear-gradient(90deg,#c98a86,var(--red))}
.cmp-val{flex:0 0 auto;min-width:74px;text-align:right;font-variant-numeric:tabular-nums}
.cmp-net{margin-top:12px;padding-top:12px;border-top:1px dashed var(--line-2);font-size:13.5px}
.cmp-net b{font-size:17px;margin:0 6px}
.cmp-net .small{display:block;margin-top:2px}

/* 趋势柱状图 */
.tchart{display:flex;align-items:flex-end;gap:6px;height:150px;padding-top:6px}
.tcol{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;height:100%}
.tstack{flex:1;width:100%;display:flex;flex-direction:column;justify-content:flex-end;gap:2px}
.tb{border-radius:3px 3px 0 0;min-height:2px;transition:height .3s}
.tb.in{background:var(--green)}
.tb.out{background:var(--red)}
.tl{font-size:11px;color:var(--ink-3);white-space:nowrap}

/* 迷你占比条 */
.mini-track{width:100%;min-width:70px;height:8px;border-radius:999px;background:#f0ece4;overflow:hidden}
.mini-fill{height:100%;background:linear-gradient(90deg,var(--gold-soft),var(--gold))}
.mini-fill.alt{background:linear-gradient(90deg,#cbb894,var(--gold))}
.rng{display:flex;align-items:center;gap:10px;margin-bottom:9px}
.rng-lab{flex:0 0 78px;font-size:13px;color:var(--ink-2)}
.rng-val{flex:0 0 auto;font-size:12.5px;color:var(--ink-3);font-variant-numeric:tabular-nums}

/* 往来 Top */
.top-list{display:flex;flex-direction:column;gap:2px}
.top-row{display:flex;align-items:center;gap:10px;padding:8px 6px;border-radius:8px;
  text-decoration:none;color:inherit}
.top-row:hover{background:#f7f3ec}
.top-no{flex:0 0 20px;height:20px;line-height:20px;text-align:center;border-radius:50%;
  background:#f4eddd;color:var(--gold);font-size:12px}
.top-nm{flex:1;min-width:0;display:flex;flex-direction:column}
.top-nm em{font-style:normal;font-size:12px;color:var(--ink-3)}
.top-val{flex:0 0 auto;font-size:12.5px;color:var(--ink-3);font-variant-numeric:tabular-nums}

/* 待回礼 */
.gstats + .gpanel,.gpanel{margin-bottom:0}
.ret-row{display:flex;align-items:center;gap:12px;padding:10px 0;border-bottom:1px solid var(--line)}
.ret-row:last-child{border-bottom:none}
.ret-main{flex:1;min-width:0;display:flex;flex-direction:column}
.ret-main em{font-style:normal;font-size:12px;color:var(--ink-3)}
.ret-amt{font-variant-numeric:tabular-nums;white-space:nowrap}

/* 打印礼单 */
@media print{
  #topbar,footer,.ghead-act,.gadd,.gtabs,.gov-item .gov-lab,.btn,
  .ret-row .btn,.gtable th:last-child,.gtable td:last-child{display:none !important}
  .wrap,.gwrap{max-width:none;margin:0;padding:0}
  .card,.gpanel,.gov .gov-item{box-shadow:none;border-color:#999}
  body{background:#fff}
}

/* ============ 礼簿：年度看板 / KPI / 徽章 ============ */
.gboard{display:grid;gap:12px;grid-template-columns:repeat(4,minmax(0,1fr));margin:16px 0 0}
.gboard-item{display:flex;flex-direction:column;gap:3px;padding:15px 17px;border-radius:var(--radius);
  background:linear-gradient(180deg,#fffdf8,#f8f3ea);border:1px solid var(--line);box-shadow:var(--shadow)}
.gboard-item b{font-family:var(--font-serif);font-size:23px;line-height:1.2}
.gboard-item em{font-style:normal;font-size:12px}
.gboard-item em.in{color:var(--green)}
.gboard-item em.out{color:var(--red)}

.gkpi{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(min(140px,100%),1fr));margin-top:12px}
.kpi{display:flex;flex-direction:column;gap:2px;padding:11px 13px;border-radius:10px;
  background:#faf7f0;border:1px solid var(--line)}
.kpi span{font-size:12px;color:var(--ink-3)}
.kpi b{font-family:var(--font-serif);font-size:18px;font-weight:700;color:#8a6d3b}
.kpi b em{font-style:normal;display:block;font-size:11.5px;color:var(--ink-3);font-family:var(--font-sans)}

/* 差额徽章 */
.gbadge{display:inline-block;padding:3px 10px;border-radius:999px;font-size:12px;white-space:nowrap}
.gbadge.owe{background:#f5e9e8;color:var(--red);border:1px solid #eed8d6}
.gbadge.out{background:#eaf0e9;color:var(--green);border:1px solid #d8e3d6}
.gbadge.clear{background:#f0ece4;color:var(--ink-3);border:1px solid var(--line-2)}
b.owe{color:var(--red)}
b.outg{color:var(--green)}
b.clearg{color:var(--ink-3)}

/* 回礼建议 */
.gadvice{margin-top:12px;padding:10px 12px;border-radius:10px;font-size:13px;
  background:#f4eddd;border:1px solid #ece0c8;color:#7a6338}
.gadvice b{font-size:15px;color:var(--red)}

.rng-list{margin-top:12px;padding-top:12px;border-top:1px dashed var(--line-2)}

@media (max-width:760px){
  .gboard{grid-template-columns:repeat(2,minmax(0,1fr))}
  .gboard-item b{font-size:20px}
}

/* ============ 通讯录 ============ */
.ctag{display:inline-block;padding:2px 9px;border-radius:999px;font-size:12px;
  background:#f4eddd;color:#8a6d3b;border:1px solid #ece0c8}

/* 卡片头：标题、说明、操作挤一行，窄屏自动折行 */
.card-hd{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:10px}
.card-hd h3{margin:0;font-family:var(--font-serif);font-size:16px}
.card-hd .btn{margin-left:auto}
/* 审批状态：待审批等表态、通过已落账、驳回待改 */
.rtag{display:inline-block;padding:2px 9px;border-radius:999px;font-size:12px;
  background:rgba(74,74,74,.1);color:#5a5a5a;border:1px solid #e2e2e2}
.rtag.wait{background:rgba(226,161,28,.14);color:#8a6d3b;border-color:#ece0c8}
.rtag.ok{background:rgba(47,107,69,.12);color:#2f6b45;border-color:#d6e5da}
.rtag.no{background:rgba(190,60,45,.12);color:var(--red);border-color:#f0d5d0}

/* 家谱：纵向分层，同辈横排，层与层之间一道竖线连下去 */
.ftree{display:flex;flex-direction:column;align-items:center}
.ftier{display:flex;flex-direction:column;align-items:center}
.ftier-lb{font-size:12px;color:var(--ink-3);margin-bottom:7px}
/* 层间的竖线：家谱要看得出「上下相承」，不能只是几堆人 */
.fjoin{width:2px;height:22px;background:var(--line-2);border-radius:1px;
  position:relative}
.fjoin:before,.fjoin:after{content:'';position:absolute;left:50%;
  transform:translateX(-50%);width:6px;height:6px;border-radius:50%;
  background:var(--paper);border:1px solid var(--line-2)}
.fjoin:before{top:-3px}
.fjoin:after{bottom:-3px}
.ftier-row{display:flex;gap:12px;flex-wrap:wrap;justify-content:center}
.fcard{min-width:130px;padding:10px 14px;border-radius:9px;text-align:center;
  background:var(--paper-2);border:1px solid var(--line);box-shadow:var(--shadow)}
/* 「本人」这代是家谱的中心，标出来 */
.fcard.me{background:rgba(190,60,45,.09);border-color:#f0d5d0}
.fcard b{display:block;font-family:var(--font-serif);font-size:15px;margin-bottom:2px}
.fcard span{display:block;font-size:12px;color:var(--ink-3)}
/* 称呼是家谱的骨架：它一变，这位亲人的辈分就跟着变 */
.fcard .fterm{font-size:12.5px;color:#8a6d3b;margin-bottom:3px}
/* 已故的亲人素净些，忌辰在日历里另有着落 */
.fcard.gone{opacity:.84}
.fcard-act{margin-top:7px;display:flex;gap:6px;justify-content:center}
/* 亲属网图谱：连线用 SVG 画，节点是圆角方块。
   窄屏放不下就横向滚动，不把字缩到看不清 */
.kinnet-scroll{overflow-x:auto}
.kinnet-scroll svg{display:block;margin:0 auto;width:100%;min-width:560px;height:auto}
.kinnet .kn-sp{stroke:#c8a26a;stroke-width:1.6}
.kinnet .kn-dn{fill:none;stroke:#c2b9aa;stroke-width:1.6}
.kinnet .kn-lb{fill:var(--ink-3);font-size:12px}
.kinnet .knode rect{fill:var(--paper-2);stroke:var(--line);stroke-width:1}
.kinnet .knode .kn-nm{fill:var(--ink);font-family:var(--font-serif);font-size:15px}
.kinnet .knode .kn-tm{fill:#8a6d3b;font-size:12px}
.kinnet .knode .kn-dg{fill:var(--ink-3);font-size:13px}
.kinnet .knode:hover rect{stroke:#c8a26a}
/* 「本人」是这张图的原点，标出来；已故的素净些 */
.kinnet .knode.me rect{fill:rgba(190,60,45,.09);stroke:#f0d5d0}
.kinnet .knode.gone rect{fill:#f7f4ef;stroke:#e4ded3}
.kinnet .knode.gone .kn-nm{fill:var(--ink-2)}
.kmodesw{margin:12px 0 2px}
.ctel{color:var(--green);text-decoration:none;font-variant-numeric:tabular-nums}
.ctel:hover{text-decoration:underline}
.gtable td em{font-style:normal;font-size:12px;color:var(--ink-3);display:block;margin-top:2px}

/* 人情往来小计 */
.cgift{display:flex;flex-direction:column;gap:2px;font-size:12.5px}
.cgift .in{color:var(--green)}
.cgift .out{color:var(--red)}
.cgift .gbadge{align-self:flex-start;margin-top:2px}

/* 即将生日 */
.bd-list{display:flex;flex-direction:column;gap:2px}
.bd-row{display:flex;align-items:center;gap:12px;padding:9px 0;border-bottom:1px solid var(--line)}
.bd-row:last-child{border-bottom:none}
.bd-row.soon .bd-days{background:var(--red);color:#fff}
.bd-days{flex:0 0 56px;height:24px;line-height:24px;text-align:center;border-radius:999px;
  background:#f4eddd;color:#8a6d3b;font-size:12px}
.bd-main{flex:1;min-width:0;display:flex;flex-direction:column}
.bd-main em{font-style:normal;font-size:12px;color:var(--ink-3)}
.bd-soon{color:var(--red)}

/* 从礼簿补充 */
.miss-list{display:flex;flex-direction:column;gap:6px;max-height:260px;overflow:auto}
.miss-row{display:flex;align-items:center;gap:8px;padding:7px 9px;border-radius:8px;
  background:#faf7f0;border:1px solid var(--line);cursor:pointer;font-size:13.5px}
.miss-row:hover{background:#f7f3ec}
.miss-row em{font-style:normal;font-size:12px;color:var(--ink-3)}

/* 选人弹层 */
.pk-list{display:flex;flex-direction:column;gap:4px;max-height:320px;overflow:auto}
.pk-row{display:flex;flex-direction:column;gap:2px;align-items:flex-start;width:100%;
  padding:10px 12px;border-radius:9px;border:1px solid var(--line);background:#faf7f0;
  cursor:pointer;text-align:left;font:inherit;color:inherit}
.pk-row:hover{background:#f4eddd;border-color:#ece0c8}
.pk-row em{font-style:normal;font-size:12px;color:var(--ink-3)}
.pk-gift{font-size:12px;color:var(--ink-3);font-variant-numeric:tabular-nums}

/* ============ 家庭 ============ */
.fm-list{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(min(300px,100%),1fr))}
/* 三格：头像 / 正文 / 操作。
   正文那格必须能收（minmax(0,1fr)）——否则电话、徽标会把整张卡撑破 */
.fm-card{display:grid;grid-template-columns:auto minmax(0,1fr) auto;
  align-items:start;gap:12px;padding:13px 15px;border-radius:12px;
  background:var(--paper-2);border:1px solid var(--line);box-shadow:var(--shadow);position:relative}
.fm-card.soon{border-color:#eed8d6;background:linear-gradient(180deg,#fffaf8,#fbf4f1)}
.fm-av{flex:0 0 40px;height:40px;line-height:40px;text-align:center;border-radius:50%;
  background:linear-gradient(180deg,#f4eddd,#ece0c8);color:#8a6d3b;
  font-family:var(--font-serif);font-size:19px;font-weight:700}
.fm-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.fm-nm{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.fm-nm b{font-family:var(--font-serif);font-size:16px;font-weight:700}
.fm-meta{display:flex;gap:12px;flex-wrap:wrap;font-size:12.5px;color:var(--ink-3)}
.fm-note{font-size:12px;color:var(--ink-3)}
.fm-gift{display:flex;gap:8px;align-items:center;flex-wrap:wrap;font-size:12.5px;margin-top:2px}
.fm-gift .in{color:var(--green)}
.fm-gift .out{color:var(--red)}
.fm-act{display:flex;flex-direction:column;gap:4px}

/* 事务与纪念日 */
.aff-list{display:flex;flex-direction:column}
/* 三格：勾选 / 正文 / 操作。
   天数标签跟着标题走，不再单独占一列——它和下面那行 meta 说的
   是同一件事，却要多分一份宽度，窄屏下就把标题挤成竖条了 */
.aff-row{display:grid;grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid var(--line)}
.aff-row:last-child{border-bottom:none}
.aff-row.overdue .aff-main b{color:var(--red)}
.aff-row.done .aff-main b{color:var(--ink-3);text-decoration:line-through}
.aff-main{min-width:0;display:flex;flex-direction:column}
.aff-main em{font-style:normal;font-size:12px;color:var(--ink-3)}
.aff-tl{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;min-width:0}
.aff-day{font-size:12px;white-space:nowrap}
.aff-day.out{color:var(--red)}
.aff-day.soon{color:var(--gold)}
.aff-act{display:flex;gap:4px}
/* 事务操作弹窗里的简述 */
.aff-dlg{display:flex;flex-direction:column;gap:5px}
.aff-dlg b{font-family:var(--font-serif);font-size:15px}
.aff-done-hd{display:flex;align-items:center;justify-content:space-between;
  margin-top:14px;padding-top:12px;border-top:1px dashed var(--line-2);
  font-size:13px;color:var(--ink-3)}

@media (max-width:760px){
  .fm-list{grid-template-columns:minmax(0,1fr)}
  .fm-act{flex-direction:row}
}

/* ============ 待来往事件（首页） ============ */
.pend-list{display:flex;flex-direction:column}
.pend-row{display:flex;align-items:center;gap:12px;padding:11px 0;border-bottom:1px solid var(--line)}
.pend-row:last-child{border-bottom:none}
.pend-row.soon .pend-day{background:var(--red);color:#fff}
.pend-row.done{opacity:.62}
.pend-day{flex:0 0 68px;height:24px;line-height:24px;text-align:center;border-radius:999px;
  background:#f4eddd;color:#8a6d3b;font-size:12px}
.pend-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.pend-main em{font-style:normal;font-size:12px;color:var(--ink-3)}
.pend-act{display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:flex-end}
.pend-act em{font-style:normal;font-size:12px;color:var(--ink-3)}
/* 首页：待确认的支出。与「来往提醒」同一套排版 */
.appr-card{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.appr-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.appr-main b{font-family:var(--font-serif);font-size:15px}
.appr-main em{font-style:normal;font-size:12.5px;color:var(--ink-3)}
.appr-act{flex-shrink:0}

/* ============ 宴席事项（家庭） ============ */
.gpanel.feast{border-color:#ece0c8;background:linear-gradient(180deg,#fffdf8,#faf5ec)}
.feast-row{display:flex;gap:12px;align-items:flex-start;padding:12px 0;border-bottom:1px solid var(--line)}
.feast-row:last-child{border-bottom:none}
.feast-row.pub{background:transparent}
.feast-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.feast-nm{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.feast-nm b{font-family:var(--font-serif);font-size:16px;font-weight:700}
.feast-main em{font-style:normal;font-size:12px;color:var(--ink-3)}
.feast-detail{font-size:13px;color:var(--ink-2);margin-top:2px}
.feast-act{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}

/* ============ 来往事件统计（通讯录） ============ */
.cevt{display:flex;flex-direction:column;gap:2px;font-size:12.5px}
.cevt-line{display:flex;align-items:baseline;gap:5px;white-space:nowrap}
.cevt-line span:first-child{color:var(--ink-3)}
.cevt-line b{font-size:13px;color:#8a6d3b}
.cevt .btn{margin-top:3px;align-self:flex-start}

.modal.wide{max-width:640px}
.evstat-list{display:flex;flex-direction:column}
.evstat-row{display:flex;align-items:center;gap:10px;padding:8px 0;border-bottom:1px solid var(--line)}
.evstat-row:last-child{border-bottom:none}
.evstat-row b{flex:0 0 auto;font-weight:600}
.evstat-row em{font-style:normal;flex:1;min-width:0;font-size:12px;color:var(--ink-3)}
.evstat-row .amt{font-variant-numeric:tabular-nums;white-space:nowrap}
.evstat-row .amt.in{color:var(--green)}
.evstat-row .amt.out{color:var(--red)}
.evstat-net{margin-top:12px;padding:10px 12px;border-radius:10px;
  background:#f4eddd;border:1px solid #ece0c8;font-size:13.5px}
.evstat-net b{font-size:17px;margin:0 4px}
.evstat-net .small{display:block;margin-top:2px}

@media (max-width:760px){
  .pend-row{flex-wrap:wrap}
  .pend-act{width:100%;justify-content:flex-start}
  .feast-row{flex-direction:column}
  .feast-act{justify-content:flex-start}
  .modal.wide{max-width:calc(100vw - 32px)}
}

/* ============ 姓名实时搜索通讯录 ============ */
.ns-list{display:flex;flex-direction:column;gap:4px;margin-top:6px;max-height:180px;overflow:auto}
.ns-row{display:flex;flex-direction:column;gap:2px;align-items:flex-start;width:100%;
  padding:8px 10px;border-radius:8px;border:1px solid var(--line);background:#faf7f0;
  cursor:pointer;text-align:left;font:inherit;color:inherit}
.ns-row:hover{background:#f4eddd;border-color:#ece0c8}
.ns-row em{font-style:normal;font-size:12px;color:var(--ink-3)}

/* ============ 有序多选（发布成员） ============ */
.ord-pick{display:flex;flex-wrap:wrap;gap:6px}
.ord-row{display:flex;align-items:center;gap:6px;padding:7px 11px;border-radius:999px;
  border:1px solid var(--line);background:#faf7f0;cursor:pointer;font:inherit;
  font-size:13.5px;color:inherit}
.ord-row:hover{background:#f7f3ec}
.ord-row.on{background:linear-gradient(180deg,#f4eddd,#ece0c8);border-color:#d9c9a6;color:#8a6d3b}
.ord-no{font-size:11.5px;color:#8a6d3b;min-width:52px}
.ord-row.on .ord-no{font-weight:700}
.fm-card .host,.feast-main .host{color:#8a6d3b}

/* 送礼按钮 */
.btn.send{background:linear-gradient(180deg,#f4eddd,#ece0c8);border-color:#d9c9a6;color:#8a6d3b}
.btn.send:hover{background:linear-gradient(180deg,#eee4cf,#e3d5b8)}
.cevt .btn:not(:first-of-type){margin-left:4px}

/* ============ 后台：全站内容管理 ============ */
.adm-tabs{flex-wrap:wrap}
.tbl td em{display:block;font-style:normal;margin-top:2px}
.tbl td .badge{display:inline-block}
.row-act{white-space:nowrap;display:flex;gap:6px;align-items:center;justify-content:flex-end}
.row-act .btn{margin:0}

/* ================= 后台：UI 增强 ================= */
/* 统计卡：图标 + 抬升 */
.stat{transition:transform .18s ease, box-shadow .18s ease}
.stat:hover{transform:translateY(-3px);box-shadow:var(--shadow-hi)}
.stat .ico{
  display:flex;align-items:center;justify-content:center;
  width:34px;height:34px;border-radius:11px;flex:none;
  font-family:var(--font-serif);font-size:16px;font-weight:700;
  background:linear-gradient(165deg,#f6efdd,#ecdfc2);color:#8a6d3b;
  border:1px solid rgba(217,201,166,.7);
}
.stat.c1 .ico{background:linear-gradient(165deg,#eef3f7,#dfe8ef);color:#2b7fd4;border-color:rgba(43,127,212,.28)}
.stat.c2 .ico{background:linear-gradient(165deg,#f3f1ea,#e7e3d7);color:#6b6152;border-color:rgba(150,140,120,.28)}
.stat.c3 .ico{background:linear-gradient(165deg,#f0f5f0,#e1ece3);color:#2b9d63;border-color:rgba(43,157,99,.28)}
.stat.c4 .ico{background:linear-gradient(165deg,#f7efef,#eddfdc);color:#d8382a;border-color:rgba(216,56,42,.24)}
.stats.sm .stat{padding:12px 14px}
.stats.sm .stat .num{font-size:22px}
.stats.sm .stat .ico{width:28px;height:28px;font-size:14px;border-radius:9px}

/* 标签页：胶囊式 */
.tabbar{background:#f6f1e6;border:1px solid var(--line);border-radius:999px;padding:4px;gap:2px}
.tabbar a{
  border-radius:999px;padding:7px 15px;font-size:14px;color:var(--ink-2);
  white-space:nowrap;transition:background .15s ease,color .15s ease;
}
.tabbar a:hover{background:rgba(255,255,255,.7);color:var(--ink)}
.tabbar a.active{
  background:linear-gradient(180deg,#fffdf8,#f7f0e0);color:#8a6d3b;font-weight:600;
  box-shadow:0 1px 2px rgba(80,55,25,.08);border:1px solid rgba(217,201,166,.6);
}
.tabbar a.active::after{display:none}

/* 表格：斑马纹 + 悬停 + 表头吸顶 */
.table-wrap{border-radius:var(--radius);overflow:auto}
table.data th,table.tbl th{
  position:sticky;top:0;z-index:1;background:linear-gradient(180deg,#faf5ea,#f4eddd);
  font-size:13px;color:#6d5a34;white-space:nowrap;
}
table.data tbody tr:nth-child(even),table.tbl tbody tr:nth-child(even){background:rgba(250,245,235,.45)}
table.data tbody tr:hover,table.tbl tbody tr:hover{background:#f7f1e3}
table.data td,table.tbl td{vertical-align:middle;padding:10px 12px}
table.data td.name a,table.tbl td b{letter-spacing:.02em}
.tbl td.num,.data td.num{text-align:right;font-variant-numeric:tabular-nums}
td .muted,td em.muted{color:var(--ink-3)}

/* 空状态 */
.adm-empty{
  display:flex;align-items:center;gap:10px;padding:26px;border-radius:var(--radius);
  border:1px dashed var(--line-2);background:#fbf8f1;color:var(--ink-3);font-size:14px;
}
.adm-empty .ico{
  width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  background:#f1ead9;color:#a08f6f;font-family:var(--font-serif);
}

/* 会员档案 */
.prof-at{margin-left:8px;font-size:13px;font-weight:400;color:var(--ink-3)}
.prof-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px}
.prof-box{border:1px solid var(--line);border-radius:var(--radius);background:#fbf8f1;padding:14px}
.prof-box h4{margin:0 0 10px;font-size:13px;letter-spacing:.08em;color:#8a6d3b;font-family:var(--font-serif)}
.prof-data{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
.prof-cell{
  border:1px solid var(--line);border-radius:10px;background:#fffdf8;padding:8px 10px;
  display:flex;flex-direction:column;gap:2px;
}
.prof-cell span{font-size:12px;color:var(--ink-3)}
.prof-cell b{font-size:17px;font-family:var(--font-serif);color:#6d5115}
.prof-cell a{text-decoration:none;color:inherit}
.prof-cell a:hover b{color:var(--red)}
.prof-money{margin-top:10px;font-size:13px;color:var(--ink-2)}
.prof-money b{font-family:var(--font-serif)}
.prof-acts{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px}
.prof-link{color:var(--ink);text-decoration:none;border-bottom:1px dashed var(--line-2)}
.prof-link:hover{color:var(--red);border-bottom-color:var(--gold-soft)}

/* 趋势图（收 / 送双色柱） */
/* 12 个月并排最少也要 300px 出头，卡片只占半栏时根本放不下——
   让它横滑，而不是把月份标签压没 */
.trend{display:flex;align-items:flex-end;gap:6px;height:150px;padding:6px 2px 0;
  overflow-x:auto;overflow-y:hidden}
.trend-col{flex:1 0 24px;min-width:24px;display:flex;flex-direction:column;
  align-items:center;gap:5px;height:100%}
.trend-bars{
  flex:1;width:100%;display:flex;align-items:flex-end;justify-content:center;gap:3px;
}
.trend-bars i{
  display:block;width:8px;min-height:2px;border-radius:3px 3px 0 0;transition:height .3s ease;
}
/* 收 = 绿、送 = 红，与礼簿板块的语义保持一致（此前两者是反的） */
.trend-bars .b-in{background:linear-gradient(180deg,#5d8f6c,#2b9d63)}
.trend-bars .b-out{background:linear-gradient(180deg,#b8443f,#d8382a)}
.trend-col span{font-size:11px;color:var(--ink-3);white-space:nowrap}
.trend-legend{display:flex;gap:14px;align-items:center;margin-top:8px;font-size:12px;color:var(--ink-2)}
.trend-legend i{display:inline-block;width:9px;height:9px;border-radius:2px;margin-right:5px}

/* 横条 */
.bar-row{display:flex;align-items:center;gap:10px;padding:6px 0}
.bar-lb{width:76px;font-size:13px;color:var(--ink-2);flex:none}
.bar-track{flex:1;height:9px;border-radius:999px;background:#f0e9da;overflow:hidden}
.bar-track i{display:block;height:100%;border-radius:999px;
  background:linear-gradient(90deg,#ee6a56,#d8382a)}
.bar-v{width:76px;text-align:right;font-size:12.5px;color:var(--ink-2);font-variant-numeric:tabular-nums}

/* 待办 */
.todo-list{display:flex;flex-direction:column;gap:8px}
.todo-row{
  display:flex;align-items:center;gap:12px;padding:11px 14px;border-radius:var(--radius);
  border:1px solid var(--line);background:#fffdf8;text-decoration:none;color:inherit;
  transition:background .15s ease,box-shadow .15s ease;
}
.todo-row:hover{background:#f9f4e9;box-shadow:var(--shadow)}
.todo-row.warn{border-color:rgba(192,86,79,.35);background:linear-gradient(180deg,#fdf7f5,#fbf1ee)}
.todo-ic{
  width:28px;height:28px;border-radius:9px;flex:none;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(165deg,#f6efdd,#ecdfc2);color:#8a6d3b;
  font-family:var(--font-serif);font-size:14px;font-weight:700;
}
.todo-row.warn .todo-ic{background:linear-gradient(165deg,#f7e9e6,#eed9d5);color:#d8382a}
.todo-tx{flex:1;display:flex;flex-direction:column;gap:2px;min-width:0}
.todo-tx b{font-size:14px}
.todo-tx em{font-style:normal;font-size:12px;color:var(--ink-3)}
.todo-ct{font-size:13px;font-family:var(--font-serif);color:#6d5115;flex:none}

/* 搜索结果 */
.adm-list .adm-row:hover{background:#f9f4e9}

/* ============ 家庭绑定 / 注销 ============ */
.bind-tag{display:inline-block;margin-top:5px;padding:2px 8px;border-radius:999px;
  font-size:11.5px;border:1px solid var(--line);background:#f6f1e6;color:var(--ink-3)}
.bind-tag.ok{border-color:rgba(43,157,99,.3);background:#eaf1ec;color:#2b9d63}
.bind-tag.wait{border-color:rgba(226,161,28,.35);background:#f7f0dd;color:#8a6d3b}
.bind-inv{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.bi-tx{flex:1;min-width:200px}
.bi-act{display:flex;gap:6px}
.bind-sub{margin:12px 0 6px;font-size:12px;letter-spacing:.06em;color:#8a6d3b;font-family:var(--font-serif)}
.bind-sub:first-child{margin-top:0}
.bind-list{display:flex;flex-direction:column;gap:6px}
.bind-row{display:flex;align-items:center;gap:12px;padding:9px 12px;border-radius:var(--radius);
  border:1px solid var(--line);background:#fffdf8;text-decoration:none;color:inherit}
.bind-row:hover{background:#f9f4e9}
.bind-row>div:first-child{flex:1;min-width:0}
.danger-zone{border-color:rgba(192,86,79,.3)}

/* ============ 图形展示（各板块「图显示」） ============ */
.gfx{background:var(--paper-2);border:1px solid var(--line);border-radius:var(--radius);padding:16px 18px}
.gfx-hd{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  margin-bottom:12px;flex-wrap:wrap}
.gfx-hd h3{margin:0;font-size:15px;font-family:var(--font-serif);font-weight:600;color:var(--ink)}
.gfx-hd .muted{font-size:12px}
.gfx-svg{display:block;width:100%;height:auto;overflow:visible}
.gfx-bar{transition:opacity .15s}
.gfx-bar:hover{opacity:.78}
.gfx-arc{transition:opacity .15s}
.gfx-arc:hover{opacity:.78}
.gfx-empty{padding:26px 0;text-align:center;font-size:13px;color:var(--ink-3)}

/* CSS 柱图：宽度天然跟随容器，窄卡片里也不会像 SVG 那样被缩成一根线。
   柱子与标签放在同一列，天然对齐；列宽有上下限，列少时不会拉出一片空白。 */
.gfx-bars{display:flex;align-items:flex-end;justify-content:center;gap:8px;height:172px}
.gfx-bcol{flex:1 1 44px;min-width:18px;max-width:56px;height:100%;
  display:flex;flex-direction:column;justify-content:flex-end;align-items:center}
.gfx-bpair{flex:1;width:100%;display:flex;align-items:flex-end;justify-content:center;gap:3px;
  border-bottom:1px solid var(--line)}
.gfx-bpair i{flex:1 1 0;min-height:2px;border-radius:4px 4px 0 0;transition:height .35s ease}
.gfx-bpair i.in{background:var(--green)}
.gfx-bpair i.out{background:var(--red)}
.gfx-bcol:hover .gfx-bpair i{opacity:.78}
.gfx-bcol > span{font-size:10.5px;color:var(--ink-3);margin-top:5px;max-width:100%;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gfx-rank-i.top{background:var(--red);color:#fff}

/* 登录卡上的站点公告 */
.auth-notice{
  margin:0 0 15px;padding:9px 12px;border-radius:9px;
  background:#fdf6e8;border:1px solid #efe0c4;
  font-size:12.5px;line-height:1.62;color:#8a6a2e;
}

/* 图表网格：宽图占满，窄图并排 */
.gfx-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(340px,100%),1fr));gap:16px;margin-top:16px}
.gfx-grid .gfx{margin:0}
.gfx-wide{grid-column:1/-1}

/* 环形图 + 右侧图例 */
.gfx-donut-wrap{display:flex;align-items:center;gap:20px;flex-wrap:wrap}
.gfx-donut-wrap .gfx-legend{flex:1;min-width:150px;margin:0}

/* 横向排行条 */
.gfx-rank{display:flex;flex-direction:column;gap:9px}
.gfx-rank-row{display:flex;align-items:center;gap:10px;font-size:13px}
.gfx-rank-i{flex:0 0 18px;height:18px;border-radius:50%;background:#f2ebdd;color:var(--ink-3);
  font-size:11px;display:inline-flex;align-items:center;justify-content:center}
.gfx-rank-lb{flex:0 0 auto;min-width:76px;max-width:120px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;color:var(--ink-2)}
.gfx-rank-track{flex:1;height:8px;border-radius:999px;background:#f0e9db;overflow:hidden;min-width:40px}
.gfx-rank-track i{display:block;height:100%;border-radius:999px;transition:width .35s}
.gfx-rank-v{flex:0 0 auto;min-width:62px;text-align:right;font-family:var(--font-serif);
  font-weight:600;color:var(--ink)}
.gfx-rank-v em{display:block;font-size:11px;font-weight:400;font-style:normal;color:var(--ink-3)}

/* 图例 */
.gfx-legend{list-style:none;margin:14px 0 0;padding:0;display:flex;flex-direction:column;gap:6px}
.gfx-legend li{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--ink-2)}
.gfx-legend i{flex:0 0 9px;width:9px;height:9px;border-radius:2px}
.gfx-legend li span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gfx-legend li b{font-family:var(--font-serif);color:var(--ink)}
.gfx-legend li em{flex:0 0 44px;text-align:right;font-style:normal;color:var(--ink-3)}

/* 视图切换条：左侧标题 + 右侧切换 */
.vbar{display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex-wrap:wrap;margin-bottom:14px}
.vbar-t h2{margin:0;font-size:17px;font-family:var(--font-serif);font-weight:600}
.vbar-t .desc{font-size:12.5px;color:var(--ink-3);margin-top:2px}

/* ============ 迎宾落地页 ============ */
.lp{max-width:1040px;margin:0 auto;padding:28px 24px 4px}
.lp-hero{text-align:center;padding:34px 0 28px}
.lp-seal{width:62px;height:62px;margin:0 auto 16px;border-radius:16px;
  display:flex;align-items:center;justify-content:center;
  background:linear-gradient(145deg,var(--red),#a82318);color:#fff7ec;
  font-family:var(--font-serif);font-size:30px;
  box-shadow:0 10px 26px -12px rgba(216,56,42,.9)}
.lp-hero h1{font-family:var(--font-serif);font-size:34px;margin:0;letter-spacing:.04em}
.lp-tagline{margin:6px 0 0;color:var(--gold);font-size:15px;letter-spacing:.06em}
.lp-lead{max-width:640px;margin:15px auto 0;color:var(--ink-2);font-size:15px;line-height:1.85}
.lp-lead b{font-weight:600;color:var(--ink)}
.lp-act{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;margin-top:26px}
.lp-act-note{margin-top:12px;font-size:12.5px;color:var(--ink-3)}
.lp-hint.warn{color:var(--red)}

.lp-sec{margin-top:38px}
.lp-sec-hd{margin-bottom:15px;padding-bottom:10px;border-bottom:1px solid var(--line);
  display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}
.lp-sec-hd h2{margin:0;font-family:var(--font-serif);font-size:21px;letter-spacing:.03em}

.lp-scenes{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(min(272px,100%),1fr))}
.lp-card{background:var(--paper-2);border:1px solid var(--line);
  border-radius:var(--radius);padding:19px 20px;box-shadow:var(--shadow)}
.lp-card-hd{display:flex;align-items:center;gap:11px;margin-bottom:10px}
.lp-icon{width:34px;height:34px;flex:0 0 auto;border-radius:10px;display:flex;
  align-items:center;justify-content:center;font-family:var(--font-serif);font-size:17px;
  background:linear-gradient(145deg,#fbf3e4,#f0e5cd);color:var(--gold);
  border:1px solid #e8dcc2}
.lp-card-hd h3{margin:0;font-family:var(--font-serif);font-size:16px}
.lp-card-desc{margin:0 0 12px;color:var(--ink-2);font-size:13.5px;line-height:1.72}
.lp-points{list-style:none;margin:0;padding:0;display:grid;gap:6px}
.lp-points li{position:relative;padding-left:15px;font-size:12.8px;color:var(--ink-3)}
.lp-points li::before{content:'';position:absolute;left:0;top:8px;width:5px;height:5px;
  border-radius:50%;background:var(--gold-soft)}

.lp-roles{display:grid;gap:12px}
.lp-role{display:flex;align-items:center;justify-content:space-between;gap:18px;
  width:100%;text-align:left;padding:14px 18px;background:var(--paper-2);
  border:1px solid var(--line);border-radius:var(--radius);color:inherit;
  font:inherit;cursor:pointer;transition:border-color .18s,box-shadow .18s}
.lp-role:hover{border-color:var(--line-2);box-shadow:var(--shadow);text-decoration:none}
.lp-role p{margin:2px 0 0}
.lp-role-act{flex:0 0 auto;color:var(--gold);font-size:13px;white-space:nowrap}

.lp-priv{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(min(310px,100%),1fr))}
.lp-priv-item{display:flex;gap:10px;align-items:flex-start;padding:12px 14px;
  background:rgba(255,253,248,.7);border:1px solid var(--line);border-radius:12px}
.lp-check{width:20px;height:20px;flex:0 0 auto;margin-top:1px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;font-size:11px;
  color:var(--green);background:#eef4ef;border:1px solid #d3e2d7}
.lp-priv-item b{font-size:13.6px;font-weight:600}
.lp-priv-item p{margin:2px 0 0}

.lp-foot{margin-top:34px;padding:16px 0 28px;border-top:1px solid var(--line);
  display:flex;justify-content:space-between;align-items:center;gap:14px;flex-wrap:wrap}

/* 管理入口：留一条路给管理员，但不再摆在明面上 */
.lp-adm{font-size:12px;color:var(--ink-3);text-decoration:none;opacity:.45}
.lp-adm:hover{opacity:1;color:var(--ink-2)}

/* 账号中心：大字模式开关 */
.aged-sw{display:flex;align-items:center;gap:9px;cursor:pointer;font-size:14px;
  user-select:none}
.aged-sw input{width:17px;height:17px;flex:0 0 auto;cursor:pointer;accent-color:var(--red)}

/* 登录卡：演示入口与「回到迎宾页」 */
.auth-demo{margin-top:16px;padding-top:15px;border-top:1px dashed var(--line)}
/* 演示按钮用淡金描边：比正文有分量，又不抢「登录」的位置 */
.auth-demo .btn{background:linear-gradient(180deg,#fffdf8,#fbf5e9);
  border-color:var(--gold-soft);color:var(--gold);font-weight:600}
.auth-demo .btn:hover{background:#fff8e9;border-color:var(--gold);color:var(--gold)}
.auth-back{display:block;text-align:center;margin-top:14px;font-size:12.5px;color:var(--ink-3)}
.auth-back:hover{color:var(--gold)}
.btn.lg{padding:11px 24px;font-size:15px;border-radius:11px}

/* ============ 移动端底部 Tab 导航 ============ */
/* 桌面不出现；手机上顶栏导航要横向翻，底部 Tab 才是单手能点的那个 */
.mtabs{display:none}
@media (max-width:768px){
  /* 用 sticky 而不是 fixed：sticky 在文档流里还占着位置，
     页脚自然排在它上面，不会像 fixed 那样被压住，也不用测量高度去避让。
     排在 DOM 最后一项，滚动时始终吸在视口底部。 */
  .mtabs.show{
    display:flex;position:sticky;bottom:0;z-index:60;
    background:rgba(255,253,248,.97);
    backdrop-filter:saturate(150%) blur(12px);
    border-top:1px solid var(--line);
    box-shadow:0 -8px 24px -18px rgba(80,55,25,.45);
    padding:5px 2px calc(5px + env(safe-area-inset-bottom,0px));
  }
  .mtabs a{
    flex:1 1 0;min-width:0;display:flex;flex-direction:column;
    align-items:center;justify-content:center;gap:3px;
    padding:5px 2px;border-radius:10px;
    text-decoration:none;color:var(--ink-3);
    -webkit-tap-highlight-color:transparent;
  }
  .mtabs .tab-ico{
    width:26px;height:26px;border-radius:8px;display:flex;
    align-items:center;justify-content:center;
    font-family:var(--font-serif);font-size:14px;line-height:1;
    transition:background .16s,color .16s;
  }
  .mtabs .tab-name{
    font-size:11px;line-height:1.2;max-width:100%;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }
  .mtabs a.active{color:var(--red);font-weight:600}
  .mtabs a.active .tab-ico{
    background:linear-gradient(145deg,var(--red),#a82318);color:#fff7ec;
    box-shadow:0 4px 10px -6px rgba(216,56,42,.9);
  }
  .main{padding:18px 14px 24px}
  /* 板块切换交给底部 Tab，顶栏不再重复排一排导航，只留品牌与搜索 */
  .topbar .nav{display:none}
  /* 表格列多（表头不折行），手机上放不下就让表格自己横向滚动，
     别把整页撑出横向滚动条。后台的表格多数没包 .table-wrap，所以两类都覆盖 */
  .gtable,.tbl,.data{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch}
}

/* ============ 适老化大字模式 ============ */
/* 长辈用：正文、按钮、表单整体放大，点击区加厚，配色不改 */
body.aged{font-size:17px;line-height:1.78}
body.aged .main{font-size:17px}
body.aged .muted{font-size:16px}
body.aged .small{font-size:15px}
body.aged .card{font-size:17px}
body.aged .btn{font-size:16.5px;padding:9px 18px;border-radius:12px}
body.aged .btn.sm{font-size:15px;padding:7px 13px}
body.aged .input{font-size:16.5px;padding:11px 13px}
body.aged .input::placeholder{font-size:16px}
body.aged .field label{font-size:15px}
body.aged .section-title h2{font-size:19px}
body.aged .page-head h1{font-size:26px}
body.aged .page-head .sub{font-size:16px}
body.aged .topbar{height:auto;min-height:62px}
body.aged .nav a{font-size:16px;padding:7px 12px}
body.aged .mtabs .tab-name{font-size:13.5px}
body.aged .mtabs .tab-ico{width:30px;height:30px;font-size:16px}
body.aged .mtabs.show{padding-bottom:calc(7px + env(safe-area-inset-bottom,0px))}
body.aged .lp-lead{font-size:17px}
body.aged .lp-card-desc{font-size:16px}
body.aged .lp-points li{font-size:15px}
body.aged .lp-priv-item b{font-size:16px}
body.aged .lp-priv-item p{font-size:15px}

@media (max-width:640px){
  .lp{padding:20px 16px 4px}
  .lp-hero{padding:16px 0 20px}
  .lp-hero h1{font-size:27px}
  .lp-lead{font-size:14px}
  .lp-act .btn{flex:1 1 auto}
  .lp-role{flex-direction:column;align-items:flex-start;gap:8px}
  .lp-role-act{color:var(--ink-3)}
}

/* ============ 页面装修：左区块 / 中预览 / 右属性 ============ */
.decor-wrap{display:grid;grid-template-columns:252px minmax(0,1fr) 250px;
  gap:14px;align-items:start}
.decor-col{padding:16px 14px}
.decor-list{display:flex;flex-direction:column;gap:6px}
.decor-item{display:flex;align-items:center;gap:8px;padding:7px 8px;
  border:1px solid var(--line);border-radius:8px;background:var(--paper)}
.decor-item.is-cur{border-color:var(--gold);background:var(--gold-soft)}
.decor-item.is-off{opacity:.5}
.decor-no{flex:0 0 auto;width:16px;color:var(--ink-3);font-size:12px}
.decor-nm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font-size:13.5px;color:inherit;text-decoration:none}
.decor-op{display:flex;gap:4px;flex:0 0 auto}
.decor-op .btn{padding:2px 7px;min-height:0;font-size:12px}
.decor-frame{border:1px solid var(--line);border-radius:12px;overflow:hidden;background:#fff}
.decor-frame iframe{display:block;width:100%;height:620px;border:0}
/* 手机预览：收成一台手机的样子。宽度用 min() 兜住，
   不然窄屏上这个固定宽度会把整栏撑破 */
.decor-frame.is-phone{width:min(414px,100%);max-width:100%;margin:0 auto;
  border-radius:26px;border:8px solid #2b2b2b}
.decor-frame.is-phone iframe{height:720px}
.decor-prop-row{padding:7px 0;border-bottom:1px solid var(--line);font-size:13.5px}
.decor-prop-act{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px}
.decor-gap{flex:1 1 auto}
/* 窄屏上三栏放不下，改成上下排列。
   这里必须是 minmax(0,1fr)：裸 1fr 会被手机壳那个宽度撑开，
   而栏里装了预览框，一撑整页就横向溢出 */
@media(max-width:1180px){.decor-wrap{grid-template-columns:minmax(0,1fr)}}
