Build & Push Docker Image / build (push) Has been cancelled
Refresh the homepage around new hero/services/roadmap sections, shared design tokens, and updated brand assets. Co-authored-by: Cursor <cursoragent@cursor.com>
120 lines
5.4 KiB
Markdown
120 lines
5.4 KiB
Markdown
# Typography
|
||
|
||
Persian-first typography system using **IRANSansX** (FaNum — Persian digits baked into the font). Canonical scale: `lib/typography.ts`. Prefer `type.*` classes or `<Typography variant="…">` over ad-hoc `text-*` stacks.
|
||
|
||
## Font family
|
||
|
||
| Role | Stack |
|
||
| --- | --- |
|
||
| Sans (UI) | `IRANSansX`, system-ui, sans-serif |
|
||
| Mono | `ui-monospace`, SF Mono, Menlo, Consolas, monospace |
|
||
|
||
Loaded via `@font-face` in `app/globals.css`. Body applies `font-family: "IRANSansX"` with `text-align: start` (right in RTL).
|
||
|
||
## Global base
|
||
|
||
| Element | Line height | Letter spacing | Alignment |
|
||
| --- | --- | --- | --- |
|
||
| `body` | `1.75` | `normal` | `start` |
|
||
| `h1–h6` | `1.45` | `normal` | `start` |
|
||
| `p` | `1.8` | `normal` | `start` |
|
||
|
||
Tracking is almost always `tracking-normal` (Persian). Avoid `tracking-tight` except decorative mono display (`display-mono`).
|
||
|
||
**Prefer** `text-start` (right in RTL). Section captions (`section-intro`) use `text-justify` with `text-align-last: start` so multi-line captions justify while the last line stays right-aligned. Avoid justify on body paragraphs and titles.
|
||
|
||
## Scale
|
||
|
||
Use via:
|
||
|
||
```tsx
|
||
import { type, typeSpacing, typeMeasure } from "@/lib/typography";
|
||
import { Typography, SectionTitle } from "@/components/ui/typography";
|
||
import { toPersianDigits } from "@/lib/persian-digits";
|
||
|
||
<h2 className={type.h2}>عنوان بخش</h2>
|
||
<Typography variant="section-intro" className={typeMeasure.prose}>
|
||
توضیح کوتاه
|
||
</Typography>
|
||
<span>{toPersianDigits(24)}</span>
|
||
```
|
||
|
||
| Requested level | Variant | Size / weight | Default element | Use |
|
||
| --- | --- | --- | --- | --- |
|
||
| Heading 1 | `h1` / `display` | 3xl→5xl, extrabold / bold | `h1` | Page / hero titles |
|
||
| Heading 2 | `h2` / `cta-title` | 2xl→4xl, bold | `h2` | Major sections |
|
||
| Heading 3 | `h3` | lg→xl, bold | `h3` | Subsections / features |
|
||
| Body Large | `body-lg` | lg, leading 1.8 | `p` | Prominent intros (same size as captions) |
|
||
| Body | `body` | base, leading 1.8 | `p` | Standard copy |
|
||
| Small Text | `body-sm` | sm, leading 1.75 | `p` | Dense / secondary |
|
||
| Caption | `caption` | xs, muted | `span` | Meta, footnotes |
|
||
| Micro | `micro` | 11px (0.6875rem) | `span` | Dense chrome / mockups / step badges |
|
||
| Button Text | `button` / `button-lg` | sm / base, medium, leading-none | `span` | Wired into `Button` sizes |
|
||
| Navigation | `nav` / `nav-mobile` | sm / base, medium | `span` | Header / mobile menu |
|
||
| — | `eyebrow` | sm medium, muted | `p` | Section labels |
|
||
| — | `label` | sm medium | `span` | Form labels |
|
||
| — | `card-title` / `card-desc` | base bold / sm | `h3` / `p` | Cards |
|
||
| — | `section-intro` | lg muted, justify | `p` | Section captions under headings |
|
||
| — | `stat` | 4xl→5xl bold primary | `span` | KPI numbers |
|
||
|
||
## Reading measure
|
||
|
||
| Token | Class | Use |
|
||
| --- | --- | --- |
|
||
| `typeMeasure.narrow` | `max-w-md` | Short support under a heading |
|
||
| `typeMeasure.prose` | `max-w-2xl` | Standard paragraph / intro |
|
||
| `typeMeasure.wide` | `max-w-3xl` | Longer multi-paragraph blocks |
|
||
|
||
## Alignment
|
||
|
||
- Titles: **right-aligned** (`text-start` in RTL).
|
||
- Section captions (`section-intro`): justify with last line start (right in RTL) when 2+ lines.
|
||
- Body paragraphs: right-aligned; do not justify.
|
||
- Hero marketing headlines may use `text-center` when the composition requires it — override with `className="text-center"`.
|
||
- Do not inherit `text-center` onto multi-line section captions.
|
||
|
||
## Numbers
|
||
|
||
- Prefer explicit Persian digits in copy (`۲۴`) or `toPersianDigits()` / `formatPersianNumber()`.
|
||
- IRANSansXFaNum also shapes Latin digits visually; still prefer explicit Persian for dates, counters, stats, and steps.
|
||
- Keep Latin only for technical IDs, versions, emails, and code.
|
||
|
||
## Button text
|
||
|
||
`Button` sizes pull from `type.button` (sm/default) and `type["button-lg"]` (lg). Horizontal padding tokens in `globals.css` are slightly wider for Persian glyphs. Do not wrap button labels in `<Typography>` unless building a non-`Button` control.
|
||
|
||
## Hierarchy rules
|
||
|
||
1. One `h1` per page (or `display` acting as the page title).
|
||
2. Section titles use `h2` / `cta-title`; subsections use `h3`/`h4`.
|
||
3. Pair titles with at most one short supporting sentence (`section-intro` or `body` + `text-muted-foreground`).
|
||
4. Use `text-balance` on large headings (already in scale) for better wrap in Persian.
|
||
5. Blog article prose uses `.blog-content` rules in `globals.css`—do not override casually.
|
||
|
||
## Stacking
|
||
|
||
```tsx
|
||
<div className={typeSpacing.sectionStack}>
|
||
<p className={type.eyebrow}>خدمات</p>
|
||
<h2 className={cn(type.h2, typeSpacing.eyebrowToHeading)}>…</h2>
|
||
<p className={cn(type["section-intro"], typeSpacing.headingToBody, typeMeasure.prose)}>…</p>
|
||
</div>
|
||
```
|
||
|
||
## Forbidden
|
||
|
||
- Inter / Roboto / Arial as primary UI fonts.
|
||
- Random `text-[15px]` / `text-[1.05rem]` (use `type.micro` for dense chrome).
|
||
- `tracking-widest` on Persian body copy.
|
||
- `text-justify` on body paragraphs / titles (section captions are the exception).
|
||
- Using `font-bold` everywhere—follow the scale weights.
|
||
- Physical `text-left` / `mr-` / `ml-` / `pr-` / `pl-` when logical `text-start` / `ms-` / `me-` / `ps-` / `pe-` work.
|
||
- Overriding scale sizes with `sm:text-5xl` / `lg:text-6xl` on `type.display` / `type.h*`.
|
||
- Using `type.h2` on an `h3` (or vice versa) — keep element level and scale token aligned.
|
||
|
||
## Related
|
||
|
||
- [buttons.md](./buttons.md)
|
||
- [responsive.md](./responsive.md)
|
||
- [accessibility.md](./accessibility.md)
|