A working demo of the theming described in my writeup of the okLCH color system I created for the Unified Design Language project. While that design system doesn't use Tailwind, I've applied the same thinking to this site, so we end up with a pretty close approximation.
You can play around below. The demo is scoped to its container, so it won't affect the rest of the page, but you can always change the whole site's theme in the header if you land on something you like.
oklch to okLab when compiled as of Tailwind ~v4.2, so inspected values may not match what's in the code. Shouldn't really matter though, since the two convert cleanly, but just FYI.How it works
* just on this site, not the actual projectColors are controlled by data-hue and data-neutral attributes on the <Theme> component, each of which assigns a given color ramp to the alias variables that feed into the theme. These will cascade down from any ancestor, so you can scope overrides to a section of the page.
╔──────────────────╗
│ colors.css │
╚────────┬─────────╝
│
╭──────────────┴──────────────╮
│ │
▼ ▼
╔────────────────╗ ╔───────────────╗
│ hues.css ├─ ─ ─ ─ ─►│ globals.css │
╚────────────────╝ ╚──────┬────────╝
│ │
│ Tokens
│ │
╰──╮ ╭──────────────╯
│ │
│ ▼
╔╌╌╌╌╌╌╌╌│╌╌╌╌╌<Theme>╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╗
╎ ╭──▼───────╮ ╭──────────────╮ ╎
╠─────│ data-hue ├─┤ data-neutral │─────╣
╎ ╭──╯╌╌╌╌╌╌╌╌╌╌╰─╯╌╌╌╌╌╌╌╌╌╌╌╌╌╌╰──╮ ╎
╎ │ {children} │ ╎
╎ ╰─────────────────────────────────╯ ╎
╚╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╝Aliases
Raw oklch palettes are registered with Tailwind in colors.css, making them available as both CSS variables and utility classes (bg-ruby-500, text-sand-200, etc.).
Two alias scales, --hue-* and --neutral-*, help power theming beyond what the semantic tokens provide. This also lets us re-theme components without having to touch the semantic token definitions if we don't need to. By default, they both point to the sand palette, but setting data-hue or data-neutral on any ancestor swaps the entire scale for another color ramp.
File structure
Semantic tokens
Semantic tokens like --primary, --background, and --ring are declared on :root, [data-theme] and reference these aliases. Because [data-theme] is in the selector, the tokens re-evaluate whenever hue or neutral variables are overridden on a descendant.
(I think they're too limited for practical use, but I'm using shadcn tokens on this site. It's mostly a thought experiment to see how far I can push them / test how my colors work with them; this isn't what's used in the actual project.)
Radius
Just for fun, I made the base radius = 10 for easier math, and I also wanted to play with odd-numbered radii.
So you have the --radius base value with these odd multipliers. Instances of <Theme> will inject a new --radius CSS variable, so updated values cascade down and re-scale instances.
I also capped the values with some eyeballing to avoid overly large radii; I'd prefer to use a more precise approach, but this is a quick and dirty solution.
PS — If you're wondering what the --ellipse-factoris for, it has nothing to do with theming. I made a utility class for squircle corners, and that'll offset the radius variable to get the desired effect.