From d53b8cd0cc2323d9437834e4d8b8a8d00c59aba3 Mon Sep 17 00:00:00 2001 From: SkateSpots Date: Mon, 26 Oct 2026 21:44:16 +0700 Subject: [PATCH] fix(ui): harden menus for all locales MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - LanguageSelector was still rendering the new SVG flag paths as text; use there too and give every flag a fixed 24px slot (SVG/emoji align). - Language dropdown w-48 -> w-72 with truncate + hover titles, so 'Português (Brasil)' / 'Português (Portugal)' no longer clip. - Settings language grid 1 column on phones / 2 on sm+. - Header More menu w-48 -> w-64; header nav keeps its scroll, bottom nav keeps truncation. - :lang(hi/th/ja/ko/zh) disables uppercase/tracking-wide so Devanagari, Thai and CJK menu labels are not letter-spaced. - tsc, 101 tests, build and full-route smoke green. --- AGENTS.md | 7 ++++++ src/components/LanguageToggle.tsx | 40 ++++++++++++++++++------------- src/components/Layout.tsx | 2 +- src/index.css | 21 ++++++++++++++++ 4 files changed, 52 insertions(+), 18 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 2f64c6f..7419eec 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2727,6 +2727,13 @@ similar are internal endpoints/hook names, not credits — leave them.) `@fontsource/noto-sans-devanagari` (400/500/700) is **lazy-loaded** for `hi` via `lib/localeFonts.ts` (same pattern as CJK) and the CSS stack includes `'Noto Sans Devanagari'` before `system-ui`. +- **Menu hardening across all locales:** the language dropdown is `w-72` with + `truncate` + a fixed 24px flag slot (SVG and emoji align); the settings + language grid is 1 column on phones / 2 on `sm+`; the header **More** menu is + `w-64`; the header nav scrolls (`overflow-x-auto scrollbar-hide`) so long + labels never push the logo/controls; the bottom nav truncates its labels. + `:lang(hi/th/ja/ko/zh)` removes `uppercase`/`tracking-wide`, because + Devanagari/Thai/CJK labels look broken when letter-spaced. - Translation sources were split by namespace into `/tmp/opencode/i18n-src/batch1..7.json` (regenerate from `en.ts` if re-translating). When adding new UI strings, add them to `en`/`es` **and all diff --git a/src/components/LanguageToggle.tsx b/src/components/LanguageToggle.tsx index e3185aa..12ef4e5 100644 --- a/src/components/LanguageToggle.tsx +++ b/src/components/LanguageToggle.tsx @@ -79,7 +79,11 @@ function Flag({ flag, className }: { flag: string; className?: string }) { /> ); } - return {flag}; + return ( + + {flag} + + ); } /** @@ -124,11 +128,11 @@ export function LanguageToggle({ compact = false, inline = false, className, var : 'text-muted-foreground hover:bg-muted hover:text-foreground' )} > - -
- {lang.nativeName} + +
+ {lang.nativeName} {lang.nativeName !== lang.name && ( - {lang.name} + {lang.name} )}
{language === lang.code && ✓} @@ -166,7 +170,7 @@ export function LanguageToggle({ compact = false, inline = false, className, var )} - +
e.stopPropagation()} @@ -189,15 +193,15 @@ export function LanguageToggle({ compact = false, inline = false, className, var language === lang.code && 'bg-primary/10 text-primary' )} > - -
- {lang.nativeName} + +
+ {lang.nativeName} {lang.nativeName !== lang.name && ( - {lang.name} + {lang.name} )}
{language === lang.code && ( - ✓ + ✓ )} ))} @@ -220,23 +224,25 @@ export function LanguageSelector() { return (
-
+
{languages.map((lang) => ( diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index 2985fb3..ac78241 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -623,7 +623,7 @@ export function Layout({ children, noPadding }: LayoutProps) { {t('nav.more')} - + {/* Catalog items the user hasn't pinned to the top bar. Auth-only items (stash/collections/contacts/wallet/messages) only show when logged in. */} diff --git a/src/index.css b/src/index.css index 1963df5..66c5538 100644 --- a/src/index.css +++ b/src/index.css @@ -914,3 +914,24 @@ select { .ss-sheet-table td.ss-cell-name > input { max-width: 100%; } .ss-sheet-table td.ss-cell-actions { justify-content: flex-end; padding-top: 0.35rem; } } + +/* ── Caseless scripts ───────────────────────────────────────────────────── + The nav/menu labels use `uppercase tracking-wide` for the Latin UI. Those + classes are no-ops or actively wrong for Devanagari, Thai and CJK: letter + spacing separates conjuncts and uppercase does nothing. Keep the labels + natural when the document language is one of those. */ +:lang(hi) .uppercase, +:lang(th) .uppercase, +:lang(ja) .uppercase, +:lang(ko) .uppercase, +:lang(zh) .uppercase { + text-transform: none; +} + +:lang(hi) .tracking-wide, +:lang(th) .tracking-wide, +:lang(ja) .tracking-wide, +:lang(ko) .tracking-wide, +:lang(zh) .tracking-wide { + letter-spacing: 0; +}