Owner review 50 — the patterns in the page review (2026-10-30)
Status: Draft · Date: 2026-10-30 · The owner reviewed the 40 pages redrawn in round 49 on the page review (https://claude.ai/artifact/EKvHgpfADndkXvjNPhRQHF), plus one more: 28 fine, 13 to fix, notes on 14. Then: "I reviewed them all. Do the same what we did with our review on the previous round." This record groups the notes into patterns, audits each pattern with evidence, and fixes each at the level it comes from. Companions: review 49, the research, and the library's § 1.7, § 1.22 and the Live pages.
How this was investigated
- The notes. Every mark, note and earlier note on the review page (85
reviewsdocuments) and every answer given (79replies). The notes of 10-28 still marked on L2-05, L3-02, L3-26 and L3-40 belong to retired cards (their pages were folded in round 48), so they are closed. - The colours, measured. A colour probe rendered all 1,332 frames of the six page boards and recorded every painted colour (fill, border, outline, text, glyph) with the component it paints, in light and dark, mapped to the palette's roles.
- The app. The status-to-tone table (
packages/app/src/presentation/components/status/status-variant-maps.ts), the live colour (packages/ui/src/pulse-dot-color.ts), the live band (SessionLiveBand, status canon); the three wizards onWizardShell(클럽 만들기, 일정 만들기, onboarding) step by step against the boards; match generation end to end (the canon,AddRoundSheet, thegenerate_session_roundRPC, the 대진표 and the scorecard's round start); the visitor club page (club-detail-screen.tsx→/clubs/[id]/preview) and/join-club; the practice log (practice-log-screen.tsx). - The outside. Live scoreboards and tournament tools (ATP, UEFA, club tournament software, Korean and padel apps), the colour roles of Atlassian, Primer, Carbon, Apple and Material, Toss TDS form components and Apple's list, disclosure and settings guidance, and identity-first profiles (research).
1. The direction in one paragraph
A thing on screen has one meaning, and the system, not the page, says what it looks like: a colour is a meaning held by one canon, as a gap is a seam held by one canon (review 49). A page is about one subject, and a role sees that same page with its own layer on top: the operator the scoreboard, the club reviewing an applicant that person's profile, a visitor the club's home. Every page about a person opens on the person's Block, and 신뢰 is its door. Tabs each answer one question, and the set follows the session's type. The boards draw what the app implements (the wizards' steps, match generation's pipeline) in the revamp's grammar, and forms speak one grammar: what you choose is a row, what you type is a field.
2. The patterns
T1 — Colour has a grammar, held by a canon
The owner: "For sessions in progress, the status bar should take on the live color. Can we now do a full color pass on all pages to ensure we have a concrete grammar and every page abides by it?" (L2-02).
Why it recurred (the finding). The boards had a palette but no meaning table: each page chose a tone, about 150 times. Measured on every frame:
- 진행 중 was the live red on its Tag and the info purple on 일정 상세's bar.
- The info purple meant "live" on that bar and "a task waiting on the host" on six Notices (참석 시간을 정하지 않았어요, 신청 2건, 입금 확인 3건, 입력할 점수 …), where the app says needs-attention is the warning tone.
- 환불 대기 was purple on 회비 and amber on 일정 상세.
- The danger red stood for six things (live, error, destructive, unread, Sunday, a loss).
The app already has the table, status-variant-maps.ts, the "single source of truth" for status tones; the boards never mirrored it.
The fix, at the root.
- The colour canon (
scripts/lib/flat-v2-colour-canon.json, library § 1.7). Itsstatusmirrors the app's maps (session, match, RSVP, dues, score, payment, joinability, recruitment, attendance, consent, challenge, the rating change). Itsmeaningsare the UI meanings, each with a one-line note: live, error, destructive, unread, required, Sunday, loss, deadline, task, attention, shortfall, waiting, done, win, online, open. - A page states a meaning and never a hue. FvkTag, FvkNotice and FvkT take
meaning; kit pieces with a built-in meaning stamp it themselves (a danger button is destructive, the red count is unread, the required mark, a field error, the live ring, Sunday, a record's lost points, the rating change). - The verifier enforces it (
colour,scripts/lib/flat-v2-verify-colour.mjs, with its canary). A status hue painted with no meaning fails, as does a meaning painted in another tone and a status tone set with no meaning. Category and illustration colours (courts, maps, photos, club marks, provider brands, the result scale) are exempt by name. - The canon holds the app's parity (
scripts/__tests__/flat-v2-colour-canon.test.mjs): every domain status takes the app's tone, the rating change followseloDeltaTone, and the painted hues are the kit palette's. - Live has its own colour (the owner's answer to § 6, question 1: "Give live its own colour token, apart from the error red"). The app's S2 role
$live(raspberry#A7135E, pink#EE82C0in dark) is the Live tag's tone,LIVE_PULSE_COLOR, the session strip's live palette and the boards' live ring, dot and status bar; the status maps readin_progress → live. The status bar of a session in play is a live Notice: the live fill with the live dot, never the alert glyph.
Measured. 1,282 findings; 971 cleared by the kit's built-in meanings; 311 page decisions, each made on its board.
T2 — One page per subject; a role is an overlay
The owner: "So 대진표 is basically a scoreboard with an operator overlay, no? Design it upon the scoreboard and make the tasks of the operator clean and separate" (L3-39); "가입 심사 can also lead with a block. Let's treat it as a proper application page where votes can be performed on the user's profile. We are always highlighting users in this app" (L3-32); "What I find baffling is that I thought we already had a non-member facing home page of a club, which would what non-members would view to apply" (L4-04).
Finding. Three pages re-drew their subject for a role:
- The 대진표 console re-drew the scoreboard as a list of its own (코트, 점수 입력 전, 다음 경기).
- 가입 심사 re-drew the person as a small row.
- 클럽 가입하기 re-drew the club's facts (fee, policy, full, archived). The app shows a visitor the club's own page (
/clubs/[id]/preview, folded into the visitor 클럽 홈 in review 41), and its/join-clubis invite-code entry only.
Fix. The subject's page, with the role's layer on top:
- The operator: 스코어카드 운영. It is the same scoreboard, the same tabs and the same cards.
- Each card carries its one state action. A live Block opens score entry; a queued match on a free court has 시작; a finished match waiting has 검토.
- Exceptions go to an inbox: a header button with a count, rows each with its own action.
- The CTA band holds the phase's one action: 경기 시작 → N라운드 시작 → N라운드 대진 짜기 → 본선 대진 만들기 → 일정 끝내기.
- Structural edits sit in the header's ⋯.
- Research: actions on the match itself (Challonge), an exceptions queue (Battlefy, Facebook's member requests), structure on its own screen (Tournated). No source uses an edit-mode toggle.
- The club deciding on an applicant: 가입 심사. It is the applicant's profile, led by the person's Block, with the application (message, history with the club) and the vote attached at the foot.
- A visitor: the club's visitor home. It draws each join path the app has: 바로 가입; 승인 후 가입 with one message and 신청 검토 중; 초대 전용. 클럽 가입하기 becomes 초대 코드로 가입, the code alone, and it opens that home.
T3 — Person pages lead with the person's Block; 신뢰 is its door
The owner: "We can try to incorporate 신뢰 into the hero, which I think can be turned into a block? I think all profile pages lead with a block. Do you get why? 신뢰 can be a label inside the block, and opening up the 신뢰 page can then render the progress bar. Clicking that 신뢰 label leads to the 신뢰 page" (L2-06).
Why a Block. A Block is the app's statement of a page's one subject (홈's day, 기록's rating); these pages are about a person, so every one opens on the same object, wherever it is met. And the facts another player weighs before playing with someone (who, how good, which club, whether they show up) get one fixed place. Strava, LinkedIn and 당근 (매너온도 beside the name) lead with exactly that block (research § 5).
Fix.
- The identity Block leads every person page: 프로필, 공개 프로필, 가입 심사, and 신뢰 기록's officials' view.
- The Block carries one door, 신뢰 72점, or the steps before five sessions (신뢰 3/5회). It opens 신뢰 기록.
- The meter and its evidence live on 신뢰 기록. The 신뢰 section leaves 프로필 and 공개 프로필.
T4 — A tab answers one question; the tab set follows the session type
The owner: "So I think brackets need a separate tab in case a live tournament is taking place. And group-based matches need better visual separation. So live matches should provide an overview on all ongoing matches and queued matches per court ... 일정 should show a clean view on all groups and scheduled matches. Brackets show the brackets well ... each tab needs to serve a specific function ... research how we can make that happen for different session types" (L3-38).
Research (§ 1). One tab, one question:
- ATP: Live, Schedule by court with 'Starts at' / 'Followed by', Draws by round chips.
- UEFA: one card per group, separated by card and heading, never by a hue.
- Club apps: one screen of all courts.
- Toss: at most four fixed tabs.
Fix. One registry, FVK_SCORE_TABS, read by 스코어카드 and its operator view.
- The tab set by session type:
- rotation and league: LIVE · 일정 · 순위;
- tournament: LIVE · 일정 · 대진표 · 순위;
- 코트승급전: 코트 · 일정 · 순위 (the court ladder, built and now drawn);
- a single match: no tabs.
- What each tab holds:
- LIVE is the courts now, each court's match in play and then its queue.
- 일정 is every match by round, or by group card in a tournament. A finished match keeps its score there, so results fold in and the separate 결과 tab retires.
- 대진표 is the bracket, a round per screen.
- 순위 is the tables, one card per group.
- The default tab follows the phase: LIVE in play, 순위 after the end.
T5 — Match generation, drawn as its one pipeline
The owner: "we are missing pages on how session generate matchups. Can you dig into what we've implemented and decided about match generation so that you can provide a structured, cohesive and seamless experience in terms of it?" (L2-02).
Finding (research-generation). The canon's pipeline is 대상 → 구성 → 생성 → 검토 → 확정 → 시작 → 기록.
- What the app builds: 대진 짜기 (the session's players and arrivals, 경기 가능성, the 방식 list: four doubles or three singles presets, KDK, 순위매칭전, 코트승급전) → 대진 미리보기 (per court, the bench 이번 판 휴식, 다시 생성) → 대진 저장 (the commit). Round by round, the next one by 라운드 추가. 경기 시작 starts the session, and each round is started on the scorecard. A 교체 Sheet adjusts a scheduled match.
- What the boards drew: the start and the record. A one-step Sheet stood for 구성 and 생성, with no review and no commit. There was no tournament set-up, no 코트승급전 tab, and no way in before the session reads 마감.
Fix.
- The new page 대진 짜기 (L3-47). 구성 (the readout of who plays and on how many courts, the 방식 list by format) → 미리보기 (courts, the bench, 다시 생성) → 저장.
- The same page in next-round mode is 라운드 추가. A rolling style waits for the last round's scores.
- Its tournament mode is the method (조별리그, 토너먼트, 전적매칭 토너먼트, 전원부활전, with the code's recommendation) and the code's knobs (조별 인원, 진출 방식, 진출 인원, 조 편성).
- The door. The session's 관리 has 대진 짜기 from an open session, as the app does.
- The rest of the pipeline sits on the operator's scoreboard (T2): the 교체 Sheet, the round start, and 코트승급전's 코트 tab (T4).
- The lead's calls, for veto (§ 6):
- keep the preview, so the draw is a proposal until 저장;
- one round at a time;
- 경기 시작 and N라운드 시작 stay two steps, as the code has them.
T6 — The app's wizards are the source; the revamp reskins them
The owner: "And can you ensure that all steps in our wizards implement what's already implemented? There's not much to change in the wizards other than migrating to the new ui/ux theme" (L4-02).
Finding (research-wizards, file:line on both sides).
클럽 만들기 has 9 steps in the app, 10 on the board. The board missed:
- step 2's per-court panel;
- step 3's 다음 일정 추가, court subset and seven 반복 options;
- step 5's 모집 목표 receipt;
- step 6's 회비 calculator;
- the review's 대표 색상.
It also added rows the app lacks.
일정 만들기 missed 경기 분위기, 혼복 and 무관, 60분 and 직접 입력, the capacity calculator, 공지, and 신청 마감's 없음 and 직접 설정.
Four defaults contradicted the app.
Fix (the rule).
- The app decides the steps, fields, options and defaults.
- The language pass decides the words (the lead's rulings of 2026-10-20 stand).
- The library decides the controls (the fee fork, the shared date picker, § 1.21's questions).
- A board addition with no app counterpart goes, unless a dated owner ruling stands behind it.
- Out of scope: onboarding, whose redesign the owner asked for (L0-04).
T7 — One form grammar
The owner, on L4-06 경기 규칙, L4-07 테니스장 추가, L4-09 단톡방 만들기, L4-11 프로필 수정 and L4-21 입금 계좌: "All the functionalities are there, but how can we make it seem more polished and in line with our ui/ux revamp decisions so far?"
Finding. Each mixes three grammars:
- Fields with labels above;
- label-left Cells;
- full-width bordered steppers.
Fields float without groups, a grey 접기 button hides options, and checkboxes lead bare rows. 일정 만들기, one list of Cells, is the revamp's form.
Fix (library § 1.22, Forms).
- A form that edits answers that exist is one list of value rows, the list 일정 만들기 ends on: label left, the answer right, and its pencil (or a picker's chevron) opening its editor. 경기 규칙, 프로필 수정 and a set 입금 계좌 are such forms. The rules below are for asking answers that do not exist yet (a creation form, a wizard step, an editor Sheet).
- What you choose, toggle or count is a row (label left, value or compact control right); only typed text is a Field with its label above.
- Every form is grouped, one topic under each head.
- What depends on an answer nests under its row.
- Rare options sit behind one disclosure row (고급 설정, a turning chevron, a label that never changes), never a 접기 button.
- Two to five short options are a Choice set; longer ones are check rows with their meaning on line 2.
- A people picker shows the picked faces as a strip on top, then search, then rows with the check trailing, and its action names the count.
- One action in the band, naming the result.
Research: Toss ListRow and TextField; Apple lists, disclosure and settings; Material settings.
T8 — One page shape in every state, and each door in its home
The owner: "I like the new look on 할 일 as a horizontal list. Maybe we can apply this when there's nothing to do so the page now has a consistent grammar across all states" (L1-01); "Perhaps the 연습 기록 nav can live somewhere else? It seems to break the continuity of the match focused records section. Where should we put it? Do we have a dedicated practice mode anywhere?" (L1-04).
Fix.
- 홈 keeps its three lanes in every state. With nothing to do, 할 일 holds one quiet card, 할 일을 모두 마쳤어요.
- The app has a practice log and no practice mode. The log records a type and a duration, dated today, and is reached from 프로필's menu. So 연습 기록 leaves 기록's match records for one Cell at the end of 프로필, as in the app.
3. Page by page
| Page | Patterns | The fix |
|---|---|---|
| L1-01 홈 | T8 | the three lanes in every state; 할 일을 모두 마쳤어요 |
| L1-04 기록 | T8 | 연습 기록 leaves for 프로필 |
| L1-05 프로필 | T3, T8 | the Block's 신뢰 door; the meter to 신뢰 기록; 연습 기록's Cell |
| L2-01 클럽 홈 (visitor) | T2 | each join path the app has |
| L2-02 일정 상세 | T1, T5 | the live status bar; host tasks in the task tone; 대진 짜기 from an open session; 스코어카드 보기 |
| L2-06 공개 프로필 | T3 | led by the person's Block with its 신뢰 door |
| L3-01 신뢰 기록 | T3 | the meter and its evidence |
| L3-32 가입 심사 | T2, T3 | the applicant's profile with the application and the vote |
| L3-38 스코어카드 | T4 | the tab set by session type; LIVE by court; 일정 by group card; the bracket tab; 코트승급전's 코트 tab |
| L3-39 스코어카드 운영 | T2, T5 | the scoreboard with the operator's layer; the 교체 Sheet |
| L3-47 대진 짜기 (new) | T5 | 구성 → 미리보기 → 저장; next-round and tournament modes |
| L4-01 일정 만들기, L4-02 클럽 만들기 | T6 | the app's steps, fields, options and defaults |
| L4-04 초대 코드로 가입 | T2 | the code alone |
| L4-06, L4-07, L4-09, L4-11, L4-21 | T7 | the form grammar |
| Every page | T1 | the colour canon |
4. Library changes
- § 1.7, The colour canon: the canon is the colours' one source; a page states a meaning; the meanings and their notes; how to add one.
- § 1.22, Forms: the seven rules (T7).
- Block, identity: the 신뢰 door; it leads every person page.
- Trust (신뢰): the meter lives on 신뢰 기록.
- Live pages: the tab sets by session type; the operator's layer; 대진 짜기.
5. Batches
At most three agents at a time, one writer per board file.
- The kit and the canon (the lead). The colour canon, the
colourcheck and its parity test; the kit's meanings; the identity Block's 신뢰 door; the live Notice;FVK_SCORE_TABS; 대진 짜기 in the session's doors. - Wave A (three boards).
- Detail: 스코어카드 and its operator view, and the whole board's colour.
- Hub: 홈, 기록, 프로필, the visitor home, and its colour.
- Forms: the form grammar, the wizards and 초대 코드, and its colour.
- Wave B.
- Detail: 대진 짜기, 일정 상세, and the person pages.
- Lists and auth: their colour, and 연습 기록's new parent.
6. For the owner
- Live's hue. Answered: live has its own colour (
$live), apart from the error red. - 결과 folds into 일정. A finished match keeps its score in 일정, so a tournament has four tabs (LIVE · 일정 · 대진표 · 순위). Keep, or bring 결과 back as a fifth?
- 프로필's 신뢰 section (fine in round 49) moved into 신뢰 기록, so every person page reads the same: the Block's door, then the meter one tap away.
- 대진 짜기, the lead's calls:
- the preview stays, so the draw is a proposal until 저장;
- one round at a time;
- 경기 시작 and N라운드 시작 stay two steps, as the code has them;
- the host reaches it from an open session.