Skip to content

Decision log — detail pages flat language

Status: Reference · Scope: every owner ruling that produced the flat detail-page language (docs/twomore_design_system/wireframes/detail-flat-language.jsx). The wireframe board shows only the shipped final state; this log keeps the "why," including the two rejected options each FINAL ruling reverses.

DateRulingOutcomeWhere it lives in code
2026-09-05Section boundary: a hairline between every peer row, including a section's firstRejected — a section edge read as just one more row, no distinct "new group" signalsuperseded by packages/ui/src/fact-row-visual.ts, list-row-visual.ts
2026-09-06Section boundary: whitespace-only (32px gap + a heavier title, no line)Rejected — read as crammed on device once 6–12 blocks stackedsuperseded by packages/ui/src/flat-column-defaults.ts
2026-09-06 (FINAL)Divider law — dividers separate SECTIONS only; peers inside a section are spacing-only (12px padding); a divider between peers is allowed only when each peer is itself a multi-component blockDecided, shippedpackages/ui/src/flat-column.tsx, flat-column-defaults.ts, fact-row-visual.ts, row-list.tsx
2026-09-06(c)Section-divider seam valueRetuned 20/1/20 → 24/1/24 under the seam ladderpackages/ui/src/flat-column-defaults.ts (FLAT_COLUMN_DEFAULT_GAP = '$6')
2026-09-05Media-hero title placement: white text over a photo scrim vs. title below the photo on the canvasDecided — below the photo; a scrim can't guarantee contrast, and the failure mode was the tinted-ground + chrome-hero combination, not the hero alonepackages/ui/src/media-hero.tsx
2026-09-05Where tint survives on an otherwise flat pageDecided — Well · Callout · Banner · empty state · shelf tile · input background only; the stat strip stays hairline-only, not tintedpackages/ui/src/well.tsx, callout.tsx, banner.tsx, stat-strip.tsx
2026-09-05DetailShell canvas rollout: flip the tinted→flat default everywhere at once vs. opt in screen by screenDecided — opt in via ground="canvas", flip the default once all 11 screens are convertedpackages/ui/src/detail-shell.tsx
2026-09-06(b)ActionIconRow anatomy: space-between + content-sized items vs. equal-ratio flex:1 cells with a full-cell pressed stateDecided — equal-ratio cells (re-grounded to match the already-shipped component)packages/ui/src/action-icon-row.tsx
2026-09-06(b)Hero titleBadge slot — one entity-state badge trailing the title, separate from the badges rowShipped, then retired by the one-badge-home ruling below (2026-09-06(g))packages/ui/src/media-hero.tsx, type-hero.tsx
2026-09-06Venue verification badge / "confirmed only" filterDecided — no unverified/verified badge or filter anywhere; "verified" renders only on an owner-verified venuepackages/app/src/domain/venue-trust.ts (deriveVenueTrustTier)
2026-09-06Affordance law — every tappable element shows exactly one resting cue (chevron, button chrome, $primary link ink, or a state layer + chevron/glyph)Decidedpackages/ui/src/pressable.tsx, list-row.tsx, well.tsx; lint @twomore/pressable-needs-affordance
2026-09-06(c)Spacing & alignment system — one 6-rung seam ladder (XS4/S8/M12/L16/XL24/XXL48, one token per relationship) + two alignment rails (TEXT 16, FULL-BLEED 0), replacing ad hoc per-screen valuesAdopted and builtpackages/ui/src/seams.ts, flat-column.tsx, bottom-cta-band.tsx, section-header-metrics.ts, stat-strip.tsx
2026-09-06(e)Middle-dot (·) joins inside meta/sub textDecided — removed; hero meta is string | string[] (one fact per line), a second fact rides as a trailing badge instead of being joined into the labelpackages/ui/src/media-hero.tsx, type-hero.tsx, fact-row.tsx, list-row.tsx
2026-09-06(e)Meta-text grammar — one color/weight tier per slot (primary meta = cardBody/$textSecondary; secondary/sub/eyebrow = cardMeta/$textTertiary; caption = smaller cardBody)Decidedpackages/ui/src/text.tsx, tokens.ts
2026-09-06(e)Graphics-lead law — avatars/logos/thumbnails render left and top, never as a trailing or bottom-right overlayDecided — TypeHero gained a leading slot; the club member-faces cluster moved to FlatColumn's lead rowpackages/ui/src/type-hero.tsx, media-hero.tsx, flat-column.tsx
2026-09-06(f)Palette — OKLCH-defined ladders (one fixed hue, ~even L steps, a designed not-reversed dark-gray scale, dark primary promoted to its tone-80 step) vs. the previous ramp (a gray700 hue/chroma kink, dark gray as a literal reversal of light, dark-primary-button APCA 52)Adopted, livepackages/ui/src/tokens.ts, packages/app/src/config/themes/classic-grass.theme.ts
2026-09-06(g)One badge home — a hero used to scatter badges across three homes (media status overlay, titleBadge, badges row); collapse to Option A (one row, fixed order state → verification → category, directly under the title) vs. Option B (inline trailing the title)Decided — Option A shipped; titleBadge and the media status overlay retiredpackages/ui/src/media-hero.tsx, type-hero.tsx
2026-09-06(h)Hero composition — every hero opens with SEAM.hero(16) under the chrome/media band (never the generic SEAM.chrome/12), the eyebrow spans the rail above the identity row, and a leading graphic top-aligns with the title lineDecidedpackages/ui/src/type-hero.tsx, media-hero.tsx
2026-09-07Two grammars (cards for browsing, flat for detail) vs. one grammar keyed on content shape — flat sections for every detail page AND every homogeneous list; object cards only for session/club/venue collections; one canvas groundDecided — one grammar; the club-ops screens, the guest review flow and the venue finder's non-card chrome all go flatdocs/canon/components.md (Canvas law), /wireframes/club-ops, /wireframes/guest-roster, /wireframes/venue-finder
2026-09-07Canvas migration order for the still-tinted list/settings shells: big-bang vs. by nav tree vs. by migration risk (shell then chrome, flat-row screens first)Decided — by risk, on the condition that every migrated screen honours the group-spread law (equal cells, fixed gap, centered content) and the seam ladder/wireframes/canvas-migration (decision record), packages/ui/src/cell-row.tsx, stat-strip.tsx
2026-09-07Session-card bookmark: on the participation (meter) row vs. the strip band's right poleRuled off the meter row; the strip right pole answer was then overtaken the same day by the owner's "we are moving away from top strips" (next row)packages/app/src/domain/session-strip.ts, session-strip-ui.tsx
2026-09-07(b)Session summary card top strip — the owner: "we are moving away from top strips for session summary cards". No earlier ruling retires it (v6 band shipped 2026-07-28). Proposal drawn: state word + tone on the closing row, my standing badges beside the meter, bookmark in the tile's top-right corner (corners law on the tile)Proposal on /wireframes/session-card, awaiting the owner's confirmation before the card, the detail-screen band and the strip-map board changesession-card-v2.tsx, session-strip-ui.tsx, domain/session-strip.ts
2026-09-07Club summary card corners law (tier top-left, alarm top-right; discover top-right reserved)Confirmed as the established member card; the iteration-23 alternatives are retired from the boardpackages/features/clubs/src/shared/club-card.tsx
2026-09-07(b)Discover club card — the owner: same corners law (tier top-left, recruitment stat top-right) plus a bottom terms-chip row (join policy · dues); replaces the four-way terms-zone questionDrawn (D23-E); the terms row sits under the identity chips — placement to confirm, then buildclub-card.tsx, club-photo-seam.tsx
2026-09-07(b)Club detail tabs — the home tab stands; 일정 · 채팅 · 랭킹 · 멤버 · 회비 panes rework to the flat layoutDrawn on /wireframes/club-detail-redesign; build after the drawings are approvedclub-detail/sessions-pane.tsx, members-pane.tsx, dues-pane.tsx, ranking-tab.tsx
2026-09-07(b)Review boards — options A/B/C vs. one recommended path per boardDecided — every proposal board opens with one FlPath block; the phones are the pathdocs/twomore_design_system/wireframes/_kit.jsx (FlPath)
2026-09-07(c)Session card bookmark — tile corner vs. right of the weather on the venue lineOwner: right of the weather; drawn in WFSessionCardV3 (kit), used by the session-card and club-detail boardsproposal — session-card-v2.tsx once confirmed
2026-09-07(c)Discover club card corners — recruitment STATUS (N명 모집 중) top-right; the member/capacity chip stays on the seam; terms chips as the bottom rowOwner direction, drawn (D23-E)club-card.tsx, club-photo-seam.tsx once confirmed
2026-09-07(c)Club detail — all six tabs flat, no session cards with top strips inside the detail pageConfirmed; the redesign board's next-session card is the no-strip card, the 일정 tab is compact rowsclub-detail/* panes
2026-09-07(c)Venue finder streamlining (near-me default, zero-query state, kind-aware facets with counts, card v3)Approved — build queue (held until Codex's venue branch is reconciled, since it touches the same finder files)/wireframes/venue-finder (approved lane)
2026-09-07(c)Board hygiene, found by screenshotting the built boards with the local headless Chromium — the "misaligned hero" was a caption wrapper's text-align:center leaking into every phone on the guest board; the club-detail redesign rendered no phones at all (a board without an anatomy sheet hid its states); the tier-range badge wrapped onto two lines in a three-chip rowFixed at the source: WFPhone owns text-align:left; anatomy-less boards show every state; the badge never wraps. Screenshot verification is now part of the board loopdocs/twomore_design_system/wireframes/_kit.jsx, scripts/build-wireframes.mjs
2026-09-07(d)Guest review detail → a GUEST PROFILE page: identity-only hero (no 게스트 chip, no dates as meta), a participation strip (참석 · 노쇼 · 첫 참석 · 최근 참석), a qualification checklist for admittance, and visit-history rows; members keep the member profile pageOwner direction, drawn on /wireframes/guest-roster phone (b)join-review-detail-screen.tsx once approved
2026-09-08(a)Club summary card seam: the member faces + capacity cluster sits at the seam's RIGHT end, the flag alone on the left ("it's supposed to be at the end") — reverses 2026-09-06's beside-the-flag placement; two reversals, the corners law standsFinal — corners lawpackages/features/clubs/src/shared/club-photo-seam.tsx (CLUSTER_RIGHT_INSET), kit WFClubCard
2026-09-08(b)Session state word: no lead icon beside the status text; the live pulse is the only glyphFinalsession-strip-ui.tsx (SessionStateInline)
2026-09-08(c)Session card closing row: attention + standing chips render as badges (SessionStripChipBadge); the countdown sub is omitted when the lead already names the moment (곧 시작, 우천 예보, live); LIVE is the one state that keeps a top strip bandFinalsession-card-v2.tsx, session-strip-ui.tsx, kit WFSessionCardV3/WFSessionStateWord
2026-09-08(d)Bookmark is visible on every session card (outline unsaved, filled saved) right of the weather, and it is the toggle; the detail header keeps its ownFinalsession-card-v2.tsx + SessionSaveButton variant="card"
2026-09-07(d)Spacing and alignment on every component — owner repeated the rule; boards now carry a build-time rhythm check (space-between + off-ladder px values, RHYTHM=1 for the list) and are screenshot-verified before deployStanding rulescripts/build-wireframes.mjs
2026-09-08(e)Compaction rulings (audit §3, boards /wireframes/compaction-*) — D1 YES: CollapsingTopBar on EVERY detail page with a graphical hero (title reveals on scroll); the hero must not restate the session title (drop it from the session model's hero, sessionTitle stays a list-card derivation only) and the flat one-fact-per-row metadata under hero titles is rejected → research/reuse a compact IDENTITY pattern and apply it to every hero; detail-page side spacing must match club detail's rail. D2 KEEP the StatStrip as the numbers row, each detail page choosing its key facts (no restatement elsewhere). D3 key badges live BESIDE the title, never below; the header live dot stays. D4 NO — 정보 stays expanded. D11 YES rules once per session; open: a visual anchor at the top of live pages. D12 NO collapse; each detail page gets its own pass. D5/D6 keep the three full screens AND the 홈 schedule block (alternative would be auto-posting/pinning upcoming meets in the feed). D10 NO — title left + bell right symmetry stays. D8 YES merge the two scope controls. D7 YES merge ELO/reliability, heatmap stays OPEN, trend card = delta. D9 YES attendance once + reliability into the ELO sheet; profile meta (클럽, 구력) become badges, with a merged club-logo+name badge.owner

Superseded boards

Six *-detail-redesign wireframes (drawn 2026-08-30/31 into the club-detail place-surface format — one-card heroes, card-boxed sections on a $card canvas) predate the Canvas law (owner, 2026-09-02) and are superseded by the flat-language board; their role-density findings (participant/host/guest slots) still stand.

Markdown remains the source of truth. Run yarn docs:check before handoff.