Files
anwar-pi-website/DESIGN_SYSTEM.md
T

75 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DESIGN_SYSTEM — anwarpy.ai
> Canonical tokens live in `web/src/app/design.css`. This file documents them and the rules for using them. If CSS and this file disagree, fix one of them in the same PR.
## 1. Design personality
Editorial, calm, premium-dark. Ink surfaces, champagne accents, generous whitespace, Arabic-first typography. Restraint is the brand: one accent color, used sparingly; motion is short and soft; nothing blinks, nothing bounces.
## 2. Color tokens
| Token | Value | Role |
|---|---|---|
| `--ink` | `#131519` | page background (`--bg`) |
| `--ink-2` | `#17191d` | raised background |
| `--basalt` | `#1c1f24` | card/surface (`--surface`) |
| `--seam` | `#2b2f36` | hairline borders (`--border`) |
| `--seam-2` | `#3a3f47` | hover border, stronger seam |
| `--mist` | `#ece9e3` | primary text (`--fg`) |
| `--stone` | `#a3a09a` | muted text (`--muted`) |
| `--dim` | `#7b7974` | faintest text (meta only) |
| `--champagne` | `#d4b47c` | THE accent (`--accent`) — badges, CTAs, highlights |
| `--champagne-ink` | `#1a150c` | text/icons on champagne (`--accent-ink`) |
Rules:
- Never introduce a new hue. Semantic aliases (`--bg`, `--surface`, `--fg`, `--muted`, `--border`, `--accent`) are the only tokens components may use — raw hex is for `design.css` only.
- Champagne on ink or champagne-ink on champagne. Never champagne text on basalt for body copy (contrast), never stone below 14px.
- Success/warning/error states (form errors, honest 503s) use `--mist`/`--stone` + wording first; reserve red only where the CSS already defines it. Do not invent traffic-light colors.
## 3. Typography
- **Readex Pro** (Arabic + Latin, single family), loaded in `layout.tsx` via `next/font/google`, weights 300–700. `--font-display: var(--font-sans), "Segoe UI", sans-serif`.
- Scale: hero H1 ~2.5rem/700; section H2 ~1.5rem/600; body 1rem/400 with line-height ≥1.8 for Arabic; meta/captions 0.875rem `--stone`.
- Arabic-first: `direction: rtl` at the page root; Arabic quotes «»; numerals via `formatNumber` (Arabic-Indic where the site does).
- **LTR islands** inside RTL text use `<bdi dir="ltr">`: `anwarpy.ai`, `$10`, code, identifiers, agent names (GPTBot…). Never let a raw Latin token break RTL flow.
- No `<br>` for spacing; use margins. No font-size below 0.75rem.
## 4. Spacing & shape
- Space scale: 4 / 8 / 12 / 16 / 24 / 32 / 48 / 64px. Section padding 48–64px; card padding 16–24px; page max-width container per existing layout (centered, ≥24px gutters).
- Radii: cards/pills 8–12px; badges/buttons pill (999px) where the existing CSS does; inputs match buttons.
- Borders: 1px `--seam` everywhere; hover → `--seam-2`. No heavy shadows; elevation = `--ink-2`/`--basalt` layering, not blur.
## 5. Component inventory (build from these, extend the list, never fork it)
Existing, in `src/components/` + route CSS: `topnav.tsx`, `site-menu.tsx`, `nav-links.tsx`, `footer.tsx`, `anwarpi-background.tsx`, `set-body-attr.tsx`.
Recurring patterns (CSS classes are the contract):
- **Buttons**: `.btn`, `.btn.btn-primary` (champagne bg, `--accent-ink` text), disabled/coming-soon state = «قريباً» pill, wired to `subscribe-button.tsx comingSoon` prop. Disabled buttons are visually disabled from first paint and explain why in Arabic.
- **Badges/pills**: access badge «مجاني» / «للأعضاء»; content-type badge (note/tutorial/case_study/comparison); «وصول مبكر مجاني» champagne strip.
- **Notice strip**: the early-access notice on articles — champagne-tinted band, verbatim copy from PRD §3.2, never a modal.
- **Guide card**: surface card, dek line, meta row (category · reading minutes · «حُدّث»), champagne hover seam. Topic hubs and «ابدأ من هنا» reuse it.
- **Article body**: headings, paragraphs, lists, blockquote, code (LTR island, scrollable), **real `<table>`** for tabular data (never screenshot/ASCII), links `--champagne` underline.
- **Forms**: label above input, input bg `--ink-2`, border `--seam`, error text = the API's Arabic sentence verbatim, loading state disables + keeps label, success replaces form state («تم! سنراسلك عند تفعيل العضوية.»).
- **Tables renderer**: for Lexical table nodes — mobile-safe overflow wrapper.
New components: reuse an existing class first, then extend `design.css` (or the route's CSS) — do not add a component library (no shadcn/radui/MUI) and no Tailwind (decision, 2026-10-11).
## 6. Motion
- Durations 150–250ms, ease-out. Hover: border color + 1–2px translate. Entrances: fade/rise ≤8px.
- No parallax, no infinite loops, no scroll-hijack. Reduced-motion: honor `prefers-reduced-motion` for any added animation.
- Micro-interactions (like button) may pulse once on success — once, not looping.
## 7. Accessibility floor (enforced by `npx hyperframes check` on the brag video; treat as the site bar too)
- Contrast: body text ≥ 4.5:1, large text ≥ 3:1 (`--stone` on `--basalt` passes; `--dim` only ≥1.5rem or decorative).
- Focus visible: 2px `--champagne` outline on interactive elements.
- Every image has meaningful Arabic `alt` (covers: the guide title); icon buttons have `aria-label`.
- Landmarks: header/nav/main/footer; one H1 per page; heading order never skips.
- Forms: `<label for>`, `aria-live="polite"` status regions (existing pattern: `#notify-done`).
## 8. Cover images
Generated via `npm run covers` (`scripts/generate-covers.mjs`) — 1200×630, ink/champagne system, Arabic title shaping checked. og:image dimensions are asserted in tests/evidence (1200×630). Don't hand-drop covers of other sizes.