veza/apps/web/src/styles/design-system.css
senke 95e31646cb feat(ui): Sidebar refactor, premium skeletons, ContentFadeIn transitions
- Sidebar: useSidebarNavigation hook, ARIA, token-based layout
- Layout: lg:ml-main-expanded/collapsed (replace arbitrary ml-64)
- TrackCardSkeleton + PlaylistCardSkeleton: KŌDŌ tokens, min-heights for CLS
- ContentFadeIn: 200ms fade-in with --ease-out
- TrackGrid, PlaylistList, LibraryPage: integrate skeletons + fade-in
- Player: player-bar subcomponents, useAudioAnalyser
- Tests: TrackGrid wrapper (QueryClient, ToastProvider)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 22:51:51 +01:00

583 lines
No EOL
15 KiB
CSS

/* ═══════════════════════════════════════════════════════════════════════════
VEZA FUSION DESIGN SYSTEM
Combining: KŌDŌ (Cyber/Gaming) + BOTANICAL (Nature) + Spectre Astral (Space)
═══════════════════════════════════════════════════════════════════════════ */
/* ─────────────────────────────────────────────────────────────────────────
1. DESIGN TOKENS
───────────────────────────────────────────────────────────────────────── */
:root {
/* === CORE PALETTE === */
/* Dark Bases (Cyber) */
--veza-void: #050508;
--veza-ink: #0a0b0f;
--veza-graphite: #12131a;
--veza-slate: #1a1c26;
--veza-steel: #252836;
--veza-nadir: #0b0c10;
--veza-surface: #1f2833;
/* Neon Accents (Cyber) */
--veza-cyan: #00fff7;
--veza-cyan-dim: #00c4bd;
--veza-spectral-cyan: #66fcf1;
--veza-turquoise: #45a29e;
--veza-magenta: #ff00ff;
--veza-magenta-dim: #cc00cc;
--veza-lime: #b8ff00;
--veza-lime-dim: #8fcc00;
--veza-orange: #ff6b00;
/* Nature Tones (Botanical) */
--veza-sage: #87a878;
--veza-sage-light: #a8c499;
--veza-sage-dark: #6b8a5e;
--veza-moss: #4a5d42;
--veza-moss-deep: #3a4a35;
--veza-mint: #c8e0c0;
--veza-mint-light: #e8f4e4;
--veza-leaf: #7cb342;
/* Earth Tones (Botanical) */
--veza-soil: #5c4d3c;
--veza-bark: #8b7355;
--veza-sand: #d4c5a9;
--veza-clay: #c49a6c;
/* Space/Astral (Spectre) */
--veza-lavender: #8a7ea4;
--veza-ember: #e6b89c;
--veza-coral: #c97c6b;
--veza-sky: #7ba3b8;
--veza-berry: #8b687a;
/* Paper & Light */
--veza-paper: #faf9f6;
--veza-cream: #f5f3ee;
--veza-linen: #ebe8e0;
--veza-stone: #d8d4cc;
--veza-white: #f5f5f5;
--veza-white-pure: #ffffff;
/* Text */
--veza-text: #2c2c2c;
--veza-text-light: #4a4a4a;
--veza-text-muted: #7a7a7a;
--veza-text-faint: #a8a8a8;
/* Greys */
--veza-grey-100: #e0e0e0;
--veza-grey-200: #bdbdbd;
--veza-grey-300: #9e9e9e;
--veza-grey-400: #757575;
--veza-grey-500: #616161;
/* Semantic */
--veza-success: #36e5d1;
--veza-success-nature: #5a8a4a;
--veza-warning: #ffab00;
--veza-warning-nature: #c4923a;
--veza-error: #ff1744;
--veza-error-soft: #b55a5a;
--veza-info: #00b0ff;
--veza-info-nature: #5a7a8a;
/* Gaming UI */
--veza-xp-gold: #ffd700;
--veza-hp-red: #ff3333;
--veza-mp-blue: #3399ff;
--veza-shield: #9c27b0;
/* Terminal */
--veza-terminal-green: #00ff00;
--veza-terminal-amber: #ffb000;
--veza-terminal-blue: #00bfff;
--veza-matrix: #003300;
/* === GRADIENTS === */
--gradient-neon: linear-gradient(135deg,
var(--veza-cyan) 0%,
var(--veza-magenta) 50%,
var(--veza-lime) 100%);
--gradient-cyber: linear-gradient(135deg,
var(--veza-spectral-cyan) 0%,
var(--veza-lavender) 100%);
--gradient-sunset: linear-gradient(135deg,
var(--veza-orange) 0%,
var(--veza-magenta) 100%);
--gradient-forest: linear-gradient(135deg,
var(--veza-moss) 0%,
var(--veza-leaf) 50%,
var(--veza-lime) 100%);
--gradient-nature: linear-gradient(135deg,
var(--veza-sage) 0%,
var(--veza-moss) 100%);
--gradient-space: linear-gradient(135deg,
var(--veza-lavender) 0%,
var(--veza-ember) 100%);
--gradient-terminal: linear-gradient(180deg,
var(--veza-matrix) 0%,
var(--veza-void) 100%);
--gradient-gaming: linear-gradient(135deg,
var(--veza-orange) 0%,
var(--veza-xp-gold) 100%);
/* === TYPOGRAPHY === */
--font-display: 'Orbitron', 'Noto Sans JP', system-ui, sans-serif;
--font-heading: 'Barlow', 'Noto Sans JP', system-ui, sans-serif;
--font-body: 'Inter', 'Barlow', system-ui, sans-serif;
--font-serif: 'Source Serif 4', Georgia, serif;
--font-mono: 'JetBrains Mono', 'IBM Plex Mono', 'Consolas', monospace;
/* Font Sizes - Modular Scale */
--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 */
/* === SPACING === */
--space-1: 0.25rem;
/* 4px */
--space-2: 0.5rem;
/* 8px */
--space-3: 0.75rem;
/* 12px */
--space-4: 1rem;
/* 16px */
--space-5: 1.25rem;
/* 20px */
--space-6: 1.5rem;
/* 24px */
--space-8: 2rem;
/* 32px */
--space-10: 2.5rem;
/* 40px */
--space-12: 3rem;
/* 48px */
--space-16: 4rem;
/* 64px */
--space-20: 5rem;
/* 80px */
--space-24: 6rem;
/* 96px */
/* === BORDERS & RADIUS === */
--radius-none: 0;
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 16px;
--radius-2xl: 24px;
--radius-full: 9999px;
--radius-organic: 60% 40% 50% 50% / 55% 50% 40% 60%;
/* Manga-style clip paths */
--clip-manga: polygon(0 0,
calc(100% - 12px) 0,
100% 12px,
100% 100%,
12px 100%,
0 calc(100% - 12px));
--clip-manga-lg: polygon(0 0,
calc(100% - 20px) 0,
100% 20px,
100% 100%,
20px 100%,
0 calc(100% - 20px));
--clip-hex: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
--clip-badge: polygon(0 10%,
10% 0,
90% 0,
100% 10%,
100% 90%,
90% 100%,
10% 100%,
0 90%);
/* === SHADOWS & GLOWS === */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.5);
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.5);
--shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.5);
--shadow-soft: 0 18px 45px rgba(0, 0, 0, 0.45);
/* Semantic shadows — use these for consistent card/modal/tooltip elevation */
--shadow-card: var(--shadow-soft);
--shadow-modal: var(--shadow-xl);
--shadow-tooltip: var(--shadow-md);
--shadow-card-hover: 0 8px 30px rgba(0, 0, 0, 0.25);
/* Button primary glow (hover) — avoids arbitrary shadow in components */
--button-primary-glow: 0 0 20px color-mix(in oklch, var(--primary) 25%, transparent);
--button-primary-glow-hover: 0 0 50px color-mix(in oklch, var(--primary) 35%, transparent);
/* Player — thumb glow and hover glow for floating bar */
--player-thumb-glow: 0 0 10px white;
--player-hover-glow: 0 0 50px color-mix(in oklch, var(--cyan-500) 15%, transparent);
/* Queue drawer — current track highlight */
--queue-item-current-glow: 0 0 15px color-mix(in oklch, var(--primary) 12%, transparent);
/* Slider (progress, volume) — track fill and thumb glow */
--slider-thumb-glow: 0 0 10px oklch(0.75 0.18 195 / 0.5);
/* Activity / status dots (dashboard, indicators) — use in index.css or where --cyan-500 etc. are defined */
--status-dot-glow-cyan: 0 0 8px oklch(0.75 0.18 195 / 0.8);
--status-dot-glow-lime: 0 0 8px oklch(0.72 0.19 145 / 0.8);
--status-dot-glow-magenta: 0 0 8px oklch(0.65 0.25 330 / 0.8);
/* Card glow variants (hover) */
--shadow-card-glow-cyan: 0 0 30px oklch(0.75 0.18 195 / 0.15);
--shadow-card-glow-magenta: 0 0 30px oklch(0.65 0.25 330 / 0.15);
/* Cover / hero depth (album art, profile header, full player) */
--shadow-cover-depth: 0 20px 50px rgba(0, 0, 0, 0.5);
/* Gaming / XP gold glow */
--shadow-gold-glow: 0 0 15px oklch(0.85 0.16 85 / 0.4);
/* FAB and floating CTA glow (stronger than button primary) */
--shadow-fab-glow: 0 0 30px color-mix(in oklch, var(--primary) 50%, transparent);
--shadow-fab-glow-hover: 0 0 40px color-mix(in oklch, var(--primary) 70%, transparent);
/* Neon Glows */
--glow-cyan: 0 0 20px var(--veza-cyan), 0 0 40px rgba(0, 255, 247, 0.3);
--glow-magenta: 0 0 20px var(--veza-magenta), 0 0 40px rgba(255, 0, 255, 0.3);
--glow-lime: 0 0 20px var(--veza-lime), 0 0 40px rgba(184, 255, 0, 0.3);
--glow-orange: 0 0 20px var(--veza-orange), 0 0 40px rgba(255, 107, 0, 0.3);
--glow-terminal:
0 0 10px var(--veza-terminal-green), 0 0 20px rgba(0, 255, 0, 0.2);
--glow-spectral: 0 0 22px rgba(102, 252, 241, 0.25);
/* === ANIMATIONS === */
--ease-out: cubic-bezier(0.33, 1, 0.68, 1);
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
--ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
--ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
--duration-instant: 100ms;
--duration-fast: 150ms;
--duration-normal: 250ms;
--duration-immersive: 200ms;
--duration-slow: 400ms;
--duration-slower: 600ms;
/* === LAYOUT === */
/* Shell layout (sidebar, header) is defined in index.css — single source of truth */
--max-width: 1400px;
--max-width-content: 1200px;
--max-width-narrow: 1120px;
}
/* ─────────────────────────────────────────────────────────────────────────
2. DARK THEME OVERRIDES
───────────────────────────────────────────────────────────────────────── */
.dark,
[data-theme='dark'] {
--veza-paper: #1a1c1a;
--veza-cream: #222422;
--veza-linen: #2a2c2a;
--veza-stone: #3a3c3a;
--veza-text: #e8e8e4;
--veza-text-light: #c8c8c4;
--veza-text-muted: #8a8a86;
--veza-text-faint: #5a5a58;
--veza-mint-light: #2a3228;
}
/* ─────────────────────────────────────────────────────────────────────────
3. KEYFRAME ANIMATIONS
───────────────────────────────────────────────────────────────────────── */
@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@keyframes logo-pulse {
0%,
100% {
filter: drop-shadow(0 0 8px var(--veza-cyan));
}
50% {
filter: drop-shadow(0 0 20px var(--veza-magenta));
}
}
@keyframes graffiti-shake {
0%,
100% {
transform: rotate(0deg);
}
25% {
transform: rotate(-2deg);
}
75% {
transform: rotate(2deg);
}
}
@keyframes gentle-pulse {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.6;
transform: scale(0.9);
}
}
@keyframes neon-flicker {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.8;
}
75% {
opacity: 0.95;
}
}
@keyframes slide-up {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slide-down {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes scale-in {
from {
opacity: 0;
transform: scale(0.9);
}
to {
opacity: 1;
transform: scale(1);
}
}
/* ─────────────────────────────────────────────────────────────────────────
4. UTILITY CLASSES
───────────────────────────────────────────────────────────────────────── */
/* Text Gradients */
.text-gradient-neon {
background: var(--gradient-neon);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.text-gradient-cyber {
background: var(--gradient-cyber);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.text-gradient-nature {
background: var(--gradient-nature);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.text-gradient-space {
background: var(--gradient-space);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Glow Effects */
.glow-cyan {
box-shadow: var(--glow-cyan);
}
.glow-magenta {
box-shadow: var(--glow-magenta);
}
.glow-lime {
box-shadow: var(--glow-lime);
}
.glow-terminal {
box-shadow: var(--glow-terminal);
}
/* Clip Paths */
.clip-manga {
clip-path: var(--clip-manga);
}
.clip-manga-lg {
clip-path: var(--clip-manga-lg);
}
.clip-hex {
clip-path: var(--clip-hex);
}
.clip-badge {
clip-path: var(--clip-badge);
}
/* Animations */
.animate-logo-spin {
animation: logo-spin 10s linear infinite;
}
.animate-logo-pulse {
animation: logo-pulse 3s ease-in-out infinite;
}
.animate-graffiti-shake {
animation: graffiti-shake 0.3s ease-in-out;
}
.animate-gentle-pulse {
animation: gentle-pulse 3s ease-in-out infinite;
}
.animate-neon-flicker {
animation: neon-flicker 2s ease-in-out infinite;
}
.animate-slide-up {
animation: slide-up var(--duration-normal) var(--ease-out);
}
.animate-slide-down {
animation: slide-down var(--duration-normal) var(--ease-out);
}
.animate-fade-in {
animation: fade-in var(--duration-normal) var(--ease-out);
}
.animate-scale-in {
animation: scale-in var(--duration-normal) var(--ease-out);
}
/* Hover Effects */
.hover-lift {
transition:
transform var(--duration-fast) var(--ease-out),
box-shadow var(--duration-fast) var(--ease-out);
}
.hover-lift:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-lg);
}
.hover-glow-cyan:hover {
box-shadow: var(--glow-cyan);
}
.hover-glow-magenta:hover {
box-shadow: var(--glow-magenta);
}
.hover-scale {
transition: transform var(--duration-fast) var(--ease-out);
}
.hover-scale:hover {
transform: scale(1.05);
}
/* Backdrop Effects */
.backdrop-blur-cyber {
backdrop-filter: blur(16px) saturate(180%);
background: rgba(5, 5, 8, 0.85);
}
.backdrop-blur-nature {
backdrop-filter: blur(12px);
background: rgba(250, 249, 246, 0.9);
}
.dark .backdrop-blur-nature {
background: rgba(26, 28, 26, 0.9);
}
/* Border Styles */
.border-neon {
border: 1px solid rgba(0, 255, 247, 0.3);
}
.border-nature {
border: 1px solid var(--veza-mint);
}
.border-gradient-neon {
border-image: linear-gradient(135deg, var(--veza-cyan), var(--veza-magenta)) 1;
}