lotusui
A Go design system for desktop and mobile — one codebase, native apps. Web when you want it.
GitHub

Dark mode

Not a mode — a palette. Build both themes at startup, swap a pointer.

lotusui has no dark mode: dark is a Palette like any other, applied with WithPalette. DefaultDarkPalette ships in the box — the same lavender brand on a deep cool-gray canvas, every ladder keeping the light palette's ORDER (faint → prominent), so components never know which world they're in. Try it live: pick Midnight in this site's palette picker — every demo on every page flips.

Usage

Construct both themes once at startup; following the system appearance (or a user setting) is a pointer swap — no rebuild, no reload, no per-frame cost.

Go
light := lotusui.NewTheme()
dark := lotusui.NewTheme(lotusui.WithPalette(lotusui.DefaultDarkPalette))

th := light
if prefersDark {
	th = dark
}

Custom dark palettes

A dark palette follows two rules. Panels sit slightly LIGHTER than the canvas — elevation still reads as "closer to the light", exactly as white cards do on the tinted light page. And status pairs invert their construction: light ink on a deep tinted well, instead of deep ink on a pastel. Start from DefaultDarkPalette and override tokens the same way you would the light one.

Go
night := lotusui.DefaultDarkPalette
night.BrandSolid = myBrand      // pastels pop on dark even better
night.BrandFg = myBrandLight    // the readable ink flips to a light sibling

dark := lotusui.NewTheme(lotusui.WithPalette(night))

Contrast stays checked

The build-time theme generator validates dark palettes with the same WCAG contrast checks as light ones — lotusui theme -config theme.json -strict makes an unreadable pairing a build failure, whichever world it is in.

lotusui is a Go design system for native desktop and mobile — and the web when you want it. Docs demos are the real components (WebAssembly) — one gallery app, each Preview an iframe addressed by URL hash.