/** * Glassmorphism / Liquid Glass theme tokens * * Isolated module: all glass-specific tokens and utilities live here. * Changing upstream Keycloakify or shadcn files should not affect this file, * and changes here are intentionally scoped to the login theme. */ :root { /* Blur radius — keep between 10–20px for GPU/UX balance */ --glass-blur: 14px; --glass-blur-heavy: 20px; /* * Light theme glass tokens. * Higher opacity than typical Dribbble glass so the card is readable * and clearly separated from the animated background. */ --glass-bg: hsla(0 0% 100% / 0.42); --glass-bg-solid: hsla(0 0% 100% / 0.82); --glass-bg-scrim: hsla(0 0% 100% / 0.62); --glass-border: hsla(0 0% 100% / 0.58); --glass-border-highlight: hsla(0 0% 100% / 0.85); --glass-shadow: 0 14px 44px hsla(220 40% 16% / 0.18); --glass-shadow-elevated: 0 24px 64px hsla(220 40% 12% / 0.24); /* Ambient background blobs — saturated and fairly opaque so the glass has something to refract */ --glass-ambient-1: hsla(250 85% 62% / 0.55); --glass-ambient-2: hsla(320 80% 58% / 0.5); --glass-ambient-3: hsla(190 90% 52% / 0.48); --glass-ambient-4: hsla(40 95% 58% / 0.42); /* Text stability on busy backgrounds */ --glass-text-shadow: 0 1px 2px hsla(0 0% 0% / 0.1); } @media (prefers-color-scheme: dark) { :root { /* Dark glass needs to be noticeably darker/tinted or it disappears on a dark page */ --glass-bg: hsla(220 20% 14% / 0.62); --glass-bg-solid: hsla(220 20% 10% / 0.9); --glass-bg-scrim: hsla(220 20% 8% / 0.78); --glass-border: hsla(0 0% 100% / 0.18); --glass-border-highlight: hsla(0 0% 100% / 0.32); --glass-shadow: 0 14px 44px hsla(0 0% 0% / 0.45); --glass-shadow-elevated: 0 24px 64px hsla(0 0% 0% / 0.55); /* Dark-mode blobs: still vivid but not overwhelming */ --glass-ambient-1: hsla(250 85% 58% / 0.4); --glass-ambient-2: hsla(320 80% 55% / 0.36); --glass-ambient-3: hsla(190 90% 50% / 0.36); --glass-ambient-4: hsla(40 95% 55% / 0.3); --glass-text-shadow: 0 1px 3px hsla(0 0% 0% / 0.4); } } /* Reduced transparency: make glass almost opaque and drop the blur */ @media (prefers-reduced-transparency: reduce) { :root { --glass-bg: hsla(0 0% 100% / 0.95); --glass-bg-solid: hsla(0 0% 100% / 0.99); --glass-bg-scrim: hsla(0 0% 100% / 0.99); --glass-border: hsla(0 0% 0% / 0.14); --glass-border-highlight: hsla(0 0% 0% / 0.1); --glass-blur: 2px; --glass-blur-heavy: 2px; } @media (prefers-color-scheme: dark) { :root { --glass-bg: hsla(220 20% 8% / 0.97); --glass-bg-solid: hsla(220 20% 6% / 0.99); --glass-bg-scrim: hsla(220 20% 6% / 0.99); --glass-border: hsla(0 0% 100% / 0.14); --glass-border-highlight: hsla(0 0% 100% / 0.1); } } } /* Base glass layer — use for cards, panels, overlays */ .glass { /* Tinted fill plus a subtle top-left sheen to mimic physical glass */ background: linear-gradient( 145deg, hsla(0 0% 100% / 0.22) 0%, hsla(0 0% 100% / 0.06) 55%, hsla(0 0% 100% / 0.14) 100% ), var(--glass-bg); backdrop-filter: blur(var(--glass-blur)) saturate(145%); -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(145%); border: 1px solid var(--glass-border); box-shadow: inset 0 1px 0 0 var(--glass-border-highlight), inset 0 0 0 1px hsla(0 0% 100% / 0.04), var(--glass-shadow); border-radius: 1rem; } /* More opaque glass — used behind dense text or form sections */ .glass-solid { background: linear-gradient( 145deg, hsla(0 0% 100% / 0.18) 0%, hsla(0 0% 100% / 0.04) 55%, hsla(0 0% 100% / 0.1) 100% ), var(--glass-bg-solid); backdrop-filter: blur(var(--glass-blur-heavy)) saturate(125%); -webkit-backdrop-filter: blur(var(--glass-blur-heavy)) saturate(125%); border: 1px solid var(--glass-border); box-shadow: inset 0 1px 0 0 var(--glass-border-highlight), inset 0 0 0 1px hsla(0 0% 100% / 0.04), var(--glass-shadow); border-radius: 0.875rem; } /* Scrim gradient for text protection on glass surfaces */ .glass-scrim { background: linear-gradient( 180deg, var(--glass-bg-scrim) 0%, color-mix(in oklab, var(--glass-bg-scrim) 85%, transparent) 100% ); } /* Fallback for browsers without backdrop-filter support */ @supports not (backdrop-filter: blur(12px)) { .glass { background: var(--glass-bg-solid); backdrop-filter: none; -webkit-backdrop-filter: none; } .glass-solid { backdrop-filter: none; -webkit-backdrop-filter: none; } } /* Ambient background blobs — keep some definition so the glass can refract them */ .glass-ambient-blob { position: absolute; border-radius: 50%; filter: blur(44px); opacity: 0.85; will-change: transform, opacity; animation: glass-float 20s ease-in-out infinite alternate; } @media (prefers-reduced-motion: reduce) { .glass-ambient-blob { animation: none; opacity: 0.6; } } @keyframes glass-float { 0% { transform: translate3d(0, 0, 0) scale(1); } 100% { transform: translate3d(30px, -40px, 0) scale(1.15); } } /* Extra mesh layer behind the card: sharper color bands for stronger refraction */ .glass-ambient-mesh { position: absolute; inset: 0; opacity: 0.7; background: radial-gradient( circle at 20% 30%, var(--glass-ambient-1) 0%, transparent 45% ), radial-gradient(circle at 80% 20%, var(--glass-ambient-2) 0%, transparent 40%), radial-gradient(circle at 60% 80%, var(--glass-ambient-3) 0%, transparent 45%), radial-gradient(circle at 30% 75%, var(--glass-ambient-4) 0%, transparent 40%); filter: blur(28px); will-change: transform; animation: glass-mesh-drift 30s ease-in-out infinite alternate; pointer-events: none; } @media (prefers-reduced-motion: reduce) { .glass-ambient-mesh { animation: none; opacity: 0.5; } } @keyframes glass-mesh-drift { 0% { transform: scale(1) translate3d(0, 0, 0); } 100% { transform: scale(1.08) translate3d(-20px, 10px, 0); } } /* Text stability helper */ .glass-text-stable { text-shadow: var(--glass-text-shadow); }