← Cockpit Wireframes Pages by level Navigation map
Library — conversation and scoring▾
Shipped app (old grammar)Components · 공유 키트상세 페이지 — 플랫 언어Session Card · 밴드 없는 카드
홈 · Home
Home · 홈
시작 · Entry
Onboarding · 시작
ArchiveStrip Map · 세션 스트립 전체 시나리오Headers · 헤더 아이콘Card Continuity · 카드 = 상세의 예고편Session Hero · 더 조용한 공유 카드 (제안)Session Share Card · 히어로 = 공유 카드Session List Frame · 날짜 섹션 · 패널 필터 · 2+2 카드Compaction — 일정 · 코트 · 스코어카드Compaction — 클럽 상세 · 홈Compaction — 기록 · 프로필Live anchor — 진행 중 밴드Density · 카드 밀도토스트 — 리디자인 제안Club List · 클럽Clubs · 클럽클럽 상세 — 여섯 탭 플랫운영 섹션 — 플랫 목표위저드 내비게이션 — 결정 보드드래프트 복원 — 무음 복원클럽 조 편성 — 모델 결정 보드게스트 → 회원 — 심사 흐름Page polish — titled postsWeb app — desktop layoutProduct questions — openWeb app — desktop adaptation, round 2Visual tone — pure white, flat rows, one Tag, a colour budgetLibrary — chrome, surfaces, rows, labelsLibrary — controls, overlays, states, formsLibrary — page patterns, scaling, motionLibrary — additions from the pagesEmpty-once — 프로필 빈 섹션Notification groups — 할 일 밴드 그룹화Profile Cockpit · 프로필 압축Session Detail — Redesign · 일정Venue Detail — Redesign · 테니스장Profile Detail — Redesign · 프로필Tournament Detail — Redesign · 대항전Applicant Detail — Redesign · 가입 심사Canvas Migration — 회비 · 멤버 · 규칙Record Detail — Redesign · 기록Venue Finder · 코트 찾기Venue Filters · 코트 필터 재구성Notifications · 알림Panel Placement · 하단 고정
For owner review

Library — conversation and scoring

Post rows, comments, message bubbles and the composer, reactions, and how a played match gets its score: any player enters it and it is settled, a player may ask for a review, and the host or an official decides.

PostRow

One post of the club feed: who wrote it, what they wrote, what they showed, and how the club reacted.

