Lane J: emoji and glyphs in information-dense lists, and the tiering of information (2026-10-09)
Status: Reference · Date: 2026-10-09 · Evidence appendix for list-surfaces-spec-2026-10-09.md. Frame, crop and script paths refer to the session scratch directory (not committed); App Store frames are re-fetchable from the store URLs in the tables.
Scope: colour/layout research, ledger row 14 and board visual-tone.jsx T5 (BEFORE 12px emoji in rows / RECOMMENDED lucide strokes / ALTERNATIVE glyphs only in the hero, rows quiet). Owner ruled: "I like the alternative so that we have tiers of information", "inline icons are minimised in peers; icons are action targets".
Evidence tags: [P] primary page fetched and read this session · [S] only a search-engine summary or secondary page was available (flagged, lower weight) · [C] computed here · [F] frame inspected with the Read tool · [R] our repo, read-only. Frame names are files under bench/crops/ (Korean consumer), bench/b_crops/ (category peers), bench/crops_c/ (global); enlarged montages of the frames I counted are in bench/lane_j/m1.png … m12.png.
0. Answer in six lines
- List rows: no decorative fact glyphs. In 32 peer list-frames, 21 (66%) carry zero fact-category glyphs and 27 (84%) carry at most one; no peer puts a colour system emoji in front of a fact in a row. The research does not show glyphs slow scanning (it mostly shows icon+text is as fast or faster for finding targets), so the case for quiet rows rests on Apple/M3 "text in lists", peer practice, positional stability of our template, and our colour budget, not on a scanning-speed result.
- Hero/detail: 2–4 glyph-led facts is peer-normal (Meetup 2, Spond 3, TeamSnap 4, Smash profile 3) and is the one place a glyph is not redundant, because the hero fact carries no label word. The rows below the hero should be label + value (Somoim, Smartscore, Toss pattern), not glyph + label.
- Emoji is the worst glyph kind for our hero on four measured counts: vendor drawing varies (🎾 is a ball only on Apple, WhatsApp, Huawei, X and Toss Face), its colour is far above the brand (p90 chroma 78–95 vs brand 46.3), it is read aloud by name unless hidden (our
GlyphSlothides nothing), and it has already cost two Android clipping fixes. Default recommendation: lucide stroke 2.0 in the label's colour; if the owner wants colour in the hero, an owned flat set of 4–6 glyphs (Toss's own reasoning), never OS emoji. - The glyph vocabulary is the real problem:
SESSION_FACT_GLYPHhas 21 fact glyphs, at least 12 of them metaphors for abstract facts (🎯 level, ⏳ deadline, 📝 approval, 🏷️ type, 🏅 style, 📈 ELO, 🔄 rotation, 📋 cancel policy, 📣 notice, 🔁 recurrence, 📏 match rules, 👤 status). NN/g: only home/print/search are near-universal. Concrete facts (date, place, fee) can take a glyph; abstract ones cannot. - Weather is the one documented exception (
visual-accents.ts:62): the emoji is the data. Keep it, but give it an accessible name and keep it out of list rows. - One thing I could not verify and the brief quotes: M3's "use only when they aid recognition". I found no such sentence; the verifiable M3 text is "Keep items short and easy to scan. Show icons, text, and actions in a consistent format."
1. Evidence table
| # | Claim | Source (URL) | Finding | Applies to us |
|---|---|---|---|---|
| E1 | Icons need visible labels; few icons are universal | NN/g, Harley 2014 https://www.nngroup.com/articles/icon-usability/ [P] | "a text label must be present alongside an icon"; only home, print, magnifier named as universal; "most icons continue to be ambiguous"; clock-icon test: "Not a single test participant clicked this icon". No general rule about icons beside text in lists. | Every glyph of ours has its text, so Harley's risk (icon alone) does not apply. But at least 12 of our 21 fact glyphs are metaphors for abstract facts (📏 match rules, 📋 cancel policy, 🔄 rotation, 📈 ELO, 🏅 style, 🏷️ type, 📝 approval, 🎯 level, ⏳ deadline, 📣 notice, 🔁 recurrence, 👤 status) where no emoji is self-evident. |
| E2 | Icon+text beats text-only for finding a known item in menus | Majrashi 2022, Behaviour & Information Technology 41(1) 32-50, https://ideas.repec.org/a/taf/tbitxx/v41y2022i1p32-50.html [P] (abstract) | Two experiments, 18 participants each, seated and walking: text-and-icon menus gave faster selection (medium menus seated; short and medium walking), fewer wrong selections (walking, medium), a better learning curve. | This is the strongest counter-evidence and must be named: glyphs help when the user hunts for one target among heterogeneous labels. A session row is not a menu; the user reads time, format, level of one row, in a fixed order. Does not support a glyph per fact. Does not show harm either. |
| E3 | Same direction, small samples, older/other contexts | Repokari 2002 (n=15, icons faster than words on a small display) and Larish et al. 1990 (labels changed recall, not selection time) https://garyperlman.com/hfeshci/Abstracts/90_424-428.html; Springer 2021 list-menu eye-tracking https://link.springer.com/chapter/10.1007/978-3-030-78227-6_5 (paywalled) [S] | Summaries only: icons ≥ text for visual search; "minor gaps" between text-only and icon+text app list menus. | Directional only. All are target-search tasks. |
| E4 | Icon+text improves scanning of a list of links | Baymard, account dashboard https://baymard.com/blog/use-icons-in-the-account-dashboard [P] | Adding a representative icon to each text link "significantly improved" scannability; 81% of sites use text only. Sample size not stated. Items are account features (navigation), not facts. | Supports glyphs on navigation rows (our settings/profile list rows can keep a leading stroke icon), not on fact lines inside a card. |
| E5 | People locate things by position more than by graphic | UIE "Orbitz Can't Get A Date" 2006, via https://uxmyths.com/post/715009009/myth-icons-enhance-usability [S] | Changing icon images was absorbed; shuffling icon positions confused users. | Our row template is fixed (time · format · tier), so position, not a glyph, tells the user what a segment is. |
| E6 | Labels help learning early, the benefit fades | Wiedenbeck 1999, BIT 18(2) 68-82 [S] (could not retrieve the paper; secondary summaries only, one of them a patent, one a blog) | Labels speed early learning and perceived ease; benefit short-lived; icons "do not necessarily help the user find a menu item better than a text label alone" (Zuschlag's reading). | Not retrievable at primary level; do not cite as a finding. |
| E7 | Users scan the left edge and see ~2 words | NN/g "First 2 Words" https://www.nngroup.com/articles/first-2-words-a-signal-for-scanning/ [P] | After the first few items users run their eyes "down the text's left side"; most see about 2 words of a list item; numerals squeeze meaning into the "tiny stump of text". | Our rows start with ⏰ then 19:00. The numeral is the nanocontent; a leading glyph spends the left-edge slot first (my inference, no study of glyph+numeral). Self-labelling values (19:00, 8,000원, NTRP 3.0–4.0) need no category glyph. |
| E8 | Decorative imagery is ignored, informative imagery is looked at | NN/g eyetracking https://www.nngroup.com/articles/photos-as-web-content/ [P] | Amazon thumbnails: 0.9 fixations vs 4.4 on text (18% vs 82% of viewing time); informative photos studied intensely, generic ones "mainly ignored". | About photos, not glyphs; by analogy only. Already used in ledger row 13. |
| E9 | Saturation is the salience channel; "if everything is contrasted, nothing stands out" | NN/g visual hierarchy https://www.nngroup.com/articles/visual-hierarchy-ux-definition/ [P] | "Bright colors naturally stand out, so use them for important items"; limit big elements to ≤2; use ≤3 sizes. | Colour emoji are the most saturated pixels on our rows (E20): three per card × many cards works against "brand for one action and one block". |
| E10 | Progressive disclosure: defer secondary, ≤2 levels | NN/g https://www.nngroup.com/articles/progressive-disclosure/ [P] | "Defers advanced or rarely used features to a secondary screen"; "designs that go beyond 2 disclosure levels typically have low usability". | About features/screens, not decoration. By analogy: list (answer), hero (answer + context), detail rows (all facts). Two levels, which is the limit NN/g names. |
| E11 | Information scent: self-explanatory labels, no purely decorative images | NN/g https://www.nngroup.com/articles/information-scent/ [P] | "Avoid generic, purely decorative images"; labels "clear and self-explanatory". | Supports label/value self-description over category glyphs. |
| E12 | Apple: prefer text in lists | HIG Lists and tables https://developer.apple.com/design/human-interface-guidelines/lists-and-tables (read via https://developer.apple.com/tutorials/data/design/human-interface-guidelines/lists-and-tables.json) [P] | "Prefer displaying text in a list or table. A table can include any type of content, but the row-based format is especially well suited to making text easy to scan and read." "Keep item text succinct." "you could list item titles only, letting people choose an item to reveal its content in a detail view." A "small image in the leading end of a row, followed by a brief explanatory label" is a named row style. | Verbatim support for quiet rows and for list→detail tiering. The leading small image is identity (avatar, thumbnail), not a fact glyph. |
| E13 | Apple: symbols beside text = outline, one colour | HIG SF Symbols https://developer.apple.com/design/human-interface-guidelines/sf-symbols (JSON endpoint as above) [P] | "The outline variant works well in toolbars, lists, and other places where you display a symbol alongside text"; monochrome = "one color to all layers". | If glyphs are used at all next to text: outline, one colour. Matches lucide at the label colour. |
| E14 | Apple on emoji in UI | HIG pages fetched: lists-and-tables, sf-symbols, inclusion [P] | No emoji guidance found. Only the inclusion page mentions emoji (avoid gender-specific avatars/emoji). | Cannot cite Apple for or against emoji. |
| E15 | Material 3 lists | material-components-android List.md https://github.com/material-components/material-components-android/blob/master/docs/components/List.md [P]; m3.material.io/components/lists/guidelines is client-rendered and returned no text | Anatomy: leading icon, leading avatar, leading video thumbnail all "(optional)"; guidance "Keep items short and easy to scan. Show icons, text, and actions in a consistent format." | The quote "use only when they aid recognition" was not found in any M3 page I could read. Do not attribute it. M3 makes leading icons optional and asks for consistency. |
| E16 | Seed Tag Group = icon+text metadata, one line | https://seed-design.io/llms/components/tag-group.txt [P] | Purpose: "아이콘과 텍스트 태그를 수평으로 나열해 여러 속성·상태·메타데이터를 한눈에 보여주는". Used for "카드형 콘텐츠에서 메타데이터 표시", "상세 페이지에서 부가 정보 묶음 제시", profile summaries. Icon before or after the label, never both; t2/t3/t4 = 12/13/14pt; 6–10 characters, one line; priority truncation. | The one design system that endorses glyph+text metadata in cards. Reality check in frames: Danggeun (its owner) shows one grey pin per marketplace row (danggeun_f1) and none in danggeun_f2/f7. Seed makes it available, not mandatory. Glyph colour = label colour. |
| E17 | Emoji shape varies by vendor by design | Unicode UTS #51 https://unicode.org/reports/tr51/ [P] (first 100k of 133k chars) | "The shape of the character can vary significantly"; "The set of supported emoji sequences may vary by platform"; presentation "typically multicolored"; emoji have "about the same vertical placement and advance width as CJK ideographs". | Variance is by design. The CJK-width note is why a 12px emoji needs a ~20px line box. |
| E18 | Same emoji, different renderings, different readings | Miller et al., ICWSM 2016 https://ojs.aaai.org/index.php/ICWSM/article/view/14757 [P] (abstract); Tigwell & Flatla, MobileHCI 2016 (n=436) https://discovery.dundee.ac.uk/en/publications/oh-thats-what-you-meant-reducing-emoji-misunderstanding/ [P] (abstract) | Ratings of the same rendering disagreed on sentiment 25% of the time, more across platforms; Tigwell: ratings vary within and across platforms. | Both studies are about face/sentiment emoji. Object emoji (🎾 ⏰) are weaker evidence. The object-emoji evidence is E19 and Toss (E21). |
| E19 | Our glyphs differ across vendors | Emojipedia https://emojipedia.org/tennis and https://emojipedia.org/alarm-clock [P] | 🎾 = "Tennis Racquet and Ball"; Apple, WhatsApp, JoyPixels, Huawei, Twitter/X and Toss Face show only a ball, most others include a racket. ⏰ is the Alarm clock, commonly used for "alarms… deadlines". | Our format: '🎾' is racket+ball on Android, ball on iPhone. time: '⏰' says "alarm" for a start time (the ledger's deadline fact has its own ⏳). |
| E20 | Colour emoji vs our palette | [C] Google Noto emoji artwork (512px stills from fonts.gstatic.com/s/e/notoemoji/latest/<cp>/512.png: the same art family as Android's Noto Color Emoji, not the font's bitmap strike), CIELAB D65, pixels with alpha > 0.5 | Mean chroma C*ab: ⏰ 35.9, 📅 27.4, 🎾 45.3, 🎯 57.6, 💰 68.4, 🔒 58.7. p90 chroma 78–95 (🎯 94.7, 🎾 93.8, ⏰ 84.5, 📅 81.4, 💰 79.1). Share of pixels with C*≥30: 34% (📅) to 84% (💰). Tokens: brand #006D37 46.3, error #B8332E 63.1, optic #C6E84B 76.2, warningFill #F5B301 80.7, ink #0D100E 1.5, $textSecondary 5.8. | A 12px emoji brings pixels more saturated than the brand block and as saturated as the optic/warning fills, three per row. Ink-coloured meta text is C* ≈ 2–6. Five glyphs already span ≥4 hue families (red, yellow, yellow-green, blue; see bench/lane_j/emoji-12px-dpr123.png) against the ledger's ≤7 per viewport. Apple's set not measured. |
| E21 | Toss made its own emoji font to fit a flat UI | Toss, "토스페이스 제작기" https://toss.im/tossfeed/article/outsight-tossface [P] | 3,600 emoji; OS emoji differ per OS, are "입체적이고 설명적" (3D, descriptive) against a flat UI, and when small OS emoji are enlarged "과한 디테일에서 큰 이질감"; some OS versions show nothing; Toss's emoji are "아주 작은 크기의 아이콘으로 활용되겠죠? 기존 아이콘과 조화롭게" (used as very small icons, must harmonise with the icons); flat/iconic, circles and straight lines, curves hurt "명시성" at small size; one palette that reads on white and black; "이모지를 하나만 넣으면 … 훨씬 캐주얼하고 편안하게" (one emoji makes a finance screen casual). Also claims OS emoji need vendor permission for commercial apps (their statement, not checked). | Toss's answer to "emoji in a flat UI" was an owned set matched to its icons, not system emoji. The "casual" effect is a designer assertion with no measurement. In the Toss frames I opened, emoji-style art is a leading identity tile per row (toss_f5: 3D clover, tile, shoe; crops_c/m_toss_5), never an inline fact glyph; rows' meta lines are text (toss_f0, toss_f2). |
| E22 | Our own platform-clipping record | [R] packages/ui/src/text.tsx:44-55 (EMOJI_LINE_HEADROOM = 8: "Noto ≈1.2×, Samsung One UI ≈1.4×… clipped the 🎯 / 🌱 bottoms on the owner's phone while the emulator's Noto fit"); packages/ui/src/glyph-fact-row.tsx:5-13, 116-122 (2026-09-18/19 fixes) | A 12px emoji needs a 20px line box on every Android vendor we support. | Two device-QA bugs in two days for decoration. Stroke glyphs have no vendor font. |
| E23 | Accessibility: decorative glyphs must be ignorable; emoji are announced | WCAG 1.1.1 Understanding https://www.w3.org/WAI/WCAG21/Understanding/non-text-content.html [P]; Intuit https://contentdesign.intuit.com/style-and-usage/emoji/ [P]; React Native props https://reactnative.dev/docs/accessibility [S]; React Native Testing Library https://oss.callstack.com/react-native-testing-library/docs/api/misc/accessibility [S] | Pure decoration = "serving only an aesthetic purpose, providing no information, and having no functionality" and must be "implemented in a way that it can be ignored by assistive technology". Intuit: "Read the content as a screen reader would. Does the alt text make sense?" (party popper → "tada"). RN: accessibilityElementsHidden (iOS), importantForAccessibility="no-hide-descendants" (Android; "no" does not hide descendants per RNTL docs), aria-hidden. | GlyphSlot has no hiding (grep of packages/ui/src: hiding exists only in pulse-dot.tsx, corner-count-badge.tsx, charts). Today VoiceOver/TalkBack read the CLDR name ("alarm clock") before 19:00 on every row. The "announced by name" behaviour itself is documented by secondary sources only (EmojiFYI, a 2017 WebAIM thread) [S]; test on device. |
| E24 | Product style guides on emoji | Dynatrace https://styleguide.dynatrace.com/docs/style/emoji [S]; Intuit (above) [P]; Washington Post https://build.washingtonpost.com/resources/guides/emoji-guide [S] | Dynatrace: no emoji in UI, use standard icons where an icon would go; Intuit: "When in doubt, don't use them", ≤1 per message, "Don't replace a word with an emoji"; WaPo: copy must stand without the emoji. | Convergent but about text copy, enterprise tone. Weak for a sports-club consumer app; useful for the "must survive deletion" test. |
| E25 | Baymard: list-item info must be separable | Guideline #448 https://baymard.com/guidelines/448-visual-separation-of-list-item-info-elements [P] (issue summary only; body is paywalled) | "If users can't quickly and accurately discern key product attributes when scanning list item info…they could overlook suitable items." | Supports clear segmentation (MetaSegments/MetaBreak dots) of attributes; does not say how. |
| E26 | 12px emoji legibility | [C] render of the Noto art at 12px × DPR 1/2/3, bench/lane_j/emoji-12px-dpr123.png | At 1× the glyph is a blurred 12×12 blob; at 2× and 3× all five are crisp and recognisable. No published legibility measurement found. | Legibility is not the argument against 12px emoji on phones. The arguments are colour, vendor variance, announcement, clipping. |
2. Peer count: inline glyphs per row
Definitions. Fact glyph = a small glyph leading a fact in a row that stands for its category (pin = place, clock/calendar = when, people = capacity/format, bolt/tip = fee). Counted per row. Not counted: rating star (the glyph is the unit), engagement counters (♥ 💬), RSVP/state marks, identity tiles (avatar, logo, thumbnail), controls. "Colour" = whether the fact glyph is coloured or the text colour. Confidence: H = frame ≥ 600px wide and glyphs resolved; M = 250–600px; L = ≤ 260px thumbnail, glyph count may be off by one.
| Frame (file) | Row type | Fact glyphs / row | Other marks in the row | Separator | Colour | Conf |
|---|---|---|---|---|---|---|
crops/toss_f0 | account rows | 0 | leading tile, 송금 button | none; "·" in footer links | n/a | H |
crops/toss_f2 | securities rows | 0 | leading logo | none | n/a | H |
crops/toss_f5 (+crops_c/m_toss_5) | rewards rows | 0 | leading 3D emoji-style art tile (identity) | none | n/a | H |
crops/danggeun_f1 | marketplace rows | 1 (pin before "300m · 서초동 · 1분 전") | ♥ count, 바로구매 badge | "·" | text colour (grey) | H |
crops/danggeun_f2 | community rows | 0 | 👍 5 💬 8 counters | "·" | n/a | H |
crops/danggeun_f7 | real-estate rows | 0 | ♡ on photo | "·" | n/a | H |
crops/navermap_f2 | trend place rows | 0 | ☆ bookmark action, #tag chip | "•" | n/a | H |
crops/kakaomap_f7 | ranked place rows | 0 | ★ rating, ▢ bookmark action | "|" | n/a | H |
crops/baemin_f2 | restaurant rows | 3 (recent-order clock, delivery time, tip mark) | ★ rating, 4 outline tags | none | three colours (blue, blue, teal) | H |
crops/ohouse_f5 / ohouse_f6 | content / contractor rows | 0 / 0 | ★ rating (f6) | "·" and "|" | n/a | H |
crops/kakaotalk_f3 | open-chat rows | 0 | crown + pin status marks, count | none | grey | H |
crops/kakaobank_f2 | account rows | 0 | leading tile; emoji in user-named chip ("저금통 ☕") | none | n/a | H |
b_crops/band_3 | schedule card | 0 | one chip with glyph (참가신청서) | none | n/a | M |
b_crops/somoim_3 | 정기모임 rows | 1 (pin) | avatar stack | none | grey | L |
b_crops/munto_3 | 소셜링 rows | 2 (pin, people) | ♥ on photo | "·" | text colour (grey) | M |
b_crops/munto_4 | 라운지 플레이스 rows | 3 (pin, ⊙ count, calendar) | ♥ on photo | "·" | text colour (grey) | M |
b_crops/smash_1 | 소셜매칭 rows | 1 (people before "혼복, 남1 여1 · 1-2년") | 1/4명 count | "·" | text colour (grey) | L |
b_crops/greenlight_6 | 스포츠 조인 rows | 3 (sport, pin, calendar), a key-value stack | badge on photo | none (stacked) | text colour (grey) | M |
b_crops/flapfootball_1 | 소셜매치 rows | 0 (count glyphs ♥/👁/seat at ~9px) | counters | none | n/a | L |
b_crops/frip_3 | 액티비티 rows | 0 | ★ 5.0 (199); filter chips carry glyphs (controls) | none | n/a | M |
b_crops/tennisfriends_3 | 매칭정보 cards | 1 (people before 1/3) | 2 tag chips, one with a glyph | none | green/blue chips | L |
b_crops/courtmate_2 / courtmate_3 | 정기전 / 내 경기 rows | 0 / 0 | avatars | none | n/a | L |
b_crops/meetup_1 | event cards | 0 | ★ 4.9 inline, avatar stack | "•" | n/a | M |
b_crops/spond_5 | event rows | 0 | 3 RSVP counters (✓ ? ✗) | none | brand blue | M |
b_crops/usta_2 | tournament rows | 3 (calendar, pin, pin) | none (stacked) | black outline | M | |
crops_c/m_uber_3 | ride rows | 1 (person = seats) | "•" | black | H | |
crops_c/m_airbnb_1 | listing cards | 0 | ★ 4.92 | "·" | n/a | H |
crops_c/playtomic_4 (+_2) | club / match | 0 | optic level chips, avatars | none | n/a | H |
b_crops/strava_5 | activity feed | 1 (activity-type glyph) | stats as label-over-value columns | none | n/a | M |
b_crops/kimcaddie_3 | place card | 0 | ★ 9.5 | "|" | n/a | M |
Totals (32 frames): 0 fact glyphs in 21 (66%), 1 in 6, 2 in 1, 3 in 4 (Baemin coloured; Munto, Greenlight, USTA monochrome). ≤1 in 27 (84%). Mean 0.63. Nearest genre (sport / social / event / club, 15 frames): 0 in 7, 1 in 4, 2 in 1, 3 in 3; mean 1.0. Colour system emoji as a fact glyph in a row: 0 of 32. (Munto titles carry user-typed emoji; Kakaobank chips carry a user-chosen emoji; Notion pages carry user-chosen emoji: identity, not fact.) The only colourful inline glyphs are Baemin's vector marks, in a delivery marketplace where time and fee are the decision. Where peers do use inline glyphs (Munto, Greenlight, USTA, Smash, Danggeun), they are monochrome in the meta text's own grey/black, which is exactly the T5 RECOMMENDED treatment, not the T5 BEFORE treatment.
Action-target icons. In every frame I opened that had a header bar the icons were action targets on the right (search, bell, menu, cart, share, ♥, bookmark) and a bottom bar: danggeun_f1/f2, toss_f2/f3, kakaotalk_f3/f5, munto_3/4, band_2, nol_f2, naver_f2/f3, kakaomap_f1/f7. Observed, not counted; it supports the owner's second sentence.
Hero / detail tier (9 frames)
| Frame | What the fact block looks like | Glyph-led facts | Colour |
|---|---|---|---|
b_crops/meetup_3 | event hero: date line, then place line, each with a leading glyph and a trailing action glyph (calendar-add, map) | 2 of 2 | coloured (pink calendar, orange pin), owned vector art |
crops_c/spond_0 (+b_crops/spond_0) | tournament hero: date/time, venue + address, group; then Responses with 4 state glyphs | 3 of 3 facts (+4 state rows) | brand-blue strokes |
b_crops/teamsnap_1 | game detail: caption label + value, leading glyph in a blue circle | 4 of 4 | brand blue |
b_crops/smash_5 (L: 259px frame) | profile facts: 연령대, 중요한 것, 경기 후 루틴 | 3 of 3 | black outline ~16px |
b_crops/kimcaddie_2 | amenity grid, glyph above a label (장비보관, 왼손타석, 주차가능, 새벽영업) | 4 (grid, not fact lines); header facts are text | line art |
b_crops/somoim_5 | 일시 / 위치 / 비용 / 참석 as grey label word + value | 0 | n/a |
b_crops/smartscore_8 | 주소 / 코스 label–value rows; 저녁(3부), 4명 모집 as text chips | 0 | n/a |
crops_c/m_airbnb_5 | "May 22 – 26 · Hosted by Erinn" | 0 | n/a |
b_crops/band_3 (detail card) | "Today 오전 8:00 – 오후 7:00 / 서울 영등포구…" | 0 | n/a |
Glyph-led detail facts appear in 5 of 9 frames (Western event/team apps and a Korean profile); when present: 2–4. Korean activity-app detail pages (Somoim, Smartscore) use label words. Playtomic's match/club detail with fact lines was not in the frame set, so it is not counted.
3. The rule
3.1 Three tiers
| Tier | Where | Facts rendered as | Decoration |
|---|---|---|---|
| List | any repeated row or card in a feed (SessionCardV2, club rows, venue rows, roster rows) | text segments with MetaSegments/MetaBreak dots, numerals first | none (see 3.2) |
| Hero | the identity block at the top of a detail page (FlTypeHero/TypeHero/MediaHero facts) | glyph + text, inline, one line each | 2–4 glyph-led facts (see 3.3) |
| Detail rows | the fact block below the hero (FactRow, SpecList, session-record) | label + value pairs (장소 / 대치유수지체육공원) | none; the label word is the category cue |
Rationale: E12 (Apple: text in lists, titles in the list and content in the detail view), E10 (≤2 disclosure levels), E15 (M3 icons optional, consistent), E1/E11 (a label word beats a glyph as the meaning carrier), and the peer split in section 2.
3.2 List rows
- No decorative fact glyphs. Facts are text; order is fixed by template (time · format · level); segments separated by the existing middle dot (
MetaSegments,MetaBreak); values self-identify (19:00,복식,NTRP 3.0–4.0,8,000원,1/4명). This is the Naver Map / Kakao Map / Toss / Meetup / Airbnb / Band / Playtomic pattern (21 of 32 frames). - Allowed non-text marks, each doing a job (none is a fact-category glyph): (a) identity at the leading edge (avatar, venue photo or map tile,
ClubAvatar, tier dot); (b) state marks with a label or a colour-independent shape (참석 ✓, 마감, the lock for a gated level, RSVP counters as inspond_5); (c) a rating/count whose glyph is its unit (★, ♥); (d) trailing action targets. - Cap: one non-identity glyph per row. Munto/Greenlight/USTA at 2–3 are the ceiling of peer practice and all three use the text colour; if ever reintroduced the only compliant form is a 14–16px stroke at the row's meta colour, never emoji, never coloured. The default is zero.
- Do not rely on the glyph to distinguish two adjacent facts of the same type (e.g. place vs travel distance): reorder or label in words; Danggeun's single pin is the only peer case, and its value text ("300m") self-identifies.
- Navigation/setting rows (profile menu, settings): a leading stroke icon per row is fine (Baymard E4, M3 leading icon, Apple row style). That is a different row type from a fact line.
3.3 Hero / detail facts
- Count: 2–4 glyph-led facts, recommended 3. Peers: Meetup 2, Spond 3, TeamSnap 4, Smash 3. Seed: one line, 6–10 characters each (E16). Recommended three: when (date and time on one line,
9월 19일 (토) 19:00, as Meetup does), where (venue), fee (8,000원). The board's ALTERNATIVE shows two (📅 date, ⏰ time) and keeps 장소 in the list below; either is inside the peer range. Optional fourth: capacity (n/m). - Which facts get a glyph: concrete-object facts only (calendar, pin, money, people). Never abstract facts: level/format/rules/rotation/ELO/cancel policy/approval/type. They are shown as text,
TierRangeBadgeorStatusBadge, in the detail rows. This takes the vocabulary from 21 glyphs to about 4. - Why the hero is the right tier: the hero line has no label word (
9월 19일 (토)stands alone), so the glyph is the category cue, not a redundant one (E1: icon + label beats either alone; here there is no label). Below the hero the label word exists, so the glyph would be the redundant half. - Glyph size and colour: 16px stroke in a 20px slot, stroke 2.0 (ledger row 14: 1.33px at 16px matches Pretendard 500 stems of 1.46px at 14px), colour = the fact text's colour (
$textfor the value, never$iconMuted; Seed's rule,danggeun_f1, Apple one-colour symbols E13). Same lucide family as the header icons. - Detail rows below: label (secondary, 14/500) + value (ink); no glyph.
3.4 Glyph kind for the hero: emoji vs stroke vs owned set (numbers)
| Axis | A. System emoji (today, hero only) | B. Lucide stroke 2.0 (T5 RECOMMENDED) | C. Owned flat set, Toss Face style, 4–6 glyphs |
|---|---|---|---|
| Platform variance | vendor-drawn: 🎾 ball-only on Apple/WhatsApp/Huawei/X/Toss Face vs racket elsewhere (E19); Samsung ≈1.4×, Noto ≈1.2× line growth (E22) | identical everywhere (SVG) | identical (SVG/vector) |
| Colour | Noto p90 chroma 78–95; 34–84% of pixels C*≥30; brand 46.3 (E20) | the label's colour (ink C* 1.5, secondary 5.8) | designer-set; Toss uses one palette legible on white and black (E21); cap each glyph at brand chroma or below |
| Size / legibility | 12px = ~12×12 device px at 1×, crisp at 2–3× (E26); needs 20px line box (E22) | 16px in 20px slot, 1.33px stroke | same slot; Toss: free curves "hurt 명시성" at small size, so circles + straight lines |
| Accessibility | announced by CLDR name unless hidden; "alarm clock" for a start time (E19, E23) | trivially decorative, hide | same as B |
| Dark mode | colours fixed; no token control | automatic via token | two palettes to maintain |
| Cost | zero assets, but two Android clipping fixes in 2 days (E22) | zero (family already in the app) | 4–6 drawings; Toss's 3,600-glyph effort is not the model |
| Peer precedent at hero | none found (peers use owned vectors) | Spond, TeamSnap, Smash (strokes) | Meetup (coloured calendar/pin vectors) |
| Fits "brand for one action and one block" (ledger) | no: most saturated pixels on the page | yes | only if monochrome or two-tone |
Recommendation: B for the hero. If the owner wants warmth in the hero, C with two-tone (ink + brand tint) glyphs. If the owner prefers to keep emoji in the hero (the board's ALTERNATIVE as drawn), the research does not show harm from two or three of them, but the conditions are: ≤ 3 emoji, a fixed list, replace ⏰ with a non-alarm clock (🕖 or none), accept 🎾's two shapes, hide from assistive tech and give the hero line an accessible name that states the category, keep the emojiLineHeight box. I rank A last on every axis except cost-to-ship.
3.5 Accessibility handling
- Every hero glyph is decorative: wrap the glyph slot with
aria-hidden+accessibilityElementsHidden(iOS) +importantForAccessibility="no-hide-descendants"(Android;"no"is not enough, E23). Reuse the pattern already inpulse-dot.tsx:115-116. - The hero fact line's accessible name states the category and value (
일시 9월 19일 (토) 19:00), so no meaning lives only in the glyph (WCAG 1.1.1 decoration test: "pure decoration… no information"). This is my application of 1.1.1, not a rule found in a source. - List rows have no glyph, so there is nothing to hide.
- Weather exception: the emoji is the data (
visual-accents.ts:62-75: lucide's cloud family loses the differentiating mark). Keep it, at hero/detail tier, withaccessibilityLabel= the condition word (맑음/비…). If it must appear in a row, it is the row's single non-identity glyph and also carries the label. - Test on device: VoiceOver and TalkBack announcements of emoji are documented only by secondary sources here.
3.6 What happens to the 12px emoji today
| Today | Where | Becomes |
|---|---|---|
⏰ 🎾 on GlyphFactRow density="inline", 🎯/🔒 on the tier band | session-card-v2.tsx:405-450 (list row, 3 glyphs per row) | remove all three; row reads 19:00 · 복식 with MetaBreak dots and TierRangeBadge. 🔒 becomes a state: the badge's existing muted treatment plus a 14px stroke Lock at $textSecondary (the one allowed glyph). density="inline" has then no caller: delete the variant (no dead code). |
SESSION_FACT_GLYPH, 21 emoji keys, at least 12 of them abstract metaphors | session-card-v2.tsx:143-…, consumed by session-record.tsx:51-79, session-fact-rows.tsx, notice-section.tsx, public-pickup-preview-screen.tsx | shrink to the hero set (when, where, fee, capacity) as lucide icon names; the other 17 keys are deleted and their rows become label + value |
SpecList / FactRow icon= emoji column | packages/ui/src/spec-list.tsx:14-69, fact-row.tsx:72,255 | detail rows lose the emoji column; label word stays. Callout leading emoji (callout.tsx:36-58): keep for weather/notice banners only, hidden from AT unless it carries the state |
GlyphSlot emoji= (20px emoji box) | glyph-fact-row.tsx:15-47 | remains only for the weather exception; GlyphSlot default (16px icon slot) is the hero glyph slot |
Hero chips (GlyphFactRow density="chip") | type-hero.tsx, media-hero.tsx, club card | facts inline (T3) with stroke glyphs at the text colour, ≤4 |
Lane C's "12px emoji fact glyphs could stay as the dense-row icon" (bench/lane-c-platform-global.md:206) | lane C | superseded by this lane: dense rows carry no glyph |
Prevention (the repo's "every fix ships with prevention" rule): a lint/ArchUnit-style gate that fails on an emoji literal in a facts/GlyphFact.emoji config outside an allowlist (weather), with a known-positive canary (the repo's "gates need canaries" lesson), and a parity check that GlyphFactRow density="inline" does not exist once removed. This is a suggestion, not something I verified against the existing gates.
4. What the research does NOT support
- That inline glyphs slow scanning of a dense list. No study I found measures glyph-before-fact lines. The nearest controlled work (Majrashi 2022, the Baymard account-dashboard note, Repokari, Larish) shows icon+text equal to or faster than text-only for finding a target among labels. Quiet rows are justified by Apple/M3 text-in-lists, peer practice (66% zero), our fixed template, and the colour budget, not by a speed result. The owner should not be told "research shows glyphs hurt".
- That decorative glyphs are "ignored". NN/g's ignored-vs-attended finding is about photos and ad-like elements (Amazon thumbnails 0.9 vs 4.4 fixations; banner blindness), not icons. Applying it to glyphs is analogy.
- That 12px emoji are illegible. Rendered at 12px × DPR 2–3 all five are recognisable (E26). The 1× web case is blurred.
- Miller 2016 / Tigwell 2016 for our glyphs. Both measure sentiment of face emoji; 📅 ⏰ 🎾 are object emoji. Our variance evidence is Emojipedia (E19), Toss (E21) and our own clipping log (E22).
- A numeric ideal for hero glyph count. 2–4 comes from five peer frames and Seed's one-line tag group; no study fixes the number.
- M3 "use only when they aid recognition". Not found (E15).
- Apple or Material guidance on emoji. None found (E14, E24 are corporate style guides about copy).
- Wiedenbeck 1999 as a finding. Paper not retrieved; only secondary summaries (E6).
- That Toss puts emoji in rows. Toss's article says emoji are used as very small icons in the app, but in the four frames I opened they are leading tiles (identity) and rows' meta lines are text.
- That our owned-set option (C) is evidenced as better than strokes (B). It is precedent (Meetup, Toss), not a measured advantage; I rank B first on cost and consistency.
5. Caveats
- Frame sample. App Store screenshots are curated marketing frames, 2–4 per app, so lists in them may be tidier or busier than real use; counts are visual, by me, with lower confidence on frames ≤ 260px wide (
b_crops/somoim_3,smash_1,flapfootball_1,tennisfriends_3,courtmate_*), flagged L. Playtomic fact lines (match detail) are missing from the set. - Colour numbers come from Google's Noto emoji artwork at 512px (same art family as Android's Noto Color Emoji, but not the installed font's bitmap strike), thresholded at alpha > 0.5, CIELAB D65. Apple Color Emoji and Samsung's set were not available; they are likely similar in order of magnitude but not measured. Chroma of a glyph at 12px is anti-aliased and lower at the edges.
- Secondary-source items flagged [S]: Repokari, Larish, Springer 2021 (summaries), UIE 2006, Wiedenbeck, Dynatrace, WaPo, RN accessibility props (search summary), emoji announcement behaviour. The Apple and M3 quotes come from machine-readable endpoints (Apple's JSON data service, the Material repo mirror); the m3.material.io page itself returned no text, so any M3 page content beyond the repo doc is unverified.
- Toss's claims (casual feel, vendor permission for OS emoji) are the company's statements; I did not test them.
- Seed Tag Group exists as a published component; I could not see a Seed-built list in the frames that uses more than one glyph per row.
- NN/g "first 2 words" concerns links and list items on desktop; applying it to a leading glyph on mobile is my inference.
- Tier analogy. Progressive disclosure is about features across screens; mapping it to list/hero/detail is a design judgement the evidence does not test.
- All repo reads were read-only (
packages/ui/src/{text,glyph-fact-row,spec-list,fact-row,pulse-dot}.tsx,packages/app/src/presentation/components/sessions/session-card-v2.tsx,packages/app/src/config/visual-accents.ts,docs/twomore_design_system/wireframes/visual-tone.jsxT5); nothing under the repo was modified. Working files:bench/lane_j/(montages, Noto art, Apple HIG JSON/text, M3 List.md).