# Design System — mohfarawati.de The visual language for the public site and admin. This documents the token system that already lives in `app/globals.css` and `tailwind.config.ts`, and defines the layers that are still missing (type scale, spacing rhythm) so the site has one consistent, premium base before any page is redesigned. Source of truth for values: `app/globals.css` (`:root` + `.dark`). Tailwind mappings: `tailwind.config.ts`. This file is the *usage guide* for those tokens. --- ## Direction: Warm Premium (work-forward) Chosen visual direction. Every design decision serves these principles: 1. **The work is the hero.** Layouts lead with project imagery and a strong title hierarchy; chrome stays quiet. 2. **One decisive accent.** The warm red-orange brand color appears sparingly — primary CTAs, one highlighted word, active/selected states, focus. Everything else is neutral ink on light/dark surfaces. Accent is a punctuation mark, not a background. 3. **Generous whitespace + restraint.** Space and type hierarchy carry the premium feel — not borders, gradients, or decoration. "Too busy" is the default failure mode; cut before adding. 4. **Depth, softly.** Elevation via one soft shadow layer and the large 24px radius already in the tokens. Avoid stacking shadows or heavy borders. 5. **Light + dark parity.** Every token has a dark value; never hardcode a hex. 6. **Arabic is first-class.** RTL layout, no uppercase or letter-spacing on Arabic text, slightly looser line-height. Latin uses Museo, Arabic uses Dubai. Colors and fonts are fixed by the owner and are **not** changed by this system — it only organizes and documents them and adds the missing scale layers. --- ## 1. Color tokens All colors are HSL channel triplets consumed as `hsl(var(--token))`. Light is `:root`, dark is `.dark`. ### Base | Token | Light | Dark | Use | |---|---|---|---| | `--background` | `0 0% 100%` | `222 22% 8%` | Page canvas | | `--foreground` | `222 24% 10%` | `210 20% 96%` | Primary ink | | `--muted` | `220 14% 96%` | `222 16% 14%` | Quiet fills | | `--muted-foreground` | `220 10% 42%` | `217 10% 64%` | Secondary text | ### Surfaces (elevation ramp) | Token | Light | Dark | Use | |---|---|---|---| | `--surface-1` | `0 0% 100%` | `222 22% 9%` | Base card | | `--surface-2` | `220 16% 97%` | `222 18% 12%` | Raised card / section tint | | `--surface-3` | `220 14% 94%` | `222 16% 15%` | Highest / hover | | `--surface-inverse` | `222 24% 12%` | `210 20% 96%` | Inverted blocks | Step surfaces 1 → 2 → 3 for hierarchy. Do not invent intermediate greys. ### Brand + semantic (use sparingly) | Token | Light | Dark | Use | |---|---|---|---| | `--brand-primary` / `--primary` / `--ring` | `9 73% 50%` | `9 78% 56%` | The one accent: CTAs, highlight word, focus | | `--brand-secondary` | `12 64% 58%` | `12 74% 64%` | Accent gradient partner, live dots | | `--primary-foreground` | `210 40% 98%` | `210 40% 98%` | Text on accent | | `--destructive` | `0 84% 60%` | `0 63% 31%` | Errors only | ### Status | Token | Light | Dark | |---|---|---| | `--status-success` / `--status-success-soft` | `145 63% 42%` / `145 58% 92%` | `145 68% 66%` / `145 36% 18%` | | `--status-warning` / `--status-warning-soft` | `36 92% 44%` / `41 96% 90%` | `42 96% 66%` / `35 40% 18%` | Reserved for real state (success/warning feedback), never decoration. ### Lines + hero | Token | Light | Dark | Use | |---|---|---|---| | `--border` | `220 13% 90%` | `222 14% 18%` | Default hairline | | `--border-strong` | `220 11% 82%` | `222 12% 26%` | Emphasis divider | | `--hero-base` / `--hero-ink` | `260 22% 95%` / `226 43% 11%` | `222 24% 10%` / `210 20% 96%` | Hero backdrop base + ink | Tailwind exposes these as `bg-background`, `text-foreground`, `bg-surface-2`, `text-brand-primary`, `border-border`, `bg-status-success-soft`, etc. **Accent budget:** at most one accent-filled element per view (usually the primary CTA). Additional emphasis uses ink weight/size, not more color. --- ## 2. Typography ### Fonts (fixed) | Script | Family | Variable | Utility | Weights | |---|---|---|---|---| | Latin (default) | Museo Sans Rounded | `--font-museo` | `.font-latin` | 300, 500, 700, 900 | | Arabic | Dubai | `--font-dubai` | `.font-arabic` | 300, 400, 700 | Applied on `body` (Latin) and `html[lang="ar"]` (Arabic) in `globals.css`. ### Type scale (to add as tokens in 2.3) A single documented scale replaces ad-hoc sizes. Latin values; Arabic overrides noted below. | Role | Size (clamp) | Weight | Line-height | Tracking | |---|---|---|---|---| | `display` | `clamp(2.75rem, 8vw, 5.5rem)` | 900 | 0.95 | -0.03em | | `h1` | `clamp(2.25rem, 5vw, 3.5rem)` | 700 | 1.05 | -0.02em | | `h2` | `clamp(1.75rem, 3.5vw, 2.5rem)` | 700 | 1.1 | -0.015em | | `h3` | `1.375rem` (22px) | 700 | 1.2 | -0.01em | | `title` | `1.125rem` (18px) | 500 | 1.3 | 0 | | `body-lg` | `1.125rem` (18px) | 400 | 1.7 | 0 | | `body` | `1rem` (16px) | 400 | 1.7 | 0 | | `small` | `0.875rem` (14px) | 400 / 500 | 1.6 | 0 | | `caption` | `0.8125rem` (13px) | 500 | 1.5 | 0 | | `overline` | `0.75rem` (12px) | 500 | 1.4 | 0.14em, uppercase | **Arabic overrides:** never `uppercase`, never letter-spacing (breaks joins); add ~0.1 to line-height on display/h1/h2; cap weight at 700 (Dubai has no 900). The `overline` role for Arabic uses normal tracking and normal case. Only two Latin weights per view in body copy (regular 400 + one bold). Reserve 900 for `display` only. --- ## 3. Radius | Token | Value | Use | |---|---|---| | `--radius-surface` | `24px` | Cards, panels, large containers (`rounded-surface` / `lg` / `xl`) | | `--radius-nested` | `16px` | Nested elements, inputs, buttons (`rounded-nested` / `sm` / `md`) | | `--radius-pill` | `9999px` | Pills, badges, toggles (`rounded-pill`) | The generous 24px surface radius is part of the premium feel — keep it consistent; do not mix arbitrary radii. --- ## 4. Elevation (shadows) | Token | Use | |---|---| | `--shadow-xs` / `shadow-xs` | Subtle lift (hairline cards) | | `--shadow-sm` / `shadow-sm` | Small controls, pills | | `--shadow-card` / `shadow-card` | Default raised card | | `--shadow-panel` / `shadow-panel` | Floating panel / glass surface | | `--shadow-md`, `--shadow-lg` | Reserved for overlays; use rarely | Discipline: most surfaces are flat with a hairline border. Raise with **one** shadow layer at a time. Never stack `shadow-lg` on nested elements. --- ## 5. Spacing + layout ### Containers | Token | Value | Use | |---|---|---| | `--container-narrow` | `48rem` | Reading width, forms | | `--container-default` | `72rem` | Standard page content | | `--container-wide` | `80rem` | Galleries, wide grids | | `--container-admin` | `88rem` | Admin workspace | Header: `--header-height: 4.5rem`. ### Vertical rhythm (to formalize in 2.3) Existing: `--section-space: 3.5rem`, `--content-space: 1.5rem` (`spacing.section`, `spacing.content`). Premium layouts need more air. Recommended section rhythm to add: | Token | Value | Use | |---|---|---| | `section-sm` | `3rem` | Tight sections | | `section` | `5rem` (mobile) → `7rem` (lg) | Default between major sections | | `section-lg` | `8rem`+ | Hero-adjacent breathing room | Internal gaps use rem steps: `1rem`, `1.5rem`, `2rem`. --- ## 6. Motion framer-motion, restrained. Entrance pattern (see `components/layout/site-hero.tsx`): - item: `opacity 0→1`, `y 16→0`, `duration 0.54`, ease `[0.22, 1, 0.36, 1]` - container stagger: `0.13`, delay `0.08` Rules: entrance + hover only; respect `prefers-reduced-motion`; no looping or attention-grabbing motion on content. --- ## 7. Component conventions - **Cards** route through `components/ui/app-card.tsx` (`AppCard` with `level`/`layer`/`padding`). Use `level` to express hierarchy — do not restyle cards ad hoc. - **Buttons**: one `primary` (accent) per view; others `outline`/`ghost`. - **Badges**: `success`/`warning` variants map to status tokens; `outline` for neutral tags. - **Inputs**: `--radius-nested`, `--border`, focus uses `--focus-ring`. - **Inline feedback** (admin): `components/admin/admin-flash.tsx`. --- ## 8. Do / Don't **Do** - Lead with imagery and whitespace; let type hierarchy do the work. - Use the accent once per view, deliberately. - Keep one radius language (24 / 16 / pill) and one shadow layer. - Test every screen in light and dark, and Arabic RTL. **Don't** - Fill backgrounds with brand color or gradients. - Add a second accent hue. - Apply uppercase/letter-spacing to Arabic text. - Stack shadows or mix arbitrary radii/greys. - Put decoration where whitespace would do.