Najjar\NajjarV02 729ab71c2c
Some checks are pending
CI/CD / test-and-build (push) Waiting to run
CI/CD / deploy (push) Blocked by required conditions
Refactor code structure for improved readability and maintainability; removed redundant code blocks and optimized function calls.
2026-05-20 18:03:42 +04:00

205 lines
6.1 KiB
Markdown

# Design System
Reusable design tokens + scales extracted from the Luxam reference build. Drop into `globals.css` (Tailwind v4 `@theme`) of any new project to start with the same DNA.
---
## Color palette
```css
@theme {
/* Backgrounds obsidian → graphite layering */
--color-obsidian: #08080A; /* page background */
--color-graphite: #15161A; /* dark glass card */
--color-graphite-2: #1C1D22; /* slightly lifted card variant */
/* Foreground */
--color-bone: #F4F0E6; /* primary text on dark */
--color-mist: #C7C2B5; /* secondary/muted text */
/* Brand gold spectrum (use sparingly + structurally) */
--color-gold: #D4A437; /* core brand gold */
--color-gold-light: #F2C25B; /* hover, highlight, gradient stops */
--color-gold-deep: #7A4A12; /* gradient base */
--color-ember: #B5731A; /* warm secondary */
/* Sustainability accent (use only where ecology theme applies) */
--color-emerald: #1F8F6B;
--color-emerald-glow: #3FD8A4;
}
```
**Usage rules**
- **Background:** `bg-obsidian` body, `bg-graphite/40 backdrop-blur-sm` cards.
- **Borders:** `border-bone/10` default, `border-gold/30` on hover, `border-gold/40` active.
- **Text:** `text-bone` titles, `text-mist` body/secondary, `text-gold-light` brand accents.
- **Never use** raw `#fff` or pure `#000`. Always `bone` or `obsidian`.
- **Gradients:** single-axis brand gradient `from-gold-light via-gold to-gold-deep`. No rainbow.
---
## Typography
```ts
// app/layout.tsx
import { Cormorant_Garamond, Geist, Geist_Mono } from "next/font/google";
const display = Cormorant_Garamond({
subsets: ["latin"],
variable: "--font-display",
weight: ["400", "500", "600"],
display: "swap",
});
const sans = Geist({ subsets: ["latin"], variable: "--font-sans", display: "swap" });
const mono = Geist_Mono({ subsets: ["latin"], variable: "--font-mono", display: "swap" });
```
**Hierarchy**
| Role | Font | Size |
|---|---|---|
| Hero H1 | `font-display` (serif) | `text-[clamp(2.6rem,7vw,6.4rem)] leading-[1.0] tracking-[-0.02em]` |
| Section H2 | `font-display` | `text-[clamp(2.4rem,5vw,4.6rem)] leading-[1.02] tracking-[-0.02em]` |
| Card H3/H4 | `font-display` | `text-2xl md:text-3xl` |
| Body | `font-sans` (inherited default) | `text-base md:text-lg leading-[1.7]` |
| UI label | `font-sans` | `text-[10px] md:text-[11px] font-medium uppercase tracking-[0.22em]` |
| Nav link | `font-sans` | `text-sm font-medium tracking-[0.005em]` |
| Stats number | `font-display` | `text-5xl md:text-6xl` (responsive smaller on mobile) |
**Avoid**
- `font-mono` on long values or body text.
- `tracking-[0.3em]+` on small labels.
- `leading-[0.95]` on serif headlines (clips ascenders).
**Helper class** for one-color brand text:
```css
.gold-text {
background: linear-gradient(90deg, #FFEFC5, #F2C25B 40%, #D4A437 80%, #7A4A12);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
```
---
## Spacing scale
Section padding lives **only** on the `Section` primitive:
```tsx
// components/ui/Section.tsx
className={cn("relative scroll-mt-24 py-16 md:scroll-mt-28 md:py-20 lg:py-24", className)}
```
- Mobile: `py-16` (64 px)
- Tablet: `md:py-20` (80 px)
- Desktop: `lg:py-24` (96 px)
- All anchored sections get `scroll-mt-24 md:scroll-mt-28` for sticky-nav clearance.
**Don't** override per-section unless there's a structural reason. Centralize.
Card padding: `p-6 md:p-7` standard, `p-7 md:p-10` for hero/feature cards.
Grid gaps: `gap-4 md:gap-5` standard, `gap-6 md:gap-8` for large cards.
---
## Border radius scale
```css
--radius-xs: 4px;
--radius-sm: 8px;
--radius-md: 14px;
--radius-lg: 22px;
--radius-xl: 32px;
```
Tailwind shortcuts to match: `rounded-2xl` (cards), `rounded-3xl` (hero panels), `rounded-full` (pills + buttons).
---
## Motion
```ts
// shared variants
const cardGrid: Variants = {
hidden: {},
visible: { transition: { staggerChildren: 0.08, delayChildren: 0.15 } },
};
const cardCell: Variants = {
hidden: { opacity: 0, y: 24, filter: "blur(6px)" },
visible: {
opacity: 1, y: 0, filter: "blur(0px)",
transition: { duration: 0.8, ease: [0.16, 1, 0.3, 1] },
},
};
```
- Entrance ease: `[0.16, 1, 0.3, 1]` (cubic-bezier "out-quart-ish").
- Duration: hero 1.3s, cards 0.8s, hover 0.3-0.5s.
- Hover lift: `-translate-y-1` max. No `-translate-y-2`+ (jumpy).
- Halo pulse: `[0.5, 0.85, 0.5]` opacity, 6s loop. Wrap in `!reduce && (...)`.
- `useReducedMotion()` must be read in any animated component.
**Forbidden**
- Bouncy springs (`stiffness > 200`) on entrance.
- Scale jumps > 1.05 on hover for cards.
- Parallax > 200 px translate range.
- Marquees without `mask-image` edge fade.
---
## Visual textures
| Class | Purpose |
|---|---|
| `noise-bg` | Subtle film-grain background overlay |
| `grain` | Animated grain (use sparingly on cards) |
| `metallic-divider` | Thin gold-tinted divider line |
| `radial-gold` | Faint amber radial wash (positioned absolute, blur-3xl) |
| `radial-emerald` | Same, emerald variant |
| `hairline-t`, `hairline-b` | 1 px top/bottom hairline borders |
| `mask-fade-y`, `mask-fade-x` | Edge fade masks |
Define these as utilities in `globals.css` per the Luxam reference.
---
## Hover state pattern
Every card/button uses the same hover vocabulary:
1. `-translate-y-1` lift (cards) or `-translate-y-0.5` (buttons).
2. Border step up: `border-bone/10 → border-gold/30 (or /35 /40)`.
3. Background step up: `bg-graphite/40 → bg-graphite/60`.
4. Amber radial glow bottom-right: `radial-gradient(circle, rgba(212,164,55,0.28), transparent 70%)` blurred.
5. Gold underline sweep (cards): `absolute bottom-0 left-0 h-px w-0 ... group-hover:w-full`.
6. Optional: top hairline gold gradient fade-in.
7. Icon disc gets `rotate-[8deg]` + amber halo shadow.
Apply via `group` + `group-hover:` Tailwind variants never per-element JS listeners.
---
## Container widths
```tsx
// components/ui/Container.tsx three variants
size="default" max-w-7xl
size="wide" max-w-[1480px]
size="narrow" max-w-3xl
```
All variants: `mx-auto px-6 md:px-10`.
---
## When in doubt
- More dark, less gold.
- More space, less content.
- Less motion, more restraint.
- Real photography > illustration.
- Editorial typography > corporate sans.