diff --git a/apps/backoffice/src/styles.css b/apps/backoffice/src/styles.css index 3d99d51ae..46ef17e86 100644 --- a/apps/backoffice/src/styles.css +++ b/apps/backoffice/src/styles.css @@ -1,4 +1,7 @@ -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); +/* Inter carries no Ge'ez glyphs, so Noto Sans Ethiopic is loaded alongside it. + Without it every Amharic string in the app renders in whatever the OS + happens to substitute — different on Windows, macOS and Android. */ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Noto+Sans+Ethiopic:wght@400;500;600;700&display=swap'); *, *::before, *::after { box-sizing: border-box; } diff --git a/apps/e2e/visual/theme.spec.ts-snapshots/backoffice-gallery-dark-desktop-chromium-win32.png b/apps/e2e/visual/theme.spec.ts-snapshots/backoffice-gallery-dark-desktop-chromium-win32.png index fe9da8df6..a3836a31b 100644 Binary files a/apps/e2e/visual/theme.spec.ts-snapshots/backoffice-gallery-dark-desktop-chromium-win32.png and b/apps/e2e/visual/theme.spec.ts-snapshots/backoffice-gallery-dark-desktop-chromium-win32.png differ diff --git a/apps/e2e/visual/theme.spec.ts-snapshots/backoffice-gallery-dark-tablet-chromium-win32.png b/apps/e2e/visual/theme.spec.ts-snapshots/backoffice-gallery-dark-tablet-chromium-win32.png index b2ac0a6c9..cc4d3a1cc 100644 Binary files a/apps/e2e/visual/theme.spec.ts-snapshots/backoffice-gallery-dark-tablet-chromium-win32.png and b/apps/e2e/visual/theme.spec.ts-snapshots/backoffice-gallery-dark-tablet-chromium-win32.png differ diff --git a/apps/e2e/visual/theme.spec.ts-snapshots/backoffice-gallery-light-desktop-chromium-win32.png b/apps/e2e/visual/theme.spec.ts-snapshots/backoffice-gallery-light-desktop-chromium-win32.png index 79df6ccab..ff08cf4f6 100644 Binary files a/apps/e2e/visual/theme.spec.ts-snapshots/backoffice-gallery-light-desktop-chromium-win32.png and b/apps/e2e/visual/theme.spec.ts-snapshots/backoffice-gallery-light-desktop-chromium-win32.png differ diff --git a/apps/e2e/visual/theme.spec.ts-snapshots/backoffice-gallery-light-tablet-chromium-win32.png b/apps/e2e/visual/theme.spec.ts-snapshots/backoffice-gallery-light-tablet-chromium-win32.png index c98ab52b8..8fcaa1290 100644 Binary files a/apps/e2e/visual/theme.spec.ts-snapshots/backoffice-gallery-light-tablet-chromium-win32.png and b/apps/e2e/visual/theme.spec.ts-snapshots/backoffice-gallery-light-tablet-chromium-win32.png differ diff --git a/apps/e2e/visual/theme.spec.ts-snapshots/portal-gallery-dark-desktop-chromium-win32.png b/apps/e2e/visual/theme.spec.ts-snapshots/portal-gallery-dark-desktop-chromium-win32.png index 406819423..fcb53cffa 100644 Binary files a/apps/e2e/visual/theme.spec.ts-snapshots/portal-gallery-dark-desktop-chromium-win32.png and b/apps/e2e/visual/theme.spec.ts-snapshots/portal-gallery-dark-desktop-chromium-win32.png differ diff --git a/apps/e2e/visual/theme.spec.ts-snapshots/portal-gallery-dark-tablet-chromium-win32.png b/apps/e2e/visual/theme.spec.ts-snapshots/portal-gallery-dark-tablet-chromium-win32.png index c4ccb4e98..96c9165fb 100644 Binary files a/apps/e2e/visual/theme.spec.ts-snapshots/portal-gallery-dark-tablet-chromium-win32.png and b/apps/e2e/visual/theme.spec.ts-snapshots/portal-gallery-dark-tablet-chromium-win32.png differ diff --git a/apps/e2e/visual/theme.spec.ts-snapshots/portal-gallery-light-desktop-chromium-win32.png b/apps/e2e/visual/theme.spec.ts-snapshots/portal-gallery-light-desktop-chromium-win32.png index 69b66859a..e50811108 100644 Binary files a/apps/e2e/visual/theme.spec.ts-snapshots/portal-gallery-light-desktop-chromium-win32.png and b/apps/e2e/visual/theme.spec.ts-snapshots/portal-gallery-light-desktop-chromium-win32.png differ diff --git a/apps/e2e/visual/theme.spec.ts-snapshots/portal-gallery-light-tablet-chromium-win32.png b/apps/e2e/visual/theme.spec.ts-snapshots/portal-gallery-light-tablet-chromium-win32.png index f6cf3fc82..465a9af2d 100644 Binary files a/apps/e2e/visual/theme.spec.ts-snapshots/portal-gallery-light-tablet-chromium-win32.png and b/apps/e2e/visual/theme.spec.ts-snapshots/portal-gallery-light-tablet-chromium-win32.png differ diff --git a/apps/portal/src/app/theme/portal.css b/apps/portal/src/app/theme/portal.css index 6b5fec975..93a2ac64a 100644 --- a/apps/portal/src/app/theme/portal.css +++ b/apps/portal/src/app/theme/portal.css @@ -1,6 +1,9 @@ /* Portal global styles — loaded after Mantine's CSS, no Tailwind preflight so it never fights Mantine's base styles. */ -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap'); +/* Inter carries no Ge'ez glyphs, so Noto Sans Ethiopic is loaded alongside it. + Without it every Amharic string in the app renders in whatever the OS + happens to substitute — different on Windows, macOS and Android. */ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Noto+Sans+Ethiopic:wght@400;500;600;700&display=swap'); :root { --ema-surface-light: #f5f8fc; diff --git a/libs/shared/src/lib/theme/base-theme.ts b/libs/shared/src/lib/theme/base-theme.ts index 43dc11c80..73315594a 100644 --- a/libs/shared/src/lib/theme/base-theme.ts +++ b/libs/shared/src/lib/theme/base-theme.ts @@ -15,13 +15,18 @@ import { createTheme, rem } from '@mantine/core'; /** * The type stack. * - * Ge'ez support is added in the font stage, not here: Inter carries no Ethiopic - * glyphs today, so every Amharic string falls back to an arbitrary OS font. - * Inserting "Noto Sans Ethiopic" changes metrics, which would make this - * structural refactor look like a visual change. + * Noto Sans Ethiopic sits directly after Inter rather than being swapped in by + * a `[lang='am']` rule. Browsers fall back per *glyph*, not per element, so one + * stack renders Latin in Inter and Ge'ez in Noto automatically — including + * inside a single string. That matters here: a registry is full of mixed-script + * lines like an Amharic name beside a Latin IMO number, and a language-scoped + * swap would render one half of those in the wrong face. + * + * Inter carries no Ge'ez glyphs at all, so before this the Amharic half of a + * bilingual system rendered in whatever the OS happened to substitute. */ export const EMA_FONT_STACK = - 'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'; + 'Inter, "Noto Sans Ethiopic", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'; export const baseTheme = createTheme({ fontFamily: EMA_FONT_STACK, @@ -29,16 +34,16 @@ export const baseTheme = createTheme({ headings: { fontFamily: EMA_FONT_STACK, fontWeight: '700', - // Exactly the portal's original values. Ethiopic's taller ascenders may - // want a little more leading, but that is a typography change and belongs - // with the font work — not smuggled into a structural refactor whose whole - // claim is that it changes nothing for the portal. + // A little looser than the portal's original values. Ge'ez has taller + // ascenders and deeper descenders than Latin, so a heading set to Inter's + // natural leading clips its Amharic rendering — which only became visible + // once Ethiopic was actually being rendered rather than substituted. sizes: { - h1: { fontSize: rem(32), lineHeight: '1.25' }, - h2: { fontSize: rem(25), lineHeight: '1.3' }, - h3: { fontSize: rem(21), lineHeight: '1.35' }, - h4: { fontSize: rem(17), lineHeight: '1.4' }, - h5: { fontSize: rem(15), lineHeight: '1.45' }, + h1: { fontSize: rem(32), lineHeight: '1.3' }, + h2: { fontSize: rem(25), lineHeight: '1.35' }, + h3: { fontSize: rem(21), lineHeight: '1.4' }, + h4: { fontSize: rem(17), lineHeight: '1.45' }, + h5: { fontSize: rem(15), lineHeight: '1.5' }, }, }, diff --git a/libs/ui/src/lib/dev/ThemeGallery.tsx b/libs/ui/src/lib/dev/ThemeGallery.tsx index ba90fd555..77e7ec41e 100644 --- a/libs/ui/src/lib/dev/ThemeGallery.tsx +++ b/libs/ui/src/lib/dev/ThemeGallery.tsx @@ -117,6 +117,9 @@ export function ThemeGallery() { {/* Mixed-script line: the case a [lang] font swap would break. */} Amharic: አበበ ግርማ — SF-2024-0001 — የአዲስ አበባ ወደብ + {/* Ge'ez at heading size, where its taller ascenders clip first. */} + የኢትዮጵያ ማሪታይም ባለስልጣን + የመርከበኞች መዝገብ — Seafarer Registry Monospace: ET-IMO-0231 · 28,450 GT