Owner review 27 — rulings (2026-10-15)
Status: Superseded in part — the score-owed 참석 hold retired in review 28 (live mode); 예정 narrowed to your own sessions in review 39; the 홈 composition replaced by reviews 28–39 · Date: 2026-10-15
Covers: the owner's four answers to review 26:
- The last score must end a recorded session, and players may opt out of scoring.
- Joined sessions must be explicit on 홈, because the grey 참석 Tag is too weak.
- The pin is the surface cue.
- 내 경기 should become "upcoming".
It also answers the owner's question about the flat layout: "most of the pages I see seem like list-based layouts that are simply rendered against a flat layout. Am I seeing this right? What makes flat layouts effective? What are we not doing?"
Boards:
flat-v2-hub§ 홈: the group "Proposal: 홈 composed by the page laws".flat-v2-lib-social: the scoring specs.
1. A recorded session ends with its last score
Recorded or casual: one choice per session.
- The host chooses 점수 기록 or 기록 안 함 when creating the session, and the session's facts show the choice before anyone joins.
- A player who does not want to be scored joins a casual session.
- A casual session asks for no score, rates nothing and holds no match behind another: the scorecard shows the draw only.
- Score-driven draws (King of the court, Mexicano, Americano) need scores, so they are recorded only.
- The choice already exists in the model as the
recordingaxis ofGenerationPolicy(recorded|casual), derived today fromisFriendly.
Recommendation, open to veto: per session, not per player. If one player opted out inside a doubles match, the other three would lose their rating for it.
The rule for recorded sessions (library §10, principle 7 and A14):
- A player's session ends with their last settled match. The session closes only when every match is settled. The host's 경기 종료 waits for that.
- Time never closes a recorded session.
- The end-time job still ends play, because
statusstays the truth about playing. - Until every match is settled, the session reads 점수 입력 대기, not 종료, and names the matches still owed.
- The end-time job still ends play, because
- No timer voids a match, and nothing expires.
- Removed: the 30-day 기록 제외 (
noResultVoidDays, A13). - Removed: the players' 7-day entry window (
entryWindowDays). Any player of the match may enter a missing score at any time. - The match row's "expired" state becomes "owed": the players keep 점수 입력, and the row says 점수를 넣어야 일정이 끝나요.
- Removed: the 30-day 기록 제외 (
- The only ways out are explicit. A match is settled by a score, or by 경기 중단 (기권, 부전승, 취소됨, or 일시 중단 then 미완료), recorded by a player, the host or an official.
- Backstop. A player who owes a score cannot 참석 another recorded session until the score is in.
- The CTA reads 지난 경기 점수부터 입력해 주세요, with the door to that match.
- Any of the four players can enter it, so nobody is stuck waiting on someone else.
- 할 일 shows 점수 입력 to the four players and to the session's host until the score is in.
Code, at the migration:
- A derived
deriveSessionCloseGate, built likederiveRecruitmentStatus, gates the host's 경기 종료 and the session's label. private.auto_advance_session_statuses()keeps ending play, but never voids a match.- The 참석 RPC refuses with
score_owedwhile the player owes a score. - The 30-day void and the entry window go.
- A friendly session becomes casual and stops asking for scores.
2. 홈: make joined explicit
What 홈 shows. Your sessions (your RSVPs) and your clubs' sessions you have not answered. Saved sessions, the favourites you expected to see, were not included. They now join the open group.
The grey 참석 Tag is the wrong tool, not only too weak. A per-row badge on a mixed list makes every row carry its own state.
- What peers do: they separate the two structurally.
- Spond's home shows only the events you are invited to; the group shows all of them (Spond help).
- Meetup keeps "Your calendar" apart from Explore (Meetup help).
- The proposal ("홈 composed"): joined and open never share a list.
- The Block is your next game, as a statement: "09:00 시작", the venue and 6/8 참석. It shows a session you have joined, never an open one.
- 내 일정 holds your other games this week as agenda rows. A date column replaces the map, because the question here is "when". There is no Tag unless something is wrong (입금 필요, 예비).
- 참여할 수 있는 일정 holds your clubs' open sessions and your saved ones. Each row has a map with the surface pin, the spots left ("2자리 남음", "친구 2명") and an inline 참석 button, tonal so the ball stays the screen's one action. The 참석 button opens the confirm sheet with the fee and the cancellation terms, so commitment still follows disclosure.
- Three signals now say "joined" versus "open": the section, the row's form (date versus map), and the action (only open rows carry 참석).
- With nothing joined this week, the Block says so and opens 번개 찾기, and the open sessions sit right under it. That is the join path the FAB question was after.
- Status: a proposal on the board. It becomes the 홈 Ideal when the owner approves it.
3. The surface pin
Done. The map's pin takes the court surface's colour:
- hard
#089AC3 - clay
#8D3D00 - grass
#83971F
It is red only where the surface is unknown. The ring and band options are removed.
The pin is a hint for regulars. The surface is still spoken in the row's name and written on session detail and on venue rows.
In code: the static map is requested without its marker (marker=false), and the pin is drawn over its centre, so its colour is ours.
4. 내 경기 becomes 예정
Yes. 예정 (Upcoming) shows the same two groups as 홈 (내 일정, then 참여할 수 있는 일정), across every upcoming day and sectioned by day.
- 저장됨 folds in. Saved sessions are part of the open group, and a filter chip keeps the saved-only view.
- The 경기 tab becomes three panes:
- 예정: your world, meaning your sessions, your clubs' sessions and your saved ones.
- 번개 찾기: the public.
- 테니스장.
- 홈's 전체 보기 goes to 예정 at that day.
This will be drawn in the composition pass (§5), with the same grammar as the composed 홈.
5. The flat layout: what we are not doing
Yes, the owner is seeing it right. Flat v2 changed the containers but not the composition.
- What it changed: there are no cards, shadows, outlines or fills. Whitespace and a title separate the sections, and one rail aligns everything.
- What it didn't change: every page is still a stack of equal-weight titled sections, and each section is a list.
- 홈 is the Block and then one row type, repeated.
- 기록 is the Block and then 8 sections: 내 전적, 최근 ELO 추이, 개인 기록, 활동, 종목별 승률, 최고의 파트너, 클럽 랭킹 and 내 기록.
- 프로필 is the Block and then 7 sections.
Take the cards off a card layout and you get a list. Take them off a list and you get the same list.
What makes a flat layout work. Without containers, hierarchy has four tools left: size, weight, space and position. So a flat page has to make the choices a card layout can put off: what is the one thing, what comes second, and what leaves the page.
- Readers scan in layers. NN/g's layer-cake pattern is "by far the most effective way to scan pages". People skim the headings and read only where a chunk looks relevant (NN/g). When every chunk has the same form, the heading is the only signal left.
- Form follows the data.
- Cards are for mixed content and rows for alike items (EU component library).
- Apple Weather gives each module a shape that fits its data, and puts rain first when rain is coming (MacRumors).
- Edit hard. Per Toss's announcement of its home redesign (Toss):
- the account totals sit on top, with an inline 송금 on each account;
- spending comes next, as a calendar;
- then proactive reminders;
- lower-value items (credit score, insurance) moved off home to 전체.
- Keep signifiers. Flat design's main failure is the lost cue that something can be tapped (NN/g). We already guard this with the chevron law and Buttons for commands.
The page laws (proposal):
| # | Law | What it means here |
|---|---|---|
| C1 | One job, one dominant answer | The first screen gives the page's answer in one module (the Block); everything else supports it |
| C2 | Edit | A hub page holds three or four modules; everything else is one tap away |
| C3 | Form follows the question | When → a date or agenda; where → a map; who → faces; how it is going → a chart; how many → a number; a few alike → rows (three at most, the preview law) |
| C4 | Statements, not labels | "09:00 시작", "2자리 남음", "이번 달 6경기, 지난달보다 2경기 많아요" rather than "4/8" or "총 경기 47" |
| C5 | Order follows state | Live, then owed, then next, then open, then the rest |
| C6 | The obvious action sits in its module | 참석 on an open session, 입금 on a fee due, 점수 입력 on an owed match; tonal, because the ball stays the screen's one action |
| C7 | Three levels of scale | Hero, module, row; the gap above a module is larger than any gap inside it |
What the laws would change on the other hubs (not drawn yet):
- 기록: the ELO Block; one statement for the month with the trend under it; 클럽 랭킹 at three rows. 개인 기록, 활동, 종목별 승률 and 최고의 파트너 move to one page behind "내 기록".
- 프로필: the identity Block and three modules (최근 경기, 친구, 업적). 매너 태그, 신뢰 and 연습 기록 move to their own pages.
- 클럽 홈: already the most composed (the MediaBand, shelves, the feed). C5 puts the next session you can join first, and C4 rewrites its counts as statements.
- 경기 › 예정: the 홈 grammar, day by day.
Next: once the owner approves the laws and the composed 홈, recompose 기록, 프로필, 클럽 홈 and 경기 › 예정 the same way, wireframe-first. Then add the laws to the library as §1.14, "Page composition".
6. 홈 composed in full
The owner asked to see the whole tab under the seven laws before accepting them ("I want what the home tab would actually look like if composed under the new rules"). The first proposal applied them only in part: it had no state-driven hero (C5), no faces (C3) and no action inside the hero (C6). The board now draws six states in the group "Proposal: 홈 composed by the seven page laws".
| State | Hero (C1, chosen by state: C5) | Then (C2: three or four modules) | Laws it shows |
|---|---|---|---|
| An ordinary day | Your next game: "09:00 시작", the venue and the weather; the faces of who plays with you and "이서연, 박지훈 님 외 4명과 함께 쳐요" | 내 일정 (agenda rows, a Tag only for 입금 필요), 참여할 수 있는 일정 (map, spots left, 참석) | C1, C3 who → faces, when → dates, C4, C6, C7 |
| A fee due | The same game; its door becomes 입금하기 ›, the meta "참가비 10,000원, 오늘 18:00까지", the line "입금하면 참석이 확정돼요" | as an ordinary day | C6 the action in its module, C4 |
| Playing now | Your match on court (the match Block: faces, teams, 스코어카드 ›), the line "다음 경기는 1번 코트예요" | 내 일정 only; nothing to join while you play | C5 live first, C2 edit |
| A score owed | The owed match (the match Block, door 점수 입력 ›, the line "점수를 넣어야 일정이 끝나요") | 내 일정 (tomorrow's game moves here), 참여할 수 있는 일정 with 참석 held and the note why | C5 owed before next, the review-27 backstop |
| Nothing joined | "다음 7일, 일정 없음", door 번개 찾기 › | 참여할 수 있는 일정, joinable from 홈 | C1, C6 |
| Official | Your next game, as an ordinary day | 할 일, 내 일정, 참여할 수 있는 일정 | C2 at its limit (four modules) |
New pieces this needs, all proposals:
- Faces under a day Block: the Avatar row 12 below the Block, then a Caption row (attach object), as one module.
- The agenda date column: a 48 gray100 tile with the weekday over the date, in the row's thumb slot.
- The match Block's
overdueline. - A disabled 참석 on open rows while a score is owed.
Everything else is the approved library.
What it does not change: the header, the tab bar, the FAB by role, the preview law and the bell rules (review 26).