Themes
BugPort ships two themes: a cream-canvas light theme that is the default and the face of the brand, and a warm dark theme that stays plum-tinted rather than going pure black. This page explains both, shows how this very docs site maps the aubergine palette onto Infima CSS variables, covers contrast and accessibility per theme, and gives a token-mapping table with the real hex values.
Theming in BugPort is not "invert everything". It is two deliberate moods built from the same palette, each tuned for legibility.
The cream-canvas light theme
Light is the primary theme and where most of the product lives. Its defining move is that the page background is Cream Canvas #fefbff, not flat white. White is reserved for elevated cards, so the surface hierarchy is legible the moment a screen loads.
- Page background: Cream Canvas #fefbff (warm, never pure white).
- Content surface: white cards with a 1px Iris Edge #eac8fe or ash border and a 16px radius.
- Support surface: Lavender Wash #f9f0ff for grouped filters and passive summaries.
- Text: Eggplant Ink #2e0039 for headings, Midnight Plum #1d1c1d for body, Graphite #454245 for secondary, Steel #696969 for muted.
- Accent: Iris Mid #730394 for primary actions, active nav, and links.
The warm dark theme
Dark is warm, not cold. It leans on the plum family so it still feels like BugPort and not a generic dark mode. Avoid pure black (#000000) — it reads harsh against the brand's warmth.
- Page background: a deep plum-tinted near-black derived from Midnight Plum #1d1c1d / Eggplant Ink #2e0039, not pure black.
- Content surface: a raised plum panel above the background; borders soften to low-opacity iris tints.
- Accent: shift toward the brighter end of the ramp — Violet Glow #d17dfe and Iris Edge #eac8fe read better on dark than Iris Mid does.
- Text: near-white on the page; strong white on the inverse plum bands.
How the docs site maps tokens
This Docusaurus site is itself a reference implementation. It maps the aubergine ramp onto Infima's CSS variables (the --ifm-* custom properties) rather than fighting the framework:
- The primary ramp (
--ifm-color-primaryand its light/dark steps) is built from the Iris ramp, with Iris Mid #730394 as the centre. - The navbar uses a plum-deep surface so the brand reads immediately at the top of every page.
- The site defaults to light mode, matching the cream-canvas product feel, with the dark theme available as an opt-in.
- Lavender surfaces back the custom MDX components (hints, cards, do/don't blocks) via the
bp-*classes layered on top of Infima.
The takeaway for product teams: you do not need a bespoke theming engine to be on-brand. Map the ramp onto whatever variable system your framework already exposes, keep the navbar/header plum, and default to the cream light mode.
Contrast and accessibility per theme
Theme work is legibility work. A few rules carry most of the weight:
- Strong white text on inverse. On Plum Deep #481a54 / Plum Shadow #3d0157 bands, text must be strong white (or Iris Edge #eac8fe for muted) — never mid-grey on plum.
- Don't use Iris Mid for small body on cream without testing. Iris Mid #730394 on Cream Canvas #fefbff is fine for links and headings but can fall short for small body and captions. Test it, and prefer Eggplant Ink / Midnight Plum / Graphite for running text.
- Muted text has a floor. Steel #696969 is the muted limit on light; do not go lighter for body-sized text.
- Carry focus states across themes. Visible focus rings (Iris Edge / Violet Glow) must remain obvious in both light and dark.
When to use the inverse plum surface
The Plum Deep inverse is a punctuation mark, not a paragraph. Use it for:
- One or two narrative bands on a marketing page — a storytelling moment that breaks the cream rhythm.
- Milestone and upgrade moments — a workspace crossing a threshold, a celebratory confirmation, an "add storage" prompt framed as progress (storage, never seats).
Do not build whole dashboards, forms, or dense data tables on the inverse surface. Its power comes from scarcity; overuse turns a signal into noise.
Token mapping
The same semantic token resolves to different hex per theme. Real values:
| Token | Light value | Dark value |
|---|---|---|
surface/page | Cream Canvas #fefbff | Plum-tinted near-black from #1d1c1d |
surface/card | White #ffffff | Raised plum panel above #2e0039 |
surface/support | Lavender Wash #f9f0ff | Low-opacity Iris Edge #eac8fe tint |
surface/inverse | Plum Deep #481a54 | Plum Deep #481a54 |
text/heading | Eggplant Ink #2e0039 | Near-white |
text/body | Midnight Plum #1d1c1d | Near-white |
text/muted | Steel #696969 | Iris Edge #eac8fe (muted) |
accent/primary | Iris Mid #730394 | Violet Glow #d17dfe |
border/brand | Iris Edge #eac8fe | Low-opacity iris tint |
Design and build against the semantic token (accent/primary), never the raw hex. That is what lets the same component render correctly in both themes — the token swaps Iris Mid for Violet Glow underneath without the component knowing.
Theme do's and don'ts
- Keep light on cream, with white cards and lavender support.
- Make dark warm and plum-tinted; brighten accents toward Violet Glow.
- Use strong white text on every inverse band.
- Reserve the plum inverse for one or two narrative or milestone moments.
- Don't use pure white as the light page background.
- Don't use pure black in the dark theme.
- Don't set small body or caption text in Iris Mid on cream without contrast testing.
- Don't build dense tables or forms on the inverse surface.