Rohan Kartik All build notes

#design decisions #aurora hero #voice and process

Noise is what makes the aurora feel like a surface

The aurora background on the home and about pages started as a CSS gradient. It was pretty, but it read as a CSS gradient. Smooth, flat, banded where the color stops are. The fix was a noise overlay that sits on top of the gradient inside the same hero element.

The implementation is one ::after pseudo-element on .hero-v5 with a base64-encoded PNG of dense low-frequency noise:

.hero-v5::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url('data:image/png;base64,...');
  opacity: 0.14;
  mix-blend-mode: multiply;
  pointer-events: none;
}

Three values that all matter together. The opacity is 0.14, which is low enough that the noise reads as texture rather than dirt. mix-blend-mode multiply darkens the underlying aurora instead of overlaying gray pixels, so the color shifts get richer rather than washed out. pointer-events: none keeps the layer non-interactive so it doesn’t intercept clicks.

The noise file is a data URI rather than a referenced asset. The reason is that ::after with a separate URL would mean an additional request on a hero that’s already weight-conscious. A 4 KB inline PNG inside the CSS bundle is cheaper than a 4 KB request with all its overhead.

The texture is what makes the gradient feel like it has paper or atmosphere behind it. Without it, the eye reads “purple gradient.” With it, the eye reads “soft surface that happens to be purple.” It’s the difference between a Photoshop document and a photograph of a Photoshop document.

The about page reuses this exact noise via the byte-for-byte extraction in ship.sh. One canonical noise definition, two surfaces using it.

The principle: a gradient is information. A gradient plus noise is a place.