mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-29 22:23:01 +00:00
714 lines
18 KiB
CSS
714 lines
18 KiB
CSS
/* ============================================
|
|
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;
|
|
}
|