+);
+
+const Avatar = ({ member }: { member: GameMember }) => (
+
+);
+
+// 정확히 4명 선택 시, 4명이 이루는 다이아몬드 대진 관계(변 4개 + 대각선 2개 = 총 6쌍)를 그대로 시각화한다.
+const DiamondMatchup = ({
+ members,
+ matchups,
+}: {
+ members: GameMember[];
+ matchups: Map;
+}) => {
+ const [topLeft, bottomLeft, topRight, bottomRight] = members;
+ const infoFor = (a: GameMember, b: GameMember) =>
+ matchups.get(getMatchupKey(a.id, b.id)) ?? {
+ count: 0,
+ type: "first" as const,
+ };
+
+ return (
+
+ {/* overflow-visible: 외곽 4개 선이 viewBox 경계(0/160)에 걸쳐 있어 기본 clip 시
+ stroke의 절반이 잘려 대각선보다 얇게 보이므로, 잘리지 않도록 노출한다. */}
+
+
+ {/* 노드는 아바타 폭(w-10)으로 고정해 그리드 꼭짓점(x=92/252)에 정확히 중앙 정렬한다.
+ 이름은 whitespace-nowrap으로 양옆 대칭 오버플로우시켜 아바타 위치에 영향을 주지 않게 한다. */}
+
+
+ {topLeft.name}
+
+
+
+
+
+
+ {bottomLeft.name}
+
+
+
+
+ {topRight.name}
+
+
+
+
+
+
+ {bottomRight.name}
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+// 4명이 아닌 인원수(1~3명, 5명 이상)에서는 다이아몬드 도형이 성립하지 않으므로,
+// 동일한 배지 색 규칙을 유지하는 쌍별 리스트로 대체한다.
+const PairListMatchup = ({
+ members,
+ matchups,
+}: {
+ members: GameMember[];
+ matchups: Map;
+}) => {
+ const pairs: [GameMember, GameMember][] = [];
+ for (let i = 0; i < members.length; i++) {
+ for (let j = i + 1; j < members.length; j++) {
+ pairs.push([members[i], members[j]]);
+ }
+ }
+
+ if (pairs.length === 0) {
+ return (
+