@import 'tailwindcss'; @import 'tw-animate-css'; @custom-variant dark (&:is([data-theme="dark"] *)); /* ╔══════════════════════════════════════════════════════════════════════════╗ ║ SUMI DESIGN SYSTEM v2.0 — "L'encre et la lumière" ║ ║ VEZA × TALAS — Single Source of Truth ║ ║ Ref: apps/web/docs/DESIGN_SYSTEM_REFERENCE.md ║ ╚══════════════════════════════════════════════════════════════════════════╝ */ /* ═══════════════════════════════════════════════════════════════════════════ DARK THEME (default) — Ink on void ═══════════════════════════════════════════════════════════════════════════ */ :root, [data-theme="dark"] { /* ═══ BACKGROUNDS ═══ */ --sumi-bg-void: #0c0c0f; --sumi-bg-base: #121215; --sumi-bg-raised: #1a1a1f; --sumi-bg-overlay: #222228; --sumi-bg-hover: #2a2a31; --sumi-bg-active: #32323a; --sumi-bg-wash: #18181d; /* ═══ SURFACES ═══ */ --sumi-surface-inset: #101013; --sumi-surface-subtle: #1e1e24; --sumi-surface-card: #1a1a1f; --sumi-surface-elevated: #242430; /* ═══ BORDERS ═══ */ --sumi-border-faint: rgba(255,255,255, 0.06); --sumi-border-default: rgba(255,255,255, 0.10); --sumi-border-strong: rgba(255,255,255, 0.16); --sumi-border-focus: rgba(139,170,220, 0.50); --sumi-border-accent: rgba(139,170,220, 0.30); /* ═══ TEXT ═══ */ --sumi-text-primary: #f0ede8; --sumi-text-secondary: #a8a4a0; --sumi-text-tertiary: #706c68; --sumi-text-disabled: #4a4844; --sumi-text-inverse: #121215; --sumi-text-link: #8baade; /* ═══ PIGMENTS — Les 4 Pigments d'accent ═══ */ --sumi-accent: #7c9dd6; --sumi-accent-hover: #93afe0; --sumi-accent-active: #6b8dc6; --sumi-accent-muted: rgba(124,157,214, 0.20); --sumi-accent-subtle: rgba(124,157,214, 0.12); --sumi-accent-emphasis: #5a7fba; --sumi-vermillion: #d4634a; --sumi-vermillion-hover: #de7a64; --sumi-vermillion-subtle: rgba(212,99,74, 0.12); --sumi-sage: #7a9e6c; --sumi-sage-hover: #8eb280; --sumi-sage-subtle: rgba(122,158,108, 0.12); --sumi-gold: #c9a84c; --sumi-gold-hover: #d6b860; --sumi-gold-subtle: rgba(201,168,76, 0.12); /* ═══ SEMANTIC ═══ */ --sumi-success: var(--sumi-sage); --sumi-success-subtle: var(--sumi-sage-subtle); --sumi-warning: var(--sumi-gold); --sumi-warning-subtle: var(--sumi-gold-subtle); --sumi-error: var(--sumi-vermillion); --sumi-error-subtle: var(--sumi-vermillion-subtle); --sumi-info: var(--sumi-accent); --sumi-live: #e05a5a; --sumi-online: var(--sumi-sage); /* ═══ TYPOGRAPHY ═══ */ --sumi-font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; --sumi-font-heading: 'Space Grotesk', 'Inter', sans-serif; --sumi-font-mono: 'JetBrains Mono', 'SF Mono', 'Consolas', monospace; --sumi-font-serif: 'Noto Serif JP', Georgia, serif; --sumi-text-4xl: 2.25rem; --sumi-text-3xl: 1.875rem; --sumi-text-2xl: 1.5rem; --sumi-text-xl: 1.25rem; --sumi-text-lg: 1.125rem; --sumi-text-md: 1rem; --sumi-text-base: 0.875rem; --sumi-text-sm: 0.8125rem; --sumi-text-xs: 0.75rem; --sumi-leading-none: 1; --sumi-leading-tight: 1.25; --sumi-leading-snug: 1.375; --sumi-leading-normal: 1.5; --sumi-leading-relaxed: 1.625; --sumi-leading-loose: 1.75; --sumi-tracking-tighter: -0.03em; --sumi-tracking-tight: -0.015em; --sumi-tracking-normal: 0; --sumi-tracking-wide: 0.025em; --sumi-tracking-wider: 0.05em; --sumi-tracking-widest: 0.1em; --sumi-weight-light: 300; --sumi-weight-regular: 400; --sumi-weight-medium: 500; --sumi-weight-semibold: 600; --sumi-weight-bold: 700; /* ═══ SPACING ═══ */ --sumi-space-0-5: 2px; --sumi-space-1: 4px; --sumi-space-1-5: 6px; --sumi-space-2: 8px; --sumi-space-2-5: 10px; --sumi-space-3: 12px; --sumi-space-4: 16px; --sumi-space-5: 20px; --sumi-space-6: 24px; --sumi-space-8: 32px; --sumi-space-10: 40px; --sumi-space-12: 48px; --sumi-space-16: 64px; --sumi-space-20: 80px; /* ═══ RADIUS ═══ */ --sumi-radius-xs: 2px; --sumi-radius-sm: 4px; --sumi-radius-md: 6px; --sumi-radius-lg: 12px; --sumi-radius-xl: 16px; --sumi-radius-2xl: 20px; --sumi-radius-full: 9999px; /* ═══ SHADOWS ═══ */ --sumi-shadow-xs: 0 1px 2px rgba(0,0,0,0.30); --sumi-shadow-sm: 0 2px 4px rgba(0,0,0,0.25), 0 1px 2px rgba(0,0,0,0.20); --sumi-shadow-md: 0 4px 12px rgba(0,0,0,0.30), 0 2px 4px rgba(0,0,0,0.15); --sumi-shadow-lg: 0 8px 24px rgba(0,0,0,0.35), 0 4px 8px rgba(0,0,0,0.20); --sumi-shadow-xl: 0 16px 48px rgba(0,0,0,0.40), 0 8px 16px rgba(0,0,0,0.20); --sumi-shadow-2xl: 0 24px 64px rgba(0,0,0,0.50); --sumi-shadow-glow: 0 0 0 3px rgba(124,157,214,0.25); --sumi-shadow-glow-lg: 0 0 20px rgba(124,157,214,0.15); /* ═══ GLASS ═══ */ --sumi-glass-bg: rgba(18,18,21, 0.80); --sumi-glass-border: rgba(255,255,255, 0.08); --sumi-glass-blur: 12px; /* ═══ SCROLLBAR ═══ */ --sumi-scrollbar-track: transparent; --sumi-scrollbar-thumb: rgba(255,255,255, 0.10); --sumi-scrollbar-hover: rgba(255,255,255, 0.18); /* ═══ MOTION ═══ */ --sumi-duration-instant: 75ms; --sumi-duration-fast: 150ms; --sumi-duration-normal: 200ms; --sumi-duration-slow: 300ms; --sumi-duration-slower: 500ms; --sumi-ease-default: cubic-bezier(0.25, 0.1, 0.25, 1); --sumi-ease-out: cubic-bezier(0.33, 1, 0.68, 1); --sumi-ease-in: cubic-bezier(0.32, 0, 0.67, 0); --sumi-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); --sumi-ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1); --sumi-ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.1); --sumi-transition-colors: color var(--sumi-duration-fast) var(--sumi-ease-default), background-color var(--sumi-duration-fast) var(--sumi-ease-default), border-color var(--sumi-duration-fast) var(--sumi-ease-default); --sumi-transition-opacity: opacity var(--sumi-duration-fast) var(--sumi-ease-default); --sumi-transition-transform: transform var(--sumi-duration-normal) var(--sumi-ease-out); --sumi-transition-shadow: box-shadow var(--sumi-duration-fast) var(--sumi-ease-default); /* ═══ Z-INDEX ═══ */ --sumi-z-base: 0; --sumi-z-raised: 10; --sumi-z-dropdown: 100; --sumi-z-sticky: 200; --sumi-z-overlay: 300; --sumi-z-modal: 400; --sumi-z-popover: 500; --sumi-z-toast: 600; --sumi-z-tooltip: 700; --sumi-z-max: 999; /* ═══ LAYOUT ═══ */ --sumi-max-width: 1400px; --sumi-max-width-content: 1200px; --sumi-max-width-narrow: 800px; --sumi-max-width-prose: 65ch; --sumi-sidebar-width: 240px; --sumi-sidebar-collapsed: 64px; --sumi-header-height: 56px; --sumi-player-height: 80px; /* ═══ CONTEXTUAL ACCENTS (feature-specific) ═══ */ --graffiti-magenta: #c840a0; --gaming-gold: #d4b040; --terminal-green: #3eaa5e; --sakura: #e0a0b8; /* ═══ SHADCN/RADIX SEMANTIC MAPPING ═══ */ --background: var(--sumi-bg-base); --foreground: var(--sumi-text-primary); --card: var(--sumi-surface-card); --card-foreground: var(--sumi-text-primary); --popover: var(--sumi-bg-overlay); --popover-foreground: var(--sumi-text-primary); --primary: var(--sumi-accent); --primary-foreground: var(--sumi-text-inverse); --secondary: var(--sumi-bg-hover); --secondary-foreground: var(--sumi-text-primary); --muted: var(--sumi-bg-hover); --muted-foreground: var(--sumi-text-secondary); --accent: var(--sumi-bg-hover); --accent-foreground: var(--sumi-text-primary); --destructive: var(--sumi-vermillion); --destructive-foreground: #ffffff; --success: var(--sumi-success); --success-foreground: #ffffff; --warning: var(--sumi-warning); --warning-foreground: var(--sumi-text-inverse); --info: var(--sumi-info); --info-foreground: var(--sumi-text-inverse); --border: var(--sumi-border-default); --input: var(--sumi-border-default); --ring: var(--sumi-border-focus); --radius: var(--sumi-radius-md); /* Charts */ --chart-1: var(--sumi-accent); --chart-2: var(--sumi-vermillion); --chart-3: var(--sumi-sage); --chart-4: var(--sumi-gold); --chart-5: #8b7ec8; /* Sidebar mapping */ --sidebar: var(--sumi-bg-raised); --sidebar-foreground: var(--sumi-text-secondary); --sidebar-primary: var(--sumi-accent); --sidebar-primary-foreground: var(--sumi-text-primary); --sidebar-accent: var(--sumi-accent-subtle); --sidebar-accent-foreground: var(--sumi-text-primary); --sidebar-border: var(--sumi-border-faint); --sidebar-ring: var(--sumi-accent); /* Sidebar active item indicator */ --sidebar-active-indicator: inset 2px 0 0 0 var(--sidebar-primary); /* ═══ LAYOUT PRIMITIVES (preserved from previous system) ═══ */ --layout-content-max-width: 100rem; --layout-main-min-height: calc(100vh - 4rem); --layout-page-min-height: 37.5rem; --layout-page-min-height-sm: 25rem; --layout-story-decorator-min-height: 12rem; --layout-gap: 1rem; --layout-gap-sm: 0.75rem; --layout-gap-lg: 1.5rem; --layout-drawer-max-height: 60vh; --layout-panel-max-height: 70vh; --layout-list-max-height: 25rem; --layout-modal-max-height: 85vh; --layout-modal-max-height-sm: 80vh; --layout-modal-max-height-xs: 70vh; --layout-modal-max-height-lg: 90vh; --layout-lyrics-height: 60vh; --layout-lyrics-height-sm: 50vh; --layout-chat-height: calc(100vh - 6.25rem); --layout-chat-main-height: calc(100vh - 6rem); --layout-stream-height: calc(100vh - 6rem); --layout-modal-full-height: calc(100vh - 2rem); /* App shell — header, main offsets and margins (sidebar-driven) */ --header-height: 4rem; --main-offset-top: 5rem; --main-offset-bottom: 9rem; --main-margin-left-expanded: 18rem; --main-margin-left-collapsed: 7rem; --header-left-expanded: 18rem; --header-left-collapsed: 5rem; /* Sidebar layout */ --sidebar-width-expanded: 15rem; --sidebar-width-collapsed: 5rem; --sidebar-offset-left: 1.5rem; --sidebar-offset-top: 5rem; --sidebar-offset-bottom: 1.5rem; --sidebar-z-index: 95; --sidebar-overlay-z-index: 90; --player-z-index: var(--sumi-z-sticky); } /* ═══════════════════════════════════════════════════════════════════════════ LIGHT THEME — Washi Paper (和紙) ═══════════════════════════════════════════════════════════════════════════ */ [data-theme="light"] { --sumi-bg-void: #f0ece4; --sumi-bg-base: #f6f3ed; --sumi-bg-raised: #ffffff; --sumi-bg-overlay: #ffffff; --sumi-bg-hover: #ede9e1; --sumi-bg-active: #e4e0d8; --sumi-bg-wash: #f8f6f1; --sumi-surface-inset: #ebe7df; --sumi-surface-subtle: #f2eee6; --sumi-surface-card: #ffffff; --sumi-surface-elevated: #ffffff; --sumi-border-faint: rgba(0,0,0, 0.05); --sumi-border-default: rgba(0,0,0, 0.10); --sumi-border-strong: rgba(0,0,0, 0.18); --sumi-border-focus: rgba(80,110,170, 0.45); --sumi-border-accent: rgba(80,110,170, 0.25); --sumi-text-primary: #1a1816; --sumi-text-secondary: #5c5854; --sumi-text-tertiary: #8a8580; --sumi-text-disabled: #b5b0aa; --sumi-text-inverse: #f0ede8; --sumi-text-link: #4a6fa5; --sumi-accent: #4a6fa5; --sumi-accent-hover: #3a5f95; --sumi-accent-active: #5a7fb5; --sumi-accent-subtle: rgba(74,111,165, 0.12); --sumi-accent-muted: rgba(74,111,165, 0.20); --sumi-accent-emphasis: #3d5f90; --sumi-vermillion: #b84a35; --sumi-vermillion-hover: #a03e2e; --sumi-vermillion-subtle: rgba(184,74,53, 0.12); --sumi-sage: #5a7e4e; --sumi-sage-hover: #4d6e42; --sumi-sage-subtle: rgba(90,126,78, 0.12); --sumi-gold: #9a7d2e; --sumi-gold-hover: #8a6d20; --sumi-gold-subtle: rgba(154,125,46, 0.12); --sumi-live: #c84040; --sumi-shadow-xs: 0 1px 2px rgba(0,0,0,0.05); --sumi-shadow-sm: 0 2px 4px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04); --sumi-shadow-md: 0 4px 12px rgba(0,0,0,0.08), 0 2px 4px rgba(0,0,0,0.04); --sumi-shadow-lg: 0 8px 24px rgba(0,0,0,0.10), 0 4px 8px rgba(0,0,0,0.05); --sumi-shadow-xl: 0 16px 48px rgba(0,0,0,0.12), 0 8px 16px rgba(0,0,0,0.06); --sumi-shadow-2xl: 0 24px 64px rgba(0,0,0,0.15); --sumi-shadow-glow: 0 0 0 3px rgba(74,111,165,0.25); --sumi-glass-bg: rgba(255,255,255, 0.85); --sumi-glass-border: rgba(0,0,0, 0.06); --sumi-scrollbar-thumb: rgba(0,0,0, 0.12); --sumi-scrollbar-hover: rgba(0,0,0, 0.22); --primary-foreground: #ffffff; } /* ═══════════════════════════════════════════════════════════════════════════ TAILWIND THEME MAPPING ═══════════════════════════════════════════════════════════════════════════ */ @theme inline { /* Typography */ --font-sans: var(--sumi-font-body); --font-heading: var(--sumi-font-heading); --font-mono: var(--sumi-font-mono); --font-serif: var(--sumi-font-serif); /* Semantic color mapping to Tailwind utilities */ --color-background: var(--background); --color-foreground: var(--foreground); --color-card: var(--card); --color-card-foreground: var(--card-foreground); --color-popover: var(--popover); --color-popover-foreground: var(--popover-foreground); --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --color-secondary: var(--secondary); --color-secondary-foreground: var(--secondary-foreground); --color-muted: var(--muted); --color-muted-foreground: var(--muted-foreground); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); --color-destructive: var(--destructive); --color-destructive-foreground: var(--destructive-foreground); --color-border: var(--border); --color-input: var(--input); --color-ring: var(--ring); /* Extended semantic */ --color-success: var(--success); --color-success-foreground: var(--success-foreground); --color-warning: var(--warning); --color-warning-foreground: var(--warning-foreground); --color-info: var(--info); --color-info-foreground: var(--info-foreground); /* SUMI direct accent access */ --color-sumi-accent: var(--sumi-accent); --color-sumi-vermillion: var(--sumi-vermillion); --color-sumi-sage: var(--sumi-sage); --color-sumi-gold: var(--sumi-gold); --color-gaming-gold: var(--sumi-gold); --color-terminal-green: #3eaa5e; --color-graffiti-magenta: #c840a0; --color-sakura: #e0a0b8; /* Chart colors */ --color-chart-1: var(--chart-1); --color-chart-2: var(--chart-2); --color-chart-3: var(--chart-3); --color-chart-4: var(--chart-4); --color-chart-5: var(--chart-5); /* Shadows — wired to SUMI tokens (auto dark/light) */ --shadow-xs: var(--sumi-shadow-xs); --shadow-sm: var(--sumi-shadow-sm); --shadow-md: var(--sumi-shadow-md); --shadow-lg: var(--sumi-shadow-lg); --shadow-xl: var(--sumi-shadow-xl); --shadow-2xl: var(--sumi-shadow-2xl); /* Card-specific shadows */ --shadow-card: var(--sumi-shadow-sm); --shadow-card-hover: var(--sumi-shadow-md); /* Radius */ --radius-sm: var(--sumi-radius-sm); --radius-md: var(--sumi-radius-md); --radius-lg: var(--sumi-radius-lg); --radius-xl: var(--sumi-radius-xl); --radius-2xl: var(--sumi-radius-2xl); --radius-full: var(--sumi-radius-full); /* Sidebar */ --color-sidebar: var(--sidebar); --color-sidebar-foreground: var(--sidebar-foreground); --color-sidebar-primary: var(--sidebar-primary); --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); --color-sidebar-accent: var(--sidebar-accent); --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); --color-sidebar-border: var(--sidebar-border); --color-sidebar-ring: var(--sidebar-ring); } /* ═══════════════════════════════════════════════════════════════════════════ BASE STYLES ═══════════════════════════════════════════════════════════════════════════ */ @layer base { * { @apply border-border outline-ring/50; } html { scroll-behavior: smooth; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } body { @apply bg-background text-foreground; font-feature-settings: "cv02", "cv03", "cv04", "cv11"; } /* Paper grain texture — barely perceptible washi feeling */ body::before { content: ''; position: fixed; inset: 0; background: url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E"); opacity: 0.012; pointer-events: none; z-index: 9998; mix-blend-mode: overlay; } ::selection { background: var(--primary); color: var(--primary-foreground); } /* Custom Scrollbar — thin, subtle */ ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-track { background: var(--sumi-scrollbar-track); } ::-webkit-scrollbar-thumb { background: var(--sumi-scrollbar-thumb); border-radius: var(--sumi-radius-full); transition: background-color 0.2s ease; } ::-webkit-scrollbar-thumb:hover { background: var(--sumi-scrollbar-hover); } @supports (scrollbar-width: thin) { * { scrollbar-width: thin; scrollbar-color: var(--sumi-scrollbar-thumb) transparent; } } /* Typography — headings use Space Grotesk */ h1, h2, h3, h4, h5, h6 { @apply font-heading font-semibold tracking-tight text-foreground; text-wrap: balance; } h1 { @apply text-4xl md:text-5xl; } h2 { @apply text-3xl md:text-4xl; } h3 { @apply text-2xl md:text-3xl; } h4 { @apply text-xl md:text-2xl; } h5 { @apply text-lg md:text-xl; } h6 { @apply text-base md:text-lg; } p { @apply text-muted-foreground leading-relaxed; text-wrap: pretty; } a:not([class]) { @apply text-primary transition-colors; } a:not([class]):hover { @apply text-primary/80; } code { @apply font-mono text-sm bg-muted px-1.5 py-0.5 rounded; } pre { @apply font-mono text-sm bg-muted p-4 rounded-lg overflow-x-auto; } } /* ═══════════════════════════════════════════════════════════════════════════ SUMI UTILITY CLASSES ═══════════════════════════════════════════════════════════════════════════ */ @layer utilities { /* Layout primitives — standard widths/heights for app shell and pages */ .max-w-layout-content { max-width: var(--layout-content-max-width); } .min-h-layout-main { min-height: var(--layout-main-min-height); } .min-h-layout-page { min-height: var(--layout-page-min-height); } .min-h-layout-page-sm { min-height: var(--layout-page-min-height-sm); } .min-h-layout-story { min-height: var(--layout-story-decorator-min-height); } .max-h-layout-drawer { max-height: var(--layout-drawer-max-height); } .max-h-layout-panel { max-height: var(--layout-panel-max-height); } .max-h-layout-list { max-height: var(--layout-list-max-height); } .max-h-layout-modal { max-height: var(--layout-modal-max-height); } .max-h-layout-modal-sm { max-height: var(--layout-modal-max-height-sm); } .max-h-layout-modal-xs { max-height: var(--layout-modal-max-height-xs); } .max-h-layout-modal-lg { max-height: var(--layout-modal-max-height-lg); } .h-layout-modal-sm { height: var(--layout-modal-max-height-sm); } .h-layout-lyrics { height: var(--layout-lyrics-height); } .h-layout-lyrics-sm { height: var(--layout-lyrics-height-sm); } .h-layout-chat { height: var(--layout-chat-height); } .h-layout-chat-main { height: var(--layout-chat-main-height); } .h-layout-stream { height: var(--layout-stream-height); } .h-layout-modal-full { height: var(--layout-modal-full-height); } /* Sidebar layout utilities */ .w-sidebar-expanded { width: var(--sidebar-width-expanded); } .w-sidebar-collapsed { width: var(--sidebar-width-collapsed); } .left-sidebar { left: var(--sidebar-offset-left); } .top-sidebar { top: var(--sidebar-offset-top); } .bottom-sidebar { bottom: var(--sidebar-offset-bottom); } .z-sidebar { z-index: var(--sidebar-z-index); } .z-sidebar-overlay { z-index: var(--sidebar-overlay-z-index); } .z-player { z-index: var(--player-z-index); } /* App shell — header / main offsets */ .h-header { height: var(--header-height); } .pt-main { padding-top: var(--main-offset-top); } .pb-main { padding-bottom: var(--main-offset-bottom); } .ml-main-expanded { margin-left: var(--main-margin-left-expanded); } .ml-main-collapsed { margin-left: var(--main-margin-left-collapsed); } /* Responsive margin-left for main */ @media (min-width: 1024px) { .lg\:ml-main-expanded { margin-left: var(--main-margin-left-expanded); } .lg\:ml-main-collapsed { margin-left: var(--main-margin-left-collapsed); } .lg\:left-main-expanded { left: var(--main-margin-left-expanded); } .lg\:left-main-collapsed { left: var(--main-margin-left-collapsed); } .lg\:w-player-bar-expanded { width: calc(100vw - var(--main-margin-left-expanded) - 1rem); } .lg\:w-player-bar-collapsed { width: calc(100vw - var(--main-margin-left-collapsed) - 1rem); } } /* Player bar width: mobile (no sidebar) */ .w-player-bar { width: calc(100vw - 2rem); } .left-header-expanded { left: var(--header-left-expanded); } .left-header-collapsed { left: var(--header-left-collapsed); } /* Shell transition — sidebar width/opacity */ .transition-shell { transition: width var(--sumi-duration-normal) var(--sumi-ease-out), opacity var(--sumi-duration-normal) var(--sumi-ease-out), transform var(--sumi-duration-normal) var(--sumi-ease-out); } /* Respect prefers-reduced-motion */ @media (prefers-reduced-motion: reduce) { .transition-shell { transition: none; } .player-bar-entrance { animation: none !important; } } /* Sidebar active nav item — left border indicator */ .sidebar-active-indicator { box-shadow: var(--sidebar-active-indicator); } /* Glass Effect */ .glass, .sumi-glass { background: var(--sumi-glass-bg); backdrop-filter: blur(var(--sumi-glass-blur)); -webkit-backdrop-filter: blur(var(--sumi-glass-blur)); border: 1px solid var(--sumi-glass-border); } /* Typography utilities — SUMI hierarchy */ .font-heading { font-family: var(--sumi-font-heading); } .font-serif { font-family: var(--sumi-font-serif); } .text-display { @apply text-4xl font-bold tracking-tight; } .text-heading-1 { @apply text-3xl font-semibold tracking-tight; } .text-heading-2 { @apply text-2xl font-semibold; } .text-heading-3 { @apply text-xl font-medium; } .text-heading-4 { @apply text-lg font-medium; } .text-body-lg { @apply text-base leading-relaxed; } .text-body { @apply text-sm leading-relaxed; } .text-caption { @apply text-xs text-muted-foreground; } .text-label { @apply text-xs font-medium uppercase tracking-wider text-muted-foreground; } /* SUMI typography classes (from design system) */ .sumi-display { font-family: var(--sumi-font-heading); font-size: var(--sumi-text-4xl); font-weight: var(--sumi-weight-bold); line-height: var(--sumi-leading-tight); letter-spacing: var(--sumi-tracking-tighter); } .sumi-h1 { font-family: var(--sumi-font-heading); font-size: var(--sumi-text-3xl); font-weight: var(--sumi-weight-semibold); line-height: var(--sumi-leading-tight); letter-spacing: var(--sumi-tracking-tight); } .sumi-h2 { font-family: var(--sumi-font-heading); font-size: var(--sumi-text-2xl); font-weight: var(--sumi-weight-semibold); line-height: var(--sumi-leading-snug); letter-spacing: var(--sumi-tracking-tight); } .sumi-h3 { font-family: var(--sumi-font-heading); font-size: var(--sumi-text-xl); font-weight: var(--sumi-weight-medium); line-height: var(--sumi-leading-snug); } .sumi-h4 { font-family: var(--sumi-font-heading); font-size: var(--sumi-text-lg); font-weight: var(--sumi-weight-medium); line-height: var(--sumi-leading-snug); } .sumi-body-lg { font-size: var(--sumi-text-md); font-weight: var(--sumi-weight-regular); line-height: var(--sumi-leading-relaxed); } .sumi-body { font-size: var(--sumi-text-base); font-weight: var(--sumi-weight-regular); line-height: var(--sumi-leading-normal); } .sumi-body-sm { font-size: var(--sumi-text-sm); font-weight: var(--sumi-weight-regular); line-height: var(--sumi-leading-normal); } .sumi-caption { font-size: var(--sumi-text-xs); font-weight: var(--sumi-weight-regular); line-height: var(--sumi-leading-normal); } .sumi-label { font-size: var(--sumi-text-xs); font-weight: var(--sumi-weight-medium); line-height: var(--sumi-leading-normal); letter-spacing: var(--sumi-tracking-wider); text-transform: uppercase; } .sumi-mono { font-family: var(--sumi-font-mono); font-size: var(--sumi-text-sm); } /* Animation Utilities */ .animate-fade-in { animation: sumi-fade-in var(--sumi-duration-normal) var(--sumi-ease-out); } .animate-slide-up { animation: sumi-slide-up var(--sumi-duration-normal) var(--sumi-ease-out); } .animate-scale-in { animation: sumi-scale-in var(--sumi-duration-normal) var(--sumi-ease-out); } .animate-fadeIn { animation: sumi-fade-in var(--sumi-duration-normal) var(--sumi-ease-out); } .animate-scaleIn { animation: sumi-scale-in var(--sumi-duration-normal) var(--sumi-ease-out); } .animate-pop { animation: sumi-pop var(--sumi-duration-slower) var(--sumi-ease-bounce); } .animate-like-bounce { animation: like-bounce var(--sumi-duration-slow) var(--sumi-ease-out); } .animate-shake { animation: shake 0.4s ease-in-out; } .animate-spin-slow { animation: spin-slow 10s linear infinite; } .animate-achievement { animation: achievement-slide 0.5s var(--sumi-ease-spring); } .animate-eq { animation: eq-bar 0.5s ease-in-out infinite; } .animate-marquee { animation: marquee 10s linear infinite; } .animate-auth-enter { animation: auth-enter var(--sumi-duration-slow) var(--sumi-ease-out) both; } .animate-empty-state-in { animation: sumi-scale-in var(--sumi-duration-normal) var(--sumi-ease-out) both; } .animate-stagger-in { animation: sumi-slide-up var(--sumi-duration-normal) var(--sumi-ease-out) both; } .animate-glow-pulse { animation: sumi-pulse 2s ease-in-out infinite; } /* Ink Wash Texture (hero/feature sections) */ .sumi-wash-texture { position: relative; } .sumi-wash-texture::after { content: ''; position: absolute; inset: 0; background: radial-gradient(ellipse at 20% 50%, var(--sumi-accent-subtle) 0%, transparent 60%), radial-gradient(ellipse at 80% 20%, rgba(201,168,76,0.04) 0%, transparent 50%); pointer-events: none; } /* Noise texture utility */ .noise { position: relative; } .noise::before { content: ""; position: absolute; inset: 0; background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.7' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.04'/%3E%3C/svg%3E"); pointer-events: none; opacity: 0.5; mix-blend-mode: overlay; border-radius: inherit; } @media (prefers-reduced-motion: reduce) { .animate-stagger-in { animation: none; } .animate-glow-pulse { animation: none; } } } /* ═══════════════════════════════════════════════════════════════════════════ SKELETON SHIMMER — loading effect ═══════════════════════════════════════════════════════════════════════════ */ .skeleton-shimmer { background: linear-gradient( 90deg, transparent 0%, rgba(255, 255, 255, 0.06) 40%, rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0.06) 60%, transparent 100% ); background-size: 200% 100%; animation: shimmer 1.8s ease-in-out infinite; } @media (prefers-reduced-motion: reduce) { .skeleton-shimmer { animation: none; background: none; } } /* ═══════════════════════════════════════════════════════════════════════════ KEYFRAME ANIMATIONS — SUMI ═══════════════════════════════════════════════════════════════════════════ */ /* Core SUMI animations */ @keyframes sumi-fade-in { from { opacity: 0; } to { opacity: 1; } } /* S5.1: Branded loading progress bar */ @keyframes loading-progress { 0% { width: 0; transform: translateX(0); } 50% { width: 70%; transform: translateX(0); } 100% { width: 100%; transform: translateX(100%); } } @keyframes sumi-fade-out { from { opacity: 1; } to { opacity: 0; } } @keyframes sumi-slide-up { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } } @keyframes sumi-slide-down { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } } @keyframes sumi-scale-in { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } } @keyframes sumi-scale-out { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0.95); } } /* Achievement pop — the ONE playful animation (gaming touch) */ @keyframes sumi-pop { 0% { opacity: 0; transform: scale(0.8); } 60% { opacity: 1; transform: scale(1.05); } 100% { transform: scale(1); } } /* Live/status pulse */ @keyframes sumi-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } /* Ink brush stroke reveal — page transitions */ @keyframes sumi-brush-reveal { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } } /* Skeleton loading */ @keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } } /* EQ bars — "now playing" indicator */ @keyframes eq-bar { 0%, 100% { transform: scaleY(0.3); } 50% { transform: scaleY(1); } } /* Legacy-compatible animations (used in existing codebase) */ @keyframes like-bounce { 0% { transform: scale(1); } 25% { transform: scale(1.3); } 50% { transform: scale(0.9); } 75% { transform: scale(1.1); } 100% { transform: scale(1); } } @keyframes shake { 0%, 100% { transform: translateX(0); } 10%, 30%, 50%, 70%, 90% { transform: translateX(-4px); } 20%, 40%, 60%, 80% { transform: translateX(4px); } } @keyframes spin-slow { to { transform: rotate(360deg); } } @keyframes typing { 0%, 60%, 100% { transform: translateY(0); } 30% { transform: translateY(-4px); } } @keyframes marquee { 0%, 20% { transform: translateX(0); } 80%, 100% { transform: translateX(-100%); } } @keyframes achievement-slide { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } @keyframes terminal-blink { 0%, 50% { opacity: 1; } 51%, 100% { opacity: 0; } } @keyframes auth-enter { from { opacity: 0; transform: translateY(12px) scale(0.98); } to { opacity: 1; transform: translateY(0) scale(1); } } @keyframes bar-fill { from { width: 0; } } @keyframes level-up { 0% { transform: scale(1); } 50% { transform: scale(1.2); filter: brightness(1.5); } 100% { transform: scale(1); } } /* ═══════════════════════════════════════════════════════════════════════════ REDUCED MOTION ═══════════════════════════════════════════════════════════════════════════ */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } /* Keep opacity transitions for functional feedback */ .interactive { transition: opacity 100ms ease-out; } }