Eleven themes, and no box to paste CSS into
There is a field on almost every community platform's branding page labelled something like Custom CSS. It looks generous. It is the cheapest possible way for a platform to say yes to "can I make it look like mine".
We left it out on purpose.
What a CSS box actually costs
A custom-CSS field is not a feature, it is a support contract you did not know you signed.
The moment a host pastes a rule into it, they own the intersection of their CSS and every future change we make. We ship a new lesson layout; their .lesson-row { display: block } from eight months ago turns it into a column of orphaned text. They do not know we changed anything. They know their community broke, and they are right.
It also quietly breaks the things nobody tests. Contrast ratios go out the window. Focus rings get set to outline: none because they looked untidy on a desktop screenshot, and now nobody navigating by keyboard can tell where they are. Dark mode stops working, because a hard-coded #fff background does not know it is night.
And the honest part: most hosts do not want to write CSS. They want their community not to look like a spreadsheet with a logo on it. Those are different problems, and the CSS box only solves the first one.
What you get instead
Eleven complete looks. Not eleven colour swaps — eleven designed systems, each with its own type, colour, corner radius, shadow depth and light/dark treatment:
| Theme | The idea |
|---|---|
| Gallery | A well-lit room for someone else's name. |
| Sunroom | The community that feels like a well-lit room. |
| Understory | The dark mode you can live in. |
| Interchange | Your community is a transit system. Ride it. |
| Salon | A private members' club, printed on good paper. |
| Nocturne | The backstage pass, not the classroom. |
| Zine | Your community, riso-printed. |
| tempo | The community that's always on air. |
| Cordovan | Quiet luxury, hallmarked in software. |
| Moonpool | A late-night studio, lit from below. |
| Lamplight | Plum ink by day; amber lamps at night. |
You pick one from a grid in your branding settings. It re-skins the entire community — feed, courses, calendar, library, checkout, admin — from that single setting. On top of it you set a brand colour and upload a logo and cover image.
Two of them are deliberately not symmetrical, which is the sort of thing a theme system that respects itself allows. Nocturne has no mode toggle at all — it is one dark room, and a pale version of it would be a different and worse theme wearing the same name. Moonpool has two modes and both of them are dark — "Dusk" and "Abyss" — because a late-night studio lit from below does not have a daytime.
The obvious "fix" for both is to generate the missing mode automatically by flipping the lightness channel. That is how you get themes that technically have a light mode and visibly nobody designed it.
Under the hood this is one attribute on the page (data-theme, plus data-mode) resolving against one canonical set of CSS variables. No component knows which theme it is in. That is why eleven of them is maintainable and why a twelfth is a palette file rather than a project.
The setting a host cannot override
Light or dark is the member's, not yours.
If a member has explicitly picked a mode, that choice is applied before the first paint and it beats the community's own setting. A host who loves their dark theme does not get to inflict it on somebody reading in bright sunlight, or on somebody who finds light-on-dark text genuinely hard to read.
We got this subtly wrong once, and the bug is a good illustration of why the rule needs teeth. Our theme provider persisted a member's preference so it would follow them. It tracked "has this person changed something" with a single flag — so flicking the dark mode toggle also wrote the theme down as if they had chosen it. On the platform's own pages, which wear Lamplight, one flick of that toggle silently pinned Lamplight as that person's personal theme everywhere. They never chose it. Nothing errored. It just looked like we had decided for them.
The fix was to split the flag in two, so each preference is stored only if the person actually reached for that control. The principle underneath it is the one worth keeping: a preference is only a preference if it came from a decision. Inferring it from a nearby click is not consent, it is a guess with a database row attached.
Where the line is
To be clear about what this trade costs you: you cannot move the sidebar, restyle a button, or inject a font we do not ship. If your brand requires pixel-level control of a members' area, we are the wrong tool and would rather you found that out from a blog post than from a migration.
What you can do is have a community that looks deliberate on a phone at 11pm, in dark mode, with a screen reader, in a year's time, without you maintaining any of that.
That is the trade. We think it is the right one for almost everybody who is running a community rather than building one.