Overview
Compare
Inspect
A DetailShell (header-right = Settings gear only) + a SelectionChip filter row over a FeedList banded into 할 일 → 새 소식 → 이전 알림, each row the shared NotificationRowShell.
route · apps/mobile/app/home/notifications.tsx → home/src/notification-center-screen.tsx
grounded in 2 source file(s)
packages/features/home/src/notification-center-screen.tsxpackages/features/home/src/notification-center/notification-row.tsx
Spec
1
Foundations · 디자인 시스템
Spacing · 4px grid
$1 – $4
4 · 8 · 12 · 16 px
$5 – $10
20 · 24 · 32 · 40 · 48 · 64 px
Radius
$2 8 · $3 12 · $4 16 · $7 9999 (pill)
Color · Classic Grass (light)
Surface
$background #F8FBF9 · $card #FFFFFF · $surfaceTertiary #E5FAEA
Brand
$primary #006D37 · $primarySubtle #E5FAEA
Text
$text #0D100E · $textSecondary #4F5851 · $textTertiary #626C64
Border
$border #CAD4CC · $borderSubtle #DFE7E1
Status
$success #14804A · $warning #946200 · $error #B8332E
Badge intents
accent #E0F8F3/#007B6B · warning #FFF4D6/#946200 · error #FDECEC/#B8332E
Court
$courtClay #B84A2E · $courtHard #247BA0 · $courtGreen #006633
Typography · Pretendard
cardTitle · navTitle
16 / 24 · 600 · 17 / 22 · 600
cardBody · cardMeta
14 / 22 · 400 · 13 / 18 · 500
badge · micro
12 / 18 · 600 · 12 / 16 · 600
display Sm/Md/Lg/Xl
20/28 · 28/36 · 36/44 · 48/56 · 700
Primitives · @twomore/ui
Layout
YStack · XStack · Card (default/flat) · Well · Divider
Controls
Pressable · Badge · Icon · PillNav · MainTabShell · BottomCtaBand
Data viz
DateTile · CapacityRing · ProgressBar · AvatarStack · SegmentedDonutChart
Domain cards
SessionCard · ClubCard · VenueHero · SessionCompactRow · member row
Box sizes
AVATAR XS 28 · SM 32 · MD 40 · LG 44 · 2XL 88 · TOUCH_TARGET 44
Rationale
Every part is built from these — one 4px grid, the Pretendard type scale, the Classic-Grass palette, and the shared @twomore/ui primitives + domain cards.
2
Header · Settings gear only
Structure
headerRight
HeaderIconButton (Settings) → routes.signalPreferences — the ONLY header action (notification-center-screen.tsx:438-444)
Relocated
모두 읽음 moved OFF the header onto the 새 소식 band’s own SectionHeader right slot (header-icon-system rework)
3
Filter chips · with counts
Structure
Chips
SelectionChip row (a label + a SEPARATE trailing count, not one string): 전체 · 안 읽음 · 관리 (only when admin work > 0) · every category with count > 0 (helpers.ts buildFilters)
Count source
bug fix 2026-09-17 — EVERY chip count reads useSignalVisibleCounts (server-side, migration 00646), never the currently-loaded infinite-scroll page (전체 used to read feedItems.length, capped at whatever had paged in). A8 (screen audit 2026-09-23) went further: every chip counts ROWS, not quantities — 전체 = visibleCounts.total + adminRowCount (every visible signal row PLUS every admin KIND-row); 관리 = adminRowCount alone (the KIND-row count, not the item total behind them — previously it summed the raw counters, e.g. 미납 12 + 신고 1 = 69, a different unit than every other chip).
Virtual
관리 is a pseudo-category filtering the admin-attention KIND rows (never persisted Signals) but riding the same chip UI
4
Bands · 할 일 / 새 소식 / 이전 알림
Structure
Bands
the feed groups into 할 일 (todo) → 새 소식 (fresh/unread) → 이전 알림 (earlier), each a SectionHeader variant="list" (i18n/ko/notifications.ts band)
Row
NotificationRowShell — a FULL-CIRCLE (32px) icon bubble + bold-if-unread title + body + leading badges + trailing relative time + absolute dismiss ✕
Body facts
a multi-fact body (resolveSignalBody/breakdownLines) is readonly string[], rendered via MetaSegments — one line per fact, never a middle-dot-glued string (docs/canon/components.md "No middle-dot joins")
할 일 row
KIND-GROUPS (decision log ROUND-4, 2026-09-23 — see notification-groups.jsx): admin-attention groups by KIND (가입/입금확인/미납/신고/게스트), never per club. A kind held by 2+ clubs is ONE neutral group row (label + "{N}개 클럽", expands inline to per-club rows); a kind held by exactly one club is that club's own DIRECT row (the "label count" fact — e.g. "미납 9" — as the title, the club name as the sub, no chevron). Neither shape carries the old full $badgeWarningBg tint or a "관리" badge any more — a small warning dot beside the title carries the state instead.
5
모두 읽음 · inline band link
Structure
Placement
inline text link inside the 새 소식 band’s own SectionHeader right slot, gated on unreadSignalCount > 0 (notification-center-screen.tsx:273-283) — never a header action
6
Admin filter
Structure
Rows
the 관리 chip isolates the admin-attention KIND rows (KIND-GROUPS) — one row per KIND across every club the viewer admins, not one row per club and not one row per issue instance; a kind in 2+ clubs is a group row, a kind in exactly one club is that club's direct row
Band tone
band labels are never danger-toned — plain ink, weight 700, same as every other band
7
Empty
Structure
Empty
zero signals → EmptyState (Bell)