Three-layer starfield
Three tiles of radial-gradient dots, each looping its own twinkle keyframe at a different speed. A hundred stars cost one element.
background-size
A night that lights up, a grid that runs forever, and a sky you can
switch — every last interaction powered by hidden checkboxes and a CSS :has().
01 — THE CRAFT
Everything on this page is a classic CSS move. Here's the short list of what's actually doing the work.
Three tiles of radial-gradient dots, each looping its own twinkle keyframe at a different speed. A hundred stars cost one element.
background-size
The stripes aren't painted on — a second mask layer punches actual holes in the lower half, so the sky genuinely shows through.
mask-image × 2
One rotated plane, one background-position loop. Perspective does all the fake-3D math, and the tile loops exactly one cell so the seam is invisible.
perspective() rotateX()
animation-timeline: scroll() and view() drive the parallax, progress bar and card reveals. No scroll listener, no IntersectionObserver.
animation-timeline
The theme, the menu, the playground — all plain checkboxes and radios. :has() climbs the tree and restyles the whole page from any descendant.
body:has(:checked)
Native <details> accordion, smooth anchor scrolling, a pausable marquee, focus-visible rings, reduced-motion fallbacks. All in the box.
<details>
02 — PLAYGROUND
These controls are form inputs with no forms, no handlers — the state panel below is just CSS content reading the checkboxes.
03 — FIELD NOTES
The honest engineering notes — what degrades, where, and why it doesn't matter.
#mode is a checkbox, the menu is a checkbox,
the speed picker is three radios. CSS :has() lets an ancestor —
here, body — react to the state of its descendants. That's the
entire state machine on this page: no bundle, no runtime, no hydration,
no framework, no build step.
animation-timeline: scroll() and
view()) ship in Chrome, Edge and Opera. Safari and Firefox
ignore the @supports blocks and simply render the static
scene — the progress bar and parallax just don't exist there. Nothing
breaks. That's progressive enhancement as a native CSS feature.
radial-gradient dot tiles repeated via
background-size.
data-* attributes, no class on <html>.
The checkbox is the state. body:has(#mode:checked)
rewrites a handful of custom properties, and downstream styles do the
rest: sky layers crossfade on opacity, the grid color
interpolates through currentColor, mountains transition
background-color, stars dim via --star-o.
One input, ~a dozen reactive styles.
prefers-reduced-motion
block really is in there.