김
김민준3시간 전
오늘 경기 너무 즐거웠어요. 다들 수고하셨습니다! 다음 주에도 같은 시간에 만나요.
123
Ideal author line, body, photos, then hearts and comments
Photos
김
김민준3시간 전
새 코트 바닥이 깔렸어요
81
One photo 350 × 262 r12 (4:3)
김
김민준3시간 전
오늘 경기 너무 즐거웠어요. 다들 수고하셨습니다! 다음 주에도 같은 시간에 만나요.
+3
216
Three or more two squares and +N over the second
김
김민준3시간 전
이번 달 정기 모임 안내예요. 매주 일요일 오전 7시에 올림픽공원 테니스장에서 복식을 쳐요. 초보자도 환영하고, 라켓과 공은 각자 준비해 주세요. 비가 오면 전날 저녁에 공지해요. 참석 여부는 앱에서 미리 눌러 주세요.더보기
40
Long body 4 lines, then 더보기 inline on the fourth
Variants
총
총무 이서연어제
공지
10월 회비 안내예요. 이번 달부터 계좌가 바뀌었어요.
329
Pinned a neutral 공지 Tag trails the author line
김
김민준3시간 전
삭제된 게시물
Deleted the author line stays; the body is secondary
강남 라켓클럽경기 결과
9월 18일 (금)
김
이
김민준이서연
66
박
최
박지훈최유나
43
52
System: result the club is the author; the body is a neutral ResultRow (no (나), no 승/패)
강남 라켓클럽사진 업로드
+9
90
System: photos the body is the PhotoGrid preview, +N on the last
States
김
김민준3시간 전
새 코트 바닥이 깔렸어요
91
Reacted the viewer's heart is filled, in ink
김
김민준3시간 전
새 코트 바닥이 깔렸어요
91
Pressed the body settles to .98 and dims to .80
Loading avatar, two bars and a 350 × 262 block
Dark
김
김민준3시간 전
오늘 경기 너무 즐거웠어요. 다들 수고하셨습니다! 다음 주에도 같은 시간에 만나요.
123
Dark the photo carries its own colour
200% text
김
김민준3시간 전
오늘 경기 즐거웠어요
123
200% the author line wraps; the action row stays on one line
English
MK
Minjun Kim3h ago
What a great game today. See you all next week at the same time, and bring an umbrella.Show more
123
English Show more; names never cut
Anatomytop to bottom on the rail: author line, min 48: avatar 40 + 12 · name 15/22·600 ink (wraps, never cut) · time 13/18·500 secondary · ⋯ IconButton (20 glyph in a 48 target, its glyph's right edge on the rail). 12 → body 16/24·400 ink, a 4-line clamp with 더보기 15/22·600 secondary inline on the fourth line (it opens the post). 12 → photos: one = 350 × 262 r12 (4:3); two = two 171 squares r8, gap 8; three or more = two squares with "+N" 20/28·700 white on ink α0.5 over the second. 12 → action row, min 48: heart 20 + the total reaction count 13/18·600, comment 20 + count, gap 16. Posts sit 32 apart with no line.Reactionsthe feed heart carries the total and there are no chips in the feed; the post page shows the per-emoji chips under the body (Reactions) and its heart carries no number.VariantsFeed · Pinned (a neutral Tag "공지") · Deleted ("삭제된 게시물" 15/22 secondary) · System (경기 결과, 사진 업로드): the author line is the club (logo 40 r12) with a 13/18 secondary line naming the event instead of a time; the body is the result (ResultRow) or the PhotoGrid preview (three tiles, +N on the last); no ⋯.Accessibilitystops in order: the author ("김민준, 프로필"), ⋯ ("김민준 게시글 메뉴"), the post (body and photos: "게시글, 김민준, 3시간 전, {the first words}, 사진 3장"), the heart ("공감 12개", aria-pressed), the comment control ("댓글 3개"). The heart's tap toggles ❤️; its long-press (on the post page, its tap) opens the MenuSheet with the Reactions quick row.Motionpress settle; the heart fills over 100 ms; reduced motion: dim only.Replaces in codepost-row.tsx (PostFeedRow, FeedPhotoStrip) and the feed auto-rows.

Comment

A reply under a post, with one level of replies beneath it.

김
김민준2시간 전
좋은 경기였어요. 다음 주에도 같은 시간에 만나요!
답글 달기
이
이서연1시간 전
저도 같은 생각이에요. 다음에 또 쳐요!
Ideal the body indents to the name; replies one level in
김
김민준2시간 전
좋은 경기였어요. 다음 주에도 같은 시간에 만나요!
답글 달기
이
이서연1시간 전
저도 같은 생각이에요. 다음에 또 쳐요!
Collapsed replies more than two replies fold behind a tonal sm Button with a down chevron
김
김민준2시간 전
좋은 경기였어요
답글 달기
이
이서연1시간 전
저도 같은 생각이에요. 다음에 또 쳐요!
박
박서준1시간 전
다음 주엔 제가 공 가져갈게요
답글 달기
최
최유나방금
저도 참석할게요
답글 달기
Thread spacing 24 between comments, 12 to its replies
Variants and states
김
김민준2시간 전
삭제된 댓글이에요
이
이서연1시간 전
저도 같은 생각이에요. 다음에 또 쳐요!
Deleted it keeps its replies
나
나보내는 중
저도 참석할게요
답글 달기
Sending the comment is dimmed to .6
김
김민준2시간 전
정기 모임 일정이 바뀌었어요. 이번 달부터 일요일 오전 7시가 아니라 8시에 시작해요. 코트 예약이 어려워서 시간을 조금 늦췄고, 늦게 오시는 분은 단체 대화방에 미리 알려 주세요. 참석 여부는 앱에서 눌러 주세요.더보기
답글 달기
Preview 4 lines and 더보기 where comments are previewed
Dark
김
김민준2시간 전
좋은 경기였어요
답글 달기
이
이서연1시간 전
저도 같은 생각이에요. 다음에 또 쳐요!
Dark the avatar ground is gray100
200% text
김
김민준2시간 전
좋은 경기였어요
답글 달기
200% names wrap and are never cut
English
MK
Minjun Kim2h ago
Great game. See you next week!
Reply
SL
Seoyeon Lee1h ago
Same here. Let us play again soon!
English Show N more replies
Anatomyavatar 32 at the rail; the text column starts at x 64. Line 1: name 15/22·600 + the MetaBreak + time 13/18·500 secondary, with a ⋯ IconButton (20 glyph in a 48 target) at the right. Body 16/24·400 ink in the text column: full on the post page, 4 lines + 더보기 in previews. Under the body 답글 달기, a ghost sm Button (a command is a Button; its text edge sits on the text column’s edge). 답글 n개 더 보기 is a tonal sm Button with a down chevron, a disclosure (it expands in place; an action cue is a control, never bare text, owner review 48). Replies: one level; avatar 24 at x 64, text column at x 96; a deeper reply flattens with an @name; more than two replies collapse behind that Button, full width of the reply column, 12 under the last reply ("답글 3개 더 보기"). 24 between comments, 12 between a comment and its replies.Contentthe body indents to the name because short, threaded text belongs to its author; PostRow keeps its full-width body for long content and photos. Names never cut. Deleted: "삭제된 댓글입니다" in secondary; it keeps its replies.Accessibilityone stop for the comment ("김민준, 2시간 전, {body}"); ⋯ and the 답글 달기 button are their own stops; replies follow in document order.Motionthe toggle reveals over 250 ms and its chevron turns over 200 ms; reduced motion: instant.Replaces in codecomment-row.tsx (CommentRow).

MessageBubble

One message in a conversation. Bubbles stack into runs; the lines between them carry the date and system events.

김민준
9월 18일 (금)
내일 몇 시에 모일까요?
비 올 수도 있대요
14:05
9시에 올림픽공원에서 봐요
우산 챙겨 오세요
14:06
읽음
메시지 보내기
9:41
ㅂㅈㄷㄱㅅㅛㅕㅑㅐㅔ
ㅁㄴㅇㄹㅎㅗㅓㅏㅣ
⇧ㅋㅌㅊㅍㅠㅜㅡ⌫
123스페이스완료
Ideal a 1:1 thread, keyboard up: run gap 2, 12 to the composer
김민준
9월 18일 (금)
내일 몇 시에 모일까요?
비 올 수도 있대요
14:05
9시에 올림픽공원에서 봐요
우산 챙겨 오세요
14:06
9월 19일 (토)
지금 도착했어요
08:52
저도 곧 가요
08:53
읽음
메시지 보내기
9:41
Keyboard hidden the bar keeps the home inset only here
일요 복식 모임
박서준님이 입장했어요
김
김민준
다들 몇 시에 오세요?
저는 9시쯤 도착해요
14:05
이
이서연
저는 8시 50분이요
14:06
저도 9시에 가요
14:07
메시지 보내기
9:41
Group thread label and avatar on a run's first bubble
김민준
9월 18일 (금)
내일 몇 시에 모일까요?
비 올 수도 있대요
14:05
9시에 올림픽공원에서 봐요
김민준님에게 답글
비 올 수도 있대요
그럼 실내 코트로 옮겨요
9:41
ㅂㅈㄷㄱㅅㅛㅕㅑㅐㅔ
ㅁㄴㅇㄹㅎㅗㅓㅏㅣ
⇧ㅋㅌㅊㅍㅠㅜㅡ⌫
123스페이스완료
Reply target a 44 row names the message being answered
States
9시에 올림픽공원에서 봐요
14:06
Sending a 12 clock before the time; the bubble at .6
9시에 올림픽공원에서 봐요
14:06
보내는 중
Queued offline: 보내는 중 under the bubble
9시에 올림픽공원에서 봐요
14:06
보내지 못했어요다시 보내기삭제
Failed 전송 실패, then 다시 보내기 and 삭제
9시에 올림픽공원에서 봐요
14:06
읽음
Delivered the last sent bubble of a 1:1 thread: 읽음
다음 주엔 제가 공 가져갈게요
14:05
32
Reactions summary chips 4 under the bubble
Away from the bottom
김민준
9월 12일 (토)
일요일에 복식 한 번 칠래요?
좋아요. 몇 시가 편하세요?
오전 9시요
코트는 제가 예약할게요
19:40
고마워요
19:42
9월 13일 (일)
오늘 즐거웠어요
11:30
저도요. 다음 주에도 봬요
11:34
9월 18일 (금)
내일 몇 시에 모일까요?
비 올 수도 있대요
14:05
9시에 봐요
우산 챙겨요
14:06
새 메시지 3개
메시지 보내기
9:41
New messages a tonal pill 12 above the composer
Dark
김민준
9월 18일 (금)
내일 몇 시에 모일까요?
비 올 수도 있대요
14:05
9시에 올림픽공원에서 봐요
우산 챙겨 오세요
14:06
9월 19일 (토)
지금 도착했어요
08:52
저도 곧 가요
08:53
읽음
메시지 보내기
9:41
Dark mine is #505A53, 1.5 : 1 from theirs
200% text
김민준
9월 19일 (토)
지금 도착했어요
08:52
저도 곧 가요
08:53
읽음
메시지 보내기
9:41
200% bubbles wrap; the max width holds
English
김민준
Fri, Sep 18
What time should we meet?
It might rain
14:05
Let us meet at 9 at Olympic Park
14:06
Read
Message
9:41
English 24-hour times, the same formatter as Korean
Bubblepad 8 12 · r18, the sender-side corner 6 on the last bubble of a run · text 16/24 (the reading role, the same size as the composer's input). Mine: ink #15181A fill, white text, right-aligned; in dark it is #505A53, 1.5 : 1 from the other side's bubble, so the side is not the only cue. Theirs: gray100 fill, ink text, left-aligned. Max width 306 in a 1:1 thread, 266 in a group.Group senderthe first bubble of another sender's run has the sender label (13/18·600 $textSecondary, 18 tall) 4 above the bubble and an avatar 32, its top aligned with the label's top, 8 before the bubble. A 1:1 thread shows neither.Spacing2 within a run (same sender, same minute); 12 between runs; a new sender in a group is 12 above the label (34 from the previous bubble to this one); the first item is 12 below the header; 12 from the last bubble to the composer's top edge. Time: 12/18·500 secondary, 4 from the bubble's edge, bottom-aligned with the last line, on the last bubble of a run only. Date and system lines ("9월 18일 (금)", "OOO님이 입장했어요"): centred 13/18·500 secondary, 20 above and below, never a bubble.Statessending: a 12 clock glyph before the time, centred on the time’s line, the bubble at .6 · queued (offline): "보내는 중" under the bubble, the composer stays enabled · failed: "전송 실패" 13/18·600 $errorText, then 다시 보내기 and 삭제 as two ghost sm Buttons (a command is a Button, so no text actions), right-aligned 4 under the bubble with the last label’s edge on the rail; 삭제 removes the unsent message at once · delivered (the last sent bubble of a 1:1 thread): "읽음" or "전송됨" 12/18·500 secondary, right-aligned 4 under it; none in a group · reactions: summary chips under the bubble · away from the bottom: "새 메시지 3개" as a tonal sm pill (36) centred 12 above the composer, shown when the thread is more than a screen from the bottom.Accessibilityone stop per bubble: "김민준, 오후 2시 5분, {text}" (mine: "나, …"); sending and failed are in the name ("전송 실패"); the long-press has an accessibility action that opens the MenuSheet; the new-message pill is announced.Motiona new bubble fades in with an 8 rise over 150 ms (reduced motion: the fade only); on focus the thread scrolls to the newest message.Replaces in codedm-message-row.tsx and the spacing literals in use-dm-chat-items.ts and dm-thread-screen.tsx (one constants file holds the thread values).

Composer

The bar that writes the next message or comment.

메시지 보내기
Ideal attach, a gray100 field, a send circle; inert when empty
States
9시에 올림픽공원에서 봐요
Has text the send circle turns ball with an ink arrow
9시에 올림픽공원에서 봐요
Sending the circle dims while the message goes
9시에 올림픽공원에서 봐요
Offline it stays enabled; messages queue
내일 비 예보가 있어서 실내 코트로 옮기는 게 어떨까요? 실내는 대관비가 조금 더 들지만 안전해요. 의견 주세요.
Grown the field grows to five lines, then scrolls
Variants
그럼 실내로 옮겨요
Keyboard up flush on the keyboard: gap 0 and no home inset
댓글 달기
Comment composer a field and a send; no attach
김민준님에게 답글
좋은 경기였어요. 다음 주에도 같은 시간에 만나요
저도요
Reply target a 44 row above the field; × clears the target
Attach
첨부
사진
카메라
Attach the + opens a MenuSheet with two labelled rows
Dark
9시에 올림픽공원에서 봐요
Dark gray100 field; the send stays ball
English
Message
English the field is labelled Message
Anatomythe bar is min 56 (8 + the field 40 + 8) plus the home inset only while the keyboard is hidden; with the keyboard up it sits flush on it (gap 0, inset 0). On the rail, left to right: attach IconButton (24 glyph at the rail, 48 target bleeding 12 into the margin; it opens a MenuSheet with the labelled rows 사진 · 카메라) · 8 · field gray100, r20, min 40, 16/24, pad 8 16, growing to five lines (136) and then scrolling · 8 · send, a 36 circle with a 20 arrow in a 48 target, its right edge on the rail. An edge hairline draws on top while content scrolls under the bar. The thread's bottom inset is the composer height + 12.Reply-target rowa 44 row inside the composer above the field, 8 above it: "OOO님에게 답글" 13/18·600 secondary, then a one-line excerpt 13/18 secondary that ellipsizes (quoted text, not a name, so it may crop), and a × IconButton (20 glyph in a 48 target) that clears the target. It appears with the field's focus over 250 ms.Statesempty (the send circle is gray100 with a $textSecondary arrow and inert) · has text (ball circle, ink arrow) · sending · offline (stays enabled; messages queue).Accessibilitythe field is labelled ("메시지", "댓글"); attach is "첨부"; send is "보내기"; the reply-target row is read when it appears; × is "답글 취소".Motionthe bar rides the keyboard (KeyboardStickyView); the reply-target row reveals over 250 ms; reduced motion: instant.Replaces in codecompose-bar.tsx, comment-composer.tsx.

Reactions

React to a message, a post or a match result with one of six, and see who did: a quick row to react, a chip summary to see and toggle.

김민준내일 비 오면 어떻게 할까요?
답장
복사
신고
Ideal the quick row first in the object's MenuSheet
Quick row six 44 circles, gap 16; the viewer's own has a 2px ring
1252
Summary chips 32 tall; the viewer's own has a 1.5px ink ring
States and variants
Not selected a count of 0 draws no chip
Pressed the circle settles and dims
99+64321684
Many chips they wrap; counts cap at 99+
반응한 사람
김
김민준
총무
이
이서연
박
박서준
Who reacted a long-press on a chip lists people in a Sheet
Dark
125
Dark gray100 chips; the ring stays ink
English
English spoken names: Like, Heart, Clap, Fire, Laugh, Tennis ball
The setthe same on every surface, in this order: 👍 ❤️ 👏 🔥 😂 🎾 (approval, affection, applause, intensity, humour, the sport). Emoji are content here, not fact glyphs. Spoken names: 좋아요, 하트, 박수, 불꽃, 웃음, 테니스공.Quick rowat the top of the object's MenuSheet, between the title row and the first group. The six sit in 44 gray100 circles (emoji 24), gap 16, hit area 48 by slop. The viewer's current reaction has a 2px ink ring; a tap toggles it and closes the sheet. The sheet's title row shows the sender or author and a one-line excerpt of the message or post it acts on (13/18 secondary, may crop).Summaryunder the bubble or the post body: chips 32 tall, r full, gray100, pad 0 10, emoji 16 + count 13/18·600 tabular, gap 4 inside, 8 between chips and 12 between wrapped rows (each chip is a 44 target by slop, so the targets do not meet). The viewer's own has a 1.5px ink ring. A tap toggles that reaction; a long-press lists who reacted in a Sheet of PersonRows. Feed: the action row's heart carries the total and there are no chips; the heart's tap toggles ❤️.Accessibilityeach quick-row circle is a button with aria-pressed; each chip is a button ("좋아요 3명, 내가 반응함", aria-pressed); an accessibility action "누가 반응했나요" opens the list; the chips follow the message in document order.Motionring and fill change over 100 ms; counts change instantly; reduced motion: instant.Replaces in codethree vocabularies become one domain registry: REACTION_TYPES and REACTION_EMOJI (reaction.entity.ts), the local map in post-row.tsx and QUICK_REACTIONS in dm-thread/helpers.ts; the database enums migrate with the registry; the ReactionPickerModal in post-row.tsx.

ScoreEntry

One way to record a finished match: type it, keypad first. Any player, the host or an official enters it and it is settled at once; the same sheet asks for a review (appeal) or lets the host change the score.

스코어카드
9:41
2라운드 1번 코트
1세트
김
이
김민준 (나)이서연
박
최
박지훈최유나
경기 중단점수 저장
123
456
789
0⌫
Ideal Keypad up, my cell focused: nothing to choose first
스코어카드
9:41
2라운드 1번 코트
1세트
김
이
김민준 (나)이서연
6
박
최
박지훈최유나
경기 중단점수 저장
123
456
789
0⌫
Typing A digit fills the cell and focus moves on
스코어카드
9:41
2라운드 1번 코트
1세트
김
이
김민준 (나)이서연
6
박
최
박지훈최유나
4
경기 중단점수 저장
123
456
789
0⌫
Typed a win 6-4 is three taps: 6, 4, the button
스코어카드
9:41
2라운드 1번 코트
1세트
김
이
김민준 (나)이서연
4
박
최
박지훈최유나
6
경기 중단점수 저장
123
456
789
0⌫
Typed a loss 4-6 costs the same: my line is first
States
스코어카드
9:41
2라운드 1번 코트
1세트 타이브레이크, 진 쪽 점수1세트TB
김
이
김민준 (나)이서연
7
박
최
박지훈최유나
6
경기 중단점수 저장
123
456
789
0⌫
Tiebreak 7-6 opens a cell right of the 6, labelled TB above and named in the line at left while it is focused
스코어카드
9:41
2라운드 1번 코트
1세트 타이브레이크, 진 쪽 점수1세트TB
김
이
김민준 (나)이서연
7
박
최
박지훈최유나
6
5
경기 중단점수 저장
123
456
789
0⌫
Tiebreak typed 7-6(5) is four taps
스코어카드
9:41
2라운드 1번 코트
1세트
김
이
김민준 (나)이서연
6
박
최
박지훈최유나
5
6-5는 끝난 세트가 아니에요
경기 중단점수 저장
123
456
789
0⌫
Invalid The rule that failed is the only line; the button waits
스코어카드
9:41
2라운드 1번 코트
1세트
김
이
김민준 (나)이서연
6
박
최
박지훈최유나
4
경기 중단저장 중…점수 저장
123
456
789
0⌫
Saving The button shows its loading state
2라운드
1번 코트
김
이
김민준 (나)이서연
6
박
최
박지훈최유나
4
저장됐어요
Saved The row is settled; a Toast with no action
2라운드
1번 코트보내는 중
김
이
김민준 (나)이서연
6
박
최
박지훈최유나
4
연결되면 보낼게요
Queued Offline: 보내는 중 on the row, a Toast says it will send
2라운드
1번 코트
김
이
김민준 (나)이서연
6
박
최
박지훈최유나
4
이미 입력됐어요
Same score twice Someone entered the same sets: a Toast, nothing to ask
Appeal and host
스코어카드
9:41
점수 검토 요청2라운드 1번 코트
1세트
김
이
김민준 (나)이서연
6
박
최
박지훈최유나
4
검토 요청
123
456
789
0⌫
Appeal The stored score in the cells; the button asks for a check
스코어카드
9:41
점수 검토 요청2라운드 1번 코트
박지훈님이 먼저 입력했어요
입력된 점수
김
이
김민준 (나)이서연
6
박
최
박지훈최유나
4
내가 아는 점수
1세트
김
이
김민준 (나)이서연
6
박
최
박지훈최유나
3
검토 요청
123
456
789
0⌫
Turned into an appeal Another score landed first: my digits stay as mine
대진표
9:41
점수 고치기2라운드 1번 코트
1세트
김
이
김민준이서연
6
박
최
박지훈최유나
4
점수 저장
123
456
789
0⌫
Host changes it 점수 고치기 from the stored score, slot order
대진표
9:41
2라운드 1번 코트
1세트
김
이
김민준이서연
박
최
박지훈최유나
경기 중단점수 저장
123
456
789
0⌫
Host enters A host not playing enters for them: slot order, no (나)
스코어카드
9:41
2라운드 1번 코트
1세트TB2세트
김
이
김민준 (나)이서연
7
박
최
박지훈최유나
6
5
경기 중단점수 저장
123
456
789
0⌫
Best of three Set 2’s cells open; set 1’s tiebreak stays beside its own 6
스코어카드
9:41
2라운드 1번 코트
1세트TB2세트TB3세트
김민준 (나)이서연
7
6
4
박지훈최유나
6
5
7
경기 중단점수 저장
123
456
789
0⌫
Three sets, two tiebreaks Each tiebreak widens its own set and carries its own TB label; the names keep their room
2라운드
1번 코트
검토 중
김
이
김민준 (나)이서연
6
박
최
박지훈최유나
4
검토를 요청했어요
Asked The row reads 검토 중; the entrant is told only that a review was asked
Stopped before the end
스코어카드
9:41
무슨 일이 있었나요?
한 팀이 도중에 그만뒀어요
기권
한 팀이 오지 않았어요
부전승
비나 시간 때문에 멈췄어요
일시 중단
경기를 하지 않았어요
취소됨
두 팀 모두 오지 않았어요
양측 불참
다음
Reason 경기 중단 opens one list; nothing chosen, 다음 is soft
스코어카드
9:41
무슨 일이 있었나요?
한 팀이 도중에 그만뒀어요
기권
한 팀이 오지 않았어요
부전승
비나 시간 때문에 멈췄어요
일시 중단
경기를 하지 않았어요
취소됨
두 팀 모두 오지 않았어요
양측 불참
어느 팀이 그만뒀어요?
김민준 (나), 이서연
박지훈, 최유나
다음
Which team A reason that needs it reveals the team below, on the same screen
스코어카드
9:41
그때까지의 점수박지훈, 최유나 팀 기권, 김민준, 이서연 팀 승
1세트2세트
김
이
김민준 (나)이서연
6
3
박
최
박지훈최유나
4
1
기권 저장
123
456
789
0⌫
Score so far The sub states the outcome; 기권 저장 settles it
스코어카드
9:41
어디까지 했나요?일시 중단, 승패 없이 기록해요
그때까지의 점수
1세트2세트
김
이
김민준 (나)이서연
6
3
박
최
박지훈최유나
4
3
이어서 할까요?
다음 모임에 이어서
여기서 끝낼게요
미완료로 남아요
일시 중단 저장
123
456
789
0⌫
Suspended A 일시 중단 also asks if you will finish it
대진표
9:41
무슨 일이 있었나요?
한 팀이 도중에 그만뒀어요
기권
한 팀이 오지 않았어요
부전승
비나 시간 때문에 멈췄어요
일시 중단
경기를 하지 않았어요
취소됨
규칙 위반으로 실격
실격
두 팀 모두 오지 않았어요
양측 불참
어느 팀이 실격이에요?
김민준, 이서연
박지훈, 최유나
다음
Host The host also sees 실격
대진표
9:41
그때까지의 점수박지훈, 최유나 팀 기권, 김민준, 이서연 팀 승
1세트2세트
김
이
김민준이서연
6
3
박
최
박지훈최유나
4
1
기권 저장
123
456
789
0⌫
Host, score The same cells in slot order; the sub names the sides
Dark · English · 200% text
스코어카드
9:41
2라운드 1번 코트
1세트
김
이
김민준 (나)이서연
6
박
최
박지훈최유나
4
경기 중단점수 저장
123
456
789
0⌫
Dark The cells keep the 3:1 border
Scorecard
9:41
Round 2, Court 1
Set 1
M
S
Minjun Kim (You)Seoyeon Lee
J
Y
Jihun ParkYuna Choi
Stop matchSave score
123
456
789
0⌫
English Save score; Stop match
Scorecard
9:41
Ask for a reviewRound 2, Court 1
Set 1
M
S
Minjun Kim (You)Seoyeon Lee
6
J
Y
Jihun ParkYuna Choi
4
Ask for a review
123
456
789
0⌫
English, appeal Ask for a review
Scorecard
9:41
What happened?
A team stopped partway
Retired
A team didn’t come
Walkover
Stopped for rain or time
Suspended
We didn’t play
Cancelled
Neither team came
Both absent
Next
English, stop The reason Cells read the same in English
스코어카드
9:41
2라운드 1번 코트
1세트 타이브레이크, 진 쪽 점수1세트 TB
김민준 (나)이서연
7
박지훈최유나
6
5
경기 중단점수 저장
123
456
789
0⌫
200% The cells stay 48; the set and TB labels merge into one, the sheet grows upward
Doorsenter: a finished match with no score. A player’s Match row shows 점수 입력, the host’s 대신 입력, and the scorecard’s Match state block reads 점수 입력; each opens this Sheet. appeal: the Match state block’s door (the sm Door pill) 점수 검토 요청 › on an entered score. host: 점수 고치기 on the host review sheet, or on the row when no review is open. A player who opens enter after a score landed finds the score, not an empty keypad: the door is gone.Why keypad firstowner review 4, point 3: presets cluttered and no peer offers them (UTR, DUPR, Match Tennis, Playtomic all type the score); Toss’s amount entry opens on the keypad with nothing to choose first. Cost against chips: none for 6-4 or a loss (3 taps), one more for 6-1. Gain: 4 controls on screen at open instead of 18.Anatomya Sheet over the page, docked on the numeric keypad (216 + 34), top to bottom: (1) the title row 48: the match name with ×; appeal and host are titled 점수 검토 요청 and 점수 고치기 over the match. (2) The set table, the cells context of the team lines: one team per line, partners with the 1px break, names 15/22·600 (wrap, never cut); a player’s team is on top with "(나)" and its first cell is focused, a host sees slot order; each cell is a number Input 48 × 48, r12, $borderControl, 24/32·700 centred numerals, cells 8 apart, the set labels 13/18·500 above each column. (3) The tiebreak: a compact 36 × 36 Input (two digits wide, in a 44 target, no placeholder; named by a persistent TB label in the header row over it, 13/18·500 secondary like the set labels, and while focused by a live line in the header’s free space, 1세트 타이브레이크, 진 쪽 점수, 13/18·600 ink, wrapping with keep-all, the set labels on its last line; spoken as “1세트 타이브레이크, 진 쪽 점수”; from 1.5× the set and TB labels merge into one, 1세트 TB) on the line of the team that lost the tiebreak (the 6 side; at 6-6 the second line), directly right of that team’s games cell, 4 apart, as the display draws it; only at 6-6 and 7-6, focused at once. The set’s column widens by 40 on both lines (the other line keeps an empty slot), so the next set stays aligned, and the set label stays centred over the games cells; each set that needs one has its own cell. Three sets with a tiebreak leave the names under 120 at 390, so the faces drop (names are never narrowed, they wrap to two lines). (4) The footer: in enter mode the pair, a tonal 경기 중단 at one third and the primary 점수 저장 at two thirds (a command is a Button, so there is no inline text; the pair stacks with the commit on top from 1.5× text); appeal and host have the one primary button, max(16, 0) below it with the keypad up. Controls on screen: at most two cells per set and the buttons. Helper lines: none (the live tiebreak line names the focused cell, it is not a helper); a validation error is the only line and takes the helper’s place, in danger.Typinga digit fills the focused cell and focus moves to the next: a game takes one digit, so the first set is done in two taps. At 6-6 or 7-6 one tiebreak cell appears right of the losing team’s games cell for that set and takes focus; it takes two digits and focus never leaves it by itself. When a set is valid the next set’s cells appear if the match format has one. An invalid set (6-5, 8-2) shows the danger line and keeps the button soft. Taps: 6-4 is 3, a loss is 3, 7-6(5) is 4, any other score is 3.Modesenter: title = the match, the pair 경기 중단 and 점수 저장 for everyone · appeal: title 점수 검토 요청, cells prefilled with the stored score, button 검토 요청, no stop button; leaving the digits unchanged sends "please check" · host: title 점수 고치기, prefilled, slot order, button 점수 저장, no stop button · English: Save score, Ask for a review, Change the score, Stop match. The button names are the whole of the sheet’s copy: no helper line says who confirms, because nobody does.Turned into an appealtwo players enter at once (race Q1): the first commit wins; the second write is refused with score_changed and the stored score. This sheet turns into the appeal sheet in place: a warning Notice "{이름} 님이 먼저 입력했어요", the stored score as 입력된 점수, and the digits typed so far as 내가 아는 점수; one tap on 검토 요청 sends them as the proposed score. The same sets typed twice are a no-op: the Toast 이미 입력됐어요 and nothing to ask.Stop stepthe second step of the same Sheet, two screens with a back arrow in the title row and a footer button each; no helper line and no extra modal. (1) 무슨 일이 있었나요?: radio Cells, each with its outcome word trailing: 한 팀이 도중에 그만뒀어요 기권 · 한 팀이 오지 않았어요 부전승 · 비나 시간 때문에 멈췄어요 일시 중단 · 경기를 하지 않았어요 취소됨; the host and officials also see 규칙 위반으로 실격 처리. A reason that needs a team reveals 어느 팀이 그만뒀어요? (오지 않았어요, 실격이에요) below it on the same screen, the two teams as radio Cells with the player’s own marked (나): sequential reveal, nothing for 일시 중단 and 취소됨; 다음 waits for what the reason needs. (2) the score so far in the same cells, keypad up (optional for 부전승 and 취소됨); a 일시 중단 adds 이어서 할까요? with 다음 모임에 이어서 and 여기서 끝낼게요 (it becomes 미완료). This last screen is the confirmation: its sub states the outcome in words (박지훈, 최유나 팀 기권, 김민준, 이서연 팀 승) and the commit button is named for it: 기권 저장, 부전승 저장, 일시 중단 저장, 취소 저장, 실격 저장. It settles and rates at once and the Toast follows with no action; a recorded stop is not self-correctable, its entrant keeps 점수 검토 요청. Who records: retired, any player, the host or an official · walkover, cancelled and suspended, a player, the host or an official · defaulted, the host or an official only (a ruling, not a statement). 기록에서 제외 is not a stop reason: it lives on the host review sheet. The rain outcome is 일시 중단, so it never collides with the 경기 중단 button. A false retirement is an appeal like any other.Statesrest (the first cell focused, the button soft) · typing · valid (the button live) · tiebreak · invalid (2px danger border and the line above the button) · saving (저장 중… / 요청 중…) · saved · queued · the three stop screens. Dismissing with unsaved digits asks the guard Dialog.After savingthe Toast 저장됐어요 has no action: the score is rated at once, and the entrant may change it for 10 minutes (점수 고치기, the server decides); after that, or for anyone else, 점수 검토 요청. The gate opens at once and the other three players are told once (P2). Offline: the row reads 보내는 중 and the Toast 연결되면 보낼게요; the write carries its idempotency key and the revision it saw (Q5). An entry that meets a stored score is never dropped: the row reads 점수가 이미 있어요 and the unsent digits wait as a proposed score, one tap away.Spokeneach cell is named "{team names}, {n}세트 점수"; 경기 중단 is a button; validation is announced; the table reads as one group: "내 팀 김민준, 이서연. 상대 팀 박지훈, 최유나."; the stop reasons are a radio group read with their outcome words.Motionthe Sheet rises over 300 ms with the keypad; the next set’s cells appear over 200 ms; the stop step slides in from the right over 200 ms and back from the left; the turn into the appeal sheet cross-fades over 200 ms; reduced motion: a fadeReplaces in codescore-edit-sheet.tsx (ScoreEditSheet, ±1 steppers: ten taps for 6-4), score-call-sheet.tsx (ScoreCallSheet), score-correction-sheet.tsx, the inline numeric fields on match-card.tsx, multi-set-score-entry.tsx (whose progressive-row logic the table keeps); the stop step is new. Variants: 8 (enter, appeal, host, one set, bo3/5, stop × 2), was 9 with helper lines on every one.

Host review sheet

How the host or an official settles a review: keep the score, change it, or (behind ⋯) leave the match out of the record.

대진표
9:41
점수 검토3라운드 2번 코트
입력된 점수
김
이
김민준이서연
6
박
최
박지훈최유나
4
박지훈님이 입력한 점수
김
이
김민준이서연
6
박
최
박지훈최유나
3
그대로 두기이 점수로 바꾸기
With a proposal The entered score, then the one a player gave
대진표
9:41
점수 검토3라운드 2번 코트
입력된 점수
김
이
김민준이서연
6
박
최
박지훈최유나
4
그대로 두기점수 고치기
No proposal The player only asked for a check: 점수 고치기 opens the keypad
대진표
9:41
점수 검토3라운드 2번 코트
입력된 점수
김
이
김민준이서연
6
박
최
박지훈최유나
4
박지훈님이 입력한 점수
김
이
김민준이서연
6
박
최
박지훈최유나
3
그대로 두기이 점수로 바꾸기
3라운드 2번 코트
기록에서 제외
Menu The rare command sits behind ⋯: one row, in danger
대진표
9:41
점수 검토3라운드 2번 코트
입력된 점수
김
이
김민준이서연
6
박
최
박지훈최유나
4
박지훈님이 입력한 점수
김
이
김민준이서연
6
박
최
박지훈최유나
3
그대로 두기이 점수로 바꾸기
기록에서 제외할까요?ELO와 전적에서 빠져요. 나중에 다시 포함할 수 있어요.
취소제외
기록에서 제외 One danger question before it leaves the record
대진표
9:41
검토 3경기
1라운드 1번 코트
검토 중
김
이
김민준이서연
6
박
최
박지훈최유나
4
2라운드 2번 코트
검토 중
정
한
정우진한소희
6
오
윤
오세훈윤하은
2
3라운드 3번 코트
검토 중
최
오
최유나오세훈
7
김
윤
김민준윤하은
5
Several reviews The 검토 N경기 Task Cell opens a list first
Dark · English
대진표
9:41
점수 검토3라운드 2번 코트
입력된 점수
김
이
김민준이서연
6
박
최
박지훈최유나
4
박지훈님이 입력한 점수
김
이
김민준이서연
6
박
최
박지훈최유나
3
그대로 두기이 점수로 바꾸기
Dark Both buttons keep their weight
Match board
9:41
Review the scoreRound 3, Court 2
The entered score
M
S
Minjun KimSeoyeon Lee
6
J
Y
Jihun ParkYuna Choi
4
The score Jihun Park entered
M
S
Minjun KimSeoyeon Lee
6
J
Y
Jihun ParkYuna Choi
3
Keep itUse this score
English Review the score; Keep it, Use this score
Anatomya Sheet with × in the title: the title 점수 검토 over the match as its excerpt · 입력된 점수 as team lines in slot order (the entered score, the winner emphasised) · when a player proposed a score that differs, "{이름} 님이 말한 점수" under it as team lines, both teams equal (a proposal never reads as a result) · the pair 그대로 유지 (tonal) and 이 점수로 바꾸기, which with no proposal reads 점수 고치기 and opens ScoreEntry mode host prefilled. The rare, subtractive command is not in the footer: a ⋯ IconButton (label 더보기) sits in the title row before ×, and opens a MenuSheet titled with the match with one row, 기록에서 제외 (danger). Controls: ⋯, ×, two buttons. Helper lines: none.Whoa host or official who is not playing the match: club owner, admin, match_director or the session creator. A host who plays acts as a player there and another official reviews it; with none, the score stands and the review stays on the record (the appellant’s row reads 검토할 수 있는 운영자가 없어요). Opened by the 검토 N경기 Task Cell, the 검토 중 row or the P3 push.Actions그대로 유지: the review closes, the score and ratings stand, the appellant is told · 이 점수로 바꾸기 / 점수 고치기: a new revision, ratings replay, all four are told · 기록에서 제외 (⋯, then the row): a danger Dialog, 기록에서 제외할까요? with ELO와 전적에서 빠져요. 나중에 다시 포함할 수 있어요. and 취소 · 제외; then the match becomes not counted, the rating reverts by replay, all four are told, the gate stays open. The host restores it from the match with the Button 다시 기록에 포함 (a Button, never a text action); the rating replays. An appeal left for appealStandDays stands as entered.Racesthe host’s change carries the revision it replaces. If the entrant changed it in between, the host sees the new score under the Notice 방금 점수가 바뀌었어요 and decides again; an appeal that lands after a host change gets score_changed and may ask again. Nothing is ever overwritten silently.Spokenthe title is the first stop; the entered score and the proposal read as two groups: "입력된 점수. 내 팀 … 6. 상대 팀 … 4."; the buttons read their text; ⋯ is read 더보기 and opens the menuReplaces in codenothing: today a rejected call is deleted and no screen resolves it (reject_call, submit_match_score for a non-playing host). Replaces the Decide sheet of the dispute flow.

Match row states

One match in a round of the 대진표 and the scorecard: scheduled, playing, waiting for a score, entered, under review, left out of the record, held behind an earlier match, or stopped.

2라운드
1번 코트
예정
김
이
김민준이서연
박
최
박지훈최유나
2번 코트
진행 중
정
한
정우진한소희
오
윤
오세훈윤하은
3번 코트
박
한
박지훈 (나)한소희
정
윤
정우진윤하은
점수 입력
4번 코트
최
오
최유나오세훈
6
김
윤
김민준윤하은
4
5번 코트
검토 중
김
이
김민준이서연
6
박
최
박지훈최유나
4
6번 코트ELO에 반영되지 않아요
기록 제외
정
한
정우진한소희
오
윤
오세훈윤하은
Every state H0 to H5: only an open review and a left-out match wear a Tag
2라운드
1번 코트선수가 입력하는 중이에요
김
이
김민준이서연
박
최
박지훈최유나
대신 입력
2번 코트
정
한
정우진한소희
6
오
윤
오세훈윤하은
2
3번 코트
검토 중
박
한
박지훈한소희
7
정
윤
정우진윤하은
5
4번 코트ELO에 반영되지 않아요
기록 제외
최
오
최유나오세훈
김
윤
김민준윤하은
Host The host’s round: 대신 입력, then a review to open
2라운드
1번 코트
김
이
김민준 (나)이서연
박
최
박지훈최유나
점수 입력
2번 코트
정
한
정우진한소희
6
오
윤
오세훈윤하은
2
3번 코트
검토 중
김
윤
김민준 (나)윤하은
4
최
오
최유나오세훈
6
Player A player’s round: 점수 입력, then a plain result
2라운드
1번 코트
점수 입력 전
김
이
김민준이서연
박
최
박지훈최유나
3번 코트
김
이
김민준이서연
67
박
최
박지훈최유나
465
2번 코트
예정
정
한
정우진한소희
오
윤
오세훈윤하은
Spectator Anyone else: the text 점수 입력 전, no button
2라운드
1번 코트보내는 중
김
이
김민준이서연
6
박
최
박지훈최유나
4
2번 코트점수가 이미 있어요
정
한
정우진한소희
6
오
윤
오세훈윤하은
2
3번 코트검토할 수 있는 운영자가 없어요
검토 중
김
윤
김민준 (나)윤하은
4
최
오
최유나오세훈
6
4번 코트점수를 넣어야 일정이 끝나요
박
한
박지훈 (나)한소희
정
윤
정우진윤하은
점수 입력
5번 코트점수 입력 대기
정
한
정우진한소희
오
윤
오세훈윤하은
대신 입력
The odd cases One fact only where it adds to the Tag
In sequence: held behind an earlier match
1라운드
1번 코트다음 경기가 기다려요
김
이
김민준 (나)이서연
박
최
박지훈최유나
점수 입력
2라운드
2번 코트내 이전 경기 점수가 필요해요
김
이
김민준 (나)이서연
박
최
박지훈최유나
점수 입력
The blocked player Their earlier match has no score: one Button, 점수 입력
1라운드
1번 코트다음 경기가 기다려요
점수 입력 전
박
한
박지훈한소희
정
윤
정우진윤하은
2라운드
2번 코트박지훈님 경기 점수를 기다려요
대기
김
이
김민준 (나)이서연
박
최
박지훈최유나
The others in it They read who is holding it, with the Tag 대기
1라운드
1번 코트다음 경기가 기다려요
김
이
김민준이서연
박
최
박지훈최유나
대신 입력
2번 코트다음 경기가 기다려요
정
한
정우진한소희
오
윤
오세훈윤하은
대신 입력
2라운드
3번 코트2경기 점수를 기다려요
대기
김
이
김민준이서연
박
최
박지훈최유나
Host The way out is on the earlier row: 대신 입력
Round 1
Court 1The next match is waiting
M
S
Minjun Kim (You)Seoyeon Lee
J
Y
Jihun ParkYuna Choi
Enter score
Round 2
Court 2Your earlier match needs its score
M
S
Minjun Kim (You)Seoyeon Lee
J
Y
Jihun ParkYuna Choi
Enter score
Court 3Waiting for 2 scores
Held
M
S
Minjun KimSeoyeon Lee
J
Y
Jihun ParkYuna Choi
English Enter score, Held, Waiting for 2 scores
Stopped before the end
2라운드
1번 코트
기권
김
이
김민준이서연
63
박
최
박지훈최유나
41
2번 코트ELO에 반영되지 않아요
부전승
정
한
정우진한소희
오
윤
오세훈윤하은
3번 코트
실격
박
한
박지훈한소희
61
정
윤
정우진윤하은
40
Counts in the record 기권, 부전승 and 실격 have a winner: the winner is emphasised
2라운드
1번 코트6-4 3-1에서 멈췄어요
일시 중단
김
이
김민준이서연
63
박
최
박지훈최유나
41
2번 코트기록에 반영되지 않아요
미완료
정
한
정우진한소희
63
오
윤
오세훈윤하은
41
3번 코트기록에 반영되지 않아요
취소됨
박
한
박지훈한소희
정
윤
정우진윤하은
Not in the record 일시 중단, 미완료 and 취소됨 have no winner and no emphasis
Round 2
Court 1
Retired
M
S
Minjun KimSeoyeon Lee
63
J
Y
Jihun ParkYuna Choi
41
Court 2This match won’t affect ratings
Walkover
M
S
Minjun KimSeoyeon Lee
J
Y
Jihun ParkYuna Choi
Court 3Stopped at 6-4 3-1
Suspended
M
S
Minjun KimSeoyeon Lee
63
J
Y
Jihun ParkYuna Choi
41
English Retired, Walkover, Suspended: the Tag says what happened
2라운드
1번 코트
기권
김민준이서연
63
박지훈최유나
41
2번 코트2경기 점수를 기다려요
대기
김민준이서연
박지훈최유나
200% Names wrap; the Tag stays beside line 1
In the history (ResultRow)
2라운드
9월 18일 (금)6-4 3-1 기권
기권승
이
김민준 (나)이서연
63
박
최
박지훈최유나
41
9월 11일 (금)
부전패
이
김민준 (나)이서연
정
한
정우진한소희
9월 4일 (금)6-1 2-0 실격
실격승
김민준 (나)
62
오
오세훈
10
8월 28일 (금)4-6 4-3 일시 중단
일시 중단
김민준 (나)
44
윤
윤하은
63
My record Words from my side: 기권승, 부전패, 실격승; the meta line writes the score
Round 2
Fri, Sep 186-4 3-1 ret.
Win by ret.
S
Minjun Kim (You)Seoyeon Lee
63
J
Y
Jihun ParkYuna Choi
41
Fri, Sep 11
Loss by W/O
S
Minjun Kim (You)Seoyeon Lee
W
S
Woojin JungSohee Han
English Win by ret., Loss by W/O; the meta reads 6-4 3-1 ret.
Dark · English · 200% text
2라운드
2번 코트
정
한
정우진한소희
6
오
윤
오세훈윤하은
2
4번 코트
검토 중
박
한
박지훈한소희
7
정
윤
정우진윤하은
5
5번 코트ELO에 반영되지 않아요
기록 제외
최
오
최유나오세훈
김
윤
김민준윤하은
Dark The Tags keep their tone
Round 2
Court 1Players are entering it
M
S
Minjun KimSeoyeon Lee
J
Y
Jihun ParkYuna Choi
Enter for them
Court 2
M
S
Minjun KimSeoyeon Lee
7
J
Y
Jihun ParkYuna Choi
5
Court 4
Under review
M
S
Minjun KimSeoyeon Lee
7
J
Y
Jihun ParkYuna Choi
5
Court 6This match won’t affect ratings
Not counted
M
S
Minjun KimSeoyeon Lee
J
Y
Jihun ParkYuna Choi
English Under review, Not counted; Enter for them
2라운드
2번 코트
검토 중
김민준이서연
6
박지훈최유나
4
1번 코트
김민준 (나)이서연
박지훈최유나
점수 입력
200% Names wrap; the Tag and Button stay beside line 1
Anatomy
Header firsta Match shell: the header line, then one team per line. Header: the court first, then at most one fact (13/18·500 secondary, as MetaSegments), and the one trailing element at its end: a Tag (24), an sm Button (36, its own stop outside the press area) or secondary text. A fact appears only where it adds to the Tag (listed below); the Tag never repeats. Heights at 390 are measured in the DOM: 128 with a Tag, 140 with a Button, 122 with text or with nothing at the end (an entered score); at 200% text 170 with a Tag and 203 for a held row whose names wrap.Team linesdrawn by the one FvkTeamLines grammar: one team per line, 12 apart; faces by default (a 32 face, or two overlapping 8, in a 56 slot), then 12, then the names; partners share the line with the 1px break and a team is told from the next by the line itself, never by a word; the viewer’s team is first with "(나)" wherever the viewer plays, everyone else sees slot order; each team’s games in 32 wide tabular columns at the right rail. Winner emphasis on every entered score (H3, H4): names 600 ink against 400 secondary, numerals ink against secondary. A scheduled, playing or left-out row shows both teams equal.FactsH2 host: 선수가 입력하는 중이에요 · H2 past the session’s end: 점수를 넣어야 일정이 끝나요 (players, who keep 점수 입력) and 점수 입력 대기 (the host; owner review 27, no entry window) · H3 offline: 보내는 중; a queued entry that met a stored score: 점수가 이미 있어요 · H4 with no official who is not playing: 검토할 수 있는 운영자가 없어요 · H5: ELO에 반영되지 않아요 · held: 내 이전 경기 점수가 필요해요 (the blocked player), "박지훈 님 경기 점수를 기다려요" (the others in the match), "2경기 점수를 기다려요" (the host) · a match that holds a successor shows 다음 경기가 기다려요 in the fact’s place · H6: "6-4 3-1에서 멈췄어요". H3 carries no Tag and no fact: it is settled. H4 carries the Tag 검토 중 (warning weak) and no fact: the Tag says it.Helda match that cannot start yet (derived, never stored): the Tag 대기 (neutral) and no numerals. For the blocked player the row’s one Button is the action they owe on their earlier match in the Tag’s place: 점수 입력. Entered is settled, so a player whose earlier match has a score is never held; an open review does not hold. The host’s way out is on the earlier row (대신 입력), never here. The earlier row says 다음 경기가 기다려요 while it holds a successor.Tapsthe row opens the match’s page (the pair’s record and head-to-head live there, a team stat); each player’s name is its own stop after the row and opens that player’s profile; a Button is its own stop. The row has no door for a player on a scored match: no action, no chevron. The appeal affordance lives in the scorecard’s Match state block, not on the row.Spokenone stop per row, from the viewer’s side: the state first, then the teams and the court: "검토 중, 3번 코트. 내 팀 김민준, 이서연 6. 상대 팀 박지훈, 최유나 4."; a winner is spoken only on an entered score ("승"); a Button is its own stop after the rowReplaces in codelive-match-row.tsx, completed-row.tsx and the status badges of match-card.tsx; one deriveMatchResultState supplies the Tag, the action and the copy
States (lane G §6.2)
H0 예정matches.status scheduled · no Tag beyond 예정 · no rating · entered by the drawH1 경기 중in_progress · the Live Tag · start is gated: each player’s earlier matches are H3, H5, an accepted stop outcome or H6 for the othersH2 점수 입력 전awaiting_result · no Tag · the host ends the round, the next round starts, or the rotation timerH3 입력됨completed with a decisive, retired, walkover or defaulted outcome · no Tag (stop outcomes keep theirs) · rating applied at entry · any player enters it; a host or official enters or changes itH4 검토 중as H3 plus one open review · Tag 검토 중 (warning weak) · the rating stands and the gate is untouched · a player appealsH5 기록 제외completed, outcome non_competitive · Tag 기록 제외 · rating reverted by replay · the host or an official; 30 days with no resultH6 일시 중단in_progress, outcome suspended · Tag 일시 중단 (warning) · not yet rated · a stop with a score so far; it releases the gate for the othersRetired states확인 대기, 분쟁 (countered and disputed), 호스트 확정, 이의 접수 and the correction overlay are gone, with their Tags; 확정 merges into H3 and shows no Tag. A host-set result is only the attribution line the scorecard already draws.
Transitions, who may do what
A0 H0 → H1 startthe gate is open for all four players; a host or official; no override; held matches are listed with the reasonA1 H1 → H2 the match ends라운드 종료, the next round or the rotation timer · P1 to the fourA2 H2 → H3 enter 점수 저장a player of the match, a host or an official · expected_revision 0, valid sets, idempotency key, inside the entry window · revision 1; rated at once; the gate opens; P2 to the other threeA3 H3 → H3 점수 고치기the entrant, within 10 minutes of the entry, a played score replaced by a played score, no review open, expected_revision equal to the stored one · the score changes, the ratings replay, the other three players get a notice; a recorded stop is not self-correctableA4 H3 → H4 appeal 검토 요청a player of the match, within appealDays, expected_revision equal to the stored one; an optional proposed score; one open review per match · P3 to the host and the officials not playing; ratings and the gate untouchedA5 H4 → H3 그대로 유지a host or official who does not play · review closed; P4 to the appellantA6 H3 or H4 → H3 change이 점수로 바꾸기 or 점수 고치기 · as A5, with the revision carried · revision + 1, ratings replayed, P4 to the fourA7 H3 or H4 → H5 기록 제외as A5 · ratings reverted by replay; P4 to the four; the gate stays openA8 H4 → H3 withdrawnthe appellant · review closed; nobody is toldA9 H4 → H3 standsappealStandDays with no decision · closed as kept; P4 to the appellant. With no official who is not playing, the score stands and the appeal stays on the recordA10 H1 or H2 → H3 stop outcomea player, the host or an official records 기권, 부전승 or 취소됨; 실격 is host or official only; a winning side is required · as A2; walkover and cancelled are not rated; 기권 is rated per retiredMinGamesA11 H1 → H6 suspendthe host, an official or a player · the score so far and a resume plan; the gate opens for the othersA12 H6 → H1 resume, or 미완료the host or an official, at the next session or the planned day; after suspendedResumeDays, or 여기서 끝낼게요, it becomes 미완료 (not counted, not rated)A13 H2 → H5 excludea host or official, no timer (owner review 27: a recorded match never times out) · P4 to the four; no rating; reopening (H5 → H2) is the same host actionA14 the session closesevery match settled (H3, H5 or a stop outcome), derived (deriveSessionCloseGate); the host’s 경기 종료 waits for it. The end-time job still ends play (status stays the truth about playing), but the session reads 점수 입력 대기, not 종료, with the owed matches. A player’s own session ends with their last settled match (owner review 27).Recorded or casualthe host chooses 점수 기록 or 기록 안 함 when creating; the session’s facts say which before anyone joins. Casual: no score asked, nothing rated, no gate, the draw only. Score-driven draws are recorded only. GenerationPolicy.recording; a friendly session is casual.Live modeowner review 28: from check-in (or the first match starting) a player is held in the live page until their last match is settled: no tab bar, back stays, a cold start returns there, the session chat is inside, other pushes wait. Leaving early is a settlement (기권 on the remaining matches, or the host takes them out). No score is owed outside the session, so the review-27 backstop and the 할 일 Cell 점수 입력 are retired; a player who never checked in is not held.Viewersa player: H2 enter · H3 ask for a review (the entrant also 점수 고치기 for 10 minutes) · H4 read, withdraw their own · host or official not playing: H2 enter and 기록 제외 · H3 change and 기록 제외 · H4 keep, change, 기록 제외 · H5 reopen · a host who plays acts as a player; another official decides, else the score stands · anyone else reads
Races, pushes and policy
Q1 two players enter at oncefirst commit wins on score_revision; the second gets score_changed and its sheet turns into the appeal sheet with its digits kept as the proposed score. The same sets twice are a no-op (Toast 이미 입력됐어요).Q2 entering while someone editsthere is no edit state; any write between opening and sending bumps the revision, so the send is refused as in Q1. Nothing is overwritten, the host included.Q3 entering after the host enteredthe host’s entry is revision 1 like any other; a player who opens ScoreEntry afterwards sees the score, not an empty keypad, and may only appeal.Q4 an appeal racing a host changethe appeal carries the revision it was written against. If the host changed the score first, it gets score_changed under the Notice 방금 점수가 바뀌었어요 and may ask again; if the appeal lands first, the host’s change closes it. Two appeals on one revision merge into one open review.Q5 offline or late entrythe client queues the write with its idempotency key and the revision it saw; on replay Q1 to Q4 apply. A refused entry is never dropped: the row reads 점수가 이미 있어요 and the digits wait as a proposed score.Pushes P1 to P5P1 점수를 입력해 주세요 (A1, the four; once more after gateNudgeMinutes only while a successor is held) · P2 점수가 입력됐어요 (A2, the other three; the body names who: "김민준님이 6-4를 입력했어요") · P3 점수 검토 요청이 왔어요 (A4, the host and officials not playing, high) · P4 점수 검토가 끝났어요, 점수가 바뀌었어요 or 기록에서 제외됐어요 (A5 to A7, A9, A13) · P5 다음 경기를 시작할 수 있어요 (a held match is released). Each body names the round and court so it reads alone.Policy: five keysappealDays 7 · appealStandDays 7 · gateNudgeMinutes 3 · suspendedResumeDays 7 · retiredMinGames 4 (owner review 27 removed entryWindowDays and noResultVoidDays: a missing score can be entered any time and never times out). selfCorrectMinutes 10. A host change and a self-correction re-rate by replay; rating applies at entry (taste question Q1 for the owner: peers wait 24 to 72 hours).
Matches that stop
Outcomes기권 retired · 부전승 walkover · 실격 defaulted · 일시 중단 suspended · 미완료 abandoned · 취소됨 cancelled · 기록 제외. Written score: 6-4 3-1 기권 (en 6-4 3-1 ret.), 부전승 (W/O), 6-4 1-0 실격, 6-4 3-1 일시 중단, 6-4 3-1 미완료; cancelled and 기록 제외 have none. Tags are neutral weak, 일시 중단 is warning; the outcome is a word with the score, never a new colour.Counts and rateda retirement counts as a win for the side that stayed; it is rated only once either side has won retiredMinGames (4) games, on the score as played with nothing added for the games not played, at half weight (one config value; UTR documents the four-game line, the half is our house value) · walkover counts and is never rated · defaulted as retired if play started, else as walkover · suspended counts and rates nothing yet · abandoned, cancelled and 기록 제외 count nowhere. The numbers are one config object, MATCH_OUTCOME_POLICY, with a parity gate to the SQL.Winner emphasisretired, walkover and defaulted have a winner (the side that did not retire, come or get defaulted): names 600 ink against 400 secondary, numerals ink against secondary. Suspended, abandoned, cancelled and 기록 제외 have none: both teams equal.In a person’s historyviewer-relative: 기권승 / 기권패, 부전승 / 부전패, 실격승 / 실격패 (English Win by ret. / Loss by ret., Win by W/O / Loss by W/O, Win by def. / Loss by def.) as the ResultRow’s Tag; the meta line writes the score (6-4 3-1 기권). A suspended match is not in the history until it resolves.The gatea match starts only when each of its players has every earlier match in the session settled: H3, H5, an accepted stop outcome, or H6 for the others (refusal previous_unsettled). An open review does not hold it: one player must not be able to freeze a session. The host’s 라운드 시작 starts the ready ones and lists the held ones.Wordsrows have no word between the teams; running text puts " vs " between teams and " & " between partners; 대 appears only where a score is read aloud.

Score Toasts

What each scoring action says once it is done: one result Toast, no glyph, no error.

저장됐어요
이미 입력됐어요
검토를 요청했어요
그대로 유지했어요
점수를 바꿨어요
기록에서 제외했어요
Results Six actions, six result Toasts: none carries an action
Which저장됐어요 (a score was entered or corrected; no action) · 이미 입력됐어요 (the same sets were already in) · 검토를 요청했어요 (an appeal was sent) · 그대로 유지했어요, 점수를 바꿨어요, 기록에서 제외했어요 (the host’s three decisions). Each is a result Toast, 4 s, no glyph; only the first carries an action.Not herea refusal of the server ("방금 점수가 바뀌었어요") is a Notice inside the open sheet, never a Toast. The entrant is told only that a review was asked, not by whom or with what, so no Toast names the appellant.
DOM check (scripts/verify-flat-v2-boards.mjs): 111 frames, rail 0, type 0, targets 0, shadow 0, dot 0, ball 0.
Spec (grounding, anatomy)

Conversation and scoring, composed from the shared flat v2 kit.

route · flat-v2-kit-controls.jsx grounded in 14 source file(s)
packages/features/clubs/src/shared/post-row.tsxpackages/features/clubs/src/post-detail/comment-row.tsxpackages/features/clubs/src/post-detail/comment-composer.tsxpackages/features/messaging/src/dm-thread/dm-message-row.tsxpackages/features/messaging/src/dm-thread/use-dm-chat-items.tspackages/features/messaging/src/dm-thread-screen.tsxpackages/features/messaging/src/dm-thread/compose-bar.tsxpackages/ui/src/send-ball.tsxpackages/features/messaging/src/dm-thread/helpers.tspackages/app/src/domain/entities/reaction.entity.tspackages/features/sessions/src/scorecard-page/overlays/score-entry-sheet.tsxpackages/features/sessions/src/scorecard-page/schedule-match-row.tsxpackages/features/sessions/src/scorecard-page/tabs/live-tab.tsxpackages/features/sessions/src/scorecard-page/model/courts.ts