Neon Flicker
A glowing sign that stutters on, holds, and drops out for a beat now and then, like a tube that is slightly worn.
Open late
Create a neon sign text effect in pure CSS. Render the word in a thin display font with a layered text-shadow glow (0 0 4px, 0 0 12px, 0 0 28px, 0 0 56px using the accent colour). Run a 4s infinite keyframe animation with steps that look irregular: mostly fully lit, with two quick dips around 8% and 10%, and a longer dip around 62% to 66% where opacity drops to 0.35 and the glow is removed. Use linear timing so the dips are sharp, not faded. Pause the animation when the element is off screen. Under prefers-reduced-motion, keep the steady glow and remove the flicker. The text reads "Open late".
Source
'use client'
import { useEffect, useRef } from 'react'
import s from './demo.module.css'
export default function NeonFlicker({ labels }: { labels: Record<string, string> }) {
const ref = useRef<HTMLParagraphElement>(null)
useEffect(() => {
const el = ref.current
if (!el) return
const io = new IntersectionObserver(([e]) => el.toggleAttribute('data-paused', !e.isIntersecting))
io.observe(el)
return () => io.disconnect()
}, [])
return (
<p ref={ref} className={s.sign}>
{labels.text}
</p>
)
}
.sign {
--glow: var(--stage-accent);
margin: 0;
font: 300 clamp(2rem, 7vw, 2.75rem) / 1 var(--font-display);
letter-spacing: 0.04em;
color: var(--stage-ink);
text-shadow: 0 0 4px var(--glow), 0 0 12px var(--glow), 0 0 28px var(--glow), 0 0 56px var(--glow);
animation: flicker 4s linear infinite;
}
.sign[data-paused] { animation-play-state: paused; }
@keyframes flicker {
0%, 7%, 9%, 11%, 61%, 67%, 100% {
opacity: 1;
text-shadow: 0 0 4px var(--glow), 0 0 12px var(--glow), 0 0 28px var(--glow), 0 0 56px var(--glow);
}
8%, 10%, 62%, 66% { opacity: 0.35; text-shadow: none; }
}
@media (prefers-reduced-motion: reduce) {
.sign { animation: none; }
}