Skip to content

Owner review 1, lane A — leading markers, heading spacing, type, rail, blocks, strips, English, motion and accessibility (2026-10-11) ​

Status: Draft · Date: 2026-10-11 · Lane A of the owner's review of the flat v2 component boards: points 1–6, 21 and 22, plus an audit of library §3–§6 for departures from platform guidance and measured peer practice. Inputs: grammar, component library, behaviour addendum, the built boards in docs/public/wireframes/. Brief: platform guidance beats taste, measured peers beat assertions; where sources disagree, say so and recommend. Nothing outside this file was changed.

0. How to read this note ​

Evidence tags. Doc = a primary document read for this note (URL given). Code = a value read from a published design-system package or source file. Measured = measured by me on App Store frames or raw captures (method below). Derived = computed from those inputs (method stated). Unverified = not found, or only a device can answer.

How the numbers were measured.

  • Frames. 431 App Store frames (48 apps, including the English-UI sets of 7 Korean apps), fetched through the iTunes lookup API (screenshotUrls, original size via the 0x0ss.png suffix). Most are marketing mock-ups (a phone inside a panel). Two sets are raw captures and therefore exact at 3 px per pt: Apple Developer (1320 × 2868 px = 440 × 956 pt, iOS 26) and Shortcuts (1242 × 2208 px = 414 × 736 pt). The cited frames are listed with their URLs in §12 (app:n = the n-th screenshotUrls entry, from 0).
  • Scale. The screen is found as the widest run of the screen's background colour through the frame centre; pt = px ÷ (screen px ÷ 390), i.e. a 390 pt-wide screen is assumed (the same assumption as lane K). A 393, 402 or 430 pt capture reads 1–10 % low. Three cross-checks against published tokens support the assumption: Toss text 23.5–24.0 (TDS 24), 당근 16.5 (Seed 16), Airbnb 24.1 (24).
  • Margins are read from block edges (images, cards, chips, avatars, hairlines: runs of at least 14 pt) as left and right peaks, so a sideways error in the screen bounds cancels. Text first-ink is used only on text-only screens (it overstates by the side bearing, 0.5–1.5 pt). Error: about ±1 pt.
  • Vertical gaps are ink to ink on a left column band, same scale.
  • String widths are advance sums in Pretendard 1.3.9 (Regular/SemiBold, jsDelivr), no kerning, about ±2 %. Visual angle assumes 1 pt = 0.16 mm.
  • English date and time strings are Intl output of Node 22.22 (ICU 77.1, CLDR 47).

At a glance ​

