style(v2): align accents and pod-list geometry - #929
Conversation
lilyshen0722
left a comment
There was a problem hiding this comment.
Re-ran the browser check on 99260ce1. Fix verified — and it turned up an error in my own previous report that I want on the record.
The fix holds
Same method that found the clip (real elements, width/overflow relaxed then restored):
slot 56px
"Yesterday" needs 51.7px headroom 4.3px no clip
"11:59 PM" needs 51.2px headroom 4.8px no clip
"12:59 PM" needs 51.2px headroom 4.8px no clip
Instrument control: the declared stack measures 51.7px vs 43.5px for a deliberately-bogus family, so a real face from the chain is rendering rather than a generic fallback.
Correction to my #928 comment
I reported those measurements as taken "at the real inherited font (SF Pro Text 11px)." That attribution was wrong. I'd read getComputedStyle().fontFamily.split(',')[0], which returns the first declared family, not the face that actually resolved.
Forcing "SF Pro Text" alone on this machine yields exactly the bogus-font control width (43.5px) — it isn't installed. Something later in the chain is doing the rendering.
The numbers are unaffected — they were always measured on the real element with the real cascade, which is why they matched the screenshot. Only the font name I attached to them was wrong.
What this still doesn't answer, and I can't answer it here
The declared chain is "SF Pro Text", -apple-system, BlinkMacSystemFont, "SF Pro", "Helvetica Neue", "Segoe UI", "Inter", Roboto, sans-serif.
I tried to measure the Windows/Linux cases and the instrument couldn't do it: "Segoe UI", Inter, and Roboto all return the bogus-control width on this machine, i.e. none are installed. Only "Helvetica Neue" and generic sans-serif resolved. So the faces a Windows or Linux user actually gets are unmeasurable from here.
Headroom is 4.3px on a 51.7px string — about 8%. That clears the face rendering here comfortably. Whether it clears Segoe UI or a Linux DejaVu fallback is genuinely unknown, and a longer localized label (a zh-CN or de-DE "Yesterday" equivalent) would eat into it further.
Not a blocker — 56px is strictly better than 44px and the two known-bad strings now fit. Flagging because the previous slot was chosen against a measurement too, and the guard (toContain('width: 56px')) pins the number by presence and cannot tell whether it's sufficient. If the label set or font stack ever changes, nothing here goes red.
If you want that closed rather than noted: min-width: 56px with the title absorbing shrink would degrade instead of clip — a truncated pod name costs less than a truncated clock.
lilyshen0722
left a comment
There was a problem hiding this comment.
Localization risk settled — @pod-architect supplied the locale outputs, and they render in the face installed here, so the instrument could finally reach them.
Measured all three localizing branches of grouping.ts:73-90 across 15 locales at a worst-case date (28 Sept, 23:59), on the real element against the 56px slot:
45 strings measured — NOTHING clips at 56px.
tightest: ko-KR time "오후 11:59" 53.5px (2.5px headroom)
pt-BR monthDay "28 de set." 53.0px (3.0px headroom)
en-US literal "Yesterday" 51.7px (4.3px headroom)
Two things worth adding:
1. The tightest string isn't in the month-day branch. The enumeration focused there; the actual worst case is ko-KR's time branch — CJK locales prepend an AM/PM marker (오후), which is wider than any abbreviated month. Worth knowing if this slot is ever re-tuned: the binding constraint is the time branch in CJK, not the date branch in Romance languages.
2. Unrelated to width, found while measuring — the time column mixes languages.
grouping.ts:84 return 'Yesterday'; // hardcoded English literal
grouping.ts:81 date.toLocaleTimeString([], {...}) // [] = BROWSER locale
grouping.ts:87 date.toLocaleDateString([], { weekday: 'short' })
grouping.ts:89 date.toLocaleDateString([], { month, day })Three branches follow the browser's locale; the fourth is a hardcoded English string that follows nothing. So a German-locale browser renders 28. Sept. and Mi. directly above Yesterday, in one column — and none of it follows the app's own i18n language, which has en and zh-CN files sitting right there.
That's a correctness issue rather than a layout one, so it isn't this PR's job. Flagging it because ADR-020's sibling brief commits to zh-CN from day one, and this column silently opts out.
Width-wise: 56px clears every locale I can measure, and my earlier caveat about localized labels eating the headroom is now answered — it doesn't. The remaining unknown is unchanged and unmeasurable here: the Windows/Linux faces (Segoe UI, Inter, Roboto aren't installed on this machine).
Summary
Shadow audit
Classified all 42 v2 declarations: floating menus/popovers/modals and focus rings remain; resting surfaces inherit the existing no-shadow V2 tokens.
Verification
npm test -- --watchAll=false --runInBand src/v2/__tests__/v2-layout-invariants.test.ts(28 passed)npm run typechecknpm run buildnpm run lintremains blocked by the pre-existingPersonalityBuilder.tsx:440unescaped-entity error