/* ============================================ Premium Theme Styles for Crypto Platform ============================================ */ /* Import premium fonts */ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap'); @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700&display=swap'); /* Custom font declarations for premium typography */ @font-face { font-family: 'Cabinet Grotesk'; src: url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap'); font-display: swap; } /* ============================================ Root Variables & Theme Configuration ============================================ */ :root { /* Semantic color tokens — these initial defaults are overridden by the Light Mode block at the bottom of this file. */ --color-background: theme('colors.canvas.50'); --color-surface: theme('colors.white'); --color-surface-elevated: theme('colors.canvas.100'); --color-border: theme('colors.stone.200'); --color-border-subtle: theme('colors.stone.100'); /* Text colors with hierarchy */ --color-text-primary: theme('colors.stone.900'); --color-text-secondary: theme('colors.stone.600'); --color-text-tertiary: theme('colors.stone.500'); --color-text-muted: theme('colors.stone.400'); /* Interaction states */ --color-hover: theme('colors.primary.50'); --color-active: theme('colors.primary.100'); --color-focus: theme('colors.primary.500'); /* Semantic status colors */ --color-success: theme('colors.sage.500'); --color-warning: theme('colors.amber.500'); --color-error: theme('colors.coral.500'); --color-info: theme('colors.primary.500'); /* Spacing rhythm */ --spacing-unit: 0.25rem; /* Transition timing */ --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1); --transition-base: 250ms cubic-bezier(0.4, 0, 0.2, 1); --transition-slow: 350ms cubic-bezier(0.4, 0, 0.2, 1); /* Border widths */ --border-width: 1px; --border-width-thick: 2px; /* Z-index scale */ --z-dropdown: 1000; --z-sticky: 1100; --z-overlay: 1200; --z-modal: 1300; --z-popover: 1400; --z-tooltip: 1500; } /* ============================================ Global Styles & Resets ============================================ */ * { box-sizing: border-box; border-color: var(--color-border); } html { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; scroll-behavior: smooth; font-feature-settings: 'kern' 1, 'liga' 1, 'calt' 1; } body { min-height: 100vh; background: var(--color-background); color: var(--color-text-primary); line-height: 1.6; position: relative; overflow-x: hidden; } /* Subtle noise texture overlay for depth */ body::before { content: ''; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' /%3E%3C/filter%3E%3Crect width='100' height='100' filter='url(%23noise)' opacity='0.03' /%3E%3C/svg%3E"); pointer-events: none; z-index: 1; opacity: 0.4; } /* ============================================ Typography Enhancements ============================================ */ .text-display { font-family: theme('fontFamily.display'); font-weight: 700; letter-spacing: -0.04em; line-height: 1.1; } .text-balance { text-wrap: balance; } .text-gradient { background: linear-gradient( 135deg, theme('colors.primary.600') 0%, theme('colors.accent.lavender') 100% ); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .text-crypto-price { font-family: theme('fontFamily.mono'); font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1; } /* ============================================ Glass Morphism Components ============================================ */ .glass-surface { background: rgba(255, 255, 255, 0.7); backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%); border: 1px solid rgba(255, 255, 255, 0.3); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08), inset 0 0 0 1px rgba(255, 255, 255, 0.5); } .glass-surface-dark { background: rgba(15, 23, 42, 0.8); backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%); border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(255, 255, 255, 0.05); } /* ============================================ Card Components ============================================ */ .card-elevated { @apply bg-white rounded-2xl; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.03), 0 2px 4px rgba(0, 0, 0, 0.04), 0 8px 16px -4px rgba(0, 0, 0, 0.08), 0 24px 48px -12px rgba(0, 0, 0, 0.12); transition: all var(--transition-base); } .card-elevated:hover { transform: translateY(-2px); box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.03), 0 4px 8px rgba(0, 0, 0, 0.04), 0 16px 24px -8px rgba(0, 0, 0, 0.1), 0 32px 64px -16px rgba(0, 0, 0, 0.14); } .card-interactive { @apply bg-white rounded-xl p-6; border: 1px solid theme('colors.stone.200'); transition: all var(--transition-fast); cursor: pointer; position: relative; overflow: hidden; } .card-interactive::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; background: linear-gradient( 90deg, theme('colors.primary.500') 0%, theme('colors.accent.lavender') 50%, theme('colors.accent.sky') 100% ); transform: scaleX(0); transition: transform var(--transition-base); } .card-interactive:hover { border-color: theme('colors.primary.200'); background: theme('colors.primary.50'); } .card-interactive:hover::before { transform: scaleX(1); } /* ============================================ Button Styles ============================================ */ .btn-premium { @apply relative inline-flex items-center justify-center px-6 py-3 rounded-xl font-medium; background: linear-gradient( 135deg, theme('colors.primary.500') 0%, theme('colors.primary.600') 100% ); color: white; box-shadow: 0 2px 4px rgba(91, 155, 243, 0.24), 0 8px 16px -4px rgba(91, 155, 243, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.12); transition: all var(--transition-base); overflow: hidden; } .btn-premium::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient( 135deg, transparent 0%, rgba(255, 255, 255, 0.2) 50%, transparent 100% ); transform: translateX(-100%); transition: transform 0.6s; } .btn-premium:hover { transform: translateY(-1px); box-shadow: 0 4px 8px rgba(91, 155, 243, 0.32), 0 12px 24px -8px rgba(91, 155, 243, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.16); } .btn-premium:hover::before { transform: translateX(100%); } .btn-premium:active { transform: translateY(0); } .btn-glass { @apply relative inline-flex items-center justify-center px-6 py-3 rounded-xl font-medium; background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.2); color: theme('colors.stone.700'); transition: all var(--transition-base); } .btn-glass:hover { background: rgba(255, 255, 255, 0.2); border-color: rgba(255, 255, 255, 0.3); transform: translateY(-1px); } .btn-outline { @apply relative inline-flex items-center justify-center px-6 py-3 rounded-xl font-medium; background: transparent; border: 1.5px solid theme('colors.stone.300'); color: theme('colors.stone.700'); transition: all var(--transition-base); position: relative; overflow: hidden; } .btn-outline::before { content: ''; position: absolute; top: 50%; left: 50%; width: 0; height: 0; border-radius: 50%; background: theme('colors.primary.50'); transform: translate(-50%, -50%); transition: width 0.6s, height 0.6s; } .btn-outline:hover { border-color: theme('colors.primary.500'); color: theme('colors.primary.600'); } .btn-outline:hover::before { width: 300px; height: 300px; } /* ============================================ Input & Form Styles ============================================ */ .input-elevated { @apply w-full px-4 py-3 rounded-xl; background: white; border: 1px solid theme('colors.stone.200'); color: theme('colors.stone.900'); font-size: theme('fontSize.base'); transition: all var(--transition-fast); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); } .input-elevated:focus { outline: none; border-color: theme('colors.primary.500'); box-shadow: 0 0 0 3px theme('colors.primary.50'), 0 1px 2px rgba(0, 0, 0, 0.04); } .input-elevated::placeholder { color: theme('colors.stone.400'); } /* ============================================ Navigation Components ============================================ */ .nav-item-premium { @apply relative flex items-center px-4 py-2.5 rounded-xl; color: theme('colors.stone.600'); transition: all var(--transition-fast); font-weight: 500; } .nav-item-premium:hover { color: theme('colors.stone.900'); background: theme('colors.stone.50'); } .nav-item-premium.active { color: theme('colors.primary.600'); background: theme('colors.primary.50'); } .nav-item-premium.active::before { content: ''; position: absolute; left: 0; top: 50%; transform: translateY(-50%); width: 3px; height: 20px; background: theme('colors.primary.500'); border-radius: 0 3px 3px 0; } /* ============================================ Badge & Status Components ============================================ */ .badge-premium { @apply inline-flex items-center px-2.5 py-1 rounded-lg text-xs font-semibold; background: linear-gradient( 135deg, theme('colors.primary.50') 0%, theme('colors.accent.lavender/10') 100% ); color: theme('colors.primary.700'); border: 1px solid theme('colors.primary.200'); } .status-indicator { @apply relative inline-flex h-3 w-3; } .status-indicator span { @apply absolute inline-flex h-full w-full rounded-full opacity-75; animation: ping 1.5s cubic-bezier(0, 0, 0.2, 1) infinite; } .status-indicator.online span { @apply bg-sage-400; } .status-indicator.offline span { @apply bg-stone-400; } /* ============================================ Market-Specific Components ============================================ */ .price-ticker { @apply font-mono text-lg font-semibold; font-variant-numeric: tabular-nums; } .price-ticker.up { @apply text-market-bullish; } .price-ticker.down { @apply text-market-bearish; } .price-ticker.neutral { @apply text-market-neutral; } .market-card { @apply relative overflow-hidden rounded-2xl p-6; background: linear-gradient(135deg, white 0%, theme('colors.canvas.100') 100%); border: 1px solid theme('colors.stone.200'); } .market-card::before { content: ''; position: absolute; top: -50%; right: -50%; width: 200%; height: 200%; background: radial-gradient(circle, theme('colors.primary.500/5') 0%, transparent 70%); animation: float 20s ease-in-out infinite; } /* ============================================ Chart & Data Visualization ============================================ */ .chart-container { @apply relative rounded-xl p-4; background: white; border: 1px solid theme('colors.stone.200'); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04); } .chart-grid { background-image: linear-gradient(0deg, theme('colors.stone.100') 1px, transparent 1px), linear-gradient(90deg, theme('colors.stone.100') 1px, transparent 1px); background-size: 20px 20px; } /* ============================================ Loading & Skeleton States ============================================ */ .skeleton { @apply relative overflow-hidden bg-stone-200 rounded-lg; } .skeleton::after { content: ''; position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: linear-gradient( 90deg, transparent 0%, theme('colors.stone.100') 50%, transparent 100% ); animation: shimmer 2s linear infinite; } @keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } /* ============================================ Scrollbar Styling ============================================ */ .scrollbar-elegant { scrollbar-width: thin; scrollbar-color: theme('colors.stone.300') transparent; } .scrollbar-elegant::-webkit-scrollbar { width: 8px; height: 8px; } .scrollbar-elegant::-webkit-scrollbar-track { background: transparent; } .scrollbar-elegant::-webkit-scrollbar-thumb { background: theme('colors.stone.300'); border-radius: 4px; border: 2px solid transparent; background-clip: padding-box; } .scrollbar-elegant::-webkit-scrollbar-thumb:hover { background: theme('colors.stone.400'); } /* ============================================ Responsive Utilities ============================================ */ @media (max-width: 640px) { .hide-mobile { display: none; } } @media (min-width: 641px) { .show-mobile-only { display: none; } } /* ============================================ Accessibility Enhancements ============================================ */ .focus-visible:focus { outline: 2px solid theme('colors.primary.500'); outline-offset: 2px; } .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; } /* ============================================ Light Mode (Default) ============================================ */ /* * The legacy --color-* semantic tokens are now thin aliases over the canonical * channel tokens in styles/tokens.css. Because those canonical vars already * flip between :root and :root.dark, these aliases inherit dark mode for free — * no separate dark override block is needed, and they theme along with the app. */ :root { --color-background: rgb(var(--surface-canvas)); --color-surface: rgb(var(--surface)); --color-surface-elevated: rgb(var(--surface-muted)); --color-border: rgb(var(--line)); --color-border-subtle: rgb(var(--line-subtle)); --color-text-primary: rgb(var(--content)); --color-text-secondary: rgb(var(--content-secondary)); --color-text-tertiary: rgb(var(--content-muted)); --color-text-muted: rgb(var(--content-faint)); --color-hover: rgb(var(--primary-50)); --color-active: rgb(var(--primary-100)); --color-focus: rgb(var(--primary-500)); --color-success: rgb(var(--sage-500)); --color-warning: rgb(var(--amber-500)); --color-error: rgb(var(--coral-500)); --color-info: rgb(var(--primary-500)); /* Shadow tint used by elevated surfaces. */ --shadow-tint: 0, 0, 0; } /* Dark-mode overrides for component classes that hardcode light colors. Keep these scoped — the Tailwind utility classes used in TSX still need per-call `dark:` variants. This block only fixes the .btn / .card / .input component shortcuts declared above. */ :root.dark .card-elevated, :root.dark .card-interactive, :root.dark .market-card, :root.dark .chart-container { background: var(--color-surface); border-color: var(--color-border); color: var(--color-text-primary); } :root.dark .card-interactive:hover { background: var(--color-hover); border-color: var(--color-focus); } :root.dark .input-elevated { background: var(--color-surface); border-color: var(--color-border); color: var(--color-text-primary); } :root.dark .input-elevated::placeholder { color: var(--color-text-muted); } :root.dark .input-elevated:focus { border-color: var(--color-focus); box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.2), 0 1px 2px rgba(0, 0, 0, 0.4); } :root.dark .nav-item-premium { color: var(--color-text-secondary); } :root.dark .nav-item-premium:hover { color: var(--color-text-primary); background: var(--color-hover); } :root.dark .nav-item-premium.active { color: var(--color-focus); background: rgba(96, 165, 250, 0.12); } :root.dark .nav-item-premium.active::before { background: var(--color-focus); } :root.dark .btn-glass { background: rgba(255, 255, 255, 0.05); border-color: rgba(255, 255, 255, 0.1); color: var(--color-text-primary); } :root.dark .btn-glass:hover { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.2); } :root.dark .btn-outline { border-color: var(--color-border); color: var(--color-text-primary); } :root.dark .btn-outline::before { background: rgba(96, 165, 250, 0.1); } :root.dark .btn-outline:hover { border-color: var(--color-focus); color: var(--color-focus); } :root.dark .skeleton { background: #262626; } :root.dark .skeleton::after { background: linear-gradient( 90deg, transparent 0%, rgba(255, 255, 255, 0.06) 50%, transparent 100% ); } :root.dark .scrollbar-elegant { scrollbar-color: #404040 transparent; } :root.dark .scrollbar-elegant::-webkit-scrollbar-thumb { background: #404040; } :root.dark .scrollbar-elegant::-webkit-scrollbar-thumb:hover { background: #525252; } :root.dark .chart-grid { background-image: linear-gradient(0deg, #262626 1px, transparent 1px), linear-gradient(90deg, #262626 1px, transparent 1px); } :root.dark .glass-surface { background: rgba(23, 23, 23, 0.7); border-color: rgba(255, 255, 255, 0.08); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), inset 0 0 0 1px rgba(255, 255, 255, 0.04); } /* Soften the noise overlay in dark mode — at full strength on a near-black background the grain looks like dead pixels. */ :root.dark body::before { opacity: 0.15; }