#Owner pointVerdict
1Leading markersThe owner's rule is right and Apple's and Seed's practice agree with it when it covers the whole list (the slot is reserved on every row, so the text edge never moves). Headings never take a slot. Dot 8 (not 6), slot 16, centred on line 1. The hung "today" dot goes.
2Space above headingsIt is Gestalt proximity: the heading belongs to what is under it (NN/g). Eleven measured headings in six products keep 15–20 below (median 16.8) and 24–55 above (median 33.8), ink to ink. Ours is 36.6 above (fine) and 12.6 below (the outlier): change 8 → 12 below. The peers' section titles are also larger than ours (A9).
3Type scale15/22 is below every body reference for reading text (KRDS ≥ 16, M3 16/24, Seed 16/22, Apple 17; Toss's primary text is 17); it stays right for single-line UI text. Add a 16/24 reading role, raise tab labels 11 → 12, make wrapping text ≥ 1.5, raise the label cap 1.5 → 2.0.
4Side marginThere is no single standard. Platform: 16 (Material, Seed, iOS ≤ 375 pt) and 20 (iOS ≥ 390 pt, measured 20.00 at 414 and 440 pt); Toss 24. Measured third-party apps are bimodal at 16 and 24. Keep 20 at 390–440 pt, 16 below 390, 24 from 600; it does not change between 390 and 430.
5BlocksLeft-aligned; zones eyebrow → figure → meta; the affordance is one chevron on the eyebrow row; no buttons inside; one state table for all five blocks.
6StripLeft-aligned equal-pitch columns (today's pitch is 133 / 116: unequal), label above figure (same order as the Block and the spoken order), air instead of hairlines, 2–4 columns, reflow 2-up when a figure does not fit.
21EnglishOur corpus measures EN ≈ 1.33× KO width (median), 1.59× for labels of ≤ 4 syllables. The clutter comes from row L2 (368 px vs 273 px) and long Tag copy, not from dates. Write by role budgets, truncate the flex segment, never the fixed tokens.
22Motion and accessibilityKeep the timing set and tokens (they equal M3 and Seed). Change Reduce Motion to replace with a short fade, not remove. Missing: WCAG 2.5.7 dragging alternatives, 1.3.4 orientation, the OS contrast and cross-fade settings, the App Store accessibility-label checklist.

1. Leading markers: status, unread and live dots (owner point 1) ​

"When there is a dot in front, we are losing the gap in front. Make sure that we don't lose the front gap, across all components, even if we add the status dot. So everything gets pushed back."

What we have ​

  • Day header (library §3, ruling L2 in §13): a 6 px "today" dot (ball fill, 1 px ink edge) hung in the gutter at x 8–14 so the date stays on the 20 rail.
  • Unread marker (§18.2, ruling D1): a 6 px danger dot hung at x 8–14, centred on line 1, with "읽지 않음" prefixed to the spoken label.
  • Both put ink inside the 20 pt margin. Two components already follow the owner's rule: the Select-mode checkbox (24 at the rail, content shifted 36, §14) and the LiveScore serving dot (6 + 8 inside the block padding, §14).

Evidence ​

How references mark "new", "unread" or "live".

ReferenceMarkerWhere it sitsEvidence
Gmail (iOS)none: unread = bold sender and subject; category rows show a trailing count pill ("2 new")avatar 40 on the left, time and star trailingMeasured, gmail:1
Slackbold name plus a trailing purple count pill; presence = dot on the avatar's bottom-right cornertrailing, avatar cornerMeasured, slack:1
KakaoTalktrailing time and a red/orange count pill; a count badge beside the tab labeltrailingMeasured, kakaotalk:3
Toss (TDS Tab)6 × 6 #f44336 dot ("redBean")top 4, right 0 of the tab labelCode, @toss/tds-mobile 2.5.1 (npm)
Seed (당근) NotificationBadge, Listsmall = 6 px dot; large = min 18 × 18, label 11/15 bold, ≤ 4 characters; unread rows use List "Highlighted"top-right of an icon or tab; row emphasis, not a gutter dotDoc, notification-badge, spec JSON, list
Material 3 Badgesmall 6 dp; large 16 dp (label small 11/16)top-end corner of the iconCode, BadgeTokens.kt
Apple HIG, tab barsred oval with a number or "!"; "Reserve badges for critical information"on the tabDoc, Tab bars
Apple Mail, Messagesblue leading dot for unreadleading edge, text column indented for every rowObserved practice; geometry Unverified (Apple's pages give none; no raw capture exists in the store sets)

None of the measured Korean apps hangs a dot in the margin. The three working families are a leading dot in a reserved column (Apple), a trailing count (Kakao, Slack, Gmail categories), and an icon-corner dot or row emphasis (Material, Seed, Toss).

Principles the rule rests on.

  • Alignment: "Align elements to make them easier to scan, and use indentation to convey hierarchy… People assume that aligned items are related to each other, and conversely, they perceive indented items as subordinate" (HIG Layout). A text edge that jumps between rows of one list reads as hierarchy that does not exist.
  • Seed's List guideline says the same as a Don't: "내부 간격을 조정할 때 각 Item의 정렬은 일관되어야 합니다" (keep the alignment of each item consistent), with an image of items aligned differently inside one list (list). Seed also warns against list padding narrower than its 16 global gutter.
  • Even Apple's own apps keep ink off the margin: first ink sits at exactly 20.00 pt in 3 of 4 raw Apple Developer frames (1,199–1,431 rows) and in both Shortcuts frames (724–769 rows); inset-grouped cards start 20.0–20.3 pt from each edge (Measured, appledev:0, 1, 3, shortcuts:0, 2).
  • Non-text contrast (WCAG 1.4.11, 3:1): the danger dot is 5.91:1 on white; the ball-coloured today dot is 1.28:1, which is why it needs its ink edge (Derived, Understanding 1.4.11).
  • Colour is not the only cue: Apple's Differentiate Without Color Alone criteria accept shape and text cues; a dot that is present or absent is a shape cue, and the spoken prefix is the text cue.
  • Size: a 6 px dot is 0.96 mm, 8.3 arcmin at 40 cm; reading speed for older adults falls inside a 9–18 arcmin "critical print size" band (systematic review, 12 studies). 8 px is 11.0 arcmin. Peers use 6 only when the dot rides on an icon or tab, where the icon makes it findable; as a row's only cue it should be larger (Derived).

Recommendation: the leading-marker rule ​

#RuleValueWhy
LM1Keep-outNothing except full-bleed surfaces (photo, band, hairline, block fill) enters x < rail or x > 390 − rail. No dot, glyph, tag or text in the margin.The owner's rule; Apple's own apps measure 20.00 exactly.
LM2The slotA leading marker takes the first slot of the row, starting on the rail. Slot = marker + gap: dot 8 + 8 = 16 (content edge x 36); checkbox 24 + 12 = 36 (existing); rank column 24 / 32 / 40 + 12 (existing, §20.2).One ladder for every leading element; the content edge shifts right by the slot.
LM3Whole listThe slot is reserved on every row of a list that can show the marker, so all text edges match. A list that never shows the marker has no slot (no empty gutter). While Select mode is on, every row's slot is the checkbox slot (36) and the dot is hidden (the state stays in the spoken name).HIG alignment, Seed List Don't. Shifting only the marked rows would zig-zag the text edge.
LM4Headings take no slotDay header, section head and page title text stays on the rail. The today dot is dropped: "오늘" is already the relative-day label (ink, 600). If a mark is ever wanted it follows the date, 8 after, never precedes it.A heading at x 36 sits off the thumbs below it; the dot adds nothing the label does not say.
LM5Size and colour8 px circle for a row marker (6 px stays for dots that ride an icon or a tab: tab bar, header badge). Unread = danger #B8332E (5.91:1). Do not use brand ball as a dot fill.Visual angle; peers' 6 px is icon-attached; 3:1 non-text contrast.
LM6Vertical alignmentCentre on the first line's centre (L1 17/24: 12 from the text-box top; 15/22: 11), top rounded to the 4-grid (8). Not centred on the row.A 3-line row keeps the dot beside line 1, where the eye starts.
LM7With avatars, thumbsOrder: [marker 8][8][avatar 40][12][text] (text edge 88, was 72); [marker][8][thumb 56][12][text] for media rows. Presence of a person (online) is a different marker: a 10 px dot on the avatar's bottom-right with a 2 px canvas ring (Slack), not a slot. Counts stay trailing (Tag, §6).Keeps the avatar on the grid; separates "state of the row" (slot) from "state of the person" (corner).
LM8Screen readerThe dot is hidden from assistive tech; the row's one accessible name begins "읽지 않음, …" (existing D1). No live-region announcement when the dot clears. Under text scaling the dot and gap stay 8 / 8; the dot follows line 1's centre at the scaled line height.WAI guidance: state before content; B8.1 one stop per row.

Cost of the slot. 16 pt of text width on rows that carry a marker (4.6 % of 350). That is why the slot is not added to lists that never show a marker, and why counts remain trailing.

What changes ​

  • Components: Day header (remove the hung dot; spacing in §2); Unread marker (§18.2: 6 → 8, hung → slot); Select mode (§14: record the slot ladder); LiveScore serving dot (§14: use the 8 + 8 slot on both team rows).
  • Boards: components (day header and unread specimens), list-a (notifications), patterns (LiveScore, Select mode), additions.
  • Gate: a board check "no non-full-bleed element has first ink left of the rail", with the current hung dot as the known-positive canary.

2. Space above headings and the heights of bars (owner point 2) ​

"And why are we adding the extra padding on top for headers?"

What we have ​

  • Section head (library §3): title 17/24·600, action 13/18·500 + chevron 16; 32 above, 8 below (the edge rule trims the first row's top padding). In ink terms (Derived: a 17/24 Hangul line has its ink 4.6 pt below the box top and 4.7 above its bottom): 36.6 above, 12.6 below.
  • Day header: a 32-tall box, 15/22·600 date, 16 above → ink 25.5 above and 9.5 below.
  • Header 56 under the status bar; tab row 44 with 24 (title, day header) or 16 (row) below it; Band 12 with 24 above and below.

Why the space above is larger (the plain answer) ​

A heading belongs to what is under it. If the gap above and below were equal, the heading would float between two groups and the eye could attach it to either. The space above separates it from the previous group; the space below binds it to its own. That is the Gestalt law of proximity, and Nielsen Norman Group states the heading case directly: "the text from the corresponding section is usually placed closer to the heading than the text from the preceding section" and "Using varying amounts of whitespace to either unite or separate elements is key to communicating meaningful groupings" (NN/g, Proximity). HIG says the same about grouping by "negative space" (Layout). KWCAG 5.4.4 lists "line and letter spacing" among the accepted ways to keep neighbouring content distinguishable (KWCAG 2.2, 5.4.4). Equal gaps would not be "cleaner"; they would remove the grouping.

Evidence: how much (Measured, ink to ink, pt at 390) ​

ReferenceHeading ink heightGap aboveGap belowAbove ÷ belowFrame
Apple Developer (iOS 26, raw 440 pt) "Recent videos ›"17.024.317.01.4appledev:0
same, "Revisit WWDC25"17.025.017.01.5appledev:0
Toss 증권 홈 "내 계좌" (under the tab row)16.530.517.61.7toss:2
Toss 증권 홈 "내 투자"16.955.116.53.3toss:2
Airbnb "Recently viewed homes ›"17.431.715.72.0airbnb:0
Airbnb "Stay in Mexico City ›"17.133.816.02.1airbnb:0
당근 알바 "서초동 이웃들이 많이 찾는 알바"16.551.7 (band inside)15.13.4daangn:4
당근 중고차 "지금 인기있는 차"18.754.0 (band inside)20.12.7daangn:6
무신사 "최근 쇼케이스" (under the top tabs)17.227.916.81.7musinsa:4
무신사 "최근 매거진" (after a white card)17.240.916.82.4musinsa:4
NOL "숏폼으로 떠나는 해외여행" (after a carousel)17.954.117.93.0yanolja:6
Peers, median (range), n = 1117.1 (16.5–18.7)33.8 (24.3–55.1)16.8 (15.1–20.1)2.1 (1.4–3.4)
Lane K, section → section whitespace, 7 screens—median 36 (27.7–55.8)——lane K §3
Ours today14.736.612.62.9Derived from §3

Eleven measured headings in six products (seven of them Korean) keep 15.1–20.1 between the heading's ink and the content it opens (median 16.8, middle half 16.0–17.6) and 24–55 above it (median 33.8). Ours is inside the range above (36.6, a little over the median) and about 4 pt short below (12.6 against 16.8). The Korean flat feeds sit at the long end above (41–55 when a band, a card, tiles or a carousel is above; 28–31 under a tab bar) and keep the same 15–20 below. Lane K's separate set of seven section gaps (27.7–55.8, median 36) and its title → first row figures, 19.1 (카카오톡; 16.3 to its avatar strip) and 27.6 (Toss 혜택), agree. Under a tab bar the first heading sits 27.9 below it (무신사) or 30.5–31.2 (Toss 증권, mine and lane K's); ours is 24 + 4.6 = 28.6, so the 24 stays.

The 당근 seam, twice. Both 당근 frames show the same seam: 19.7–21.5 of air, an 8 pt band (7.8 measured), then 24.2–24.7 to the heading's ink. With 카카오페이 (lane K: 33 / 13.1 / 37) that makes two measured band screens; our Band (12 tall, 24 of air on each side) is between them in thickness.

Heading size. The peers' headings are larger than ours: ink 16.5–18.7 (median 17.1) against our 14.7 (17 px Hangul). For the Hangul-only headings, ink ÷ 0.868 gives about 19–21.5 px. That is a size question, not a spacing one, and it is audit item A9 (§9); the spacing below holds for either size.

Published values.

SourceAbove / belowEvidence
Toss TDS ListHeader (medium)padding top 24 / bottom 8, gap 4 to a description; (small) 16 / 4 / 0; side 24 (medium) or 20; title t5 17/25.5 bold, right link t6 15Code, @toss/tds-mobile 2.5.1 (ListHeader: vertical padding, horizontal padding and size maps)
Seed ListHeaderpaddingY 8 / 8, paddingX 16 (global gutter), gap 10; 14/19 medium, weak colour or 700 solidDoc, list-header.json (a symmetric box; any asymmetry comes from the layout around it)
Material 1 list subheadera 48 dp tile, Roboto Medium 14 sp, left-aligned with the avatar or icon (symmetric inside the tile; the previous item's own padding makes the sum asymmetric)Doc, m1 Subheaders
Material 3no subheader token; list item vertical padding 8 (12 for three lines)Code, ListItem.kt
UIKit grouped and plain tablesiOS 15 added sectionHeaderTopPadding, default "automaticDimension"; developers report 22 pt of extra space above plain headersDoc, UITableView.sectionHeaderTopPadding; the 22 pt figure is community-reported, not in Apple's text
HIG"the grouped style uses headers, footers, and additional space to separate groups of data"Doc, Lists and tables

Bar heights (the owner's second question).

BarValueEvidence
iOS navigation bar44 pt (64 pt with the 20 pt status bar, iOS 7 era; iOS 26 not documented)Doc, Apple archive, Transition Guide
Material 3 small top app bar64 dpCode, AppBarSmallTokens.kt
Seed top navigation56 px; title t6 18/24 or t5 16/22, subtitle t2 12/16Code, top-navigation.json
Ours56 under the status barbetween iOS 44 and M3 64, equal to Seed: keep

Recommendation ​

WhereTodayRecommendedResult (ink)
Section head, below812 (the row-padding step)12.6 → 16.7 (peers 16.8)
Section head, above3232 (unchanged)36.6 (peers 33.8; 24–55)
Day header32-tall box, 16 abovea 22 line box (15/22·600) with 24 above, 12 below, no fixed height25.5 / 9.5 → 28.5 / 16.5
Tabs → first heading24 (title or day header), 16 (row)unchanged, but the heading's own above-space is the seam (not additive)28.6 (peers 27.9–31.2)
Header, Band56; 12 with 24 / 24unchanged—

The rule to keep: the ink gap above is about twice the gap below (peers' median ratio 2.1) and the gap below is about 16 (peers' median 16.8). It reads from the peers, not from our ladder.

What changes ​

  • Components: Section head (§3, grammar §3 "title → first row 8" becomes 12, §4 "32 above, 8 below" becomes 32 / 12); Day header (§3 and §13 L2).
  • Boards and numbers: every screen with a section head moves its first row down 4 pt per section; day-header lists gain 10 pt per day. Re-measure the 홈, 경기, 기록 and 프로필 screens (grammar §5 totals).
  • If the owner adopts D7 (section title 20/28, audit A9): the Section head is 28 tall instead of 24 and each section moves down a further 4 pt; the box spacing (32 above, 12 below) does not change, and the ink gaps become 37.3 and 17.3, still inside the peer ranges.

3. Type scale against accessibility guidance (owner point 3) ​

"As for the type scale, can you ensure that we are following recommended accessibility guidelines?"

What we have ​

Grammar §2: display 40/48·700 · hero 24/32·700 · title 20/28·700 · headline 17/24·600 · body 15/22·400/500 · footnote 13/18·500/600 · caption 12/16·500; tab-bar labels and count tags 11/14. Behaviour addendum B6: caps reading 2.0, hero 1.7, numeral 1.5, label 1.5, chrome 1.3; every text-bearing height is a floor.

Evidence ​

What each source asks for.

SourceDefault / bodySmaller stepsFloorLine heightEvidence
Apple HIG (iOS, Large)Body 17/22Callout 16/21, Subhead 15/20, Footnote 13/18, Caption 12/16default 17, minimum 11 ("follow the recommended default and minimum text sizes")Body 1.29Doc, Typography (JSON mirror: typography.json)
Material 3Body large 16/24Body medium 14/20, small 12/16; label small 11/16Android: "Don't make the body size any smaller than 12 sp"1.50 / 1.43 / 1.33Code, TypeScaleTokens.kt; Doc, Android accessibility
Toss TDSt5 17/25.5 (primary), t6 15/22.5t7 13/19.5, st12 12/18, st13 11/16.5111.5 up to 18 px, 1.33 at 30Code, @toss/tds-mobile 2.5.1 (type map)
Seed (당근)t5 16/22t4 14/19, t3 13/18, t2 12/16t1 11/151.33–1.38Doc, typography
KRDS (Korean government design system, Pretendard GOV)body medium 17 (default); large 19small 15, xsmall 13"본문 폰트 크기는 … 최소 16px 이상""최소 150% 이상", citing WCAG 1.4.12Doc, KRDS typography; the page says Pretendard GOV defaults to 17 px because it looks smaller than other typefaces (paraphrase of the page text)
WCAG 2.2——none (1.4.4: 200 %; 1.4.10: reflow at 320 px)1.4.12: nothing may break at 1.5 / 2 / 0.12 / 0.16Doc, 1.4.12 (AA), 1.4.4, 1.4.10
KWCAG 2.2 (KS X OT0003:2022)——no minimum font size; contrast 4.5:1 (3:1 for ≥ 18 pt or 14 pt bold)—Doc, KWCAG 2.2 5.4.3; 6.1.3 controls ≥ 6.0 mm diagonal (≈ 27 dp square; ours 44 passes)
Ours15/2213/18, 12/1611/141.47 / 1.38 / 1.33 / 1.27Grammar §2

Reading of the table. Every body reference puts reading text at 16–17. 15 is the secondary step in Toss (t6), Apple (Subhead) and KRDS (small). So 15/22 is a correct size for a single-line row subtitle and the wrong size for text people have to read (comments, notices, dialogs, descriptions, inputs). KRDS adds that its Pretendard GOV looks smaller than other typefaces, which is why its default is 17.

Pretendard's metrics (Derived from the 1.3.9 font files, units per em 2048):

MetricValueConsequence
Hangul syllable advance1770 = 0.864 ema 350 pt column holds 23.8 syllables at 17 px, 25.3 at 16 px, 27 at 15 px
Hangul ink height−162…1616 = 0.868 em15 px text has 13.0 px of ink; 11 px has 9.5 px
x-height / cap height0.530 em / 0.707 emthe Latin in English mode is smaller than Hangul at the same size (x-height 7.9 px at 15 px)
hhea ascent, descent, gap1950, −494, 0 = 1.193 emline-height: normal is tight for Hangul; set it explicitly

Line height for Hangul. The white between two Hangul lines is line height − 0.868 em:

StyleRatioWhite between linesStyleRatioWhite between lines
tab 11/141.270.40 emApple body 17/221.290.43 em
caption 12/161.330.47 emours body 15/221.470.60 em
footnote 13/181.380.52 emToss t6 15/22.51.500.63 em
headline 17/241.410.54 emKRDS 17/25.5, M3 16/241.500.63 em

Our small steps leave 0.40–0.52 em, against 0.60–0.63 em in Toss, KRDS and M3. WCAG 1.4.12 does not require an author to set 1.5; it requires that the layout survive it, and KRDS adopts 150 % as the design value. Research on spacing is weak: it found no significant effect of line or letter spacing on Hangul legibility in older readers (below), and only the extremes (0.8 and 1.8) hurt on the web (Rello et al., CHI 2016, abstract-level). So the rule is "≥ 1.5 wherever text can wrap", not a larger scale.

Legibility research for older adults (the audience is 40–60).

StudyResult
Jeong 2016, J. Korea Contents Association: Hangul on smartphones, 24 adults over 65, 11 / 12 / 13 pt13 pt was more legible than 11 or 12; larger sizes were preferred in the order 13, 12, 11; letter and line spacing had no significant effect. (The page does not state the device, so the "pt" is the study's own unit.)
Systematic review, Frontiers in Psychology 2022, 12 studiesolder adults prefer larger sizes but "bigger may not always mean better"; reading speed drops sharply below a critical print size of about 0.15°–0.3° (9–18 arcmin); recommends reporting visual angle.
Rello, Pielot, Marcos, CHI 2016 (104 readers, web)readability and comprehension rose with size; 18 pt and larger recommended; spacing effects weak.

No study fixes a Hangul minimum. The visual-angle view puts the sizes in context (Derived; glyph height 0.868 em, 1 pt = 0.16 mm):

Size111213151617
arcmin at 35 cm15.016.417.720.521.823.2
arcmin at 40 cm13.114.315.517.919.120.3
arcmin at 45 cm11.712.713.815.917.018.0

At 40 cm, 11–13 px sit inside the 9–18 arcmin speed-loss band and 15 px sits at its upper edge; 16–17 px clear it. This is an indicator, not a standard.

Text scaling caps against Toss's published table (Code: the Nf function and the cap array in @toss/tds-mobile; at 200 % the scaled px are min(size × 2, cap)):

Size (px)Toss capToss at 200 %Our class, cap, at 200 %
113122chrome 1.3 → 14.3
133426label 1.5 → 19.5
153730reading 2.0 → 30
173934reading 2.0 → 34
204040header title is chrome 1.3 → 26
244040 (1.67×)hero 1.7 → 40.8
304242 (1.4×)numeral 1.5 (24 → 36, 40 → 60)

Reading, hero and numeral classes match Toss's philosophy (large sizes compress, small sizes reach 2×); Toss's tab component also stops at 140 %. Our label class (13 px) is the outlier: Toss lets 13 px reach 26 px; we stop at 19.5. A Tag carries state ("입금 필요"), so it is content, not chrome; Apple's Larger Text criteria ask content text to reach 200 %.

Colour of text (Derived; Seed's APCA thresholds: readable text Lc ≥ 75 with Lc ≥ 90 recommended, other text Lc ≥ 60 and bold below 16 px, inclusive design):

PairWCAGAPCA LcReading
ink #0D100E on white19.1:1105.5passes everything
secondary #4F5851 on white7.38:185.6passes (Seed's 75; short of 90)
secondary on gray100 #F2F2F26.59:177.9passes 75
tertiary #626C64 on white5.46:177.3passes 75
tertiary on gray1004.87:169.5below 75: keep "≥ 16 px or bold only"
white α0.8 on block #15181A (eyebrow)11.65:177.5passes

Colour is not the problem; size is.

One web finding. Safari on iOS zooms the page when an input's text is below 16 px: "If the font-size of an <input> is 16px or larger, Safari on iOS will focus into the input normally" and at 15 px or less it zooms (CSS-Tricks). Our Input text is 15/22. On apps/web that is a defect, independent of the accessibility argument.

Recommendation: the scale and its minimums ​

Role (size/line · weight)OursRecommendedChangeWhy
display (numeral)40/48·70040/48·700noneSeed t13 40/52; numerals only
hero24/32·70024/32·700noneM3 headline small 24/32, Seed t9 24/32
title20/28·70020/28·700noneToss t4 20/29
headline (row L1, button lg, section title)17/24·60017/24·600noneToss t5, KRDS default 17; a 1–2 line headline tolerates 1.41; the section title is the open question A9 / D7
reading (new role: comment, post body, dialog and notice body, toast, terms, descriptions, input and textarea text)(15/22·400)16/24·400 (500 for emphasis)newKRDS "≥ 16", M3 body large 16/24, Seed t5 16, iOS web input zoom; 1.5 ratio; keeps every height on the 4-grid (24)
body (single-line UI: row L2, cell label and value, button md / sm, tabs)15/22·400/50015/22·400/500noneToss t6, Apple Subhead, KRDS small
footnote (Tag, eyebrow, section action, helper)13/18·500/60013/18 when one line; 13/20 when it can wrap (helper, caption row, meta)line heightKRDS xsmall 13/19.5, Toss t7 13/19.5; Jeong 2016: ≥ 13
caption12/16·50012/18, only for non-essential text (chart ticks, input counter, timestamps)line height12 is the floor on Android and below Jeong's 13; Hangul ink 10.4 px
tab-bar label11/14·500/60012/16·500/600+1M3 navigation bar label is Label Medium 12/16 (NavigationBarTokens); Android floor 12 sp; two-syllable Hangul labels
count tag numeral (digits only)11/14·70011/16·700line heightM3 badge label small 11/16, Seed 11/15 bold; digits, not Hangul

Minimum size per role. Reading text 16 · primary single-line UI text 15 · informational labels (Tag, eyebrow, action, helper) 13 · non-essential text 12 · tab-bar labels 12 · digits inside badges 11 bold. Nothing in Hangul below 12. Weights: 400 only at 15 and above; 500 or heavier at 13 and below (HIG: prefer Regular, Medium, Semibold or Bold; Seed: bold below 16 px at Lc 60).

Scaling. Add the reading role to B6.2's "reading" class (cap 2.0). Raise the label class cap from 1.5 to 2.0 for Tag, Choice and button labels (Tag keeps minHeight 24 and grows); keep chrome at 1.3, numeral at 1.5, hero at 1.7. Tag at 200 % then reads 26 px beside 30 px reading text.

WCAG and KWCAG mapping after the change. 1.4.4 resize: 200 % holds for every content role; 1.4.10 reflow: the 320 frames in B6; 1.4.12 (web only): heights are floors, check overflow: hidden on nowrap Tags and Choices with a text-spacing override; 1.4.3 contrast: table above; KWCAG 5.4.3 and 6.1.3: pass.

What changes ​

  • Documents: grammar §2 (add the reading role, floors, line heights) and §3; library §1 (type line), §3 (tab bar label 12/16), B6.2 (label cap).
  • Components: PostRow and Comment bodies, Dialog and Notice bodies, Toast text, Input and TextArea text, Document sheet paragraphs, Caption row and helper text (13/20), Tab bar label, count tag line height. Heights stay on the grid: Notice and Toast keep 48 (12 + 24 + 12); Input stays 48.
  • Boards: B6 frames (re-measure Notice, Toast, Input, Dialog at 100/130/150/200 %); add the 12/16 tab bar.
  • Gates: no-text-below-12, no-400-below-15 (ESLint on textRole), and the label-cap parity test in text-scale.ts.

4. The side margin: is 20 the baseline? (owner point 4) ​

"We seem to be using 20 as the baseline. Is that the standard baseline? I thought it was like 16 or 24."

What we have ​

Rail 20 (grammar §1, ruling C10), content 350 at 390 pt, justified as "Apple grouped-list inset 20; Toss 24; Seed 16". Block padding equals the rail; the 4-up roster, 7-day calendar (7 × 50) and 3-up strip are derived from 350.

Evidence ​

Platform and design-system values.

SourceValueEvidence
UIKit root-view layout margin16 on iPhone 8 (375 pt), 20 on iPhone 11 (414) and iPhone 12 (390); 64 in landscapeDoc, Apple forum 697910 (reported layoutMargins.left 16 vs 20; an Apple Frameworks Engineer explains the system minimum margins); monday.com engineering; Use Your Loaf ("16 points for compact width and 20 for regular", iOS 11 era)
iOS inset-grouped liststhe table's layoutMargins: "The horizontal insets for UITableView (and UICollectionView lists) using .insetGrouped come from the layoutMargins"Doc, Apple Frameworks Engineer in the same thread; Apple's property page gives no number (systemMinimumLayoutMargins); HIG Layout gives none either
Apple's own apps, raw captures20.00 pt at 414 pt (Shortcuts) and at 440 pt (Apple Developer, iOS 26); inset-grouped cards 20.0–20.3 from both edgesMeasured: shortcuts:0, 2 (724–769 rows), appledev:0, 1, 3 (1,199–1,449 rows), appledev:4 cards
Material 1phones 16 dp, tablets 24 dp, baseline 8 dpDoc, m1 metrics & keylines
Material 3 ListItemstart and end padding 16 dp (vertical 8; 12 for three lines)Code, ListItem.kt
Seed (당근)global gutter 16; list padding not narrower than it; web grid margin 12 (< 768 px), 24 (≥ 768)Doc, spacing, layout, list
Toss TDS ListHeader, ListRowhorizontal padding 24 (medium, default) or 20 (small)Code, @toss/tds-mobile 2.5.1
Android design guide8 dp grid; "smaller elements … a 4 dp grid"Doc, grids and units

Correction to the citation. "Apple grouped-list inset 20" holds from 390 pt up; at 375 pt Apple's own margin is 16. "Toss 24" is the TDS default, with 20 as its documented "small" and 16 for the cards and tiles measured in the app. "Seed 16" is right.

Measured peers (pt at an assumed 390 pt screen, one row per app; "edge" = what was measured; §12 has the frames):

AppFrameMarginEdge
당근daangn:116.5list and photo edges (791 rows); Seed token 16
배달의민족baemin:215.8thumbnails, labels
네이버naver:515.6 / 15.6cards, left and right
네이버지도navermap:215.0place photos (883 rows)
올리브영oliveyoung:716.6 / 15.2cards
NOL(야놀자)yanolja:617.1 / 17.5search box, banner
무신사musinsa:116.8 / 16.4cards
Spotifyspotify:015.9tiles, headings
Slackslack:116.7 / 16.0list rows, pills
Wisewise:316.4cards
TestFlight (Apple)testflight:215.2list edge (mock-up; device width unknown)
플랩풋볼flab:119.5 / 19.5banner, date chips (781 rows)
Apple Developer (raw)appledev:020.00title, cards, headings (1,449 rows), 440 pt
Shortcuts (raw)shortcuts:020.00414 pt
Apple Podcasts, Store, Fitnessapplepodcasts:3, applestore:3, applefitness:319.1–20.7tiles, cards (mock-ups)
Toss 증권 홈toss:224 (text 23.5–24.0); tiles 20.2text, account tiles (TDS 24)
Toss 쇼핑toss:315.8 / 15.8product cards (445 rows)
카카오뱅크 내 계좌kakaobank:224 (23.6–24.8); hairline 19.5 / 19.9 (lane K)text, rows
카카오뱅크 홈kakaobank:016.4 / 16.4cards (254 rows)
KB스타뱅킹kbstar:425.0 / 25.0cards (592 / 452 rows)
카카오페이kakaopay:222.4 / 22.9cards, button
문토munto:425.7posters, chips (719 rows)
Airbnbairbnb:124.1 / 24.1photo cards (975 / 995 rows)
Stravastrava:524.5 / 25.5feed card (dark mock-up)
Nike Run Clubnrc:124.9stats, text

Counting each app once (25 apps; Toss and KakaoBank by their page text rail): 16-class (15.0–17.3): 11 apps · 20-class (19.1–20.7): 6 (five are Apple's own apps) · 22–26-class: 8. Median 19.3 and mean 19.6 sit in the gap between two clusters: the distribution is bimodal at 16 and 24, with 20 owned by Apple (Apple's TestFlight reads 15.2 on a mock-up of unknown device width, so it is not a clean exception). Lanes H and K measured the same (Cash App 15.7, Monzo 16.2, 당근페이 15.5, 카카오뱅크 15.9; hairline insets 카카오뱅크 19.5 / 19.9, 네이버 19.2 / 21.6, 테니스프렌즈 19.5 / 20.5).

By product kind. Dense thumbnail feeds, commerce, maps and utilities use 16 (당근, 배민, 네이버, 올리브영, 무신사, Spotify, Slack). Finance and editorial or premium products use 24 (Toss, 카카오뱅크, KB, 카카오페이, Airbnb, Strava, NRC, 문토). The football-match peer 플랩풋볼 uses 20.

Answer and recommendation ​

20 is not "the standard baseline"; there is none. The standards are 16 (Material, Seed, iOS up to 375 pt) and 20 (iOS from 390 pt, measured exactly in Apple's apps), and Korean products split between 16 and 24. Your recollection of "16 or 24" matches the market. 20 is defensible for a reason that is not the median: it is the one value that lies inside every family's own range (Apple 16–20, Toss 20–24, Seed and Material 16 + 4).

OptionContent at 390ForAgainst
16358Material, Seed, 11 of 25 measured apps; +8 pt text width (helps English rows and 200 % text)denser; 4 pt narrower than Apple's own margin on iOS; every board and 350-based number is re-derived
20350Apple ≥ 390 pt (measured); Toss "small" and tile edge; within 4 pt of both clusters; no rebuildnot the market mode; 4 pt wider than Material
24342Toss text rail, 카카오뱅크, Airbnb; calmest−8 pt width on already tight rows; re-derivation

Recommended rule.

  • 390–440 pt phones: 20. It does not change at 430 or 440 pt: Apple measured 20.00 at 414 and 440; Material's 16 holds to 599 dp; Toss and Seed are fixed. Only the content width grows (350 → 390 at 430): derive grids from the width (7 equal day cells, 4 roster cells), never from fixed 50 / 100 px.
  • Below 390 pt (iPhone SE and mini, Android 360 dp): 16. This is Apple's own step (16 at 375 pt) and Material's value; it protects text width on the narrowest screens. One token, SEAM.rail = width < 390 ? 16 : 20.
  • Tablets and web ≥ 600 pt: 24 (Material 1 tablet margin; Seed's 24 from 768 px) with the existing ContentColumn cap.
  • If the owner would rather follow the Korean-feed mode, 16 is equally defensible and the switch is mechanical; the evidence does not say 20 is wrong, so changing it is a taste call that costs a board rebuild.

What changes ​

  • Documents: grammar §1 (rail rule and the corrected citation), library ruling C10 (SEAM.rail becomes width-aware), the block row in grammar §4 ("padding 20" follows the rail).
  • Boards: none at 390; add a 360 frame (rail 16) to the shell specimens.
  • Code: SEAM.rail, ContentColumn (24 from 600), grid components computing from width.

5. One grammar for blocks (owner point 5) ​

"We need to define the grammar and behaviors across all blocks. What is the hierarchy of information here? Type scale and ratios? Left aligned? What gets on top, middle, and bottom for each block across different states?"

What we have ​

Five blocks, each specified on its own: the 홈 day block (350 × 144: eyebrow 13/18·600 α0.8 + chevron 16, numeral 40/48·700 ball with unit 15/22·600, meta 15/22·500 α0.85), the ELO block (160: adds an 8 progress bar and a caption), the identity block (avatar 56, name 24/32·700, level Tag, sub 15/22, edit icon), the LiveScore block (team rows, set scores 24/32·700, ball-coloured points, serving dot, host controls below) and the club hero, place variant (logo 56 overlapping the band, name 24/32·700, one MetaSegments line). Library §4, §14, §19.3. They share geometry (r16, pad 20) but no stated order of content, no common affordance rule and no state table.

Evidence ​

How references compose a "figure" block (Measured on frames; sizes are estimates from ink heights and the usual cap-height ratio, so ≈; where an estimate is not reliable the cell is qualitative).

ReferenceTop (eyebrow row)Middle (figure)Bottom (meta, actions)AffordanceAlignEyebrow : figure : metaFrame
Toss 증권 홈 · 내 투자title ≈ 20 bold"4,000,000원 ›" ≈ 34 bolddelta ≈ 15 in a semantic colour; then a controls row (13 gray, 32-high toggles)chevron after the figure; no button insideleft20 : 34 : 15 (1 : 1.7 : 0.75)toss:2
Toss 홈 · 토스뱅크 and 최근 쓴 계좌title 17 bold + › at the right; group label 13 grayrows: amount 17 bold, sub 13 graycentred link row "내 계좌 · 대출 · 증권 › "whole card; 32-high 송금 button at each row's endleft—toss:0
카카오뱅크 홈—avatar 40 + amount bold + sub 13 graychips row 13이체 pill 36 at each row's endleft—kakaobank:0
Apple Health summary cardglyph + label ≈ 15 semibold in the category colour; time ≈ 14 gray + ›figure ≈ 30 bold + unit ≈ 15 gray, same baseline; chart or ring at the right—whole card, chevron on the top rowleft15 : 30 : 15 (1 : 2.0 : 1.0)applehealth:0
Apple Health activity strip—three stats: coloured label above bold numeral + unit—1 px dividers between content-sized columnsleft—applehealth:0
Apple Fitnesscard title (small, gray) + chevronring + Move / Exercise / Stand (coloured label over numeral)bar chartwhole cardleft—applefitness:0
Cash App · Money"Cash balance" label + ›"$1,226.00" bold, about 2.4 × the label's ink heighttwo pill buttons (Add money, Withdraw)chevron on the label; buttons in the bottom zoneleftfigure ≈ 2 × labelcashapp:0
Strava activity cardavatar, name bold, meta gray, "…" at the rightactivity titlestat strip (label over larger value), photo, action rowcard press; "…" is its own controlleft—strava:5
Monzowordmark left, balance right-alignedaccount numbertwo icon chipschipssplit—monzo:0
Wise, Revolut—balance centred——centred—lane H

Lane H counted 12 blocks: left-stacked 8, centred 3 (balance-as-hero wallets), split 1; buttons inside: none in 2, one in 5, two or more in 5 (lane H §3). From the frames above:

  1. The affordance sits on the top row's trailing end in the pressable cards (Toss, Apple Health, Apple Fitness, Cash App), as a chevron or time + chevron. Buttons, when present, live in the bottom zone or at the end of a row.
  2. Figure : eyebrow is about 1.7–2.2 where it could be estimated (Toss 1.7, Apple Health 2.0, Cash App about 2); NRC's weekly hero is far higher (about 4). Our brand block's 3.1 (40 / 13) is a hero ratio, acceptable once per hub; the strip uses 1.85.
  3. The unit is a smaller sibling on the figure's baseline (Apple "steps" ≈ 0.5 × figure; ours "개 일정" 0.375 ×).
  4. Stale data states its age: Toss 증권 shows "16:50 기준" at the head of 내 계좌 (toss:2): the Korean precedent for our offline state.
  5. HIG: "place the most important items near the top and leading side" (Layout); and at large text "keep primary elements toward the top of a view even when the font size is very large" (Typography).

Recommendation: the block grammar ​

Hierarchy of information. Level 1 the figure (the answer); level 2 the eyebrow (what the figure is); level 3 the meta (the qualifier or next step). Reading order is eyebrow → figure → meta: question, answer, so-what. Always left-aligned on one text axis (8 of 12 peers; the centred wallets are the exception that proves the rule).

#RuleValue
BG1Zones, top to bottomA eyebrow row 13/18·600 α0.8 (18 tall, with the chevron at its trailing end) · 8 · B figure row 40/48·700 with the unit 15/22·600 on the baseline · 8 · C meta 15/22·500 α0.85 (a progress bar or graphic, when any, sits between B and C with 8 either side). Pad 20; min height 144 (ELO 158).
BG2Ratiosfigure : eyebrow 3.1 (once per hub); strips and other figures 1.85 (24 : 13); unit 0.375 × figure. Never two 40 figures on one screen.
BG3AffordanceThe whole block is the press target; the chevron 16 on row A is the one visible cue. No buttons inside a block. Documented exceptions: the identity block's edit icon (its own focus stop), LiveScore's host controls (below the block, not inside it).
BG4AlignmentOne left text axis; the trailing end of row A holds only the chevron (or a time + chevron on a data block).
BG5Order under text scaleZones keep their order at every scale; A and B stay at the top; at ≥ 1.5 the unit may wrap under the figure; the block grows (min height) and the chevron stays on row A (HIG: primary elements stay on top).
BG6StatesOne table for every block (below).

States, one rule for all blocks.

StateZone AZone BZone CPress / a11y
Loading40 % bar (13/18)24 % bar (40/48)60 % bar (15/22); gray100 on the block fill, pulse .6 ↔ .9, 5 s caparia-busy; not pressable
Empty (first run)staysa 24/32·700 sentence ("일정 없음", "랭킹 전"), never a "0"one next step as text ("새 일정을 만들어 보세요")pressable if the step has a destination
Errorstays"—" at α0.6"불러오지 못했어요" 15/22·500, no redpress retries; spoken "다시 시도"
Offlinestayslast known figuremeta + "· 16:50 기준" (Toss 증권 precedent); the offline strip is the only alertpress works on cached data
Long text1 line, tail ellipsisnumeral never truncates2 lines, 3 at ≥ 1.5, then ellipsis (places may crop; person names never)the block opens the full text
200 %cap 2.0 (reading class)numeral cap 1.5 (60/72)wrapsblock grows; chevron stays top-right; stack per B6.5

Applying it to the five blocks.

BlockA (eyebrow row)B (figure)C (meta)AffordanceEmpty
홈 day block"내일, 9월 19일 (토)" + ›"2" ball + "개 일정""첫 시작 09:00 · 올림픽공원" (MetaSegments; the venue crops)block → 경기 › 내 경기 (ruling H2)A "오늘", B "일정 없음", C next step
ELO block"ELO · NTRP 3.5–4.0" + ›"1,482"; progress 8 between B and C"마스터까지 518점" 12/16 captionblock → rating detailB "랭킹 전", C "경기 N번 더 기록하면 보여요"; progress hidden
Identity blockrow of avatar 56 + name 24/32·700 (2 lines, never cut) + level Tag sm; edit icon 24 ghost-inverse top-right— (the name carries the weight)"강남 테니스 클럽 · 3년 차" 15/22 α0.85block → profile; edit is its own stopname unset: "이름을 입력해 주세요" in B
LiveScoreLive row above the block (Live Tag + date and venue, §19.3)two team rows: names 15/22·600 α0.85 · set scores 24/32·700 tabular in 32 columns · current set and points in ball; serving dot in the 8 + 8 slot on both rows (§1)host controls below the block (two lg tonal Buttons + undo)participants: read-only; whole block → 경기 보드before the first point: scores "0" at α0.6
Club hero, place variantlogo 56 r12 overlapping the band by 16 + name 24/32·700 (flat, ink on canvas)—MetaSegments 15/22 secondary: "서초구 · 멤버 42 · NTRP 3.0–4.0"none (page identity); actions in the header ⋯ and 관리skeleton: logo + two bars

What changes ​

  • Documents: grammar §4 (one Brand block row becomes BG1–BG6), library §4 Block and §14 LiveScore (state table, serving-dot slot), §19.3 Club hero.
  • Boards: add error, offline, long-text and 200 % frames to each of the five blocks; draw the skeleton per zone.
  • Code: one Block primitive with eyebrow, figure, meta slots and a state prop; the five blocks become compositions of it.

6. The stat strip: equal columns, alignment, order (owner point 6) ​

"Strip. We need to divide each section equally with equal spacing and alignment. Left aligned?"

What we have ​

Library §4 Strip: 80 tall, equal columns (350 ÷ n: 116.7 for three, 87.5 for four), numeral 24/32·700 above a 13/18·500 label, a 1 × 24 #E5E5E5 hairline between columns, content left-aligned, 16 after each hairline, the first column on the rail. The board prints it: hairlines at x 137 and 253, and the figures start at x 20, 153 and 269, so the pitch between text starts is 133 then 116: the columns are equal, the content is not. That is the "equal spacing and alignment" problem the owner saw. Spoken order (B8) is label then value ("총 경기 47"); visual order is numeral then label.

Evidence ​

ReferenceOrder (top → bottom)AlignmentColumnsDividersEvidence
Nike Run Club, "This Week" statsnumeral (≈ 16–17 bold) above label (≈ 11–12 gray)left; first column's text at the railcontent-sized, equal gap 33 pt (column starts 27.0, 93.4, 193.1; labels start 27.5, 93.0, 192.7)noneMeasured, nrc:1
Strava, activity cardlabel above value (label ≈ 15 regular, value ≈ 1.35 × larger)left; the last column pinned to the right edgecontent-sized, equal gaps (space-between)noneMeasured, strava:5
Apple Health, Activity cardcoloured label above numeral + unitleftcontent-sized; pitch 233 vs 223 px in the crop (about equal)1 px hairlines, about 12 pt either sideMeasured, applehealth:0
Toss 증권 홈, 원화 / 달러 tileslabel above value (13 over 15 bold)left inside each tiletwo equal tiles, about 170 wide, gap 8, gray fill r16none (the fill is the container)Measured, toss:2
카카오뱅크 내 계좌, "총 9개 / 3,456,789원"label above numeral (13 over ≈ 28 bold)leftsingle—Measured, kakaobank:2
Instagram, TikTok profile countsnumeral above label, centred, equal columns (widely known)centredequalnoneUnverified: none of the 10 Instagram storefront frame sets contains a profile frame
Ours (board)numeral above labelleft inside equal columnsequal columns, text starts 20 / 153 / 269 (unequal pitch)1 × 24 #E5E5E5 (1.26:1)Board anatomy, flat-v2-components.html

Five of seven peers put the label first; every measured peer is left-aligned; only profile counts are centred. Dividers appear only in Apple Health, whose content-sized columns have unequal widths and need a delimiter; NRC and Strava use equal air. Our hairline has a contrast of 1.26:1, below the 3:1 that WCAG 1.4.11 asks of a graphical object that carries information, so it carries none; KWCAG 5.4.4 accepts spacing as a way to keep neighbouring content distinct. Our own grammar §4b forbids it: a line is allowed only at a sticky or tab edge, between single-line cells of one group, and as the one band; a strip hairline is none of the three, and the "delete the line and keep the gap" test applies.

Recommendation ​

#RuleValue
S1AlignmentLeft-aligned columns, equal pitch. Column i starts at rail + i × 350 / n: n = 2 → 20, 195; n = 3 → 20, 136.7, 253.3; n = 4 → 20, 107.5, 195, 282.5. Same inner structure in every column.
S2SeparationAir, no hairline. Equal pitch and a shared left edge group the columns (proximity and common alignment). If a divider is ever needed (content-sized columns, as in Apple Health), draw it 8 left of the column start, never between the rail and the first column.
S3OrderLabel above figure (13/18·500 secondary, 4, figure 24/32·700 ink, optional delta 12/16·600 below). The same order as the Block (eyebrow → figure → meta), the spoken order and the DOM order; five of seven peers.
S4SizesFigure : label 1.85 (peers 1.3–2.1). Height unchanged: 12 + 18 + 4 + 32 + 12 = 78, floor 80 (100 with deltas).
S5Count2–4 columns. Five or more is not a strip: use a Cell group. n = 2: 175 each (the Toss account tiles are the reference).
S6Long valuesA figure never shrinks and never ellipsizes. Fit test: the widest figure at the current scale ≤ pitch − 8. If it fails, reflow to a 2-up grid (rows of two, 12 apart). Examples (Derived, Pretendard Bold): n = 4 (budget 79.5): "1,482" is 64 px at 1.0, 83 px at 1.3 → reflow; n = 3 (budget 108.7): "1,482" is 83 px at 1.3 and 96 at 1.5 → keeps three columns, while "1,482점" is 110 px at 1.3 → reflows. Labels wrap to two lines instead (English "Attendance" is 69 px).
S7PressA linked column keeps its own press (.98 / .80) and a whole-column hit area; unlinked columns are plain text (one stop per column, label then value).

What changes ​

  • Documents: library §4 Strip row (order, pitch, no hairline, fit test), §19.3 "Strip with deltas" (label / figure / delta), grammar §4 Stat strip row.
  • Boards: redraw the Strip specimens (3 and 4 columns, 2-up reflow at 1.3×, English labels), remove the hairlines from every page board that uses it (기록, 프로필, club analytics).
  • Code: Strip (was CellRow): equal pitch container, label-first slots, fit-test reflow.

7. English: expansion, abbreviations, line budgets (owner point 21) ​

"The english version of the components, like the media row, is quite terrible… So many texts going over a few line, cluttering the view."

What we have ​

  • The patterns board draws English only at 200 % and at 320 wide ("Waitlisted", "Doubles NTRP 3.0–3.5"), and its time reads "9:00–11:00 AM". The code is 24-hour in both languages: formatTimeRange returns ${s}–${e} of "HH:MM" (ONE-CLOCK, F7, 2026-09-23), and the terminology guide (line 47) rules English as sentence case, "N going", "N KRW" (never won), durations "N min / N hr", relative chips "Nm / Nh / Nd", en-dash ranges "10:00–12:00", enCount / enPlural. The board and the rulings disagree on the clock.
  • The row text columns are narrow: at rail 20 the media row's text column is 193 px when a "Waitlisted" Tag trails and 242 px when a "6/8" figure trails.

Evidence ​

How much longer our English really is (Measured on all 3,292 string pairs present in both ko/ and en/ locale files; widths in Pretendard Regular, no kerning).

KO syllablesPairsMedian EN ÷ KO widthp75p90Share > 1.5×Share > 2×
1–41,4051.591.932.3457 %22 %
5–87901.311.601.8632 %5 %
9–146781.171.381.6117 %1 %
15–242811.211.391.5515 %1 %
25–40821.251.391.5111 %0 %
all3,2921.331.672.0537 %11 %

The worst short labels: 문양 → "Generated mark" (4.2×), 정원 → "Max attendees" (3.9×), 혼복 → "Mixed doubles" (3.8×), 업적 → "Achievements" (3.7×), 월 → "Month" (3.3×), 알림 → "Notifications" (3.3×). References for the same effect: Seed's Korean-source table (≤ 10 characters: 150–250 %; 11–20: 130–150 %; 31–50: 90–110 %; ≥ 71: 80 %), which "Save 저장 (2) → Save (4)" illustrates (Seed international design); the IBM table for English sources (up to 10 characters 200–300 %, over 70 characters 130 %) and the note that "each Chinese and Korean character is counted as two English characters in width" (W3C); Android's older checklist, "up to 30 % more" (archived copy). In pixels our short labels exceed the generic 30–50 % rules of thumb.

What the platforms say.

  • HIG Lists and tables: "Keep item text succinct so row content is comfortable to read. Short, succinct text can help minimize truncation and wrapping" and "an ellipsis in the middle of text can make an item easier to distinguish because it preserves both the beginning and the end of the content" (Lists and tables). HIG Writing: "write with accessibility and localization in mind" (Writing); Layout lists "text length" among the locale features to preview (Layout).
  • Android: the en-XA pseudolocale "expands the original text by adding non-accented text" to expose layout breakage (pseudolocales).
  • Seed: Badge labels "2~3단어 이내", with a max width that ellipsizes at 10 characters or more (badge); relative time in English "1s, 1min, 1h, 1d, 1w, 1mo, 1y" (and "min" "to make clear it is minutes" against months); en_US dates "Jul 16, 2015" / compact "Jul 16" / weekday "Wed, Jul 16" / "Wed, Jul 16 at 9:41 PM"; counts "1 review", "3 reviews", "30K views"; Korean 만 and 억 never carried into English.
  • Apple Style Guide on abbreviations: spell out an unfamiliar abbreviation at first use; avoid Latin abbreviations such as "e.g." (Apple Style Guide).

What CLDR produces (Derived: Intl.DateTimeFormat in Node 22, ICU 77.1 / CLDR 47, 19 Sep 2026, 09:00–11:00):

Patternen-USen-GBen-CAko-KR
weekday, month, daySat, Sep 19Sat 19 SeptSat, Sep 199월 19일 (토)
09:00–11:00, hour only9 – 11 AM (thin spaces round the en dash, U+202F before AM)09–119–11 a.m.오전 9시 ~ 11시
09:00–11:00, minutes9:00 – 11:00 AM09:00–11:009:00–11:00 a.m.오전 9:00~11:00
09:30–12:309:30 AM – 12:30 PM09:30–12:309:30 a.m.–12:30 p.m.오전 9:30 ~ 오후 12:30
relative, narrow3h ago, 5m ago3 hr ago3 hrs ago3시간 전

What Korean apps' English modes do (US-storefront frames): Toss keeps the 24-hour clock ("Last refreshed 16:50", en_toss:2) and uses short verbs and sentence case ("Send", "History", "Get points"; en_toss:0, 5); Naver Maps prints "11.10.(Mon) · PM 7:00 · 20 min" and "6:38 PM - 7:59 PM" and "2 mins ago" (en_navermap:1, 3, 4); KakaoTalk prints "PM 06:00 ~ PM 9:00" and "30 minute(s) ago" (en_kakaotalk:1, 3); Karrot (당근 for the US) follows Seed's spec: "0.2mi · 30 minutes ago", "2min", "3h ago", "1 chat · 3 favorites · 12 views" (en_karrot:1, 4, 6, 7). Korean products are not consistent and often not CLDR ("PM 7:00", "minute(s)"); do not copy them. Seed's own spec is the one to follow.

Where our rows wrap (Derived, Pretendard; Tag 13/600, L1 17/600, L2 15/400; rail 20, thumb 56, gaps 12):

StringKOEN todayEN recommended
Row L1, time09:00~11:00 101 px09:00–11:00 98 px (board draws 9:00–11:00 AM 118)09:00–11:00 98 px (12-hour option below)
Row L2, venue + format + level올림픽공원 테니스장 · 복식 · NTRP 3.0–4.0 273 pxOlympic Park Tennis Courts · Doubles · NTRP 3.0–4.0 368 pxOlympic Park · Doubles · 3.0–4.0 228 px (−38 %)
Row L2 with a Tag trailing2 segments 163 px—Olympic Park · Doubles 160 px
Text column, figure trailing242 px242 px242 px
Text column, "Waitlisted" trailing232 px ("예비")193 px193 px
Lines for L2 in that column231 (figure) or 1 (Tag, two segments)
Club L2서초구 · 멤버 42 · NTRP 3.0–4.0 214 pxSeocho-gu · 42 members · NTRP 3.0–4.0 286 pxSeocho · 42 members · 3.0–4.0 221 px
Person L2총무 · NTRP 3.5 95 pxTreasurer · NTRP 3.5 129 pxunchanged (fits)
Hero fact, date and time9월 19일 (토) 09:00–11:00 189 px—Sat, Sep 19 · 09:00–11:00 195 px (parity)
Hero fact, venue올림픽공원 테니스장 · 하드 183 pxOlympic Park Tennis Courts · Hard 265 px (fits 322 in one line)unchanged
Day header9월 18일 (금) 83 pxFri, Sep 18 72 pxunchanged

In these cells "·" stands for the MetaBreak (a 1 px bar with 8 px of air each side, 17 px per break); the boards draw the bar, never the dot (library C7). Text columns: 390 − 2 × 20 − 56 − 12 − trailing element − 12.

The clutter is row L2 (three segments with a long English venue and the "NTRP" prefix) and long Tag copy; the clock, the day header, the hero facts and person rows are not an English problem. Tag copy over the 80 px budget (13/600): "Recruitment closed" 117, "Awaiting confirmation" 133, "Refund pending" 95, "Partial payment" 94, "Awaiting reply" 87.

Recommendation ​

#RuleValue
E1Expansion budgetWrite English to ≤ 2.0 × the Korean width for labels of up to 4 syllables, ≤ 1.6 × for 5–8, ≤ 1.4 × for longer (the corpus p75). Design the box for 2.3 × at the shortest labels (p90).
E2Role limits (English)Tag ≤ 12 characters, 1–2 words (≤ 80 px at 13/600), never truncated: the copy is shortened instead (Seed: 2–3 words, ellipsis at 10). Tab: one word, ≤ 8 (HIG: "single words whenever possible"). Choice ≤ 14. Button ≤ 2 words. Header title ≤ 22 (one line at 20/28). Cell label ≤ 26.
E3DatesCLDR en-US / Seed: Sat, Sep 19 (weekday + date), day header Fri, Sep 18 + Today / Tomorrow, no year within the current year, Sep 19, 2027 otherwise; "at" only inside sentences (Sat, Sep 19 at 9:00 AM). Month abbreviation "Sep" (en-US; en-GB "Sept").
E4ClockKeep ONE-CLOCK (24-hour) for English: 09:00–11:00 costs the same width as Korean (98 vs 101 px), Toss's English keeps it, and the terminology guide rules it. The owner's 9–11 AM is the CLDR en-US form: 65 px on the hour, 85 px for 6–9:30 PM, 123 px for 9:30 AM–12 PM, i.e. shorter only on the hour. If the owner rules 12-hour for English, use CLDR formatRange (en dash, narrow no-break space before AM/PM) and keep a single formatter path.
E5Counts and numbersNumerals always; plural by Intl.PluralRules (enPlural): "1 court", "4 courts"; rows show 6/8, spoken "6 of 8 going"; compact numbers only from 10,000 (12.3K), never 만 or 억 in English. Money: the terminology guide's "N KRW" stays for prose; in tabular trailing figures allow ₩30,000 (52 px vs 75 px at 15/700) and CLDR agrees; owner and terminology ruling needed.
E6Relative timeNmin, Nh, Nd, Nw, Nmo, Ny (Seed): the guide's Nm is ambiguous between minutes and months. Amend line 47.
E7AbbreviationsAllowed: AM / PM, Mon–Sun, Jan–Dec (CLDR), the relative units above, "vs". Not allowed: Latin abbreviations (e.g., i.e.), "approx.", "No." (use "#N", ruled). Unfamiliar terms are spelled out where they first appear on a screen (NTRP stays: it is a player term).
E8One line or wrapOne line, at 100 % text: row L1, row L2, day header, Cell label, Tag, tab, button. Wrap, never truncate: hero facts, notice and dialog body, helper text, Cell values, names. In a row, the flex segment truncates (the venue or club name: tail ellipsis; a long single name may use a middle ellipsis) while the fixed tokens (format, level, count) never do.
E9Row L2 budgetAt most 2 segments when a Tag trails, 3 when a figure trails. In English rows drop generic words from venue names ("Olympic Park Tennis Courts" → "Olympic Park" through a shortName rule), drop the "-gu" suffix ("Seocho"), and omit the "NTRP" prefix in rows (keep it in detail and hero).
E10Tag copy to shorten"Recruitment closed" → Closed (42 px), "Awaiting confirmation" → To confirm (65), "Refund pending" → Refund due (69), "Partial payment" → Part paid (54), "Waitlist open" → Waitlist (45), "Awaiting reply" → Pending (52). "Waitlisted" (61), "Payment due" (79), "Closing soon" (78) already fit. Each needs the terminology guide's sign-off.
E11Gates(a) a pseudolocale test that expands every Tag, Tab and Button string to its role budget and measures it in Pretendard; (b) character limits per role in check:i18n-house-style; (c) board rows drawn in English at 100 % with a DOM check: L1 one line, L2 one line on figure rows and at most two lines on Tag rows.

What changes ​

  • Copy and rules: terminology-guide line 47 (relative chips Nmin; the money form in tables; the 24-hour clock stays), new E2 budgets, Tag copy list (E10), shortName for venues.
  • Boards: draw the session, club and person rows and the hero facts in English at 100 % beside Korean; keep the 200 % and 320 frames.
  • Code: a venue shortName helper, the E2 limits in the i18n lint, the pseudolocale width test.

8. Motion and accessibility audit (owner point 22) ​

"As for motion and accessibility, make sure you reference best practices to learn from them."

What we have ​

Behaviour addendum B7 (durations 80 / 100 / 150 / 200 / 250 / 300 ms, effects on timing, easings 0.2,0,0,1 · 0,0,0,1 · 0.3,0,1,1, press springs, a Reduce Motion table, toasts 4 / 6 / 8 s, no layout animation in virtualized lists, loops capped at 5 s) and B8 (one focus stop per row with a composed name from the same model, one h1, announcements per platform, focus return, 44 targets with hit slop, gesture alternatives, language, web keyboard patterns).

References read for this audit: HIG Motion (updated 2025-09-09) and HIG Accessibility (2025-06-09); Apple's App Store Connect evaluation criteria for Reduced Motion, Sufficient Contrast, Differentiate Without Color Alone and Larger Text; Material 3 motion in code (MotionTokens, MotionScheme, Standard and Expressive spring tokens) and the MDC Motion guide; Seed motion, feedback scale, inclusive design; WCAG 2.2 (what is new); Android accessibility; React Native AccessibilityInfo.

Keep (the spec already agrees with the references) ​

#ItemOur valueReference
K1Duration set100 / 150 / 200 / 250 / 300 ms (+ 80 press-in)Identical to M3 short2 … medium2 (100 … 300) and Seed d2 … d6 (Seed also calls ≤ 200 ms "micro" motion and > 200 ms "macro"). Nothing of ours exceeds 300 except platform pushes and loops.
K2Easingstandard (0.2,0,0,1), enter (0,0,0,1), exit (0.3,0,1,1)= M3 EasingStandard, StandardDecelerate, StandardAccelerate (MotionTokens.kt); Seed uses (0.35,0,0.35,1) / (0,0,0.15,1) / (0.35,0,1,1).
K3Effects on timing, no overshootopacity and colour on tweensM3's effects springs have damping ratio 1.0 (Standard and Expressive alike): no overshoot on colour or opacity.
K4Press: colour first, scale optionaldim always, settle dropped under Reduce MotionSeed: colour is the base feedback and scale does not happen when the OS reduce-motion setting is on (translated from the Korean page); HIG Motion: "Make motion optional".
K5Toast time and dismissal4 / 6 / 8 s, OS timeout honoured, × and tapSeed snackbar 4 s default and longer for long text (snackbar); M3 snackbar 4–10 s (MDC Web README); HIG Accessibility "Minimize use of time-boxed interface elements" and "Offer alternatives to gestures".
K6Targets44 with hit slopHIG 44 × 44 default; WCAG 2.5.8 24 × 24 (AA); Seed 44 ideal, 24 minimum; KWCAG 6.1.3 ≈ 27 dp.
K7Focus ring2 px ink, offset 2Meets the geometry (area ≥ a 2 px perimeter) and the 3:1 change of WCAG 2.4.13, which is Level AAA in the final WCAG 2.2 (Understanding 2.4.13).
K8Loopsshimmer and live dot stop after 5 sWCAG 2.2.2 (A): auto-starting movement over 5 s needs a way to stop; Apple's Reduced Motion criteria ask to consider stopping "auto-advancing carousel screens or any other ongoing motion".
K9One stop per row, composed names, Label in NameB8.1–B8.2Android: merge a group into its parent and keep descriptions short (principles); WCAG 2.5.3.
K10Colour never aloneTag text, glyph fill vs outline, shape cuesApple's Differentiate Without Color Alone criteria (shape or text beside colour); passes for Tags, tabs, selected rows (check mark + 600 weight).

Change ​

#ItemTodayReference and findingFixPri
C1Reduce Motion removes; Apple says replaceB7.7: translate, scale and layout rows vanish, and opacity cross-fades become instantHIG Accessibility: "Replacing transitions in x-, y-, and z-axes with fades". Apple's criteria: "Removing animations entirely can have a negative effect on usability and understandability"; suggested replacements: "a dissolve, highlight fade, or color shift".Under Reduce Motion keep the 100–150 ms cross-fade for sheet, dialog, menu, toast, FAB label and header title; remove only translate, scale and layout. Read prefersCrossFadeTransitions (iOS) to choose fade over cut.P1
C2Press springs are the expressive classpressIn {20, 400, 0.7}: ζ 0.60, 9.5 % overshoot, 247 ms; pressOut {15, 300, 0.7}: ζ 0.52, 14.8 %, 377 msCompose's MotionScheme KDoc: standard = "basic motion scheme for utilitarian UI elements and recurring interactions" (spatial ζ 0.9); expressive = "for prominent UI elements and hero interactions" (fast spatial ζ 0.6). A press is a recurring interaction; HIG: avoid extra motion on frequent interactions and don't make people wait.pressIn {30, 400, 0.7} and pressOut {26, 300, 0.7}: ζ 0.90, overshoot 0.1 %, settle 196 / 226 ms (integrated like the addendum's table).P3
C3Press scale as a ratiorow .98, button .97, icon .92, pill .96, fab .96, block .98Seed defines shrink as a distance (2 px, basis = max(height, width ÷ 4, 24)) so every element feels the same. Ours: a 44 icon shrinks 3.5 px, a 350 button 10.5 px wide, a block 7.0 × 2.9; Seed would give 2.0, 8.0 and 4.9 × 2.0.Optional: compute the scale from the element's size (one helper in pressable-visual.ts). Not needed for correctness.P3
C4Header actions 44two 24 glyphs in 44 targets, gap 8Android: "Ensure all touch targets are at least 48 dp, even if this extends past the UI element visual"; our primary audience is on Android.48 targets, no gap: 2 × 48 = 96 = 44 + 8 + 44, the same footprint.P2
C5Orientationorientation: portrait (iPhone and phone Android)WCAG 1.3.4 Orientation (AA): content "does not restrict its view and operation to a single display orientation" unless essential; users with a device mounted on a wheelchair arm cannot rotate it (Understanding 1.3.4). On Android 16 the lock is ignored from 600 dp anyway (B9.8).Decide: support landscape on reflow-safe screens (the 320 / 200 % frames already prove reflow), or record that portrait is not essential and accept the departure. Owner call.P2
C6Label cap 1.5Tags and Choices stop at 1.5 ×See §3: Toss lets 13 px reach 26; Apple's Larger Text criteria want content text at 200 %.Raise to 2.0.P2

Missing ​

#GapWhy it matters (reference)What to addPri
M1Dragging alternativesWCAG 2.5.7 Dragging Movements (AA, new in 2.2): "All functionality that uses a dragging movement for operation can be achieved by a single pointer without dragging". B8.7 gives screen-reader alternatives (adjustable actions, move actions, stepping); a sighted person with a tremor or a head pointer gets none (Understanding 2.5.7).TimeBandSlider, RangeBandSlider, Slider: tap the track to set the nearest thumb, plus the existing 44 Stepper for ±. Photo tile reorder: "앞으로 / 뒤로 이동" in the tile's action sheet. Chart scrub: tap a point to set the readout. SwipeAction and toast swipe already have buttons.P1
M2App Store accessibility labels (iOS build)Apple's evaluation criteria define what a claim means: Larger Text ≥ 200 % for content; Sufficient Contrast tested with Bold Text, Increase Contrast and Reduce Transparency on; Reduced Motion stops ongoing motion; Differentiate Without Color Alone tested in grayscale; VoiceOver and Voice Control for the common tasks.An "iOS build gate" checklist: five common tasks (find and RSVP, pay the fee, confirm dues, advance a wizard step, enter a score) run with each setting; a grayscale screenshot pass; record which labels to declare.P1 (at the first iOS build)
M3OS settings we do not readRN exposes prefersCrossFadeTransitions (iOS), isDarkerSystemColorsEnabled (iOS Increase Contrast), isHighTextContrastEnabled (Android), isReduceTransparencyEnabled, isGrayscaleEnabled, isBoldTextEnabled; we read Reduce Motion and plan Bold Text only.Increase Contrast / high text contrast: promote tertiary and the 1.26:1 hairlines to the secondary and edge tiers (#4F5851, #D4D4D4). Reduce Transparency: nothing to change (scrims only; the α0.8 / 0.85 block text is already 11.7:1).P2
M4WCAG 2.2 criteria not in B83.3.7 Redundant Entry (A), 3.3.8 Accessible Authentication (AA), 3.2.6 Consistent Help (A) (new in 2.2).Wizards: never ask the same value twice (prefill, copy from the last session; check 이름 and 지역 across onboarding and club creation). Email sign-in: allow paste and password managers (textContentType, autoComplete), no puzzle. Help entry in the same place on every screen.P2
M5Text spacing on the web buildWCAG 1.4.12 (AA): no loss when a user sets line height 1.5, paragraph 2, letter 0.12, word 0.16 × the font size. minHeight floors help; overflow: hidden on nowrap Tags and Choices would clip.A one-time check on apps/web with a text-spacing override on the board and three real screens; add it to the web gate.P3

Priorities. P1 = before the first public build (C1, M1, M2). P2 = in the same wave as the type changes (C4, C5, C6, M3, M4). P3 = polish (C2, C3, M5).

What changes ​

  • Addendum B7.7 (Reduce Motion table: opacity rows keep a short fade), B7.2 (press spring values), B8.7 (visible alternatives to drags), new B8.11 (OS accessibility settings), B9.8 / B8 (orientation ruling), library §2 (press, hit slop 48 on Android).
  • Boards: the motion board's Reduce-motion column, a "drag alternatives" specimen per slider, the iOS gate checklist in the contract.

9. Audit of the sections the owner did not comment on (library §3–§6) ​

Every value or behaviour that departs from current platform guidance or measured peer practice, found while checking §3 chrome, §4 surfaces, §5 rows and §6 labels against the evidence in this note. Items already settled above are cross-referenced, not repeated. P1 before the first public build · P2 with the type and spacing wave · P3 polish.

#Section · itemIssueEvidenceFixPri
A1§3 Header, action targets44 targets on a platform whose guide says 48Android: "at least 48 dp, even if this extends past the UI element visual"48 targets, gap 0 (same 96 footprint); see §8 C4P2
A2§3 Header, height and titlenone: 56 equals Seed's top navigation (56), sits between iOS (44) and M3 (64)top-navigation.json, AppBarSmallTokens (64), Apple archive (44)keep—
A3§3 Tab row (scope tabs)row 44 and a 2 pt underline are the thinnest of the references; inactive 500 vs active 600 is a small differenceM3 primary tab: container 48, active indicator 3 (PrimaryNavigationTabTokens); Toss Tab selected 700 vs 600 and grey800 vs grey600 (Code)row 48, underline 3, active 700 · inactive 500 (ink vs secondary already 19:1 vs 7.4:1)P3
A4§3 Tab bar, labels11/14 Hangul labelsM3 navigation bar label = Label Medium 12/16 (NavigationBarTokens); Android floor 12 sp; §3 above12/16 (fits: 6 + 24 + 2 + 16 = 48 in 56)P2
A5§3 Tab bar, badge dota 7 px dot (off the 4-grid and off every peer)M3 small badge 6 dp, Seed small 6 px, Toss redBean 6 × 6 (Code)6 px dot with the 1.5 canvas ring (icon-attached dots stay 6; row markers are 8, §1)P3
A6§3 FABextended pill 48 tall, collapsing to a 48 circleM3 extended FAB container 56 dp, icon 24 (ExtendedFabPrimaryTokens); it is the screen's one coloured action56 tall, 20 pad, label 15/22·600; collapsed 56 circle; list tail padding clears the 56 plus its 16 offsetP2
A7§3 CTA band, helper linethe fee and cancellation terms (money-affecting copy) are 13/18 secondaryreading-class text should be ≥ 15–16 (KRDS ≥ 16; Seed t5 16; §3); Jeong 2016 puts 13 at the lower bound for older readershelper line 15/22 secondary, ≤ 2 lines; band 118 → 148 (one line) / 170 (two); wrap, never ellipsizeP2
A8§3 Section head, action"전체 보기 ›" is 13/18·500 secondary: the navigation affordance is the smallest and lightest text on the rowToss ListHeader right link t6 15 for medium and large headers (Code); Apple Developer "Recent videos ›" sits at heading size; Shortcuts "See All" 1715/22·500 secondary with the 16 chevron; keep the 44 targetP2
A9§3 Section head, title sizethe title is the row-title style (17/24·600), so the hierarchy rests on space alone; the peers' section titles measure larger (ink median 17.1 against our 14.7, about 19–21 px Hangul); KRDS puts a 17 heading in its h4/h5 tier ("similar in size to body text") and asks for 1.25–1.5 × the body, and the new 16 reading role would leave 1.06§2 table; KRDS typography (mobile heading sizes 28 / 24 / 22 / 19 / 17 / 15; h2 = 24–22, h3 = 22–19, h4 = 19–17, h5 = 17–15; "ideal heading to body difference 1.25–1.5×"; use with care where body and heading sizes coincide). Toss's published ListHeader title is also 17/25.5 bold, and its 홈 cards use 17 bold titles while 증권 홈 reads ≈ 20 bold (§5 table), so this is a judgment, not a violationthe existing title 20/28·700 (20 = 1.25 × 16; ink 17.4 against the peer median 17.1); Section head 24 → 28; box spacing unchanged (ink 37.3 above, 17.3 below); decision D7P2
A10§3 Day header, today dothung in the margin; ball on white is 1.28:1§1remove (LM4)P1
A11§3 Bandnone: 12 tall #F2F2F2 sits inside the measured bands (7–16; Toss 16, Seed 8, M3 heavy 8)lane K §3keep—
A12§4 Block, text on inknone: eyebrow α0.8 is 11.65:1, meta α0.85 is 13.0:1, ball numeral 13.95:1§3 contrast tablekeep; add the state table (§5)—
A13§4 Stripnumeral above label, unequal text pitch, hairline outside the §4b line law§6S1–S7P2
A14§4 Notice, Dialog and Toast bodybody 15/22reading class (§3)16/24; heights stay 48P2
A15§4 Chart, labelsaxis ticks 12/16·500§3 (12 is the floor; wrapping rule 1.5)12/18, non-essential only; the values are in the readout and the spoken summaryP3
A16§4 Thumb, court tilethe hard / clay / grass tile says the surface by colour aloneApple's Differentiate Without Color Alone criteriaacceptable while the venue name and the surface word sit in the row or the hero; if a row ever shows the tile without the name, add the wordP3
A17§5 MediaRow, L2 in Englishthree segments overflow the text column§7 (368 px vs 193–242 px)E8, E9P2
A18§5 Roster cell, namesperson names at 13/18 are the smallest names in the app, in a 4-up cell about 87 px wideJeong 2016 (13 is the best of 11–13 for 65+); KRDS body ≥ 16, small 15; "names never cut" makes two lines the norm15/22·600, up to 2 lines; cell pitch 100 → 104 (one line) / 126 (two lines); the level Tag staysP2
A19§5 Cell, value and labelnone: 48 high, label secondary 7.38:1, value ink; between Apple 44 and M3 56ListTokens (56 one-line)keep—
A20§5 Row hairlines (cell tier)#E5E5E5 is 1.26:1decorative: WCAG 1.4.11 applies to information-bearing graphics; KWCAG 5.4.4 accepts lines or spacingkeep; Increase Contrast promotes it to #D4D4D4 (§8 M3)—
A21§6 Tag, English copystate labels up to 133 px against an 80 px budget§7; Seed Badge 2–3 wordsE2, E10P2
A22§6 Count tag11/14 numeral in a 20 tall pillM3 badge label small 11/16, Seed 11/15 bold: size is peer-standard (digits, not Hangul); only the line height is short11/16·700P3
A23§6 Level tagnone: ball with an ink-edged 1 px #D4D4D4 ring on whiteball on white is 1.28:1, the ring supplies the 3:1keep—
A24§6 Live tagnone: white on #B8332E is 5.91:1, pulse capped at 5 sWCAG 2.2.2; Apple Reduced Motion criteriakeep; under Reduce Motion show the static dot (§8 C1 keeps fades)—
A25§7 Switch (outside the requested scope)48 × 28 is smaller than every referenceM3 track 52 × 32, thumb 24 (SwitchTokens); Toss 50 × 30 (Code); iOS UISwitch is commonly reported as 51 × 31 (Apple forum); RN reads UISwitch.intrinsicContentSize at run time, and the size is reported to differ on iOS 2652 × 32 track, thumb 24 (28 pressed), still inside a 48 hit areaP2

10. Decisions this note needs from the owner ​

#DecisionRecommendationCost of the other way
D1Rail: 20, 16 or 24 at 390 pt (§4)20 (16 below 390, 24 from 600)16: +8 pt text width, rebuild of 350-based boards; 24: −8 pt width, rebuild
D2English clock: keep the 24-hour ONE-CLOCK, or 12-hour "9–11 AM" for English (§7 E4)keep 24-hour (same width as Korean; Toss English; terminology ruling)12-hour: a second formatter path; shorter on the hour only (65 vs 98 px), longer at :30
D3English money in tables: "₩30,000" or the ruled "30,000 KRW"; relative chips Nmin (§7 E5, E6)₩ in tabular trailing figures, Nmin; amend terminology-guide line 47"30,000 KRW" costs 23 px per figure; Nm stays ambiguous (minute or month)
D4Shorter English Tag copy (§7 E10)adopt the six shortened labelslong labels keep wrapping rows or force ellipses that B6.6 forbids
D5Orientation: support landscape on reflow-safe screens or accept the portrait lock (§8 C5)decide with the first iOS build; the 200 % and 320 frames show the layouts reflowa recorded WCAG 1.3.4 departure
D6Optional polish: press springs ζ 0.9 and distance-based press scale (§8 C2, C3)adopt the springs, skip the distance helper unless a QA finding asksnone functional
D7Section title size: keep 17/24·600 or use the 20/28·700 title role (§2, audit A9)20/28·700 (reuses an existing role; 1.25 × the new 16 reading size, as KRDS asks)17: the title stays the size of a row title and 1.06 × the reading size; the head stays 24

11. Sources ​

Apple. HIG Typography, Layout, Lists and tables, Tab bars, Motion, Accessibility, Writing (read through the JSON mirror at developer.apple.com/tutorials/data/design/human-interface-guidelines/<page>.json); UIKit systemMinimumLayoutMargins, UIView.layoutMargins, sectionHeaderTopPadding; Apple Developer Forums 697910 and 675534; Transition Guide (archive); App Store Connect evaluation criteria: Larger Text, Reduced Motion, Sufficient Contrast, Differentiate Without Color Alone; Apple Style Guide, abbreviations. Third-party explanations of the UIKit margins: Use Your Loaf, monday.com engineering.

Google and Material. Material 1 metrics and keylines, Material 1 subheaders; Compose Material 3 source (androidx-main): TypeScaleTokens, ListItem, ListTokens, NavigationBarTokens, AppBarSmallTokens, ExtendedFabPrimaryTokens, SwitchTokens, BadgeTokens, PrimaryNavigationTabTokens, MotionTokens, MotionScheme; MDC Motion; Android accessibility design, grids and units, accessibility principles, pseudolocales, localization checklist (archive); React Native AccessibilityInfo.

Design systems. Toss TDS: docs and the published package @toss/tds-mobile 2.5.1 (type map, ListHeader, Button, Tab, Switch, font-scale caps read from dist/esm/index.js). Seed (당근): typography, spacing, layout, motion, feedback scale, inclusive design, international design, components list, badge, notification-badge, snackbar, specs list-header, notification-badge, top-navigation. KRDS typography. KWCAG 2.2 (KS X OT0003:2022).

WCAG 2.2. What is new; Understanding 1.3.4, 1.4.4, 1.4.10, 1.4.11, 1.4.12, 2.4.13, 2.5.7.

Research and articles. Jeong 2016, Hangul on smartphones for adults over 65; systematic review of font size for older adults, Frontiers in Psychology 2022; Rello, Pielot, Marcos, CHI 2016; NN/g, Proximity; W3C, text size in translation; CSS-Tricks, iOS form zoom.

Data and fonts. iTunes lookup API; Pretendard 1.3.9 (jsDelivr); Unicode CLDR 47 through Node 22 Intl.

In this repository. Lane H, lane K, grammar, library, addendum, terminology guide; boards flat-v2-components.html (Strip, section specimens) and flat-v2-patterns.html (English at 200 %); packages/app/src/presentation/utils/date-format.ts (formatTimeRange); the ko/ and en/ locale files under packages/app/src/config/i18n/.

12. Frames measured ​

en_* frames are the US-storefront listing's English-UI frames of the same app. Each image is the original-size file (0x0ss.png); app:n is the n-th screenshotUrls entry, counting from 0.

FrameApp (store listing)Original-size image
toss:0토스https://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/59/80/a0/5980a0a0-d81a-3651-8fa3-075319f03f2c/0_APP_IPHONE_55_0.png/0x0ss.png
toss:2토스https://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/99/7f/60/997f60b9-3271-3cc7-9911-c7738cd67814/2_APP_IPHONE_55_2.png/0x0ss.png
toss:3토스https://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/ad/1a/44/ad1a4494-4755-0f7a-24e2-62b568ad9661/3_APP_IPHONE_55_3.png/0x0ss.png
kakaobank:0카카오뱅크https://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/da/07/6d/da076d1d-2b29-4d20-2b26-5d233ea485b3/iOS_5.5_01.jpg/0x0ss.png
kakaobank:2카카오뱅크https://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/d3/b7/5f/d3b75f62-230b-6da5-e212-bcfc20315ff2/iOS_5.5_03.jpg/0x0ss.png
daangn:1당근https://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/b9/09/25/b909256c-ad05-c6ee-620b-4486aa687519/1242_2208_2P.png/0x0ss.png
daangn:4당근https://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/b1/e1/1d/b1e11d43-ad38-713d-192e-8deb59f6ce8b/1242_2208_5p.png/0x0ss.png
daangn:6당근https://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/7d/ef/4e/7def4e1e-5ba3-269c-bd23-ffdb904ab73a/1242_2208_7p.png/0x0ss.png
baemin:2배달의민족https://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/ca/8a/1f/ca8a1fe1-fe9a-4887-a5e4-32291dd56603/3.png/0x0ss.png
naver:5네이버https://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/ec/7a/2a/ec7a2a70-f76e-428c-44fb-dba20bd642b7/Appstore_Preview_Plus_06.png/0x0ss.png
navermap:2네이버지도https://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/8f/b8/71/8fb87108-537c-69b5-d08b-bba2f798beff/iPhone_U0028ko_U0029_1242x2688_p3.png/0x0ss.png
oliveyoung:7올리브영https://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/bb/40/49/bb404961-2aea-1b7c-89fe-81d790421bfe/iOS_1242x2208__U1112_U1166_U11af_U1109_U1173_U0026_U1107_U1172_U1110_U1175.jpg/0x0ss.png
yanolja:6NOLhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/ae/ed/09/aeed096c-722c-b889-999c-2d92e03b82a1/IOS_6.9inch_U00281320x2868_U0029_5.jpg/0x0ss.png
musinsa:1온라인 패션 스토어 무신사https://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/ed/04/48/ed044883-48ac-f7b5-627f-c3faedca3e9a/430x932_01__Uc2a4_Ud1a0_Uc5b4_Ud648.png/0x0ss.png
musinsa:4온라인 패션 스토어 무신사https://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/74/8b/fb/748bfbec-3473-eb0b-a1d9-c2a124d5f48c/430x932_04__Ucf58_Ud150_Uce20_Ud310.png/0x0ss.png
flab:1플랩풋볼https://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/b6/30/5a/b6305afc-7a35-cd60-5159-c48bc9401b7a/01-match-explore.png/0x0ss.png
kbstar:4KB스타뱅킹https://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/1e/62/8e/1e628ec1-614a-9e02-ab94-5cd7ebce1123/ios_U00285.5_U0029_05.png/0x0ss.png
kakaopay:2카카오페이https://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/94/92/f4/9492f43b-0739-0e22-0a9e-ddb3c3d05c27/ios_1290x2796_3.png/0x0ss.png
munto:4문토https://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/e6/a3/62/e6a36274-569c-2366-f74f-83c514b8ca5a/ffb36cac-c0cb-4e41-bb06-15e23671184e_Apple_b5.png/0x0ss.png
kakaotalk:3카카오톡 KakaoTalkhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/4a/c9/5b/4ac95b4f-3d48-8196-6889-2cef939d6bf2/Kakaotalk_iOS_SC_KR_04.png/0x0ss.png
airbnb:0Airbnbhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/31/06/89/310689f2-dfa9-533a-3805-b976b2f414c3/250509_AppStore_Mobile_Airbnb_Carousel_01_en-US.jpg/0x0ss.png
airbnb:1Airbnbhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/a0/9d/16/a09d1611-23ae-f6bd-f109-e05bb7f35ce6/250509_AppStore_Mobile_Airbnb_Carousel_02_en-US.jpg/0x0ss.png
spotify:0Spotify: Music and Podcastshttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/f3/ce/05/f3ce0547-690a-b355-b1dd-6b6e91808279/IOS_-_5.5_-_S01_-_EN_-_CA_U005bEnglish__U0028Canada_U0029_U005d.png/0x0ss.png
slack:1Slackhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/3f/35/47/3f3547b7-c3a2-edd6-9199-21a4da9c41f0/9776126f-a44a-4ecb-aa3e-ac35f8128ba0_iOS-iPhone5.5-Screenshot02.en-GB@3x.png/0x0ss.png
gmail:1Gmailhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/b0/07/67/b00767ec-0d29-44a1-0533-87719c95cee7/APP_IPHONE_55-1.png/0x0ss.png
strava:5Strava: Run, Bike, Walkhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/e1/93/a8/e193a837-49e5-fedb-fdab-6f53aadabcdf/02ASO-5.5-ShareWithFriends-en-US.jpg/0x0ss.png
nrc:1Nike Run Club: Running Coachhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/87/6d/66/876d6689-41a7-d287-1e91-5111f2a336c0/97b95fd1-005f-4c9a-b8f9-bc1352ef194a_Nike_NikeRunClub_en-US_iOS_5.5_ScreenshotMockup_240820_02.png/0x0ss.png
wise:3Wise: Global Money Transferhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/58/e1/a3/58e1a300-5245-13c0-b37d-49227536661e/US-small-04.png/0x0ss.png
cashapp:0Cash Apphttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/8f/e0/4b/8fe04bb7-c60f-b918-d9dc-0ebe60560f44/US_MoneyMove_iPhone6.5__01.png/0x0ss.png
monzo:0Monzo Bankhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/a8/c5/2a/a8c52af4-2000-ac92-b285-c8b4d2a4c67e/iOS_1242x2208_01.jpg/0x0ss.png
testflight:2TestFlighthttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/05/e0/a0/05e0a06f-aaba-0913-90ee-d2c93fa687c1/TestFlight-iPhone6p9-iOS26-GEOS-Wrapper_03.png/0x0ss.png
appledev:0Apple Developerhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/94/69/15/94691513-f1f1-1b6f-c985-73c1fb58b337/01-discover.png/0x0ss.png
appledev:1Apple Developerhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/d3/86/3d/d3863d3f-08dc-b3ce-7609-ccff72dfdda2/02-search-swiftui.png/0x0ss.png
appledev:3Apple Developerhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/78/16/7f/78167f28-366e-f4a1-7d4b-0b5f8fb2ab7a/04-wwdc.png/0x0ss.png
appledev:4Apple Developerhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/d6/d2/df/d6d2df74-06dd-5c70-3278-f4abab45f0ef/05-account.png/0x0ss.png
shortcuts:0Shortcutshttps://is1-ssl.mzstatic.com/image/thumb/Purple123/v4/14/3f/66/143f6676-5063-0bc0-b521-4036e4f378a7/mzl.rqiimtmu.png/0x0ss.png
shortcuts:2Shortcutshttps://is1-ssl.mzstatic.com/image/thumb/Purple113/v4/a1/b1/c0/a1b1c0d1-bce9-9f10-62a8-cfafa3e4d048/mzl.xterzzpu.png/0x0ss.png
applepodcasts:3Apple Podcastshttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/8c/cd/ec/8ccdecfb-11f0-28cd-d6ea-83452aad1e48/iPhone6p9-iOS26-USEN-Podcasts-Wrapper3.png/0x0ss.png
applestore:3Apple Storehttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/67/16/d1/6716d17e-f263-b975-3898-b8e7d8df9fc6/3-Go_Further-6_5-English_U0028US_U0029.png/0x0ss.png
applefitness:0Apple Fitnesshttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/a0/e0/ad/a0e0ad1b-f65e-9134-9b7d-dca428d14346/Fitness-iPhone6p9-LuckC-USEN-Wrapper1.png/0x0ss.png
applefitness:3Apple Fitnesshttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/13/3f/22/133f22f9-d45e-101e-ab48-e0942118165f/Fitness-iPhone6p9-LuckC-USEN-Wrapper4.png/0x0ss.png
applehealth:0Apple Healthhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/76/30/5f/76305fa0-6396-ec38-dbcf-123824429b0b/Health_1.png/0x0ss.png
en_toss:0Tosshttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/b1/b6/86/b1b6861b-f685-771c-0ed7-1bde4b083447/0_APP_IPHONE_55_0.png/0x0ss.png
en_toss:2Tosshttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/1d/35/ea/1d35eacb-ed02-27b4-03df-0eca0eb7a70b/2_APP_IPHONE_55_2.png/0x0ss.png
en_toss:5Tosshttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/04/89/f4/0489f4d5-765e-238c-4d44-1f7c3a841fd9/5_APP_IPHONE_55_5.png/0x0ss.png
en_navermap:1NAVER Maps, Navigationhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/dc/f8/d5/dcf8d526-76dc-a6a7-805f-10e3433ee902/iPhone_U0028en_U0029_1242x2688_p2.png/0x0ss.png
en_navermap:3NAVER Maps, Navigationhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/43/5e/b3/435eb30b-22f9-a0bf-e5a9-a02013dbb504/iPhone_U0028en_U0029_1242x2688_p4.png/0x0ss.png
en_navermap:4NAVER Maps, Navigationhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/53/cf/e9/53cfe912-3fd4-11e7-2c02-1f9da94e8e1a/iPhone_U0028en_U0029_1242x2688_p5.png/0x0ss.png
en_kakaotalk:1KakaoTalkhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/aa/f5/28/aaf5287e-37c3-0f72-1015-b1ce44623059/Kakaotalk_iOS_SC_EN_02.png/0x0ss.png
en_kakaotalk:3KakaoTalkhttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/4f/70/3b/4f703baf-3d38-2fd2-40ac-1ccb0362c44b/Kakaotalk_iOS_SC_EN_04.png/0x0ss.png
en_karrot:1Karrothttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/e8/92/f1/e892f18e-701a-2971-8bc8-4bd912216bda/US_apple_1242x2208_pg2.jpg/0x0ss.png
en_karrot:4Karrothttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/28/71/30/2871302a-481c-8c1b-891d-f1964454083e/US_apple_1242x2208_pg5.jpg/0x0ss.png
en_karrot:6Karrothttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource221/v4/42/1e/c3/421ec35a-ef7d-a264-bfa1-5e4262ca3e2a/US_apple_1242x2208_pg7.jpg/0x0ss.png
en_karrot:7Karrothttps://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/ac/72/c2/ac72c2ff-a4cf-c834-a3b8-0b176e78e0ff/US_apple_1242x2208_pg8.jpg/0x0ss.png

13. Method and limits ​

Screen and scale. Every frame is converted to RGB; the screen background colour is the modal colour in the central 40 % of rows 28–95 % of the height; for each row whose centre pixel has that colour the run is expanded left and right (tolerance 3); the screen bounds are the median ends of the runs that are at least 97 % of the longest. pt = px ÷ (screen px ÷ 390). The two raw captures use 3 px per pt directly. The assumption of a 390 pt screen is validated against three published tokens (Toss 24, Seed 16, Airbnb 24); for the Apple mock-ups (device width 402 or 440 pt possible) values read up to 3 % low at 402 and 13 % low at 440, which cannot move 19.1–20.7 out of the 20 class.

Margins. For each row of the content area, the first and last run of at least 14 pt of non-background pixels gives a left and a right edge; the histogram peaks (merged ±1 px) are the margins. Left and right peaks of the same height confirm the screen bounds (a sideways error cancels). Text-only screens use the first ink and overstate by 0.5–1.5 pt.

Vertical gaps. Ink runs in a column band to the right of the rail (threshold 8 for light fills, 14–28 for text, 6 to catch a grey band or a white card on a grey canvas); gaps are run-to-run, so they are ink to ink, and a container's visible edge counts as the end of the previous group. Heading ink heights (16.5–18.7) correspond to about 19–22 px Hangul headings (ink ÷ 0.868 to ÷ 0.80, depending on which syllables the string contains). The 무신사 frame is named 430x932, so its screen may be a 430 pt design and its pt values up to 10 % low; the ratio above ÷ below does not depend on the scale.

Strings. Advance widths of Pretendard 1.3.9 (Regular, Medium, SemiBold, Bold) from the hmtx table, no kerning, no shaping; missing glyphs count 1 em. Row text columns: 390 − 2 × 20 − 56 − 12 − trailing − 12. The ko and en locale modules were bundled with esbuild and flattened; 3,295 Korean string leaves, 3,292 pairs present in both.

Not verified, and why. iOS Mail and Messages dot geometry (no raw capture; Apple's pages give none); Instagram and TikTok profile-count strips (none of 10 Instagram storefront sets has a profile frame); the iOS 26 UISwitch size and tab-bar height (no primary figure); Hangul-specific line-height research beyond the null result of Jeong 2016; the Korean mobile-app accessibility guideline KS X 3253 (text not found); Material 3's margin per window size class (the m3.material.io pages are script-rendered); VoiceOver and TalkBack pronunciations (need devices, already open in the addendum). Frames are marketing images, so spacing seen there is what the marketing team chose to show; the three raw Apple captures and the published tokens anchor the numbers.

Reproducing. The measurement scripts live in the session scratch directory (not committed): a downloader for the lookup API, the centre-run screen detector, the block-edge histogram, the vertical-run tool, the string-width and wrap simulator, and an esbuild bundle of the locale modules. Each step above is a few lines of NumPy, Pillow and fontTools.

14. The ten changes, in one list ​

  1. Leading markers: the owner's rule stands as a whole-list slot (dot 8 + 8, content edge 36, first-line aligned); headings never take a slot; delete the hung today dot; unread dot 6 → 8.
  2. Heading spacing: keep 32 above a section head, change 8 → 12 below; day header becomes 24 above / 12 below on a 22 line (11 measured headings in 6 products: 16.8 below, 33.8 above, ink to ink). The peers' section titles are also larger than ours: audit A9, decision D7 (title 20/28·700).
  3. Reading text 16/24: add the role for comments, dialogs, notices, toasts, descriptions and input text (KRDS ≥ 16, M3 16/24, Seed 16, iOS web input zoom); keep 15/22 for single-line UI text.
  4. Minimums: nothing in Hangul below 12; tab-bar labels 11 → 12/16; wrapping text at least 1.5 (13/20, 12/18); 500 or heavier at 13 and below; raise the label scaling cap 1.5 → 2.0.
  5. Rail: 20 stays at 390–440 pt (Apple measured 20.00 at 414 and 440), 16 below 390, 24 from 600; the citation is corrected (20 is Apple's value from 390 pt; the market is bimodal at 16 and 24).
  6. Blocks: one grammar, zones eyebrow → figure → meta, left-aligned, whole block pressable with one chevron on the eyebrow row, no buttons inside, one state table (loading, empty, error, offline, long, 200 %).
  7. Strip: equal pitch (20 / 136.7 / 253.3), label above figure, no hairlines, 2–4 columns, 2-up reflow by a fit test.
  8. English: budget by role (Tag ≤ 12 characters; row L2 ≤ 2 segments beside a Tag, 3 beside a figure), truncate the flex segment only, shortName for venues, relative chips Nmin, keep the 24-hour clock unless the owner rules otherwise (E4).
  9. Motion: keep the duration and easing tokens (they equal M3 and Seed); Reduce Motion replaces with a 100–150 ms fade instead of cutting (HIG, Apple criteria); press springs to ζ 0.9 (optional).
  10. Accessibility gaps to close: WCAG 2.5.7 drag alternatives (P1), the iOS accessibility-label checklist (P1 at the first iOS build), 1.3.4 orientation decision, OS contrast and cross-fade settings, 3.3.7 and 3.3.8; plus the audit items: 48 targets, FAB 56, Switch 52 × 32, CTA helper 15/22, section action 15, roster names 15/22.

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