Nine themes, six washes, and a little weather

Nine accent themes with matching app icons, six animated background washes, and ambient particle effects, plus the fixes that keep them smooth and legible.

Update, September 4, 2026. Boundless v2.15.0 is a complete rewrite on React Native. This post describes the SwiftUI app that came before it. The behaviour it argues for is still how the app works; the code it names is gone.

A reader is an app you stare at for hours. It should be allowed to look like something you picked.

So appearance is now three independent layers: an accent theme, an animated background wash, and an ambient effect. They combine freely, and none of them touch the reader canvas itself. The page stays the page.

Accent themes and icons

Nine accents, all built on the same four-stop gradient pattern so they stay consistent with each other:

Boundless, Nova, Ink, Mono, Reverse, Blossom, Ember, Mint, and Royal.

Each has a matching alternate app icon, so the thing on your Home Screen agrees with the thing you open. Icon and accent are chosen separately though, so a loud accent behind a plain icon is entirely allowed.

Mono and Reverse are there for anyone who wants the app to get out of the way completely. Ink needed a specific fix on the way in: its interactive tint was reading as dimmed on links and buttons, so tappable text looked disabled rather than restrained.

Background washes

Behind the tab content sits an optional animated gradient. Six choices:

  • Standard, which is no wash at all
  • Brand Wash, which follows whichever accent you picked
  • Aurora
  • Midnight
  • Sunset
  • Void

Brand Wash was wrong for a while, in a way nobody would ever file a bug about. It only branched on two accents, so every other theme quietly fell back to the default palette. It looked fine! It just wasn't doing the one thing its name promises.

Ambient effects

On top of the wash, an optional particle field: None, Snow, Rain, Stars, Sakura, or Fireflies. Slow, sparse, and drawn behind the tab chrome rather than over your content.

Two things that went wrong

Every tab was animating at once. The tab view keeps each visited tab alive, so once you'd opened all five, you had five particle fields and five gradient animations running continuously with exactly one of them visible. That produced real, measurable lag on tab switches, which is a stupid thing to pay for an effect nobody can see.

Effects now take an active flag driven by the selected tab, and render a single static frame when their tab isn't the visible one. No visual difference, no lag.

That fix had a tail, though. One tab lost its active wiring in the refactor and stopped animating its background entirely while the other four carried on. Tracking that down took longer than the original fix did, because a background that's too still is a lot less noticeable than one that's too busy.

Text was washing out over the bright parts. Section headers, grid titles, detail headers, history rows: they all sit directly over the moving gradient, and white text over a light stop of a wash is not readable.

The wrong fix is changing the text colour per theme, which buys you nine palettes of exceptions and a fresh bug every time somebody adds a wash. The right one is a shared legibility scrim behind the text, everywhere text sits over the ambient layer. The text keeps its own colour and gets a surface to sit on.

The reader chrome had the same disease from the other direction. Its buttons were hardcoded white and vanished against a light reading background. They follow the reader's own colour scheme now.

Reduce Motion

If Reduce Motion is on, the app respects it. The animation stops, the colour stays. Appearance settings are documented at /docs.