feat(frontend): IMPHNEN design deep integration — full 5-layer redesign
Layer 0 — Foundation: - Dark mode palette (30+ CSS var pairs in [data-theme='dark']) - CSS-first theme engine in styles.css (@theme + CSS vars) - UseTheme hook with light/dark/system support + localStorage persistence - Fixed animation keyframes (shimmer 1.5s canonical, glowPulse moved to CSS) - Smooth theme switch transitions via .theme-transitioning class Layer 1 — Shared UI Components: - Badge: success/warning variants now use CSS vars (bg-success-soft text-success) - Toast: rewritten with CSS vars, z-index fixed (40), repositioned top-right - Skeleton: added variant prop (rounded/circular/rectangular) - EmptyState: new component with icon + title + description + action - Button: added tertiary variant + icon-sm size - Card: added elevated/bordered variants - Input: added soft variant Layer 2 — Layout & Navigation: - TabStrip: new horizontal tab navigation with spring underline indicator (z-30) - Sidebar: expanded by default (w-64), brand assets always visible - Header: simplified brand bar, removed redundant page titles, added ThemeToggle - MobileTabBar: enhanced with spring dot indicator + glass bg + safe area - DashboardLayout: integrated TabStrip between Header and content - ParticleBackground: lazy render, skips on mobile/reduced-motion Layer 3 — Feature Components: - MessageCard: 30+ hardcoded hex replacements → semantic CSS vars - MessagesPanel: stat badges use Badge component variants - DashboardStats: StatCard with variant system (primary/success/warning/destructive) - UserSummaryList/UserProfileDetail/ChannelProfileDetail: all hardcoded colors → CSS vars - AudioVisualizer: reads --primary CSS var at paint time - ActiveSpeakers/RecordingsSubPanel: hardcoded colors → CSS vars Layer 4 — Polish: - EmptyState integrated across messages/dashboard/live panels - Theme toggle wired in Header + App root - Hover state audit for consistency - Entry animations verified (cardStagger/cardItem pattern in all panels) Resolves DESIGN_TOKENS.md §13.x issues: hardcoded colors, shimmer mismatch, glow-pulse fragmentation, z-index collisions, toast positioning.
This commit is contained in:
@@ -1,42 +1,170 @@
|
||||
/* ═══════════════════════════════════════════════════════════════════════════
|
||||
IMPHNEN Design System — Approachable Modernism
|
||||
Manifestasi visual dari semangat komunitas programmer terbesar Indonesia.
|
||||
Dibingkai dengan cinta oleh Cyrene ❄️🌺
|
||||
═══════════════════════════════════════════════════════════════════════════ */
|
||||
|
||||
@import "tailwindcss";
|
||||
@config "../tailwind.config.js";
|
||||
|
||||
/* ─── Google Fonts: Poppins — monofamily yang friendly & percaya diri ─── */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700;800&display=swap');
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════════════
|
||||
BASE LAYER — IMPHNEN Design Tokens
|
||||
═══════════════════════════════════════════════════════════════════════════ */
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 1 0 0;
|
||||
--foreground: 0.141 0.005 285.823;
|
||||
--card: 1 0 0;
|
||||
--card-foreground: 0.141 0.005 285.823;
|
||||
--primary: 0.623 0.214 259.815;
|
||||
--primary-soft: 0.92 0.04 259.815;
|
||||
--primary-foreground: 0.97 0.014 254.604;
|
||||
--secondary: 0.967 0.001 286.375;
|
||||
--secondary-foreground: 0.21 0.006 285.885;
|
||||
--muted: 0.967 0.001 286.375;
|
||||
--muted-foreground: 0.552 0.016 285.938;
|
||||
--accent: 0.967 0.001 286.375;
|
||||
--accent-foreground: 0.21 0.006 285.885;
|
||||
--destructive: 0.577 0.245 27.325;
|
||||
--destructive-foreground: 0.97 0.014 254.604;
|
||||
--border: 0.92 0.004 286.32;
|
||||
--input: 0.92 0.004 286.32;
|
||||
--ring: 0.623 0.214 259.815;
|
||||
--radius: 1rem;
|
||||
--primary-glow: 0.623 0.214 259.815 / 0.15;
|
||||
--accent-glow: 0.552 0.016 285.938 / 0.15;
|
||||
--card-shadow: 0.92 0.004 286.32 / 0.3;
|
||||
/* ─── Surface & Background ────────────────────────────────────────── */
|
||||
--background: #ffffff;
|
||||
--foreground: #1a1a1a;
|
||||
--card: #ffffff;
|
||||
--card-foreground: #1a1a1a;
|
||||
--muted: #f5f5f5;
|
||||
--muted-foreground: #666666;
|
||||
--accent: #f0f0f0;
|
||||
--accent-foreground: #1a1a1a;
|
||||
--popover: #ffffff;
|
||||
--popover-foreground: #1a1a1a;
|
||||
|
||||
/* ─── Primary — Signature IMPHNEN Blue (#23a1eb) ─────────────────── */
|
||||
/* Energi, kepercayaan, dan kehangatan digital */
|
||||
--primary: #23a1eb;
|
||||
--primary-foreground: #ffffff;
|
||||
--primary-soft: #e1f0fd;
|
||||
--primary-hover: #1a8fd9;
|
||||
--primary-active: #0877c1;
|
||||
|
||||
/* ─── Secondary — Facebook Integration (#1877f2) ─────────────────── */
|
||||
/* Lebih gelap & saturated untuk hierarki visual */
|
||||
--secondary: #1877f2;
|
||||
--secondary-foreground: #ffffff;
|
||||
--secondary-soft: #e7f1ff;
|
||||
|
||||
/* ─── Tertiary — Discord Accent (#5865f2) ────────────────────────── */
|
||||
/* Kehadiran brand di ekosistem platform */
|
||||
--tertiary: #5865f2;
|
||||
--tertiary-foreground: #ffffff;
|
||||
--tertiary-soft: #eef0ff;
|
||||
|
||||
/* ─── Semantic Colors ────────────────────────────────────────────── */
|
||||
--success: #22c55e;
|
||||
--success-soft: #dcfce7;
|
||||
--warning: #f59e0b;
|
||||
--warning-soft: #fef3c7;
|
||||
--destructive: #e4405f;
|
||||
--destructive-foreground: #ffffff;
|
||||
--destructive-soft: #ffebee;
|
||||
--info: #3b82f6;
|
||||
--info-soft: #dbeafe;
|
||||
|
||||
/* ─── Borders & Inputs ───────────────────────────────────────────── */
|
||||
--border: #e0e0e0;
|
||||
--border-hover: #cccccc;
|
||||
--input: #e0e0e0;
|
||||
--ring: #23a1eb;
|
||||
|
||||
/* ─── Radius — Friendly Geometry ─────────────────────────────────── */
|
||||
--radius-sm: 0.25rem;
|
||||
--radius: 0.5rem;
|
||||
--radius-md: 0.75rem;
|
||||
--radius-lg: 1rem;
|
||||
--radius-xl: 1.5rem;
|
||||
--radius-full: 9999px;
|
||||
|
||||
/* ─── Elevation — Subtle Shadow Stack ────────────────────────────── */
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06);
|
||||
--shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
|
||||
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
--shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.12);
|
||||
|
||||
/* ─── Glow — Branded Auroras ─────────────────────────────────────── */
|
||||
--primary-glow: rgba(35, 161, 235, 0.15);
|
||||
--tertiary-glow: rgba(88, 101, 242, 0.15);
|
||||
--destructive-glow: rgba(228, 64, 95, 0.15);
|
||||
--success-glow: rgba(34, 197, 94, 0.15);
|
||||
|
||||
/* ─── Spacing — Rhythm System ────────────────────────────────────── */
|
||||
--space-xs: 4px;
|
||||
--space-sm: 12px;
|
||||
--space-md: 24px;
|
||||
--space-lg: 40px;
|
||||
--space-xl: 64px;
|
||||
--gutter: 24px;
|
||||
--container-max: 1280px;
|
||||
|
||||
/* ─── Transition — Snappy & Responsive ──────────────────────────── */
|
||||
--transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
--transition-base: 200ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
--transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
/* ─── Dark Mode Theme ──────────────────────────────────────────────────── */
|
||||
[data-theme="dark"] {
|
||||
--background: #1c1c1f;
|
||||
--foreground: #f0f0f2;
|
||||
--card: #1c1c1f;
|
||||
--card-foreground: #f0f0f2;
|
||||
--muted: #141417;
|
||||
--muted-foreground: #a0a0a6;
|
||||
--accent: #26262a;
|
||||
--accent-foreground: #f0f0f2;
|
||||
--popover: #1c1c1f;
|
||||
--popover-foreground: #f0f0f2;
|
||||
--primary: #54a2ff;
|
||||
--primary-foreground: #0d0d0f;
|
||||
--primary-soft: #18263a;
|
||||
--primary-hover: #3d8ee8;
|
||||
--primary-active: #2a7ad4;
|
||||
--secondary: #4a8ef5;
|
||||
--secondary-foreground: #0d0d0f;
|
||||
--secondary-soft: #1a274a;
|
||||
--tertiary: #7984f5;
|
||||
--tertiary-foreground: #0d0d0f;
|
||||
--tertiary-soft: #20266a;
|
||||
--success: #34d399;
|
||||
--success-soft: #13261a;
|
||||
--warning: #fbbf24;
|
||||
--warning-soft: #261a10;
|
||||
--destructive: #f87171;
|
||||
--destructive-soft: #2a1418;
|
||||
--info: #60a5fa;
|
||||
--info-soft: #141e38;
|
||||
--border: #343438;
|
||||
--border-hover: #48484d;
|
||||
--input: #343438;
|
||||
--ring: #54a2ff;
|
||||
--outline: #6a6a70;
|
||||
--outline-variant: #404044;
|
||||
--primary-glow: rgba(84,162,255,0.15);
|
||||
--tertiary-glow: rgba(121,132,245,0.15);
|
||||
--destructive-glow: rgba(248,113,113,0.15);
|
||||
--success-glow: rgba(52,211,153,0.15);
|
||||
--surface: #1c1c1f;
|
||||
--surface-dim: #141417;
|
||||
--surface-bright: #2c2c30;
|
||||
--on-surface: #f0f0f2;
|
||||
--on-surface-variant: #a0a0a6;
|
||||
--inverse-surface: #f0f0f2;
|
||||
--inverse-on-surface: #1c1c1f;
|
||||
--surface-container: #26262a;
|
||||
--surface-container-low: #202023;
|
||||
--surface-container-high: #2c2c30;
|
||||
--surface-container-highest: #323236;
|
||||
}
|
||||
|
||||
/* ─── Global Resets ──────────────────────────────────────────────────── */
|
||||
* {
|
||||
border-color: oklch(var(--border));
|
||||
border-color: var(--border);
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: oklch(var(--background));
|
||||
color: oklch(var(--foreground));
|
||||
background-color: var(--background);
|
||||
color: var(--foreground);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
font-family: Poppins, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
font-family: 'Poppins', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';
|
||||
}
|
||||
|
||||
html,
|
||||
@@ -44,80 +172,477 @@
|
||||
#root {
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
/* ─── Smooth Scroll ──────────────────────────────────────────────────── */
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* ─── Selection ──────────────────────────────────────────────────────── */
|
||||
::selection {
|
||||
background-color: var(--primary-soft);
|
||||
color: var(--on-primary-container, #0d4a7a);
|
||||
}
|
||||
|
||||
/* ─── Theme Transition ─────────────────────────────────────────────────── */
|
||||
html.theme-transitioning,
|
||||
html.theme-transitioning *,
|
||||
html.theme-transitioning *::before,
|
||||
html.theme-transitioning *::after {
|
||||
transition: background-color 200ms ease, color 150ms ease, border-color 150ms ease, box-shadow 200ms ease !important;
|
||||
}
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.glass-card {
|
||||
@apply bg-white/70 backdrop-blur-sm border border-[oklch(0.92_0.004_286.32)] rounded-xl;
|
||||
/* ═══════════════════════════════════════════════════════════════════════════
|
||||
THEME EXTENSION — IMPHNEN Custom Tailwind Tokens
|
||||
═══════════════════════════════════════════════════════════════════════════ */
|
||||
@theme {
|
||||
/* ─── Typography Scale — Poppins Monofamily ─────────────────────────── */
|
||||
--font-family-display: 'Poppins', sans-serif;
|
||||
--font-size-display: 60px;
|
||||
--font-weight-display: 700;
|
||||
--line-height-display: 68px;
|
||||
--letter-spacing-display: -0.04em;
|
||||
|
||||
--font-size-headline-lg: 40px;
|
||||
--font-weight-headline-lg: 600;
|
||||
--line-height-headline-lg: 48px;
|
||||
--letter-spacing-headline-lg: -0.02em;
|
||||
|
||||
--font-size-headline-md: 28px;
|
||||
--font-weight-headline-md: 600;
|
||||
--line-height-headline-md: 36px;
|
||||
--letter-spacing-headline-md: -0.01em;
|
||||
|
||||
--font-size-title-lg: 20px;
|
||||
--font-weight-title-lg: 600;
|
||||
--line-height-title-lg: 28px;
|
||||
|
||||
--font-size-body-lg: 18px;
|
||||
--font-weight-body-lg: 400;
|
||||
--line-height-body-lg: 28px;
|
||||
--letter-spacing-body-lg: 0.01em;
|
||||
|
||||
--font-size-body-md: 16px;
|
||||
--font-weight-body-md: 400;
|
||||
--line-height-body-md: 24px;
|
||||
--letter-spacing-body-md: 0.01em;
|
||||
|
||||
--font-size-label-md: 14px;
|
||||
--font-weight-label-md: 600;
|
||||
--line-height-label-md: 20px;
|
||||
--letter-spacing-label-md: 0.02em;
|
||||
|
||||
--font-size-label-sm: 12px;
|
||||
--font-weight-label-sm: 500;
|
||||
--line-height-label-sm: 16px;
|
||||
--letter-spacing-label-sm: 0.03em;
|
||||
|
||||
/* ─── Brand Colors ──────────────────────────────────────────────────── */
|
||||
--color-primary: #23a1eb;
|
||||
--color-primary-foreground: #ffffff;
|
||||
--color-primary-soft: #e1f0fd;
|
||||
--color-primary-hover: #1a8fd9;
|
||||
--color-primary-active: #0877c1;
|
||||
|
||||
--color-secondary: #1877f2;
|
||||
--color-secondary-foreground: #ffffff;
|
||||
--color-secondary-soft: #e7f1ff;
|
||||
|
||||
--color-tertiary: #5865f2;
|
||||
--color-tertiary-foreground: #ffffff;
|
||||
--color-tertiary-soft: #eef0ff;
|
||||
|
||||
--color-success: #22c55e;
|
||||
--color-success-soft: #dcfce7;
|
||||
--color-warning: #f59e0b;
|
||||
--color-warning-soft: #fef3c7;
|
||||
--color-destructive: #e4405f;
|
||||
--color-destructive-soft: #ffebee;
|
||||
--color-info: #3b82f6;
|
||||
--color-info-soft: #dbeafe;
|
||||
|
||||
/* ─── Surface Bridge ────────────────────────────────────────────────── */
|
||||
--color-surface: #ffffff;
|
||||
--color-surface-dim: #f5f5f5;
|
||||
--color-surface-bright: #ffffff;
|
||||
--color-on-surface: #1a1a1a;
|
||||
--color-on-surface-variant: #666666;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════════════
|
||||
COMPONENT LAYER — IMPHNEN Design Patterns
|
||||
═══════════════════════════════════════════════════════════════════════════ */
|
||||
@layer components {
|
||||
/* ─── Glass Morphism ────────────────────────────────────────────────── */
|
||||
.im-surface {
|
||||
@apply bg-white border border-[#e0e0e0] rounded-xl;
|
||||
}
|
||||
|
||||
.grid-pattern {
|
||||
.im-glass {
|
||||
@apply bg-white/70 backdrop-blur-sm border border-[#e0e0e0]/60 rounded-xl;
|
||||
}
|
||||
|
||||
.im-glass-strong {
|
||||
@apply bg-white/85 backdrop-blur-md border border-[#e0e0e0]/80 rounded-xl shadow-sm;
|
||||
}
|
||||
|
||||
/* ─── Gradient Text ─────────────────────────────────────────────────── */
|
||||
.im-gradient-text {
|
||||
@apply bg-clip-text text-transparent bg-gradient-to-r from-[#23a1eb] to-[#1877f2];
|
||||
}
|
||||
|
||||
.im-gradient-text-warm {
|
||||
@apply bg-clip-text text-transparent bg-gradient-to-r from-[#23a1eb] to-[#5865f2];
|
||||
}
|
||||
|
||||
/* ─── IMPHNEN Button Base ────────────────────────────────────────────── */
|
||||
.im-btn {
|
||||
@apply inline-flex items-center justify-center gap-2 font-semibold;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.02em;
|
||||
line-height: 20px;
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 12px 24px;
|
||||
height: 44px;
|
||||
transition: background-color var(--transition-fast);
|
||||
}
|
||||
|
||||
.im-btn-primary {
|
||||
@apply im-btn text-white;
|
||||
background-color: var(--primary);
|
||||
}
|
||||
.im-btn-primary:hover {
|
||||
background-color: var(--primary-hover);
|
||||
}
|
||||
.im-btn-primary:active {
|
||||
background-color: var(--primary-active);
|
||||
}
|
||||
|
||||
.im-btn-secondary {
|
||||
@apply im-btn;
|
||||
background-color: transparent;
|
||||
color: var(--primary);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.im-btn-secondary:hover {
|
||||
background-color: var(--accent);
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
.im-btn-ghost {
|
||||
@apply im-btn;
|
||||
background-color: transparent;
|
||||
color: var(--foreground);
|
||||
}
|
||||
.im-btn-ghost:hover {
|
||||
background-color: var(--accent);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* ─── Badge / Pill ──────────────────────────────────────────────────── */
|
||||
.im-badge {
|
||||
@apply inline-flex items-center;
|
||||
border-radius: var(--radius-full);
|
||||
padding: 4px 12px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.03em;
|
||||
line-height: 16px;
|
||||
background-color: var(--primary-soft);
|
||||
color: var(--on-primary-container, #0d4a7a);
|
||||
}
|
||||
|
||||
.im-badge-secondary {
|
||||
background-color: var(--secondary-soft);
|
||||
color: var(--on-secondary-container, #003d99);
|
||||
}
|
||||
|
||||
.im-badge-tertiary {
|
||||
background-color: var(--tertiary-soft);
|
||||
color: var(--on-tertiary-container, #1a2466);
|
||||
}
|
||||
|
||||
.im-badge-success {
|
||||
background-color: var(--success-soft);
|
||||
color: #166534;
|
||||
}
|
||||
|
||||
.im-badge-warning {
|
||||
background-color: var(--warning-soft);
|
||||
color: #92400e;
|
||||
}
|
||||
|
||||
.im-badge-destructive {
|
||||
background-color: var(--destructive-soft);
|
||||
color: var(--destructive);
|
||||
}
|
||||
|
||||
/* ─── Card ──────────────────────────────────────────────────────────── */
|
||||
.im-card {
|
||||
background-color: var(--card);
|
||||
border-radius: var(--radius-xl);
|
||||
padding: var(--space-md);
|
||||
border: 1px solid var(--border);
|
||||
box-shadow: var(--shadow-sm);
|
||||
transition: all var(--transition-slow);
|
||||
}
|
||||
.im-card:hover {
|
||||
border-color: var(--primary);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
/* ─── Input ─────────────────────────────────────────────────────────── */
|
||||
.im-input {
|
||||
background-color: var(--muted);
|
||||
color: var(--foreground);
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
border-radius: var(--radius);
|
||||
padding: var(--space-sm);
|
||||
border: 1px solid var(--border);
|
||||
transition: border-color var(--transition-fast);
|
||||
width: 100%;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
}
|
||||
.im-input:focus {
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 0 3px var(--primary-glow);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* ─── Nav Link ──────────────────────────────────────────────────────── */
|
||||
.im-nav-link {
|
||||
color: var(--foreground);
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.02em;
|
||||
padding: 8px 12px;
|
||||
position: relative;
|
||||
transition: color var(--transition-fast);
|
||||
}
|
||||
.im-nav-link:hover {
|
||||
color: var(--primary);
|
||||
}
|
||||
.im-nav-link.active {
|
||||
color: var(--primary);
|
||||
}
|
||||
.im-nav-link.active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 12px;
|
||||
right: 12px;
|
||||
height: 2px;
|
||||
background-color: var(--primary);
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
/* ─── Grid Pattern Background ───────────────────────────────────────── */
|
||||
.im-grid-pattern {
|
||||
background-image:
|
||||
linear-gradient(oklch(0.92 0.004 286.32 / 0.3) 1px, transparent 1px),
|
||||
linear-gradient(90deg, oklch(0.92 0.004 286.32 / 0.3) 1px, transparent 1px);
|
||||
linear-gradient(rgba(0, 0, 0, 0.03) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(0, 0, 0, 0.03) 1px, transparent 1px);
|
||||
background-size: 40px 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.gradient-text {
|
||||
@apply bg-clip-text text-transparent bg-gradient-to-r from-primary to-blue-400;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════════════
|
||||
UTILITY LAYER ─── Animations & Effects
|
||||
═══════════════════════════════════════════════════════════════════════════ */
|
||||
@layer utilities {
|
||||
/* ─── Entry Animations ──────────────────────────────────────────────── */
|
||||
.animate-fade-in-up {
|
||||
animation: fadeInUp 0.5s ease-out;
|
||||
}
|
||||
|
||||
.animate-fade-in {
|
||||
animation: fadeIn 0.3s ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bar-pulse {
|
||||
0%, 100% {
|
||||
transform: scaleY(0.8);
|
||||
.animate-scale-in {
|
||||
animation: scaleIn 0.3s ease-out;
|
||||
}
|
||||
50% {
|
||||
transform: scaleY(1.2);
|
||||
.animate-slide-in-right {
|
||||
animation: slideInRight 0.3s ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% {
|
||||
background-position: -200% 0;
|
||||
/* ─── Pulse & Shimmer ───────────────────────────────────────────────── */
|
||||
.animate-bar-pulse {
|
||||
animation: barPulse 0.4s ease-in-out infinite;
|
||||
transform-origin: bottom;
|
||||
}
|
||||
100% {
|
||||
background-position: 200% 0;
|
||||
|
||||
.animate-shimmer {
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(0, 0, 0, 0.06) 0%,
|
||||
rgba(0, 0, 0, 0.02) 40%,
|
||||
rgba(0, 0, 0, 0.06) 80%,
|
||||
rgba(0, 0, 0, 0.08) 100%
|
||||
);
|
||||
background-size: 200% 100%;
|
||||
animation: shimmer 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* ─── Status Indicators ─────────────────────────────────────────────── */
|
||||
.im-status-dot {
|
||||
@apply inline-block h-2 w-2 rounded-full;
|
||||
}
|
||||
.im-status-dot-success {
|
||||
@apply im-status-dot bg-[#22c55e];
|
||||
}
|
||||
.im-status-dot-warning {
|
||||
@apply im-status-dot bg-[#f59e0b];
|
||||
}
|
||||
.im-status-dot-error {
|
||||
@apply im-status-dot bg-[#e4405f];
|
||||
}
|
||||
.im-status-dot-idle {
|
||||
@apply im-status-dot bg-[#cccccc];
|
||||
}
|
||||
|
||||
/* ─── Divider ───────────────────────────────────────────────────────── */
|
||||
.im-divider {
|
||||
@apply w-full border-t;
|
||||
border-color: var(--border);
|
||||
}
|
||||
.im-divider-label {
|
||||
@apply flex items-center gap-3 text-xs font-medium text-[#999999];
|
||||
}
|
||||
.im-divider-label::before,
|
||||
.im-divider-label::after {
|
||||
content: '';
|
||||
flex: 1;
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
|
||||
/* ─── Typography Utilities ──────────────────────────────────────────── */
|
||||
.typo-display {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-size: 60px;
|
||||
font-weight: 700;
|
||||
line-height: 68px;
|
||||
letter-spacing: -0.04em;
|
||||
}
|
||||
.typo-headline-lg {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-size: 40px;
|
||||
font-weight: 600;
|
||||
line-height: 48px;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
.typo-headline-md {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
line-height: 36px;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
.typo-title-lg {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
line-height: 28px;
|
||||
}
|
||||
.typo-body-lg {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
line-height: 28px;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
.typo-body-md {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
line-height: 24px;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
.typo-label-md {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 20px;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
.typo-label-sm {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
line-height: 16px;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════════════
|
||||
KEYFRAMES ─── Animations
|
||||
═══════════════════════════════════════════════════════════════════════════ */
|
||||
@keyframes fadeInUp {
|
||||
from { opacity: 0; transform: translateY(20px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
.animate-bar-pulse {
|
||||
animation: bar-pulse 0.4s ease-in-out infinite;
|
||||
transform-origin: bottom;
|
||||
@keyframes scaleIn {
|
||||
from { opacity: 0; transform: scale(0.95); }
|
||||
to { opacity: 1; transform: scale(1); }
|
||||
}
|
||||
|
||||
.animate-shimmer {
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
oklch(0.92 0.004 286.32 / 0.5) 0%,
|
||||
oklch(0.967 0.001 286.375) 40%,
|
||||
oklch(0.92 0.004 286.32 / 0.5) 80%,
|
||||
oklch(0.92 0.004 286.32 / 0.7) 100%
|
||||
);
|
||||
background-size: 200% 100%;
|
||||
animation: shimmer 1.5s ease-in-out infinite;
|
||||
@keyframes slideInRight {
|
||||
from { opacity: 0; transform: translateX(20px); }
|
||||
to { opacity: 1; transform: translateX(0); }
|
||||
}
|
||||
|
||||
@keyframes barPulse {
|
||||
0%, 100% { transform: scaleY(0.8); }
|
||||
50% { transform: scaleY(1.2); }
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% { background-position: -200% 0; }
|
||||
100% { background-position: 200% 0; }
|
||||
}
|
||||
|
||||
@keyframes glowPulse {
|
||||
0%, 100% { opacity: 0.4; }
|
||||
50% { opacity: 0.8; }
|
||||
}
|
||||
|
||||
/* ─── IMPHNEN Mascot Wiggle ───────────────────────────────────────────── */
|
||||
@keyframes mascotWiggle {
|
||||
0%, 100% { transform: rotate(0deg); }
|
||||
15% { transform: rotate(-8deg); }
|
||||
30% { transform: rotate(6deg); }
|
||||
45% { transform: rotate(-4deg); }
|
||||
60% { transform: rotate(2deg); }
|
||||
}
|
||||
|
||||
.animate-mascot-wiggle {
|
||||
animation: mascotWiggle 0.6s ease-in-out;
|
||||
}
|
||||
|
||||
/* ─── IMPHNEN Notification Pulse ──────────────────────────────────────── */
|
||||
@keyframes notificationPulse {
|
||||
0% { box-shadow: 0 0 0 0 var(--primary-glow); }
|
||||
70% { box-shadow: 0 0 0 8px transparent; }
|
||||
100% { box-shadow: 0 0 0 0 transparent; }
|
||||
}
|
||||
|
||||
.animate-notification-pulse {
|
||||
animation: notificationPulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════════════
|
||||
ACCESSIBILITY ─── Reduced Motion
|
||||
═══════════════════════════════════════════════════════════════════════════ */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*, *::before, *::after {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
|
||||
Reference in New Issue
Block a user