Theming
Two CSS custom properties decide how a character is painted; everything else is a token you can override.
The variables that draw a character
A character's colours come down to a few CSS custom properties.
The component sets the first few for you, from the engine's getInkVars(color). --aora-bg-base is the one you may need to change.
Light and dark
The ink is written as a light-dark() pair:
This is why the engine never subscribes to a theme change. The value is written once, and the browser re-resolves it when color-scheme flips. A thousand characters re-theme with no JavaScript, no re-render, and no flash.
color-scheme to one value
The stylesheet sets color-scheme: light dark on :root, so the page follows the system. If your application pins it to light, every light-dark() value freezes to its light variant and dark mode stops working for characters even though the rest of the page switches. Let the page own the scheme.
Every colour token is a light-dark() pair, and the page picks the half with color-scheme. That is the only dark-mode mechanism: there are no per-theme copies of the tokens. These selectors pin the scheme on any element, so one subtree can differ from the rest of the page:
Several class names are supported because application shells and documentation frameworks disagree about which to use.
Eye cut-outs
The default cute face is painted white and does not depend on the background. The eyes of the eyes and line faces are holes: filled with --aora-bg and clipped to the body, so they read as transparent on any surface, and so is the cute face of the black ink. That only holds while --aora-bg-base matches what is actually behind the character.
Override it on any ancestor and the whole subtree follows:
If you need the eyes to be a solid colour rather than a hole, pass eyeColor.
Cascade layers
The stylesheet puts its rules in three layers, from lowest to highest priority: aora.tokens, aora.base and aora.components.
One consequence is worth knowing. Any rule you write outside a layer beats every rule inside one, regardless of specificity — so overriding a component style never needs !important.
Tokens
Click any token to copy its name.
Surfaces
Text
Lines and fills
Accent
Radii
Palette
The inks are data, not CSS. Each carries three layers, because a 20px picker chip and a large filled silhouette have opposite requirements: the chip needs to be told apart from its neighbours, the body needs to stay legible on both a white and a near-black page.
| id | chip | ink (light) | ink (dark) |
|---|---|---|---|
black | #1A1A1A | #1F1F1F | #FFFFFF |
brown | #C46A32 | #D07A44 | #BF703F |
red | #E0363A | #EB4B4F | #D84549 |
orange | #F25C0F | #FF7228 | #EB6925 |
yellow | #E9A20C | #F0B326 | #DDA523 |
green | #1B9A5C | #28B06C | #25A263 |
cyan | #0899B8 | #14B0D2 | #12A2C1 |
blue | #0D7EFF | #2B8FFF | #2884EB |
violet | #6F55E0 | #846BEC | #7962D9 |
magenta | #D12D8C | #E0449E | #CE3F91 |
pink | #E8628F | #F0709F | #DD6792 |
gray | #6E7382 | #83889A | #797D8E |
black is the one special case: its dark-mode ink is white, so the neutral character is always the one with the most contrast whichever way the page is themed.
Next
- Custom shapes — register a generator of your own
- Palette — every hue in three layers
- Rendering structure — one SVG, every attribute written by hand