/*! ui/render.css —— 画布与总览树：端子（节点）、走线（边）、世代走线槽 */
/* ---------- 画布 ---------- */
#stage { flex: 1; position: relative; overflow: auto; outline: none; min-height: 0; }
#stage svg { display: block; }

/* ---------- 卡片目录：节点 ---------- */
.node-g { cursor: pointer; }

/* 性别靠卡片描边色区分（男蓝女粉）。
 * 这是上一轮我按通用反模式建议删掉、这一轮按明确要求加回来的 ——
 * 用户在 brief 里点的名，优先于「彩色边框」这类通用戒律。 */
.node-g .card {
  fill: var(--card);
  stroke: var(--rail-2);
  stroke-width: 1.4;
  transition: stroke .16s var(--ease), stroke-width .16s var(--ease);
}

.node-g.male .card { stroke: var(--male); }
.node-g.female .card { stroke: var(--female); }

.node-g:hover .card { stroke-width: 2.2; }

/* 选中：本人 + 选中的人两点变绿，两点之间的连线（.edge.path）也变绿。
 * 没有选中时，本人（视角中心）只用强调蓝标记。 */
.node-g.ego .card { stroke: var(--blue); stroke-width: 2.6; }
.node-g.sel .card { stroke: var(--sel); stroke-width: 2.6; }

.node-g .halo { fill: var(--blue); opacity: .08; }
.node-g.sel .halo { fill: var(--sel); opacity: .10; }
.node-g.dim { opacity: .25; }

.node-g text { user-select: none; }

/* 签名动作：换视角中心时卡片按新的辈分「重新归档」—— 行依次落位。
 * 与称谓总表共用同一个 keyframe 与同一组节奏（步进 9ms / 上限 130ms / .38s），
 * 见 views/table.js 的 tr.flip-in —— 同一个动作，两处呈现，节奏必须一致。
 * 动画挂在卡片内层 g 上：外层 g 的 transform 属性负责定位，内层没有定位属性，
 * CSS 的 transform 才能安全地做位移入场（属性与 CSS transform 会互相覆盖）。 */
.node-in { animation: flipIn .38s var(--ease) both; }

/* 副标目：姓名与年号，小、灰、等宽年号。
 * 墨色用 --ink-2 而不是 --ink-3：11px 的小字要过 4.5:1，
 * 浅纸上的 --ink-3 只有约 3.6:1，撑不住 —— 层级靠字号与字重让位，不靠把字调淡。 */
.n-name {
  font-size: 11px;
  font-weight: 400;
  fill: var(--ink-2);
}

/* 主标目：称谓。这是整个程序存在的理由，所以它是卡片上最重的字。
 * fit 自适应会把整张图缩到视口宽 ÷ 横向人数，字号其实被同步压小 ——
 * 所以这里靠「更大的字号 + 更重的字重」拉开与姓名的落差，缩下来仍然先读到称谓。 */
.n-role {
  font-size: 16px;
  font-weight: 700;
  fill: var(--blue);
  letter-spacing: .01em;
}

/* 女性：称谓文字跟着描边一起走粉色，与性别色呼应 */
.node-g.female .n-role { fill: var(--female); }

.n-role.plain { fill: var(--ink-2); font-weight: 500; font-size: 13px; }

.edge { fill: none; stroke: var(--rail-2); stroke-width: 1.4; stroke-linecap: round; }
.edge.marry { stroke-dasharray: 5 4; }
/* 本人 → 选中的人 的连线：只在有选中时才存在，用选中绿 */
.edge.path { stroke: var(--sel); stroke-width: 2.4; }
.edge.sel { stroke: var(--sel); stroke-width: 2.2; }

.rowrule { stroke: var(--rail); stroke-width: 1; }
/* 行线上的短刻度：把「第 N 代」的标签锚在它所属的那一行上 */
.rowtick { stroke: var(--rail-2); stroke-width: 1; }
.rowlabel {
  font-size: 11px;
  fill: var(--ink-2);
  font-family: var(--font-num);
  letter-spacing: .06em;
}

/* 世代导卡（第 N 代）的标签：11px、--ink-2，明暗都过 AA —— 不需要再分主题覆盖 */

/* ---------- 选中中间层（总览树专属） ----------
 * 点卡片只选中：绿线亮在画布上；这条出现在舞台下方，「人物详情」才开面板。
 * 显隐由 ui/core.js 的 rerender 切换（form = tree 且有选中且面板没开）。 */
.pick-bar {
  display: flex;
  gap: 12px;
  justify-content: center;
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
  background: var(--card);
  border-top: 1px solid var(--rail);
}

/* ---------- 非抚养走线 ----------
 * 生父母不在抚养人里时，那条血缘仍要看得见，但不能读成日常抚养关系 ——
 * 点线是「虚线」之外唯一还剩的线形，且**不参与选中变绿**（见 views/tree.js）。 */
.edge.noncustody {
  stroke: var(--rail-2);
  stroke-width: 1.4;
  stroke-dasharray: 1 5;
  stroke-linecap: round;
}

/* 长幼待定：右上角空心点。位置顺序只是姓名序，不能当长幼读 ——
 * 一个点比一行说明更省地方，详情面板里才有文字解释。 */
.mark-undet {
  fill: var(--card);
  stroke: var(--ink-3);
  stroke-width: 1.2;
  stroke-dasharray: 1.4 1.4;
}

/* 非抚养：卡上方的小字，与那条点线呼应 */
.mark-noncustody {
  font-size: 9px;
  letter-spacing: .04em;
  fill: var(--ink-3);
  user-select: none;
}
