veza/veza_design_system_v3.html
2026-01-04 01:44:23 +01:00

3039 lines
102 KiB
HTML

<!DOCTYPE html>
<html lang="fr" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Veza / Talas — Design System v3 · Spectre Astral</title>
<meta name="description" content="Design System v3 complet pour Veza/Talas - 250+ composants, WCAG AAA, Dark Mode natif">
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Instrument+Serif:ital@0;1&display=swap" rel="stylesheet">
<style>
/* ═══════════════════════════════════════════════════════════════════════════
DESIGN SYSTEM v3 — VEZA / TALAS — SPECTRE ASTRAL
Production-ready · 250+ Components · WCAG AAA · 600 Features Support
═══════════════════════════════════════════════════════════════════════════ */
/* ─────────────────────────────────────────────────────────────────────────
1. DESIGN TOKENS — CORE FOUNDATION
───────────────────────────────────────────────────────────────────────── */
:root {
/* ══════════════════════════════════════════════════════════════════════
SPECTRE ASTRAL — COLOR SYSTEM
══════════════════════════════════════════════════════════════════════ */
/* Core Palette */
--nadir-black: #0B0C10;
--graphite-blue: #1F2833;
--spectral-cyan: #66FCF1;
--anodized-turquoise: #45A29E;
--lavender-astral: #8A7EA4;
--soft-ember: #E6B89C;
--quiet-paper: #F3F3E0;
--muted-grey: #C5C6C7;
/* Extended Cyan Scale (Veza Primary) */
--cyan-50: #f0fdfc;
--cyan-100: #ccfbf6;
--cyan-200: #99f6ed;
--cyan-300: #5eeadb;
--cyan-400: #66FCF1;
--cyan-500: #14c4b5;
--cyan-600: #0d9d93;
--cyan-700: #0f7e76;
--cyan-800: #116460;
--cyan-900: #13534f;
--cyan-950: #052f2e;
/* Extended Lavender Scale (Talas Primary) */
--lavender-50: #faf8fc;
--lavender-100: #f3f0f7;
--lavender-200: #e9e3f0;
--lavender-300: #d7cce4;
--lavender-400: #8A7EA4;
--lavender-500: #7a6d94;
--lavender-600: #685b7e;
--lavender-700: #574c68;
--lavender-800: #4a4158;
--lavender-900: #403949;
--lavender-950: #262030;
/* Neutral Scale */
--neutral-50: #f9fafb;
--neutral-100: #f3f4f6;
--neutral-200: #e5e7eb;
--neutral-300: #d1d5db;
--neutral-400: #9ca3af;
--neutral-500: #6b7280;
--neutral-600: #4b5563;
--neutral-700: #374151;
--neutral-800: #1f2937;
--neutral-900: #111827;
--neutral-950: #030712;
/* Semantic Colors */
--success-50: #ecfdf5;
--success-100: #d1fae5;
--success-200: #a7f3d0;
--success-300: #6ee7b7;
--success-400: #34d399;
--success-500: #10b981;
--success-600: #059669;
--success-700: #047857;
--success-800: #065f46;
--success-900: #064e3b;
--warning-50: #fffbeb;
--warning-100: #fef3c7;
--warning-200: #fde68a;
--warning-300: #fcd34d;
--warning-400: #fbbf24;
--warning-500: #f59e0b;
--warning-600: #d97706;
--warning-700: #b45309;
--warning-800: #92400e;
--warning-900: #78350f;
--error-50: #fef2f2;
--error-100: #fee2e2;
--error-200: #fecaca;
--error-300: #fca5a5;
--error-400: #f87171;
--error-500: #ef4444;
--error-600: #dc2626;
--error-700: #b91c1c;
--error-800: #991b1b;
--error-900: #7f1d1d;
--info-50: #eff6ff;
--info-100: #dbeafe;
--info-200: #bfdbfe;
--info-300: #93c5fd;
--info-400: #60a5fa;
--info-500: #3b82f6;
--info-600: #2563eb;
--info-700: #1d4ed8;
--info-800: #1e40af;
--info-900: #1e3a8a;
/* ══════════════════════════════════════════════════════════════════════
TYPOGRAPHY SYSTEM
══════════════════════════════════════════════════════════════════════ */
--font-display: 'Space Grotesk', system-ui, -apple-system, sans-serif;
--font-body: 'Space Grotesk', system-ui, -apple-system, sans-serif;
--font-mono: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
--font-serif: 'Instrument Serif', Georgia, serif;
/* Font Sizes (Modular Scale 1.25) */
--text-xs: 0.75rem; /* 12px */
--text-sm: 0.875rem; /* 14px */
--text-base: 1rem; /* 16px */
--text-lg: 1.125rem; /* 18px */
--text-xl: 1.25rem; /* 20px */
--text-2xl: 1.5rem; /* 24px */
--text-3xl: 1.875rem; /* 30px */
--text-4xl: 2.25rem; /* 36px */
--text-5xl: 3rem; /* 48px */
--text-6xl: 3.75rem; /* 60px */
--text-7xl: 4.5rem; /* 72px */
--text-8xl: 6rem; /* 96px */
/* Font Weights */
--font-regular: 400;
--font-medium: 500;
--font-semibold: 600;
--font-bold: 700;
/* Line Heights */
--leading-none: 1;
--leading-tight: 1.15;
--leading-snug: 1.375;
--leading-normal: 1.5;
--leading-relaxed: 1.625;
--leading-loose: 2;
/* Letter Spacing */
--tracking-tighter: -0.05em;
--tracking-tight: -0.025em;
--tracking-normal: 0;
--tracking-wide: 0.025em;
--tracking-wider: 0.05em;
--tracking-widest: 0.1em;
--tracking-caps: 0.15em;
/* ══════════════════════════════════════════════════════════════════════
SPACING SYSTEM (4px Base)
══════════════════════════════════════════════════════════════════════ */
--space-0: 0;
--space-px: 1px;
--space-0-5: 0.125rem; /* 2px */
--space-1: 0.25rem; /* 4px */
--space-1-5: 0.375rem; /* 6px */
--space-2: 0.5rem; /* 8px */
--space-2-5: 0.625rem; /* 10px */
--space-3: 0.75rem; /* 12px */
--space-3-5: 0.875rem; /* 14px */
--space-4: 1rem; /* 16px */
--space-5: 1.25rem; /* 20px */
--space-6: 1.5rem; /* 24px */
--space-7: 1.75rem; /* 28px */
--space-8: 2rem; /* 32px */
--space-9: 2.25rem; /* 36px */
--space-10: 2.5rem; /* 40px */
--space-11: 2.75rem; /* 44px */
--space-12: 3rem; /* 48px */
--space-14: 3.5rem; /* 56px */
--space-16: 4rem; /* 64px */
--space-20: 5rem; /* 80px */
--space-24: 6rem; /* 96px */
--space-28: 7rem; /* 112px */
--space-32: 8rem; /* 128px */
--space-36: 9rem; /* 144px */
--space-40: 10rem; /* 160px */
--space-48: 12rem; /* 192px */
--space-56: 14rem; /* 224px */
--space-64: 16rem; /* 256px */
/* ══════════════════════════════════════════════════════════════════════
LAYOUT & CONTAINERS
══════════════════════════════════════════════════════════════════════ */
--container-xs: 20rem; /* 320px */
--container-sm: 24rem; /* 384px */
--container-md: 28rem; /* 448px */
--container-lg: 32rem; /* 512px */
--container-xl: 36rem; /* 576px */
--container-2xl: 42rem; /* 672px */
--container-3xl: 48rem; /* 768px */
--container-4xl: 56rem; /* 896px */
--container-5xl: 64rem; /* 1024px */
--container-6xl: 72rem; /* 1152px */
--container-7xl: 80rem; /* 1280px */
--container-max: 90rem; /* 1440px */
/* ══════════════════════════════════════════════════════════════════════
SHADOWS
══════════════════════════════════════════════════════════════════════ */
--shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
--shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25);
--shadow-inner: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
/* Colored Shadows (Glow Effects) */
--glow-cyan: 0 0 20px rgba(102, 252, 241, 0.4), 0 0 40px rgba(102, 252, 241, 0.2);
--glow-lavender: 0 0 20px rgba(138, 126, 164, 0.4), 0 0 40px rgba(138, 126, 164, 0.2);
--glow-ember: 0 0 20px rgba(230, 184, 156, 0.4), 0 0 40px rgba(230, 184, 156, 0.2);
--glow-success: 0 0 20px rgba(16, 185, 129, 0.4);
--glow-error: 0 0 20px rgba(239, 68, 68, 0.4);
/* ══════════════════════════════════════════════════════════════════════
BORDER RADIUS
══════════════════════════════════════════════════════════════════════ */
--radius-none: 0;
--radius-xs: 0.125rem; /* 2px */
--radius-sm: 0.25rem; /* 4px */
--radius-md: 0.375rem; /* 6px */
--radius-lg: 0.5rem; /* 8px */
--radius-xl: 0.75rem; /* 12px */
--radius-2xl: 1rem; /* 16px */
--radius-3xl: 1.5rem; /* 24px */
--radius-full: 9999px;
/* ══════════════════════════════════════════════════════════════════════
ANIMATIONS & TRANSITIONS
══════════════════════════════════════════════════════════════════════ */
/* Durations */
--duration-instant: 50ms;
--duration-fast: 150ms;
--duration-base: 200ms;
--duration-moderate: 300ms;
--duration-slow: 500ms;
--duration-slower: 700ms;
--duration-slowest: 1000ms;
/* Easing Functions */
--ease-linear: linear;
--ease-in: cubic-bezier(0.4, 0, 1, 1);
--ease-out: cubic-bezier(0, 0, 0.2, 1);
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
--ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
--ease-elastic: cubic-bezier(0.68, -0.6, 0.32, 1.6);
--ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
/* ══════════════════════════════════════════════════════════════════════
Z-INDEX SCALE
══════════════════════════════════════════════════════════════════════ */
--z-base: 0;
--z-raised: 10;
--z-dropdown: 100;
--z-sticky: 200;
--z-fixed: 300;
--z-modal-backdrop: 400;
--z-modal: 500;
--z-popover: 600;
--z-tooltip: 700;
--z-toast: 800;
--z-max: 9999;
}
/* ─────────────────────────────────────────────────────────────────────────
2. DARK MODE THEME (Default)
───────────────────────────────────────────────────────────────────────── */
[data-theme="dark"] {
--bg-primary: var(--nadir-black);
--bg-secondary: var(--graphite-blue);
--bg-tertiary: #242732;
--bg-elevated: #1C1D21;
--bg-surface: #15161a;
--bg-overlay: rgba(11, 12, 16, 0.85);
--text-primary: var(--quiet-paper);
--text-secondary: var(--muted-grey);
--text-tertiary: #80889a;
--text-muted: #5a6173;
--text-inverse: var(--nadir-black);
--border-primary: rgba(255, 255, 255, 0.08);
--border-secondary: rgba(255, 255, 255, 0.04);
--border-focus: var(--spectral-cyan);
--accent-primary: var(--spectral-cyan);
--accent-secondary: var(--lavender-astral);
--accent-tertiary: var(--soft-ember);
color-scheme: dark;
}
/* ─────────────────────────────────────────────────────────────────────────
3. LIGHT MODE THEME
───────────────────────────────────────────────────────────────────────── */
[data-theme="light"] {
--bg-primary: #fafafa;
--bg-secondary: #ffffff;
--bg-tertiary: #f5f5f5;
--bg-elevated: #ffffff;
--bg-surface: #f0f0f0;
--bg-overlay: rgba(250, 250, 250, 0.9);
--text-primary: var(--neutral-900);
--text-secondary: var(--neutral-600);
--text-tertiary: var(--neutral-500);
--text-muted: var(--neutral-400);
--text-inverse: var(--quiet-paper);
--border-primary: var(--neutral-200);
--border-secondary: var(--neutral-100);
--border-focus: var(--cyan-600);
--accent-primary: var(--cyan-600);
--accent-secondary: var(--lavender-600);
--accent-tertiary: var(--warning-600);
color-scheme: light;
}
/* ─────────────────────────────────────────────────────────────────────────
4. CSS RESET & BASE STYLES
───────────────────────────────────────────────────────────────────────── */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
font-size: 16px;
scroll-behavior: smooth;
-webkit-text-size-adjust: 100%;
text-size-adjust: 100%;
}
body {
font-family: var(--font-body);
font-size: var(--text-base);
font-weight: var(--font-regular);
line-height: var(--leading-normal);
color: var(--text-primary);
background: var(--bg-primary);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
min-height: 100vh;
}
/* Focus Visible for Accessibility */
:focus-visible {
outline: 2px solid var(--border-focus);
outline-offset: 2px;
}
:focus:not(:focus-visible) {
outline: none;
}
/* Selection */
::selection {
background: var(--accent-primary);
color: var(--text-inverse);
}
/* Links */
a {
color: inherit;
text-decoration: none;
transition: color var(--duration-fast) var(--ease-out);
}
/* Images */
img, svg, video {
max-width: 100%;
height: auto;
display: block;
}
/* Lists */
ul, ol {
list-style: none;
}
/* Buttons */
button {
font: inherit;
color: inherit;
background: none;
border: none;
cursor: pointer;
}
/* Screen Reader Only */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* ─────────────────────────────────────────────────────────────────────────
5. LAYOUT COMPONENTS
───────────────────────────────────────────────────────────────────────── */
.page {
display: flex;
flex-direction: column;
min-height: 100vh;
background:
radial-gradient(ellipse 80% 50% at 50% -20%, rgba(102, 252, 241, 0.08), transparent),
radial-gradient(ellipse 60% 40% at 100% 100%, rgba(138, 126, 164, 0.06), transparent),
var(--bg-primary);
}
.container {
width: 100%;
max-width: var(--container-max);
margin: 0 auto;
padding: 0 var(--space-6);
}
.container--narrow {
max-width: var(--container-4xl);
}
.container--wide {
max-width: 100rem;
}
/* ─────────────────────────────────────────────────────────────────────────
6. HEADER & NAVIGATION
───────────────────────────────────────────────────────────────────────── */
.header {
position: sticky;
top: 0;
z-index: var(--z-sticky);
backdrop-filter: blur(16px) saturate(180%);
-webkit-backdrop-filter: blur(16px) saturate(180%);
background: linear-gradient(
to bottom,
rgba(11, 12, 16, 0.95),
rgba(11, 12, 16, 0.85),
transparent
);
padding: var(--space-4) 0;
}
.header__inner {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-8);
}
.brand {
display: flex;
align-items: center;
gap: var(--space-3);
}
.brand__mark {
width: 36px;
height: 36px;
border-radius: var(--radius-full);
background:
radial-gradient(circle at 30% 20%, rgba(102, 252, 241, 0.85), transparent 55%),
radial-gradient(circle at 70% 70%, rgba(138, 126, 164, 0.8), transparent 55%),
radial-gradient(circle at 50% 50%, rgba(69, 162, 158, 0.75), transparent 65%);
box-shadow: var(--glow-cyan);
position: relative;
animation: pulse-glow 4s ease-in-out infinite;
}
@keyframes pulse-glow {
0%, 100% { box-shadow: var(--glow-cyan); }
50% { box-shadow: 0 0 30px rgba(102, 252, 241, 0.6), 0 0 60px rgba(102, 252, 241, 0.3); }
}
.brand__mark::after {
content: "";
position: absolute;
inset: 32%;
border-radius: var(--radius-full);
border: 2px solid rgba(11, 12, 16, 0.9);
backdrop-filter: blur(2px);
}
.brand__text {
display: flex;
flex-direction: column;
}
.brand__name {
font-family: var(--font-display);
font-weight: var(--font-bold);
font-size: var(--text-base);
letter-spacing: var(--tracking-wide);
text-transform: uppercase;
}
.brand__tagline {
font-size: var(--text-xs);
letter-spacing: var(--tracking-caps);
text-transform: uppercase;
color: var(--text-tertiary);
}
.nav {
display: flex;
align-items: center;
gap: var(--space-8);
}
.nav__list {
display: flex;
align-items: center;
gap: var(--space-6);
}
.nav__link {
font-size: var(--text-sm);
font-weight: var(--font-medium);
letter-spacing: var(--tracking-wide);
text-transform: uppercase;
color: var(--text-secondary);
position: relative;
padding-bottom: var(--space-1);
transition: color var(--duration-fast) var(--ease-out);
}
.nav__link::after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 0;
height: 1px;
background: linear-gradient(90deg, var(--spectral-cyan), var(--lavender-astral));
transition: width var(--duration-base) var(--ease-out);
}
.nav__link:hover {
color: var(--text-primary);
}
.nav__link:hover::after,
.nav__link--active::after {
width: 100%;
}
.nav__link--active {
color: var(--accent-primary);
}
/* ─────────────────────────────────────────────────────────────────────────
7. BUTTONS
───────────────────────────────────────────────────────────────────────── */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--space-2);
font-family: var(--font-body);
font-weight: var(--font-medium);
text-transform: uppercase;
letter-spacing: var(--tracking-wide);
border-radius: var(--radius-lg);
cursor: pointer;
transition:
transform var(--duration-fast) var(--ease-out),
box-shadow var(--duration-fast) var(--ease-out),
background var(--duration-fast) var(--ease-out),
color var(--duration-fast) var(--ease-out),
border-color var(--duration-fast) var(--ease-out);
position: relative;
overflow: hidden;
white-space: nowrap;
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
pointer-events: none;
}
/* Button Sizes */
.btn--xs {
font-size: var(--text-xs);
padding: var(--space-1-5) var(--space-3);
border-radius: var(--radius-md);
}
.btn--sm {
font-size: var(--text-sm);
padding: var(--space-2) var(--space-4);
}
.btn--md {
font-size: var(--text-sm);
padding: var(--space-3) var(--space-6);
}
.btn--lg {
font-size: var(--text-base);
padding: var(--space-4) var(--space-8);
}
.btn--xl {
font-size: var(--text-lg);
padding: var(--space-5) var(--space-10);
}
/* Button Variants */
.btn--primary {
background: linear-gradient(135deg, var(--anodized-turquoise), var(--spectral-cyan));
color: var(--nadir-black);
border: none;
box-shadow: var(--shadow-lg), 0 0 0 0 rgba(102, 252, 241, 0);
}
.btn--primary:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-xl), var(--glow-cyan);
}
.btn--primary:active {
transform: translateY(0);
}
.btn--secondary {
background: transparent;
color: var(--text-primary);
border: 1px solid var(--border-primary);
}
.btn--secondary:hover {
border-color: var(--lavender-astral);
color: var(--lavender-astral);
background: rgba(138, 126, 164, 0.1);
}
.btn--ghost {
background: transparent;
color: var(--text-secondary);
border: none;
}
.btn--ghost:hover {
color: var(--text-primary);
background: rgba(255, 255, 255, 0.05);
}
.btn--danger {
background: var(--error-600);
color: white;
border: none;
}
.btn--danger:hover {
background: var(--error-500);
box-shadow: var(--glow-error);
}
.btn--veza {
background: linear-gradient(135deg, var(--anodized-turquoise), var(--spectral-cyan));
color: var(--nadir-black);
}
.btn--talas {
background: linear-gradient(135deg, var(--lavender-astral), var(--soft-ember));
color: var(--nadir-black);
}
/* Button with Icon */
.btn__icon {
display: flex;
align-items: center;
justify-content: center;
width: 1.25em;
height: 1.25em;
}
/* Icon Only Button */
.btn--icon {
padding: var(--space-3);
border-radius: var(--radius-full);
}
/* Loading State */
.btn--loading {
color: transparent !important;
pointer-events: none;
}
.btn--loading::after {
content: "";
position: absolute;
width: 1.25em;
height: 1.25em;
border: 2px solid transparent;
border-top-color: currentColor;
border-radius: var(--radius-full);
animation: spin 0.6s linear infinite;
}
.btn--primary.btn--loading::after {
border-top-color: var(--nadir-black);
}
@keyframes spin {
to { transform: rotate(360deg); }
}
/* ─────────────────────────────────────────────────────────────────────────
8. INPUTS & FORMS
───────────────────────────────────────────────────────────────────────── */
.form-group {
display: flex;
flex-direction: column;
gap: var(--space-2);
}
.label {
font-size: var(--text-sm);
font-weight: var(--font-medium);
color: var(--text-secondary);
letter-spacing: var(--tracking-wide);
}
.label--required::after {
content: " *";
color: var(--error-500);
}
.input {
font-family: var(--font-body);
font-size: var(--text-base);
padding: var(--space-3) var(--space-4);
background: var(--bg-elevated);
border: 1px solid var(--border-primary);
border-radius: var(--radius-lg);
color: var(--text-primary);
transition:
border-color var(--duration-fast) var(--ease-out),
box-shadow var(--duration-fast) var(--ease-out),
background var(--duration-fast) var(--ease-out);
}
.input::placeholder {
color: var(--text-muted);
}
.input:hover {
border-color: var(--text-tertiary);
}
.input:focus {
outline: none;
border-color: var(--accent-primary);
box-shadow: 0 0 0 3px rgba(102, 252, 241, 0.15);
}
.input--error {
border-color: var(--error-500);
}
.input--error:focus {
box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.15);
}
.input--success {
border-color: var(--success-500);
}
.input--lg {
font-size: var(--text-lg);
padding: var(--space-4) var(--space-5);
}
.input--sm {
font-size: var(--text-sm);
padding: var(--space-2) var(--space-3);
}
.input-hint {
font-size: var(--text-sm);
color: var(--text-tertiary);
}
.input-error {
font-size: var(--text-sm);
color: var(--error-500);
display: flex;
align-items: center;
gap: var(--space-1);
}
/* Textarea */
.textarea {
min-height: 120px;
resize: vertical;
}
/* Select */
.select {
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23C5C6C7' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right var(--space-4) center;
padding-right: var(--space-12);
}
/* Checkbox & Radio */
.checkbox,
.radio {
display: flex;
align-items: center;
gap: var(--space-3);
cursor: pointer;
}
.checkbox__input,
.radio__input {
width: 20px;
height: 20px;
appearance: none;
background: var(--bg-elevated);
border: 2px solid var(--border-primary);
cursor: pointer;
transition: all var(--duration-fast) var(--ease-out);
}
.checkbox__input {
border-radius: var(--radius-sm);
}
.radio__input {
border-radius: var(--radius-full);
}
.checkbox__input:checked,
.radio__input:checked {
background: var(--accent-primary);
border-color: var(--accent-primary);
}
.checkbox__input:checked::after {
content: "✓";
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
color: var(--nadir-black);
font-weight: bold;
}
.radio__input:checked::after {
content: "";
display: block;
width: 8px;
height: 8px;
margin: 4px;
background: var(--nadir-black);
border-radius: var(--radius-full);
}
/* Toggle Switch */
.toggle {
display: flex;
align-items: center;
gap: var(--space-3);
cursor: pointer;
}
.toggle__track {
width: 48px;
height: 26px;
background: var(--bg-tertiary);
border-radius: var(--radius-full);
position: relative;
transition: background var(--duration-fast) var(--ease-out);
}
.toggle__thumb {
position: absolute;
top: 3px;
left: 3px;
width: 20px;
height: 20px;
background: var(--muted-grey);
border-radius: var(--radius-full);
transition: transform var(--duration-fast) var(--ease-spring);
}
.toggle__input:checked + .toggle__track {
background: var(--accent-primary);
}
.toggle__input:checked + .toggle__track .toggle__thumb {
transform: translateX(22px);
background: var(--nadir-black);
}
.toggle__input {
position: absolute;
opacity: 0;
pointer-events: none;
}
/* ─────────────────────────────────────────────────────────────────────────
9. CARDS
───────────────────────────────────────────────────────────────────────── */
.card {
background: var(--bg-elevated);
border: 1px solid var(--border-primary);
border-radius: var(--radius-2xl);
overflow: hidden;
transition:
transform var(--duration-base) var(--ease-out),
box-shadow var(--duration-base) var(--ease-out),
border-color var(--duration-base) var(--ease-out);
}
.card:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-xl);
border-color: var(--border-focus);
}
.card--veza {
background:
radial-gradient(circle at 0 0, rgba(102, 252, 241, 0.1), transparent 50%),
var(--bg-elevated);
border-color: rgba(102, 252, 241, 0.2);
}
.card--veza:hover {
box-shadow: var(--shadow-xl), var(--glow-cyan);
}
.card--talas {
background:
radial-gradient(circle at 100% 100%, rgba(138, 126, 164, 0.1), transparent 50%),
var(--bg-elevated);
border-color: rgba(138, 126, 164, 0.2);
}
.card--talas:hover {
box-shadow: var(--shadow-xl), var(--glow-lavender);
}
.card__header {
padding: var(--space-5) var(--space-6);
border-bottom: 1px solid var(--border-secondary);
}
.card__body {
padding: var(--space-6);
}
.card__footer {
padding: var(--space-4) var(--space-6);
border-top: 1px solid var(--border-secondary);
background: var(--bg-surface);
}
.card__image {
width: 100%;
aspect-ratio: 16/9;
object-fit: cover;
}
.card__title {
font-size: var(--text-lg);
font-weight: var(--font-semibold);
margin-bottom: var(--space-2);
}
.card__description {
font-size: var(--text-sm);
color: var(--text-secondary);
line-height: var(--leading-relaxed);
}
/* ─────────────────────────────────────────────────────────────────────────
10. BADGES & CHIPS
───────────────────────────────────────────────────────────────────────── */
.badge {
display: inline-flex;
align-items: center;
gap: var(--space-1);
font-size: var(--text-xs);
font-weight: var(--font-medium);
letter-spacing: var(--tracking-wide);
text-transform: uppercase;
padding: var(--space-1) var(--space-2);
border-radius: var(--radius-full);
}
.badge--default {
background: var(--bg-tertiary);
color: var(--text-secondary);
}
.badge--primary {
background: rgba(102, 252, 241, 0.15);
color: var(--spectral-cyan);
border: 1px solid rgba(102, 252, 241, 0.3);
}
.badge--secondary {
background: rgba(138, 126, 164, 0.15);
color: var(--lavender-astral);
border: 1px solid rgba(138, 126, 164, 0.3);
}
.badge--success {
background: rgba(16, 185, 129, 0.15);
color: var(--success-400);
border: 1px solid rgba(16, 185, 129, 0.3);
}
.badge--warning {
background: rgba(245, 158, 11, 0.15);
color: var(--warning-400);
border: 1px solid rgba(245, 158, 11, 0.3);
}
.badge--error {
background: rgba(239, 68, 68, 0.15);
color: var(--error-400);
border: 1px solid rgba(239, 68, 68, 0.3);
}
.badge--veza {
background: linear-gradient(135deg, rgba(69, 162, 158, 0.2), rgba(102, 252, 241, 0.2));
color: var(--spectral-cyan);
border: 1px solid rgba(102, 252, 241, 0.4);
}
.badge--talas {
background: linear-gradient(135deg, rgba(138, 126, 164, 0.2), rgba(230, 184, 156, 0.2));
color: var(--lavender-astral);
border: 1px solid rgba(138, 126, 164, 0.4);
}
/* Chip (larger, with icon support) */
.chip {
display: inline-flex;
align-items: center;
gap: var(--space-2);
font-size: var(--text-sm);
font-weight: var(--font-medium);
padding: var(--space-2) var(--space-4);
border-radius: var(--radius-full);
background: var(--bg-tertiary);
color: var(--text-primary);
border: 1px solid var(--border-primary);
cursor: pointer;
transition: all var(--duration-fast) var(--ease-out);
}
.chip:hover {
background: var(--bg-secondary);
border-color: var(--accent-primary);
}
.chip--active {
background: var(--accent-primary);
color: var(--nadir-black);
border-color: var(--accent-primary);
}
.chip__remove {
width: 16px;
height: 16px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-full);
background: rgba(0, 0, 0, 0.2);
font-size: 12px;
}
/* ─────────────────────────────────────────────────────────────────────────
11. AVATAR
───────────────────────────────────────────────────────────────────────── */
.avatar {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-full);
background: linear-gradient(135deg, var(--lavender-astral), var(--soft-ember));
color: var(--nadir-black);
font-weight: var(--font-semibold);
overflow: hidden;
flex-shrink: 0;
}
.avatar--xs { width: 24px; height: 24px; font-size: var(--text-xs); }
.avatar--sm { width: 32px; height: 32px; font-size: var(--text-sm); }
.avatar--md { width: 40px; height: 40px; font-size: var(--text-base); }
.avatar--lg { width: 48px; height: 48px; font-size: var(--text-lg); }
.avatar--xl { width: 64px; height: 64px; font-size: var(--text-xl); }
.avatar--2xl { width: 96px; height: 96px; font-size: var(--text-3xl); }
.avatar__image {
width: 100%;
height: 100%;
object-fit: cover;
}
.avatar__status {
position: absolute;
bottom: 0;
right: 0;
width: 25%;
height: 25%;
min-width: 8px;
min-height: 8px;
border-radius: var(--radius-full);
border: 2px solid var(--bg-elevated);
}
.avatar__status--online { background: var(--success-500); }
.avatar__status--away { background: var(--warning-500); }
.avatar__status--offline { background: var(--neutral-500); }
.avatar__status--busy { background: var(--error-500); }
/* Avatar Group */
.avatar-group {
display: flex;
flex-direction: row-reverse;
}
.avatar-group .avatar {
margin-left: -8px;
border: 2px solid var(--bg-elevated);
}
.avatar-group .avatar:last-child {
margin-left: 0;
}
/* ─────────────────────────────────────────────────────────────────────────
12. AUDIO PLAYER COMPONENTS
───────────────────────────────────────────────────────────────────────── */
.audio-player {
background: var(--bg-elevated);
border: 1px solid var(--border-primary);
border-radius: var(--radius-2xl);
padding: var(--space-5);
display: flex;
flex-direction: column;
gap: var(--space-4);
}
.audio-player--mini {
flex-direction: row;
align-items: center;
padding: var(--space-3) var(--space-4);
border-radius: var(--radius-xl);
}
.audio-player__header {
display: flex;
align-items: center;
gap: var(--space-4);
}
.audio-player__artwork {
width: 64px;
height: 64px;
border-radius: var(--radius-lg);
object-fit: cover;
background: var(--bg-tertiary);
}
.audio-player__info {
flex: 1;
min-width: 0;
}
.audio-player__title {
font-size: var(--text-base);
font-weight: var(--font-semibold);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.audio-player__artist {
font-size: var(--text-sm);
color: var(--text-secondary);
}
.audio-player__controls {
display: flex;
align-items: center;
justify-content: center;
gap: var(--space-4);
}
.audio-player__btn {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-full);
background: transparent;
color: var(--text-secondary);
transition: all var(--duration-fast) var(--ease-out);
}
.audio-player__btn:hover {
color: var(--text-primary);
background: var(--bg-tertiary);
}
.audio-player__btn--play {
width: 56px;
height: 56px;
background: var(--accent-primary);
color: var(--nadir-black);
}
.audio-player__btn--play:hover {
transform: scale(1.05);
box-shadow: var(--glow-cyan);
}
/* Waveform */
.waveform {
display: flex;
align-items: flex-end;
gap: 2px;
height: 48px;
width: 100%;
}
.waveform__bar {
flex: 1;
background: linear-gradient(to top, var(--spectral-cyan), rgba(102, 252, 241, 0.3));
border-radius: var(--radius-full);
min-width: 3px;
transition: height var(--duration-fast) var(--ease-out);
}
.waveform__bar--played {
background: var(--spectral-cyan);
}
.waveform__bar--current {
background: var(--quiet-paper);
box-shadow: var(--glow-cyan);
}
/* Progress Bar */
.progress {
position: relative;
height: 4px;
background: var(--bg-tertiary);
border-radius: var(--radius-full);
overflow: hidden;
cursor: pointer;
}
.progress__fill {
height: 100%;
background: linear-gradient(90deg, var(--anodized-turquoise), var(--spectral-cyan));
border-radius: var(--radius-full);
transition: width var(--duration-fast) var(--ease-out);
}
.progress__handle {
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
width: 12px;
height: 12px;
background: var(--spectral-cyan);
border-radius: var(--radius-full);
box-shadow: var(--shadow-md);
opacity: 0;
transition: opacity var(--duration-fast) var(--ease-out);
}
.progress:hover .progress__handle {
opacity: 1;
}
.progress--lg {
height: 8px;
}
.progress--lg .progress__handle {
width: 16px;
height: 16px;
}
/* Volume Control */
.volume {
display: flex;
align-items: center;
gap: var(--space-2);
}
.volume__slider {
width: 80px;
}
/* Time Display */
.time-display {
display: flex;
align-items: center;
justify-content: space-between;
font-size: var(--text-xs);
font-family: var(--font-mono);
color: var(--text-tertiary);
}
/* ─────────────────────────────────────────────────────────────────────────
13. CHAT COMPONENTS
───────────────────────────────────────────────────────────────────────── */
.chat-window {
display: flex;
flex-direction: column;
height: 100%;
background: var(--bg-elevated);
border: 1px solid var(--border-primary);
border-radius: var(--radius-2xl);
overflow: hidden;
}
.chat-window__header {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--space-4) var(--space-5);
border-bottom: 1px solid var(--border-primary);
background: var(--bg-tertiary);
}
.chat-window__messages {
flex: 1;
overflow-y: auto;
padding: var(--space-4);
display: flex;
flex-direction: column;
gap: var(--space-3);
}
.chat-window__input {
display: flex;
align-items: flex-end;
gap: var(--space-3);
padding: var(--space-4);
border-top: 1px solid var(--border-primary);
background: var(--bg-surface);
}
/* Message Bubble */
.message {
max-width: 75%;
display: flex;
flex-direction: column;
gap: var(--space-1);
}
.message--sent {
align-self: flex-end;
}
.message--received {
align-self: flex-start;
}
.message__bubble {
padding: var(--space-3) var(--space-4);
border-radius: var(--radius-2xl);
font-size: var(--text-sm);
line-height: var(--leading-relaxed);
}
.message--sent .message__bubble {
background: linear-gradient(135deg, var(--anodized-turquoise), var(--spectral-cyan));
color: var(--nadir-black);
border-bottom-right-radius: var(--radius-sm);
}
.message--received .message__bubble {
background: var(--bg-tertiary);
color: var(--text-primary);
border-bottom-left-radius: var(--radius-sm);
}
.message__meta {
display: flex;
align-items: center;
gap: var(--space-2);
font-size: var(--text-xs);
color: var(--text-muted);
}
.message--sent .message__meta {
justify-content: flex-end;
}
/* Typing Indicator */
.typing-indicator {
display: flex;
align-items: center;
gap: var(--space-1);
padding: var(--space-3) var(--space-4);
background: var(--bg-tertiary);
border-radius: var(--radius-2xl);
border-bottom-left-radius: var(--radius-sm);
width: fit-content;
}
.typing-indicator__dot {
width: 6px;
height: 6px;
background: var(--text-muted);
border-radius: var(--radius-full);
animation: typing-bounce 1.4s infinite ease-in-out;
}
.typing-indicator__dot:nth-child(1) { animation-delay: 0s; }
.typing-indicator__dot:nth-child(2) { animation-delay: 0.2s; }
.typing-indicator__dot:nth-child(3) { animation-delay: 0.4s; }
@keyframes typing-bounce {
0%, 60%, 100% { transform: translateY(0); }
30% { transform: translateY(-4px); }
}
/* Online Status */
.online-status {
display: flex;
align-items: center;
gap: var(--space-2);
font-size: var(--text-sm);
color: var(--text-secondary);
}
.online-status__dot {
width: 8px;
height: 8px;
border-radius: var(--radius-full);
}
.online-status--online .online-status__dot {
background: var(--success-500);
box-shadow: 0 0 8px var(--success-500);
}
.online-status--away .online-status__dot {
background: var(--warning-500);
}
.online-status--offline .online-status__dot {
background: var(--neutral-500);
}
/* ─────────────────────────────────────────────────────────────────────────
14. MODALS & DIALOGS
───────────────────────────────────────────────────────────────────────── */
.modal-backdrop {
position: fixed;
inset: 0;
background: rgba(11, 12, 16, 0.85);
backdrop-filter: blur(8px);
z-index: var(--z-modal-backdrop);
display: flex;
align-items: center;
justify-content: center;
padding: var(--space-6);
animation: fadeIn var(--duration-base) var(--ease-out);
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.modal {
background: var(--bg-elevated);
border: 1px solid var(--border-primary);
border-radius: var(--radius-2xl);
box-shadow: var(--shadow-2xl);
max-height: 90vh;
overflow: hidden;
display: flex;
flex-direction: column;
animation: slideUp var(--duration-moderate) var(--ease-spring);
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(20px) scale(0.98);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
.modal--sm { width: 100%; max-width: 24rem; }
.modal--md { width: 100%; max-width: 32rem; }
.modal--lg { width: 100%; max-width: 48rem; }
.modal--xl { width: 100%; max-width: 64rem; }
.modal--full { width: 100%; max-width: calc(100vw - 4rem); }
.modal__header {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--space-5) var(--space-6);
border-bottom: 1px solid var(--border-primary);
}
.modal__title {
font-size: var(--text-xl);
font-weight: var(--font-semibold);
}
.modal__close {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-full);
color: var(--text-secondary);
transition: all var(--duration-fast) var(--ease-out);
}
.modal__close:hover {
background: var(--bg-tertiary);
color: var(--text-primary);
}
.modal__body {
padding: var(--space-6);
overflow-y: auto;
}
.modal__footer {
display: flex;
align-items: center;
justify-content: flex-end;
gap: var(--space-3);
padding: var(--space-4) var(--space-6);
border-top: 1px solid var(--border-primary);
background: var(--bg-surface);
}
/* ─────────────────────────────────────────────────────────────────────────
15. TOAST NOTIFICATIONS
───────────────────────────────────────────────────────────────────────── */
.toast-container {
position: fixed;
bottom: var(--space-6);
right: var(--space-6);
z-index: var(--z-toast);
display: flex;
flex-direction: column;
gap: var(--space-3);
pointer-events: none;
}
.toast {
display: flex;
align-items: flex-start;
gap: var(--space-3);
padding: var(--space-4) var(--space-5);
background: var(--bg-elevated);
border: 1px solid var(--border-primary);
border-radius: var(--radius-xl);
box-shadow: var(--shadow-xl);
max-width: 400px;
pointer-events: auto;
animation: slideInRight var(--duration-moderate) var(--ease-spring);
}
@keyframes slideInRight {
from {
opacity: 0;
transform: translateX(100%);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.toast__icon {
width: 20px;
height: 20px;
flex-shrink: 0;
}
.toast--success { border-left: 3px solid var(--success-500); }
.toast--success .toast__icon { color: var(--success-500); }
.toast--error { border-left: 3px solid var(--error-500); }
.toast--error .toast__icon { color: var(--error-500); }
.toast--warning { border-left: 3px solid var(--warning-500); }
.toast--warning .toast__icon { color: var(--warning-500); }
.toast--info { border-left: 3px solid var(--info-500); }
.toast--info .toast__icon { color: var(--info-500); }
.toast__content {
flex: 1;
min-width: 0;
}
.toast__title {
font-size: var(--text-sm);
font-weight: var(--font-semibold);
margin-bottom: var(--space-1);
}
.toast__message {
font-size: var(--text-sm);
color: var(--text-secondary);
}
.toast__close {
width: 20px;
height: 20px;
color: var(--text-muted);
flex-shrink: 0;
}
.toast__close:hover {
color: var(--text-primary);
}
/* ─────────────────────────────────────────────────────────────────────────
16. TABLES
───────────────────────────────────────────────────────────────────────── */
.table-wrapper {
overflow-x: auto;
border: 1px solid var(--border-primary);
border-radius: var(--radius-xl);
}
.table {
width: 100%;
border-collapse: collapse;
font-size: var(--text-sm);
}
.table th,
.table td {
padding: var(--space-4);
text-align: left;
border-bottom: 1px solid var(--border-secondary);
}
.table th {
font-weight: var(--font-semibold);
text-transform: uppercase;
letter-spacing: var(--tracking-wide);
font-size: var(--text-xs);
color: var(--text-secondary);
background: var(--bg-surface);
}
.table tbody tr {
transition: background var(--duration-fast) var(--ease-out);
}
.table tbody tr:hover {
background: var(--bg-tertiary);
}
.table tbody tr:last-child td {
border-bottom: none;
}
/* ─────────────────────────────────────────────────────────────────────────
17. TABS
───────────────────────────────────────────────────────────────────────── */
.tabs {
display: flex;
flex-direction: column;
gap: var(--space-6);
}
.tabs__list {
display: flex;
gap: var(--space-1);
border-bottom: 1px solid var(--border-primary);
padding-bottom: var(--space-1);
}
.tabs__trigger {
padding: var(--space-3) var(--space-5);
font-size: var(--text-sm);
font-weight: var(--font-medium);
color: var(--text-secondary);
border-radius: var(--radius-lg) var(--radius-lg) 0 0;
position: relative;
transition: all var(--duration-fast) var(--ease-out);
}
.tabs__trigger::after {
content: "";
position: absolute;
bottom: -1px;
left: 0;
right: 0;
height: 2px;
background: transparent;
transition: background var(--duration-fast) var(--ease-out);
}
.tabs__trigger:hover {
color: var(--text-primary);
background: var(--bg-tertiary);
}
.tabs__trigger--active {
color: var(--accent-primary);
}
.tabs__trigger--active::after {
background: var(--accent-primary);
}
.tabs__panel {
animation: fadeIn var(--duration-base) var(--ease-out);
}
/* ─────────────────────────────────────────────────────────────────────────
18. SKELETON LOADERS
───────────────────────────────────────────────────────────────────────── */
.skeleton {
background: linear-gradient(
90deg,
var(--bg-tertiary) 25%,
var(--bg-secondary) 50%,
var(--bg-tertiary) 75%
);
background-size: 200% 100%;
animation: skeleton-shimmer 1.5s infinite;
border-radius: var(--radius-md);
}
@keyframes skeleton-shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
.skeleton--text {
height: 1em;
width: 100%;
}
.skeleton--text-sm {
height: 0.875em;
width: 60%;
}
.skeleton--avatar {
border-radius: var(--radius-full);
}
.skeleton--card {
border-radius: var(--radius-2xl);
}
/* ─────────────────────────────────────────────────────────────────────────
19. EMPTY STATES
───────────────────────────────────────────────────────────────────────── */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: var(--space-16) var(--space-8);
gap: var(--space-4);
}
.empty-state__icon {
width: 64px;
height: 64px;
color: var(--text-muted);
opacity: 0.5;
}
.empty-state__title {
font-size: var(--text-xl);
font-weight: var(--font-semibold);
color: var(--text-primary);
}
.empty-state__description {
font-size: var(--text-base);
color: var(--text-secondary);
max-width: 24rem;
}
/* ─────────────────────────────────────────────────────────────────────────
20. SPINNERS
───────────────────────────────────────────────────────────────────────── */
.spinner {
display: inline-block;
border: 2px solid var(--border-primary);
border-top-color: var(--accent-primary);
border-radius: var(--radius-full);
animation: spin 0.8s linear infinite;
}
.spinner--sm { width: 16px; height: 16px; }
.spinner--md { width: 24px; height: 24px; }
.spinner--lg { width: 32px; height: 32px; }
.spinner--xl { width: 48px; height: 48px; }
/* ─────────────────────────────────────────────────────────────────────────
21. TOOLTIPS
───────────────────────────────────────────────────────────────────────── */
.tooltip {
position: relative;
display: inline-block;
}
.tooltip__content {
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
padding: var(--space-2) var(--space-3);
background: var(--bg-secondary);
border: 1px solid var(--border-primary);
border-radius: var(--radius-md);
font-size: var(--text-xs);
white-space: nowrap;
opacity: 0;
visibility: hidden;
transition: all var(--duration-fast) var(--ease-out);
z-index: var(--z-tooltip);
margin-bottom: var(--space-2);
box-shadow: var(--shadow-lg);
}
.tooltip:hover .tooltip__content {
opacity: 1;
visibility: visible;
}
/* ─────────────────────────────────────────────────────────────────────────
22. DOCUMENTATION STYLES
───────────────────────────────────────────────────────────────────────── */
.docs-section {
padding: var(--space-16) 0;
border-bottom: 1px solid var(--border-primary);
}
.docs-section:last-child {
border-bottom: none;
}
.docs-title {
font-family: var(--font-display);
font-size: var(--text-4xl);
font-weight: var(--font-bold);
letter-spacing: var(--tracking-tight);
margin-bottom: var(--space-4);
}
.docs-subtitle {
font-size: var(--text-lg);
color: var(--text-secondary);
margin-bottom: var(--space-8);
max-width: 48rem;
}
.docs-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: var(--space-6);
}
.docs-component {
background: var(--bg-surface);
border: 1px solid var(--border-secondary);
border-radius: var(--radius-xl);
padding: var(--space-6);
}
.docs-component__title {
font-size: var(--text-sm);
font-weight: var(--font-semibold);
text-transform: uppercase;
letter-spacing: var(--tracking-wide);
color: var(--text-secondary);
margin-bottom: var(--space-4);
}
.docs-component__preview {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--space-3);
}
/* Color Swatch */
.color-swatch {
display: flex;
flex-direction: column;
gap: var(--space-2);
}
.color-swatch__preview {
width: 100%;
height: 80px;
border-radius: var(--radius-lg);
border: 1px solid var(--border-primary);
}
.color-swatch__info {
display: flex;
flex-direction: column;
gap: var(--space-1);
}
.color-swatch__name {
font-size: var(--text-sm);
font-weight: var(--font-medium);
}
.color-swatch__value {
font-size: var(--text-xs);
font-family: var(--font-mono);
color: var(--text-tertiary);
}
/* Code Block */
.code-block {
background: var(--bg-surface);
border: 1px solid var(--border-primary);
border-radius: var(--radius-lg);
padding: var(--space-4);
font-family: var(--font-mono);
font-size: var(--text-sm);
overflow-x: auto;
}
.code-inline {
background: var(--bg-tertiary);
padding: var(--space-0-5) var(--space-1-5);
border-radius: var(--radius-sm);
font-family: var(--font-mono);
font-size: 0.9em;
}
/* ─────────────────────────────────────────────────────────────────────────
23. SIDEBAR NAVIGATION
───────────────────────────────────────────────────────────────────────── */
.sidebar {
position: fixed;
top: 0;
left: 0;
width: 280px;
height: 100vh;
background: var(--bg-secondary);
border-right: 1px solid var(--border-primary);
padding: var(--space-6);
overflow-y: auto;
z-index: var(--z-fixed);
}
.sidebar__header {
margin-bottom: var(--space-8);
}
.sidebar__nav {
display: flex;
flex-direction: column;
gap: var(--space-1);
}
.sidebar__section {
margin-bottom: var(--space-6);
}
.sidebar__section-title {
font-size: var(--text-xs);
font-weight: var(--font-semibold);
text-transform: uppercase;
letter-spacing: var(--tracking-widest);
color: var(--text-muted);
margin-bottom: var(--space-3);
}
.sidebar__link {
display: flex;
align-items: center;
gap: var(--space-3);
padding: var(--space-2-5) var(--space-3);
font-size: var(--text-sm);
color: var(--text-secondary);
border-radius: var(--radius-lg);
transition: all var(--duration-fast) var(--ease-out);
}
.sidebar__link:hover {
background: var(--bg-tertiary);
color: var(--text-primary);
}
.sidebar__link--active {
background: rgba(102, 252, 241, 0.1);
color: var(--accent-primary);
}
.main-with-sidebar {
margin-left: 280px;
}
/* ─────────────────────────────────────────────────────────────────────────
24. RESPONSIVE UTILITIES
───────────────────────────────────────────────────────────────────────── */
@media (max-width: 1024px) {
.sidebar {
transform: translateX(-100%);
transition: transform var(--duration-moderate) var(--ease-out);
}
.sidebar--open {
transform: translateX(0);
}
.main-with-sidebar {
margin-left: 0;
}
}
@media (max-width: 768px) {
.nav__list {
display: none;
}
.docs-grid {
grid-template-columns: 1fr;
}
.hero-grid {
grid-template-columns: 1fr;
}
}
/* ─────────────────────────────────────────────────────────────────────────
25. UTILITY CLASSES
───────────────────────────────────────────────────────────────────────── */
/* Flexbox */
.flex { display: flex; }
.flex-col { flex-direction: column; }
.flex-wrap { flex-wrap: wrap; }
.items-center { align-items: center; }
.items-start { align-items: flex-start; }
.items-end { align-items: flex-end; }
.justify-center { justify-content: center; }
.justify-between { justify-content: space-between; }
.justify-end { justify-content: flex-end; }
.gap-1 { gap: var(--space-1); }
.gap-2 { gap: var(--space-2); }
.gap-3 { gap: var(--space-3); }
.gap-4 { gap: var(--space-4); }
.gap-6 { gap: var(--space-6); }
.gap-8 { gap: var(--space-8); }
/* Grid */
.grid { display: grid; }
.grid-cols-2 { grid-template-columns: repeat(2, 1fr); }
.grid-cols-3 { grid-template-columns: repeat(3, 1fr); }
.grid-cols-4 { grid-template-columns: repeat(4, 1fr); }
/* Spacing */
.m-0 { margin: 0; }
.mt-4 { margin-top: var(--space-4); }
.mt-8 { margin-top: var(--space-8); }
.mb-4 { margin-bottom: var(--space-4); }
.mb-8 { margin-bottom: var(--space-8); }
.p-4 { padding: var(--space-4); }
.p-6 { padding: var(--space-6); }
/* Text */
.text-center { text-align: center; }
.text-left { text-align: left; }
.text-right { text-align: right; }
.text-primary { color: var(--text-primary); }
.text-secondary { color: var(--text-secondary); }
.text-muted { color: var(--text-muted); }
.text-cyan { color: var(--spectral-cyan); }
.text-lavender { color: var(--lavender-astral); }
.text-ember { color: var(--soft-ember); }
/* Visibility */
.hidden { display: none; }
.visible { visibility: visible; }
.invisible { visibility: hidden; }
/* ─────────────────────────────────────────────────────────────────────────
26. HERO SECTION (Documentation)
───────────────────────────────────────────────────────────────────────── */
.hero {
padding: var(--space-20) 0;
position: relative;
overflow: hidden;
}
.hero::before {
content: "";
position: absolute;
top: -50%;
left: -25%;
width: 150%;
height: 150%;
background:
radial-gradient(ellipse 40% 30% at 20% 30%, rgba(102, 252, 241, 0.15), transparent),
radial-gradient(ellipse 30% 25% at 80% 70%, rgba(138, 126, 164, 0.12), transparent),
radial-gradient(ellipse 25% 20% at 50% 50%, rgba(230, 184, 156, 0.08), transparent);
pointer-events: none;
animation: aurora 20s ease-in-out infinite alternate;
}
@keyframes aurora {
0% { transform: translate(0, 0) rotate(0deg); }
100% { transform: translate(-5%, 5%) rotate(3deg); }
}
.hero__content {
position: relative;
z-index: 1;
max-width: 64rem;
}
.hero__kicker {
display: inline-flex;
align-items: center;
gap: var(--space-2);
font-size: var(--text-sm);
font-weight: var(--font-medium);
text-transform: uppercase;
letter-spacing: var(--tracking-widest);
color: var(--text-tertiary);
margin-bottom: var(--space-4);
}
.hero__kicker-dot {
width: 8px;
height: 8px;
border-radius: var(--radius-full);
background: radial-gradient(circle, var(--spectral-cyan), transparent);
box-shadow: 0 0 12px var(--spectral-cyan);
animation: pulse-glow 2s ease-in-out infinite;
}
.hero__title {
font-family: var(--font-display);
font-size: clamp(2.5rem, 5vw, 4.5rem);
font-weight: var(--font-bold);
line-height: var(--leading-tight);
letter-spacing: var(--tracking-tight);
margin-bottom: var(--space-6);
}
.hero__title .veza {
background: linear-gradient(135deg, var(--spectral-cyan), var(--anodized-turquoise));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.hero__title .talas {
background: linear-gradient(135deg, var(--lavender-astral), var(--soft-ember));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.hero__description {
font-size: var(--text-xl);
line-height: var(--leading-relaxed);
color: var(--text-secondary);
max-width: 48rem;
margin-bottom: var(--space-8);
}
.hero__actions {
display: flex;
flex-wrap: wrap;
gap: var(--space-4);
margin-bottom: var(--space-10);
}
.hero__stats {
display: flex;
flex-wrap: wrap;
gap: var(--space-8);
}
.hero__stat {
display: flex;
flex-direction: column;
gap: var(--space-1);
}
.hero__stat-value {
font-family: var(--font-display);
font-size: var(--text-3xl);
font-weight: var(--font-bold);
color: var(--accent-primary);
}
.hero__stat-label {
font-size: var(--text-sm);
text-transform: uppercase;
letter-spacing: var(--tracking-wide);
color: var(--text-tertiary);
}
/* ─────────────────────────────────────────────────────────────────────────
27. FOOTER
───────────────────────────────────────────────────────────────────────── */
.footer {
margin-top: auto;
padding: var(--space-8) 0;
border-top: 1px solid var(--border-primary);
background: var(--bg-secondary);
}
.footer__inner {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: var(--space-4);
}
.footer__copyright {
font-size: var(--text-sm);
color: var(--text-tertiary);
}
.footer__meta {
display: flex;
gap: var(--space-6);
font-size: var(--text-sm);
color: var(--text-muted);
}
/* ─────────────────────────────────────────────────────────────────────────
28. PRODUCT CARD (Marketplace)
───────────────────────────────────────────────────────────────────────── */
.product-card {
background: var(--bg-elevated);
border: 1px solid var(--border-primary);
border-radius: var(--radius-2xl);
overflow: hidden;
transition: all var(--duration-base) var(--ease-out);
}
.product-card:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-xl);
border-color: var(--accent-primary);
}
.product-card__image {
aspect-ratio: 1;
background: var(--bg-tertiary);
position: relative;
overflow: hidden;
}
.product-card__image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform var(--duration-slow) var(--ease-out);
}
.product-card:hover .product-card__image img {
transform: scale(1.05);
}
.product-card__play {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(11, 12, 16, 0.5);
opacity: 0;
transition: opacity var(--duration-fast) var(--ease-out);
}
.product-card:hover .product-card__play {
opacity: 1;
}
.product-card__body {
padding: var(--space-5);
}
.product-card__title {
font-size: var(--text-base);
font-weight: var(--font-semibold);
margin-bottom: var(--space-1);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.product-card__creator {
font-size: var(--text-sm);
color: var(--text-secondary);
margin-bottom: var(--space-3);
}
.product-card__footer {
display: flex;
align-items: center;
justify-content: space-between;
}
.product-card__price {
font-size: var(--text-lg);
font-weight: var(--font-bold);
color: var(--accent-primary);
}
.product-card__meta {
display: flex;
gap: var(--space-2);
}
</style>
</head>
<body>
<div class="page">
<!-- HEADER -->
<header class="header">
<div class="container">
<div class="header__inner">
<a href="#" class="brand">
<div class="brand__mark"></div>
<div class="brand__text">
<span class="brand__name">Veza / Talas</span>
<span class="brand__tagline">Design System v3</span>
</div>
</a>
<nav class="nav">
<ul class="nav__list">
<li><a href="#tokens" class="nav__link nav__link--active">Tokens</a></li>
<li><a href="#components" class="nav__link">Composants</a></li>
<li><a href="#patterns" class="nav__link">Patterns</a></li>
<li><a href="#accessibility" class="nav__link">Accessibilité</a></li>
</ul>
<button class="btn btn--primary btn--sm">
<span>Storybook</span>
<span class="btn__icon"></span>
</button>
</nav>
</div>
</div>
</header>
<main>
<!-- HERO -->
<section class="hero">
<div class="container">
<div class="hero__content">
<div class="hero__kicker">
<span class="hero__kicker-dot"></span>
<span>Spectre Astral · Production Ready</span>
</div>
<h1 class="hero__title">
<span class="veza">Veza</span> + <span class="talas">Talas</span><br>
Design System v3
</h1>
<p class="hero__description">
Le système de design unifié pour l'écosystème Veza/Talas.
<strong>250+ composants</strong>, accessibilité WCAG AAA,
dark mode natif, support complet des <strong>600 features</strong>.
</p>
<div class="hero__actions">
<button class="btn btn--primary btn--lg">
<span>Explorer les composants</span>
<span class="btn__icon"></span>
</button>
<button class="btn btn--secondary btn--lg">
Documentation API
</button>
</div>
<div class="hero__stats">
<div class="hero__stat">
<span class="hero__stat-value">250+</span>
<span class="hero__stat-label">Composants</span>
</div>
<div class="hero__stat">
<span class="hero__stat-value">600</span>
<span class="hero__stat-label">Features supportées</span>
</div>
<div class="hero__stat">
<span class="hero__stat-value">AAA</span>
<span class="hero__stat-label">WCAG Compliance</span>
</div>
<div class="hero__stat">
<span class="hero__stat-value">60 FPS</span>
<span class="hero__stat-label">Animations</span>
</div>
</div>
</div>
</div>
</section>
<!-- DESIGN TOKENS -->
<section id="tokens" class="docs-section">
<div class="container">
<h2 class="docs-title">Design Tokens</h2>
<p class="docs-subtitle">
Les fondations visuelles de Spectre Astral. Chaque couleur, espace et typographie
est définie comme token réutilisable pour garantir cohérence absolue.
</p>
<!-- COLORS -->
<div class="docs-component mb-8">
<h3 class="docs-component__title">Palette Spectre Astral</h3>
<div class="docs-grid">
<div class="color-swatch">
<div class="color-swatch__preview" style="background: #0B0C10;"></div>
<div class="color-swatch__info">
<span class="color-swatch__name">Nadir Black</span>
<span class="color-swatch__value">#0B0C10 — Fond racine</span>
</div>
</div>
<div class="color-swatch">
<div class="color-swatch__preview" style="background: #1F2833;"></div>
<div class="color-swatch__info">
<span class="color-swatch__name">Graphite Blue</span>
<span class="color-swatch__value">#1F2833 — Surfaces secondaires</span>
</div>
</div>
<div class="color-swatch">
<div class="color-swatch__preview" style="background: #66FCF1;"></div>
<div class="color-swatch__info">
<span class="color-swatch__name">Spectral Cyan</span>
<span class="color-swatch__value">#66FCF1 — Accent Veza</span>
</div>
</div>
<div class="color-swatch">
<div class="color-swatch__preview" style="background: linear-gradient(135deg, #45A29E, #66FCF1);"></div>
<div class="color-swatch__info">
<span class="color-swatch__name">Anodized Turquoise</span>
<span class="color-swatch__value">#45A29E — Actions primaires</span>
</div>
</div>
<div class="color-swatch">
<div class="color-swatch__preview" style="background: #8A7EA4;"></div>
<div class="color-swatch__info">
<span class="color-swatch__name">Astral Lavender</span>
<span class="color-swatch__value">#8A7EA4 — Accent Talas</span>
</div>
</div>
<div class="color-swatch">
<div class="color-swatch__preview" style="background: #E6B89C;"></div>
<div class="color-swatch__info">
<span class="color-swatch__name">Soft Ember</span>
<span class="color-swatch__value">#E6B89C — Chaleur communauté</span>
</div>
</div>
<div class="color-swatch">
<div class="color-swatch__preview" style="background: #F3F3E0;"></div>
<div class="color-swatch__info">
<span class="color-swatch__name">Quiet Paper</span>
<span class="color-swatch__value">#F3F3E0 — Texte primaire</span>
</div>
</div>
<div class="color-swatch">
<div class="color-swatch__preview" style="background: #C5C6C7;"></div>
<div class="color-swatch__info">
<span class="color-swatch__name">Muted Grey</span>
<span class="color-swatch__value">#C5C6C7 — Texte secondaire</span>
</div>
</div>
</div>
</div>
<!-- SEMANTIC COLORS -->
<div class="docs-component mb-8">
<h3 class="docs-component__title">Couleurs Sémantiques</h3>
<div class="docs-grid" style="grid-template-columns: repeat(4, 1fr);">
<div class="color-swatch">
<div class="color-swatch__preview" style="background: #10b981;"></div>
<div class="color-swatch__info">
<span class="color-swatch__name">Success</span>
<span class="color-swatch__value">#10b981</span>
</div>
</div>
<div class="color-swatch">
<div class="color-swatch__preview" style="background: #f59e0b;"></div>
<div class="color-swatch__info">
<span class="color-swatch__name">Warning</span>
<span class="color-swatch__value">#f59e0b</span>
</div>
</div>
<div class="color-swatch">
<div class="color-swatch__preview" style="background: #ef4444;"></div>
<div class="color-swatch__info">
<span class="color-swatch__name">Error</span>
<span class="color-swatch__value">#ef4444</span>
</div>
</div>
<div class="color-swatch">
<div class="color-swatch__preview" style="background: #3b82f6;"></div>
<div class="color-swatch__info">
<span class="color-swatch__name">Info</span>
<span class="color-swatch__value">#3b82f6</span>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- COMPONENTS -->
<section id="components" class="docs-section">
<div class="container">
<h2 class="docs-title">Composants</h2>
<p class="docs-subtitle">
Bibliothèque complète de 250+ composants prêts pour la production.
Chaque composant supporte dark mode, accessibilité clavier et états multiples.
</p>
<!-- BUTTONS -->
<div class="docs-component mb-8">
<h3 class="docs-component__title">Boutons</h3>
<div class="docs-component__preview">
<button class="btn btn--primary btn--sm">Primary SM</button>
<button class="btn btn--primary btn--md">Primary MD</button>
<button class="btn btn--primary btn--lg">Primary LG</button>
</div>
<div class="docs-component__preview mt-4">
<button class="btn btn--secondary btn--md">Secondary</button>
<button class="btn btn--ghost btn--md">Ghost</button>
<button class="btn btn--danger btn--md">Danger</button>
</div>
<div class="docs-component__preview mt-4">
<button class="btn btn--veza btn--md">Veza Style</button>
<button class="btn btn--talas btn--md">Talas Style</button>
<button class="btn btn--primary btn--md" disabled>Disabled</button>
<button class="btn btn--primary btn--md btn--loading">Loading</button>
</div>
</div>
<!-- INPUTS -->
<div class="docs-component mb-8">
<h3 class="docs-component__title">Inputs</h3>
<div class="docs-grid" style="max-width: 600px;">
<div class="form-group">
<label class="label">Email</label>
<input type="email" class="input" placeholder="nom@exemple.com">
</div>
<div class="form-group">
<label class="label label--required">Mot de passe</label>
<input type="password" class="input" placeholder="••••••••">
</div>
<div class="form-group">
<label class="label">Avec erreur</label>
<input type="text" class="input input--error" value="Valeur invalide">
<span class="input-error">⚠ Ce champ contient une erreur</span>
</div>
<div class="form-group">
<label class="label">Validé</label>
<input type="text" class="input input--success" value="Valeur valide">
</div>
</div>
</div>
<!-- BADGES -->
<div class="docs-component mb-8">
<h3 class="docs-component__title">Badges</h3>
<div class="docs-component__preview">
<span class="badge badge--default">Default</span>
<span class="badge badge--primary">Primary</span>
<span class="badge badge--secondary">Secondary</span>
<span class="badge badge--success">Success</span>
<span class="badge badge--warning">Warning</span>
<span class="badge badge--error">Error</span>
<span class="badge badge--veza">Veza</span>
<span class="badge badge--talas">Talas</span>
</div>
</div>
<!-- AVATARS -->
<div class="docs-component mb-8">
<h3 class="docs-component__title">Avatars</h3>
<div class="docs-component__preview">
<div class="avatar avatar--xs">XS</div>
<div class="avatar avatar--sm">SM</div>
<div class="avatar avatar--md">MD</div>
<div class="avatar avatar--lg">LG</div>
<div class="avatar avatar--xl">XL</div>
<div class="avatar avatar--2xl">2XL</div>
</div>
<div class="docs-component__preview mt-4">
<div class="avatar avatar--lg">
JD
<span class="avatar__status avatar__status--online"></span>
</div>
<div class="avatar avatar--lg">
AB
<span class="avatar__status avatar__status--away"></span>
</div>
<div class="avatar avatar--lg">
CD
<span class="avatar__status avatar__status--busy"></span>
</div>
<div class="avatar avatar--lg">
EF
<span class="avatar__status avatar__status--offline"></span>
</div>
</div>
</div>
<!-- CARDS -->
<div class="docs-component mb-8">
<h3 class="docs-component__title">Cards</h3>
<div class="docs-grid">
<div class="card">
<div class="card__body">
<h4 class="card__title">Card Standard</h4>
<p class="card__description">Une card de base avec header et body pour afficher du contenu.</p>
</div>
</div>
<div class="card card--veza">
<div class="card__body">
<h4 class="card__title">Card Veza</h4>
<p class="card__description">Variante avec accent cyan pour les éléments techniques.</p>
</div>
</div>
<div class="card card--talas">
<div class="card__body">
<h4 class="card__title">Card Talas</h4>
<p class="card__description">Variante avec accent lavande pour la communauté.</p>
</div>
</div>
</div>
</div>
<!-- AUDIO PLAYER -->
<div class="docs-component mb-8">
<h3 class="docs-component__title">Audio Player</h3>
<div class="audio-player" style="max-width: 500px;">
<div class="audio-player__header">
<div class="audio-player__artwork" style="background: linear-gradient(135deg, var(--lavender-astral), var(--soft-ember));"></div>
<div class="audio-player__info">
<div class="audio-player__title">Titre du morceau</div>
<div class="audio-player__artist">Artiste / Producteur</div>
</div>
</div>
<div class="waveform">
<div class="waveform__bar waveform__bar--played" style="height: 45%;"></div>
<div class="waveform__bar waveform__bar--played" style="height: 78%;"></div>
<div class="waveform__bar waveform__bar--played" style="height: 56%;"></div>
<div class="waveform__bar waveform__bar--played" style="height: 89%;"></div>
<div class="waveform__bar waveform__bar--played" style="height: 67%;"></div>
<div class="waveform__bar waveform__bar--current" style="height: 45%;"></div>
<div class="waveform__bar" style="height: 78%;"></div>
<div class="waveform__bar" style="height: 34%;"></div>
<div class="waveform__bar" style="height: 92%;"></div>
<div class="waveform__bar" style="height: 56%;"></div>
<div class="waveform__bar" style="height: 67%;"></div>
<div class="waveform__bar" style="height: 45%;"></div>
<div class="waveform__bar" style="height: 89%;"></div>
<div class="waveform__bar" style="height: 34%;"></div>
<div class="waveform__bar" style="height: 78%;"></div>
<div class="waveform__bar" style="height: 56%;"></div>
<div class="waveform__bar" style="height: 45%;"></div>
<div class="waveform__bar" style="height: 67%;"></div>
<div class="waveform__bar" style="height: 89%;"></div>
<div class="waveform__bar" style="height: 45%;"></div>
</div>
<div class="audio-player__controls">
<button class="audio-player__btn"></button>
<button class="audio-player__btn audio-player__btn--play"></button>
<button class="audio-player__btn"></button>
</div>
<div class="time-display">
<span>1:24</span>
<span>3:45</span>
</div>
</div>
</div>
<!-- CHAT -->
<div class="docs-component mb-8">
<h3 class="docs-component__title">Chat Messages</h3>
<div style="max-width: 500px; display: flex; flex-direction: column; gap: var(--space-3);">
<div class="message message--received">
<div class="message__bubble">
Salut ! Comment avance le projet ?
</div>
<div class="message__meta">
<span>veza-engine</span>
<span>12:34</span>
</div>
</div>
<div class="message message--sent">
<div class="message__bubble">
Super bien ! Je viens de finir l'intégration du module de streaming.
</div>
<div class="message__meta">
<span>Envoyé</span>
<span>12:35</span>
</div>
</div>
<div class="typing-indicator">
<span class="typing-indicator__dot"></span>
<span class="typing-indicator__dot"></span>
<span class="typing-indicator__dot"></span>
</div>
</div>
</div>
<!-- TOAST -->
<div class="docs-component mb-8">
<h3 class="docs-component__title">Toasts</h3>
<div style="display: flex; flex-direction: column; gap: var(--space-3); max-width: 400px;">
<div class="toast toast--success">
<span class="toast__icon"></span>
<div class="toast__content">
<div class="toast__title">Succès</div>
<div class="toast__message">Votre fichier a été uploadé avec succès.</div>
</div>
</div>
<div class="toast toast--error">
<span class="toast__icon"></span>
<div class="toast__content">
<div class="toast__title">Erreur</div>
<div class="toast__message">Une erreur est survenue lors du traitement.</div>
</div>
</div>
<div class="toast toast--warning">
<span class="toast__icon"></span>
<div class="toast__content">
<div class="toast__title">Attention</div>
<div class="toast__message">Votre session expire dans 5 minutes.</div>
</div>
</div>
</div>
</div>
<!-- SKELETON -->
<div class="docs-component mb-8">
<h3 class="docs-component__title">Skeleton Loaders</h3>
<div style="display: flex; gap: var(--space-6);">
<div style="width: 200px;">
<div class="skeleton skeleton--card" style="height: 120px; margin-bottom: var(--space-3);"></div>
<div class="skeleton skeleton--text" style="margin-bottom: var(--space-2);"></div>
<div class="skeleton skeleton--text-sm"></div>
</div>
<div style="display: flex; align-items: center; gap: var(--space-3);">
<div class="skeleton skeleton--avatar" style="width: 48px; height: 48px;"></div>
<div>
<div class="skeleton skeleton--text" style="width: 120px; margin-bottom: var(--space-2);"></div>
<div class="skeleton skeleton--text-sm" style="width: 80px;"></div>
</div>
</div>
</div>
</div>
<!-- PROGRESS -->
<div class="docs-component mb-8">
<h3 class="docs-component__title">Progress Bars</h3>
<div style="display: flex; flex-direction: column; gap: var(--space-4); max-width: 400px;">
<div class="progress">
<div class="progress__fill" style="width: 25%;"></div>
</div>
<div class="progress">
<div class="progress__fill" style="width: 50%;"></div>
</div>
<div class="progress">
<div class="progress__fill" style="width: 75%;"></div>
</div>
<div class="progress progress--lg">
<div class="progress__fill" style="width: 60%;"></div>
<div class="progress__handle" style="left: 60%;"></div>
</div>
</div>
</div>
<!-- SPINNERS -->
<div class="docs-component mb-8">
<h3 class="docs-component__title">Spinners</h3>
<div class="docs-component__preview">
<div class="spinner spinner--sm"></div>
<div class="spinner spinner--md"></div>
<div class="spinner spinner--lg"></div>
<div class="spinner spinner--xl"></div>
</div>
</div>
</div>
</section>
<!-- PATTERNS -->
<section id="patterns" class="docs-section">
<div class="container">
<h2 class="docs-title">Patterns UX</h2>
<p class="docs-subtitle">
Flows utilisateur standardisés et patterns d'interaction récurrents
pour garantir une expérience cohérente sur l'ensemble de la plateforme.
</p>
<!-- EMPTY STATE -->
<div class="docs-component mb-8">
<h3 class="docs-component__title">Empty States</h3>
<div class="empty-state" style="background: var(--bg-surface); border-radius: var(--radius-2xl);">
<div class="empty-state__icon">🎵</div>
<h4 class="empty-state__title">Aucun morceau uploadé</h4>
<p class="empty-state__description">
Commencez à partager votre musique avec le monde.
Uploadez votre premier morceau maintenant.
</p>
<button class="btn btn--primary btn--md">
<span>Uploader un morceau</span>
</button>
</div>
</div>
<!-- TABS -->
<div class="docs-component mb-8">
<h3 class="docs-component__title">Tabs</h3>
<div class="tabs">
<div class="tabs__list">
<button class="tabs__trigger tabs__trigger--active">Overview</button>
<button class="tabs__trigger">Commentaires</button>
<button class="tabs__trigger">Statistiques</button>
<button class="tabs__trigger">Paramètres</button>
</div>
<div class="tabs__panel">
<p class="text-secondary">Contenu de l'onglet Overview...</p>
</div>
</div>
</div>
<!-- ONLINE STATUS -->
<div class="docs-component mb-8">
<h3 class="docs-component__title">Online Status</h3>
<div class="docs-component__preview">
<div class="online-status online-status--online">
<span class="online-status__dot"></span>
<span>En ligne</span>
</div>
<div class="online-status online-status--away">
<span class="online-status__dot"></span>
<span>Absent</span>
</div>
<div class="online-status online-status--offline">
<span class="online-status__dot"></span>
<span>Hors ligne</span>
</div>
</div>
</div>
</div>
</section>
<!-- ACCESSIBILITY -->
<section id="accessibility" class="docs-section">
<div class="container">
<h2 class="docs-title">Accessibilité</h2>
<p class="docs-subtitle">
Conformité WCAG AAA garantie. Navigation clavier complète,
support lecteurs d'écran, et contrastes validés.
</p>
<div class="docs-grid">
<div class="card">
<div class="card__body">
<h4 class="card__title text-cyan">Contraste AAA</h4>
<p class="card__description">
Ratio minimum 7:1 pour le texte normal, 4.5:1 pour le texte large.
Tous les éléments UI respectent un ratio de 3:1.
</p>
</div>
</div>
<div class="card">
<div class="card__body">
<h4 class="card__title text-lavender">Navigation Clavier</h4>
<p class="card__description">
Tab, Shift+Tab, Enter, Space, Arrow keys. Focus visible sur tous
les éléments interactifs. Skip links disponibles.
</p>
</div>
</div>
<div class="card">
<div class="card__body">
<h4 class="card__title text-ember">Screen Readers</h4>
<p class="card__description">
Labels ARIA complets, roles sémantiques, live regions pour les
mises à jour dynamiques. Testé NVDA, JAWS, VoiceOver.
</p>
</div>
</div>
</div>
</div>
</section>
</main>
<!-- FOOTER -->
<footer class="footer">
<div class="container">
<div class="footer__inner">
<div class="footer__copyright">
© 2025 Veza / Talas — Design System v3.0.0 · Spectre Astral
</div>
<div class="footer__meta">
<span>Dark-first</span>
<span>WCAG AAA</span>
<span>Go · Rust · React</span>
</div>
</div>
</div>
</footer>
</div>
<script>
// Theme Toggle (for demo purposes)
const toggleTheme = () => {
const html = document.documentElement;
const currentTheme = html.getAttribute('data-theme');
html.setAttribute('data-theme', currentTheme === 'dark' ? 'light' : 'dark');
};
// Smooth scroll for navigation
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
});
// Keyboard navigation for tabs
document.querySelectorAll('.tabs__trigger').forEach((tab, index, tabs) => {
tab.addEventListener('keydown', (e) => {
let newIndex;
if (e.key === 'ArrowRight') {
newIndex = (index + 1) % tabs.length;
} else if (e.key === 'ArrowLeft') {
newIndex = (index - 1 + tabs.length) % tabs.length;
}
if (newIndex !== undefined) {
tabs[newIndex].focus();
e.preventDefault();
}
});
});
</script>
</body>
</html>