Initial commit: nick docs

This commit is contained in:
moojttaba
2026-05-23 20:35:34 +03:30
commit 0da235ae27
90 changed files with 18268 additions and 0 deletions

View File

@@ -0,0 +1,186 @@
---
title: Typography
tags: [design-system, typography, fonts]
created: 2026-05-23
---
# Typography
The system uses **Public Sans Variable** as the primary face with **Barlow** as a secondary (display) face, plus locale-specific Persian/Arabic faces loaded when the active language requires them.
---
## 1. Font stack
Loaded via `@fontsource-variable` (variable fonts streamed at build) plus `@fontsource/barlow`. Confirm in `frontend/package.json`:
```jsonc
"@fontsource-variable/public-sans": "^5.2.5", // Primary
"@fontsource-variable/dm-sans": "^5.2.5", // Optional preset
"@fontsource-variable/inter": "^5.2.5", // Optional preset
"@fontsource-variable/nunito-sans": "^5.2.5", // Optional preset
"@fontsource/barlow": "^5.2.5", // Secondary (display)
```
Imported in `frontend/src/app/layout.tsx` (or a fonts module) so Next can fingerprint and preload them.
Default font-family stack in the theme:
```css
font-family: "Public Sans Variable", "Helvetica", "Arial", sans-serif;
```
Display-only headings (banners, hero) may override with Barlow via the `sx` prop:
```tsx
<Typography variant="h1" sx={{ fontFamily: '"Barlow", serif' }}>Welcome</Typography>
```
---
## 2. Type scale
| Variant | Size (px) | Line height | Weight | Use |
|---|---|---|---|---|
| `h1` | 64 | 80 | 800 | Hero titles only |
| `h2` | 48 | 64 | 800 | Page titles |
| `h3` | 32 | 48 | 700 | Section titles |
| `h4` | 24 | 36 | 700 | Card titles, dialog headers |
| `h5` | 20 | 30 | 700 | Sub-section titles |
| `h6` | 18 | 28 | 700 | Item titles, sidebar headers |
| `subtitle1` | 16 | 24 | 600 | Form section labels |
| `subtitle2` | 14 | 22 | 600 | List item subtitles |
| `body1` | 16 | 24 | 400 | Body copy default |
| `body2` | 14 | 22 | 400 | Secondary copy, table cells |
| `caption` | 12 | 18 | 400 | Helper text, timestamps |
| `overline` | 12 | 18 | 700 | Tags, all-caps category labels |
| `button` | 14 | 24 | 700 | Button text — NOT uppercase |
> [!tip]
> Use `responsiveFontSizes(theme)` once at theme creation to scale `h1`/`h2` on small screens automatically.
---
## 3. Weights
The variable Public Sans face supports 100900. Convention:
| Weight | Token | Use |
|---|---|---|
| 400 | `fontWeightRegular` | Body |
| 500 | `fontWeightMedium` | Mild emphasis |
| 600 | `fontWeightSemiBold` | Subtitles, table headers |
| 700 | `fontWeightBold` | Headings |
| 800 | (raw) | Display |
Never use `font-weight: bolder` — always pick from the table.
---
## 4. Letter-spacing
- Headings (h1h2): `-1` (tight, modern)
- Overline: `+1.1` (open, all-caps)
- Body, subtitle: `0`
---
## 5. Numeric variants
Tabular figures matter for financial UI (payments, prices). Enable per-instance:
```tsx
<Typography variant="body1" sx={{ fontVariantNumeric: 'tabular-nums' }}>
{amount}
</Typography>
```
---
## 6. Multi-script support
The system officially supports Latin, **Persian (Farsi)**, and **Arabic** rendering; French and Vietnamese use Latin glyphs already covered by Public Sans; Chinese (Simplified) falls back to the OS-default CJK font (the current fontsource set does not ship CJK).
Persian/Arabic font swap is layered at theme build:
```ts
fontFamily:
locale === 'fa' || locale === 'ar'
? '"Vazirmatn", "Public Sans Variable", "Tahoma", sans-serif'
: '"Public Sans Variable", "Helvetica", sans-serif'
```
> [!note]
> "Vazirmatn" is the **recommended** Persian face for new installations — it has full Unicode coverage and a variable axis. If not installed via `@fontsource`, ship it as a self-hosted woff2 under `public/fonts/`.
For Chinese (`cn`), consider adding `"PingFang SC", "Microsoft YaHei", "Noto Sans CJK SC"` to the family at the front.
For Vietnamese (`vi`) — Public Sans already covers all needed glyphs.
---
## 7. Line-length
Aim for **4575 characters per line** on body copy. Constrain with `maxWidth`:
```tsx
<Typography variant="body1" sx={{ maxWidth: 720 }}>{longBody}</Typography>
```
---
## 8. Text truncation
Single-line:
```tsx
<Typography noWrap>{text}</Typography>
```
Multi-line (clamp at 2 lines):
```tsx
<Typography
sx={{
display: '-webkit-box',
WebkitLineClamp: 2,
WebkitBoxOrient: 'vertical',
overflow: 'hidden',
}}
>{text}</Typography>
```
---
## 9. Bidi & RTL considerations
- Don't hard-code `text-align: left/right` — use `text-align: start/end` so it flips with direction.
- For inline mixed-script (Persian + English), prefer the auto direction inside `<bdi>` or wrap with the Unicode `` (RLE) / `` (PDF) markers.
- Numeric formatting per locale handled by `Intl.NumberFormat`; do NOT translate digits manually.
---
## 10. Loading & FOUC prevention
- All fonts loaded at the route segment that needs them (Next.js best practice).
- `font-display: swap` is the default in fontsource — visible text uses fallback first, then swaps.
- For the FIRST PAINT on auth pages, preload the primary Latin face by adding `<link rel="preload" as="font" />` to the root layout.
---
## 11. Customising
Add a font:
1. `yarn add @fontsource-variable/<name>`
2. `import '@fontsource-variable/<name>'` in `src/app/layout.tsx`.
3. Add to `fontFamily` stack in `theme/options/typography.ts`.
4. Register as a settings option if user-selectable.
---
## Related
- [[Theme Configuration]] · [[Design System Overview]] · [[Colors]]
- [[Internationalization & RTL]]
- [[Settings & Theming]]