diff --git a/assets/css/app.css b/assets/css/app.css
index f0960c3..04839ae 100644
--- a/assets/css/app.css
+++ b/assets/css/app.css
@@ -468,7 +468,11 @@ textarea.input { min-height: 76px; resize: vertical; }
position: absolute; left: 0; top: 0;
will-change: transform;
}
-.kin-chart svg.kin-lines { pointer-events: none; }
+.kin-chart svg.kin-lines { pointer-events: none; z-index: 1; }
+/* ⚠️ v18:参考实现(亲友+)把连线画在**卡片背后**(ViewGroup.onDraw 在子 View 之前),
+ 所以线可以从卡中心连到卡中心、被卡面挡住即可 —— 不需要绕路。
+ 这里用 z-index 保证「连线在卡片下面」。 */
+.kin-stage { z-index: 2; }
/* 连线:夫妻短横线 + 子女下垂线,全部一条笔触 */
.kin-chart path.kin-link {
@@ -478,30 +482,42 @@ textarea.input { min-height: 76px; resize: vertical; }
vector-effect: non-scaling-stroke; /* 缩放时线不跟着变粗变细 */
}
+/* v18:卡片改成「上图下名 + 称呼」的窄长形,对齐参考实现(亲友+)的比例:
+ 参考里 50dp 宽 × 80dp 高,头像占满上半、姓名与称呼各一行贴在下半。
+ 我们把 88×106 按同样比例放大 —— 窄一点才排得下"好几代 + 兄弟姐妹"。 */
.kin-card {
position: absolute;
- display: flex; flex-direction: column; align-items: center; justify-content: center;
- gap: 2px;
- box-sizing: border-box; padding: 7px 6px 6px;
+ display: flex; flex-direction: column; align-items: center;
+ gap: 0;
+ box-sizing: border-box; padding: 4px 4px 3px;
text-align: center;
background: var(--surface);
border: 1px solid var(--line);
- border-radius: 14px;
- box-shadow: var(--shadow);
+ border-radius: 10px;
+ box-shadow: 0 1px 3px rgba(43,38,32,.10);
color: var(--ink);
transform: translate(-50%, -50%); /* 坐标给的是卡片中心 */
transition: border-color .15s ease, box-shadow .15s ease;
+ overflow: hidden;
}
.kin-card:hover {
box-shadow: var(--shadow-l); border-color: var(--brand-2); text-decoration: none;
}
.kin-card .kin-ph {
- width: 38px; height: 38px; border-radius: 50%; overflow: hidden;
+ width: 100%; height: 58px; border-radius: 7px; overflow: hidden;
background: #F1E7D6; flex: 0 0 auto;
}
.kin-card .kin-ph img { width: 100%; height: 100%; object-fit: cover; display: block; }
-.kin-card .kin-nm { font-size: 13px; font-weight: 600; line-height: 1.25; }
-.kin-card .kin-lb { font-size: 11px; color: var(--brand); line-height: 1.25; }
+.kin-card .kin-nm {
+ font-size: 12.5px; font-weight: 600; line-height: 1.25; max-width: 100%;
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
+ margin-top: 3px;
+}
+/* 称呼在姓名下面一行,用品牌色的浅字(参考实现是「(称呼)」) */
+.kin-card .kin-lb {
+ font-size: 10.5px; color: var(--brand); line-height: 1.2; max-width: 100%;
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
+}
.kin-card .kin-mark { font-size: 10px; color: var(--faint); }
/* 「我」:品牌色描边 + 光圈 */
diff --git a/templates/kin/tree.php b/templates/kin/tree.php
index 47e3866..2c99b63 100644
--- a/templates/kin/tree.php
+++ b/templates/kin/tree.php
@@ -66,6 +66,10 @@ foreach ($units as $i => $u) {
'me' => $id === (int)$meId,
'ph' => (int)($p['is_placeholder'] ?? 0) === 1,
'gender' => $g === 'm' ? 'M' : ($g === 'f' ? 'F' : 'U'),
+ // ⚠️ 长幼排序键:前端要靠它分「哥哥/弟弟」「姐姐/妹妹」。
+ // 不用生日硬排(很多人没填生日),用 Kinship 里已有的 rankValueFor ——
+ // 它先看 birth_rank,再退回生日,最后用 id 兜底,保证顺序稳定。
+ 'rank' => \App\Kinship::rankValueFor($people, $id),
];
}
if (!$cards) {
@@ -157,6 +161,19 @@ $payloadJson = json_encode(