Stroke / glow / CSS lab
Tune liquid-glass optics in real time, then copy the output.
This playground is meant for engineers who need to tune animated environments, edge glow, blur, opacity, tint strength, and motion pacing in one place. Use the repaint switch to decide when the live stylizer should affect the whole app, or keep it off while you experiment against the calmer liquid-glass baseline.
Controls
14 optical knobs
Environments
5 Codrops fields
Workflow
Tune, preview, reuse
Playground
Interactive surface tuning
Presets are mapped to likely VibeIRL use cases, but the controls remain open so engineers can explore how liquid glass, animated light, and border motion behave across several UI targets. The preview always reflects the current draft, while the repaint toggle lets that same draft flow into the shell, route backgrounds, and shared panels only when you want it to.
Linked Vibe Layer status
Curious ยท Dark glass
CSS Lab remains the optics tool. Vibe identity is read from the separate Vibe Layer provider so the two systems do not compete for control.
Live runtime theme
Tune the stylizer here, then decide when it repaints the whole app.
The lab always updates its own preview target. The repaint switch determines whether those same environment, panel, and gradient settings also propagate into the route shell, page backgrounds, and shared components across the rest of the guide.
Global repaint
App is using the default liquid-glass baseline.
Keep this off while you experiment, then flip it on to see the Codrops Aurora, Swirl, Shift, Coalesce, and Pipeline canvas fields flow through every page. When it is off, the application falls back to the calmer Vibe liquid-glass default instead of the raw stylizer draft.
Applied shell
Aurora
Baseline liquid glass is active.
Working draft
Aurora
This is what the preview target is showing right now.
Animated environment
Derived from Gradient A/B/C so stroke color follows the same recipe as the theme.
Preview target
Portfolio Overview
Every shared panel inherits this live recipe, so changing the lab also changes the shell, cards, and route backgrounds.
Generated output
CSS variables
:root {
--vibe-environment: "Aurora";
--vibe-radius: 28px;
--vibe-blur: 22px;
--vibe-stroke-width: 1.4px;
--vibe-glass-opacity: 0.40;
--vibe-tint-strength: 0.24;
--vibe-glow-intensity: 0.56;
--vibe-border-glow: 0.62;
--vibe-border-glow-radius: 42px;
--vibe-stroke-visibility: 0.76;
--vibe-bloom-radius: 88px;
--vibe-inner-highlight: 0.54;
--vibe-eyebrow-tint: 0.58;
--vibe-motion-orbit: 9.68s;
--vibe-motion-pulse: 3.59s;
--vibe-motion-notification: 1.92s;
--vibe-motion-background: 12.72s;
--vibe-stroke-orbit: 6.86s;
--vibe-stroke-sweep: 3.38s;
--vibe-stroke-notification: 1.78s;
--vibe-color-a: #ff56d6;
--vibe-color-b: #46e3ff;
--vibe-color-c: #ffd166;
}Implementation
Tailwind-friendly recipe
<div className="group relative rounded-[calc(var(--vibe-radii-lg)+4px)]">
<div
className="absolute inset-[-1px] vibe-stroke-mask blur-[18px]"
style={{ padding: 'var(--vibe-runtime-stroke-width)', backgroundImage: 'var(--vibe-gradients-emotion-loop)', opacity: 'var(--vibe-runtime-stroke-visibility)', filter: 'blur(var(--vibe-runtime-border-glow-radius))' }}
/>
<div
className="absolute inset-0 vibe-stroke-mask"
style={{ padding: 'var(--vibe-runtime-stroke-width)', backgroundImage: 'var(--vibe-gradients-emotion-loop)', opacity: 'calc(var(--vibe-runtime-stroke-visibility) * 0.78)' }}
/>
<motion.div
className="absolute left-[12%] top-[1px] h-[2px] w-[30%] mix-blend-screen"
animate={{ x: ['-14%', '156%', '-14%'], opacity: [0.14, 0.92, 0.14] }}
transition={{ duration: Number.parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--vibe-runtime-stroke-sweep')) || 3.8, repeat: Infinity, ease: 'easeInOut' }}
style={{ background: 'linear-gradient(90deg, transparent, #ff56d6, rgba(255,255,255,0.96), #46e3ff, transparent)', filter: 'blur(8px)' }}
/>
<div
className="relative overflow-hidden border border-[color:var(--vibe-colors-glass-border)]"
style={{ borderRadius: 'var(--vibe-radii-lg)', background: 'var(--vibe-colors-glass-elevated)', backdropFilter: 'blur(var(--vibe-blur-md))' }}
>
<div className="absolute inset-[2px] animate-vibe-breathe"
style={{ borderRadius: 'calc(var(--vibe-radii-lg) - 2px)', backgroundImage: 'radial-gradient(circle at 18% 18%, #ff56d633 0%, transparent 28%), radial-gradient(circle at 82% 20%, #46e3ff2a 0%, transparent 26%), radial-gradient(circle at 64% 78%, #ffd16624 0%, transparent 24%)', filter: 'blur(22px)' }} />
<div className="relative p-6">{/* content */}</div>
</div>
</div>Current theme snapshot
Runtime state
Environment
Aurora
Applied across the app right now.
Color trio
Optical state
Applied shell: radius 28px, blur 20px, opacity 34%, glow 42%, stroke 1.2px, stroke visibility 66%, eyebrow tint 44%.
Best practices
Use the lab as a calibration tool, not an excuse for one-off styling.
The point of the playground is to refine the shared system. If a recipe becomes broadly useful, promote it back into the token layer so future components can inherit it.
If the panel holds dense data, start from the Dashboard Calm preset and raise glow only if the card is selected.
If the panel is a modal or decision moment, increase radius and highlight slightly before you increase saturation.
When in doubt, soften shadow first and keep neon intensity disciplined.