Design Tokens¶
The shared vocabulary between design (Figma), web (Next.js/CSS variables), and mobile (Flutter ThemeExtension). Tokens are the single source of truth: no raw hex values, pixel sizes, or durations in component code.
Status: proposal
All values below — especially color — are starting proposals pending the brand identity project. The structure and names are stable; the values may change. Build against the tokens, not the values.
Naming convention¶
--{category}-{concept}-{variant} in kebab-case. The same names map 1:1 to Flutter (YamTokens.colorPrimary500) and to the Tailwind theme config. Semantic tokens (e.g. --color-text-primary) reference primitive tokens (e.g. --color-neutral-900) — components consume semantic tokens wherever one exists, so dark mode is a semantic remap, not a component rewrite.
1. Color¶
Primitive palette¶
Primary — Yam3at Deep Purple (brand family; celebration-royal, distinct from delivery-app teal/orange clutter in the Kuwaiti market):
| Token | Hex | Notes |
|---|---|---|
--color-primary-50 |
#F5F2FB |
Tint backgrounds, selected-state washes |
--color-primary-100 |
#E9E1F7 |
Hover washes, chips |
--color-primary-200 |
#D3C3EF |
Borders of selected items |
--color-primary-300 |
#B49BE3 |
Decorative, illustrations |
--color-primary-400 |
#9370D4 |
Secondary emphasis |
--color-primary-500 |
#7A4FC6 |
Brand mid — icons, accents |
--color-primary-600 |
#6639B0 |
Primary action color (AA on white: 6.3:1) |
--color-primary-700 |
#552E93 |
Hover/pressed of primary actions |
--color-primary-800 |
#452676 |
Headers on light surfaces |
--color-primary-900 |
#331C57 |
Deep brand, hero backgrounds |
Accent — Celebration Gold (used sparingly: milestones, featured/premium markers):
| Token | Hex |
|---|---|
--color-accent-100 |
#FBF0D9 |
--color-accent-400 |
#E3B04B |
--color-accent-500 |
#D49A2E |
--color-accent-700 |
#9C6F1C |
Neutrals (slightly warm gray so photography-heavy screens don't feel clinical):
| Token | Hex | Typical semantic use |
|---|---|---|
--color-neutral-0 |
#FFFFFF |
Surfaces |
--color-neutral-50 |
#FAF9FB |
App background |
--color-neutral-100 |
#F2F0F4 |
Cards on background, input fills |
--color-neutral-200 |
#E4E1E8 |
Dividers, borders |
--color-neutral-400 |
#A9A3B2 |
Placeholders, disabled text |
--color-neutral-600 |
#6E6879 |
Secondary text (AA on white) |
--color-neutral-800 |
#3A3542 |
Primary text alt |
--color-neutral-900 |
#231F29 |
Primary text |
Semantic status (each with a -bg tint for badges/banners):
| Token | Hex | -bg tint |
Used for |
|---|---|---|---|
--color-success-600 / --color-success-bg |
#1E8E4E |
#E6F5EC |
Confirmed, Accepted, Completed, payment success |
--color-warning-600 / --color-warning-bg |
#B4690E |
#FCF1E3 |
Pending, Negotiating, expiring soon |
--color-error-600 / --color-error-bg |
#C6303E |
#FBE9EB |
Rejected, Cancelled, failed payment, validation errors |
--color-info-600 / --color-info-bg |
#22679E |
#E7F1F9 |
Draft, informational banners, Quoted |
Semantic tokens (light / dark)¶
| Token | Light | Dark |
|---|---|---|
--color-bg-page |
neutral-50 |
#171420 |
--color-bg-surface |
neutral-0 |
#211D2B |
--color-bg-surface-raised |
neutral-0 |
#2A2537 |
--color-text-primary |
neutral-900 |
#F0EDF4 |
--color-text-secondary |
neutral-600 |
#A79FB3 |
--color-text-on-primary |
#FFFFFF |
#FFFFFF |
--color-action-primary |
primary-600 |
primary-400 (#9370D4 — AA on dark surface) |
--color-action-primary-hover |
primary-700 |
primary-300 |
--color-border |
neutral-200 |
#3B3448 |
--color-focus-ring |
primary-500 |
primary-300 |
Dark mode ships for the Customer and Vendor mobile apps at MVP (follows OS setting); web dark mode is Scale. Status colors get dark variants by raising lightness ~15% (e.g. success #3FAE6E on dark).
2. Typography¶
Families (see Arabic-First & RTL for pairing rationale):
--font-family-arabic: "IBM Plex Sans Arabic";
--font-family-latin: "IBM Plex Sans";
--font-family-display-arabic: "Noto Kufi Arabic"; /* marketing/hero only */
Type scale (rem, base 16 px). lh-ar applies when lang="ar":
| Token | Size | Weight | lh (en) | lh (ar) | Use |
|---|---|---|---|---|---|
--text-display |
2.25rem / 36px | 700 | 1.2 | 1.4 | Hero, marketing |
--text-h1 |
1.75rem / 28px | 700 | 1.25 | 1.45 | Screen titles |
--text-h2 |
1.375rem / 22px | 600 | 1.3 | 1.5 | Section headers |
--text-h3 |
1.125rem / 18px | 600 | 1.4 | 1.6 | Card titles |
--text-body-lg |
1rem / 16px | 400 | 1.5 | 1.75 | Primary body |
--text-body |
0.9375rem / 15px | 400 | 1.5 | 1.75 | Default body (15px floor protects Arabic legibility) |
--text-caption |
0.8125rem / 13px | 400 | 1.4 | 1.6 | Timestamps, helper text |
--text-overline |
0.75rem / 12px | 600 | 1.3 | 1.5 | Eyebrows (EN: +0.06em tracking; AR: tracking 0, weight only) |
Weights: --font-weight-regular: 400, --font-weight-medium: 500, --font-weight-semibold: 600, --font-weight-bold: 700. No italics token — Arabic has none; emphasis is weight/color.
3. Spacing (4pt scale)¶
| Token | Value | Typical use |
|---|---|---|
--space-1 |
4px | Icon-to-label gaps |
--space-2 |
8px | Inside chips, tight stacks |
--space-3 |
12px | Card internal padding (compact) |
--space-4 |
16px | Default screen gutter (mobile), card padding |
--space-5 |
20px | Between form fields |
--space-6 |
24px | Section spacing |
--space-8 |
32px | Between major blocks |
--space-10 |
40px | Page-level separation (web) |
--space-12 |
48px | Hero padding |
--space-16 |
64px | Marketing sections |
Rule: only these steps. Always applied via logical properties (padding-inline-*) so RTL is automatic.
4. Radii¶
| Token | Value | Use |
|---|---|---|
--radius-sm |
6px | Inputs, chips, tags |
--radius-md |
10px | Buttons, small cards |
--radius-lg |
16px | Cards, sheets, modals |
--radius-xl |
24px | Bottom sheets, hero cards |
--radius-full |
9999px | Avatars, pills, badges |
5. Elevation¶
Soft, purple-tinted shadows (never pure black) — imagery stays hero, chrome stays quiet:
| Token | Value | Use |
|---|---|---|
--elevation-0 |
none | Flat lists, admin tables |
--elevation-1 |
0 1px 3px rgba(35,28,60,.08) |
Cards at rest |
--elevation-2 |
0 4px 12px rgba(35,28,60,.10) |
Raised cards, dropdowns, sticky CTA bars |
--elevation-3 |
0 8px 24px rgba(35,28,60,.14) |
Modals, bottom sheets |
--elevation-4 |
0 16px 48px rgba(35,28,60,.18) |
Dialogs above modals (rare) |
Dark mode replaces shadows with surface-lightening (bg-surface → bg-surface-raised) plus a 20%-opacity shadow.
6. Motion¶
| Token | Value | Use |
|---|---|---|
--duration-instant |
80ms | Hover/pressed feedback |
--duration-fast |
150ms | Toggles, chips, checkbox |
--duration-base |
240ms | Sheets, dropdowns, screen transitions |
--duration-slow |
400ms | Full-screen modals, celebration entrances |
--easing-standard |
cubic-bezier(0.2, 0, 0, 1) |
Default for everything |
--easing-decelerate |
cubic-bezier(0, 0, 0, 1) |
Elements entering the screen |
--easing-accelerate |
cubic-bezier(0.3, 0, 1, 1) |
Elements leaving the screen |
Directional motion (slides, wizard step transitions) mirrors in RTL: "forward" slides leftward in Arabic. All motion collapses to opacity-only under prefers-reduced-motion. Celebration moments (payment success, booking confirmed) may use up to 800ms one-shot animation — the only exception to --duration-slow.
7. Breakpoints & layout¶
| Token | Value | Meaning |
|---|---|---|
--breakpoint-sm |
640px | Large phones landscape / small tablet |
--breakpoint-md |
768px | Tablet portrait — 2-column layouts begin |
--breakpoint-lg |
1024px | Desktop — persistent side nav (vendor/admin) |
--breakpoint-xl |
1280px | Wide desktop — max content width applies |
--layout-max-width |
1200px | Customer web content column |
--layout-max-width-admin |
1440px | Admin tables need width |
Design baseline: 360×800 (mobile-first, per Design Principles).
8. Z-index & misc¶
--z-sticky: 100 (sticky CTA bars) · --z-dropdown: 400 · --z-overlay: 800 (sheet/modal scrim) · --z-modal: 900 · --z-toast: 1000.
Touch target minimum: --size-touch-target: 48px. Focus ring: --focus-ring: 2px solid var(--color-focus-ring); outline-offset: 2px — never removed, only restyled.
Platform delivery¶
| Platform | Mechanism |
|---|---|
| Source of truth | tokens.json (W3C Design Tokens format) in the design-system repo; Figma variables synced from it |
| Web | Style Dictionary → CSS custom properties on :root / [data-theme="dark"]; Tailwind theme reads the same variables |
| Flutter | Style Dictionary → generated YamTokens ThemeExtension (light/dark) |
| Email templates | Baked-in hex at build time from the same tokens.json |
Token changes ship as versioned PRs to tokens.json reviewed by design + one dev per platform. MVP ships the light theme fully and mobile dark theme; token names are frozen at MVP even while values await branding.
Related: Design Principles · Arabic-First & RTL · Key Screens