OHC Network Wiki:Design/careui
More languages
More actions
This wiki uses careui, Open Healthcare Network's
design system (github.com/ohcnetwork/careui).
Colour, type, shape and spacing all come from careui rather than from a wiki-specific
palette.
The one rule
Never write a colour literal outside MediaWiki:Common.css.
Every component references var(--ohc-*). This is what makes dark mode
work: a literal cannot adapt, so a hardcoded colour is a dark-mode bug waiting to
be filed. Before this port there were 96 colour literals across the component
stylesheets, and dark mode was visibly broken on cards, badges, infoboxes and
navboxes.
How it fits together
| Layer | Page | Responsibility |
|---|---|---|
| Typefaces + tokens | MediaWiki:Common.css | @font-face for Figtree/Geist Mono, and every --ohc-* token for both themes. The single source of colour.
|
| Skin chrome | MediaWiki:Citizen.css | Rebinds Citizen's own OKLCH knobs to the careui tokens — accent, neutrals, surfaces, borders, radius, type scale. |
| Content | MediaWiki:Common.css | careui prose rules scoped to .mw-parser-output, plus the unified table treatment.
|
| Components | Template:*/styles.css |
Infobox, navbox, sidebar, cards, badges, admonitions. Token references only. |
Colour tokens
Values are resolved from Tailwind v4.3.2's ramps, which is what careui's own
tokens indirect onto. careui's build-time syntax (@theme inline,
--alpha()) does not survive outside a Tailwind build and is expanded
here.
| Token | Light | Dark | careui source |
|---|---|---|---|
--ohc-background |
#ffffff |
#0a0a0a |
literal |
--ohc-soft-background |
#fafafa |
#171717 |
neutral-50 |
--ohc-muted-background |
#f5f5f5 |
#262626 |
neutral-100 |
--ohc-strong-background |
#e5e5e5 |
#404040 |
neutral-200 |
--ohc-muted |
#f5f5f5 |
#262626 |
neutral-100 |
--ohc-foreground |
#0a0a0a |
#fafafa |
neutral-950 |
--ohc-muted-foreground |
#404040 |
#e5e5e5 |
neutral-700 |
--ohc-soft-foreground |
#525252 |
#d4d4d4 |
neutral-600 |
--ohc-disabled-foreground |
#d4d4d4 |
#404040 |
neutral-300 |
--ohc-placeholder-foreground |
#737373 |
#525252 |
neutral-500 |
--ohc-inverse-foreground |
#ffffff |
#000000 |
literal |
--ohc-card |
#ffffff |
#171717 |
literal |
--ohc-card-foreground |
#0a0a0a |
#ffffff |
neutral-950 |
--ohc-popover |
#ffffff |
#0a0a0a |
literal |
--ohc-popover-foreground |
#0a0a0a |
#fafafa |
neutral-950 |
--ohc-primary |
#006045 |
#00d492 |
emerald-800 |
--ohc-primary-foreground |
#ecfdf5 |
#002c22 |
emerald-50 |
--ohc-secondary |
#f5f5f5 |
#262626 |
neutral-100 |
--ohc-secondary-foreground |
#171717 |
#fafafa |
neutral-900 |
--ohc-accent |
#f5f5f5 |
#404040 |
neutral-100 |
--ohc-accent-foreground |
#171717 |
#fafafa |
neutral-900 |
--ohc-destructive |
#e7000b |
#ff6467 |
red-600 |
--ohc-destructive-foreground |
#fef2f2 |
#fef2f2 |
red-50 |
--ohc-soft-border |
#f5f5f5 |
rgba(255, 255, 255, 0.05) |
neutral-100 |
--ohc-border |
#e5e5e5 |
rgba(255, 255, 255, 0.09) |
neutral-200 |
--ohc-strong-border |
#d4d4d4 |
rgba(255, 255, 255, 0.15) |
neutral-300 |
--ohc-stronger-border |
#a1a1a1 |
rgba(255, 255, 255, 0.22) |
neutral-400 |
--ohc-inverse-border |
#ffffff |
#fafafa |
literal |
--ohc-input |
#d4d4d4 |
rgba(255, 255, 255, 0.15) |
neutral-300 |
--ohc-ring |
rgba(97, 95, 255, 0.75) |
rgba(97, 95, 255, 0.75) |
literal |
--ohc-primary-bg |
#ecfdf5 |
#002c22 |
emerald-50 |
--ohc-primary-border |
#a4f4cf |
#006045 |
emerald-200 |
--ohc-shadow-color |
rgba(0, 0, 0, 0.10) |
rgba(0, 0, 0, 0.55) |
literal |
--ohc-shadow-color-strong |
rgba(0, 0, 0, 0.18) |
rgba(0, 0, 0, 0.70) |
literal |
--ohc-chart-1 |
#f54900 |
#1447e6 |
orange-600 |
--ohc-chart-2 |
#009966 |
#00c950 |
emerald-600 |
--ohc-chart-3 |
#104e64 |
#fe9a00 |
cyan-900 |
--ohc-chart-4 |
#ffb900 |
#ad46ff |
amber-400 |
--ohc-chart-5 |
#f0b100 |
#ff2056 |
yellow-500 |
Brand ramp
careui parameterises --primary-* so a downstream project can swap the
brand ramp. We keep careui's default, emerald. The full ramp is exposed as
--ohc-primary-50 … --ohc-primary-950 for tints.
| Step | Value |
|---|---|
--ohc-primary-50 |
#ecfdf5
|
--ohc-primary-100 |
#d0fae5
|
--ohc-primary-200 |
#a4f4cf
|
--ohc-primary-300 |
#5ee9b5
|
--ohc-primary-400 |
#00d492
|
--ohc-primary-500 |
#00bc7d
|
--ohc-primary-600 |
#009966
|
--ohc-primary-700 |
#007a55
|
--ohc-primary-800 |
#006045
|
--ohc-primary-900 |
#004f3b
|
--ohc-primary-950 |
#002c22
|
Status palette
careui has no status colours — it ships primary, destructive
and a chart-1..5 set whose hues intentionally differ between light and
dark, which makes them wrong for status badges (a "development" chip must not
change hue when the reader flips theme). So this is a deliberate extension, built in
careui's idiom: same ramps, same steps careui uses for foreground/background pairs.
| Status | Ramp | Text | Background | Hairline | Used for |
|---|---|---|---|---|---|
success |
emerald | #007a55 / #00d492 |
/ | / | production, active |
info |
blue | #1447e6 / #51a2ff |
/ | / | development, stable, backend |
warning |
amber | #bb4d00 / #ffb900 |
/ | / | staging, experimental |
danger |
red | #c10007 / #ff6467 |
/ | / | inactive, deprecated |
accent |
purple | #8200db / #c27aff |
/ | / | preview, frontend |
neutral |
neutral | #404040 / #a1a1a1 |
/ | / | demo, unclassified |
Typography
| Role | Family | Source |
|---|---|---|
| Everything | Figtree Variable (300–900) | @fontsource-variable/figtree@5.2.10, pinned on jsDelivr
|
| Code | Geist Mono Variable (100–900) | @fontsource-variable/geist-mono@5.2.8, pinned on jsDelivr
|
These are the same files careui itself uses. They are declared as
@font-face in MediaWiki:Common.css, not injected from JavaScript —
the previous gadget-based approach guaranteed a flash of fallback text and in
practice often failed to apply at all.
Switzer has been dropped; careui is Figtree throughout. careui derives heading
hierarchy from weight, not colour, so every heading is
--ohc-foreground and only size and weight step down.
Shape
careui's radius scale is one --radius (10px) with ±4px steps:
sm 6 · md 8 · lg 10 · xl 14 ·
2xl 18 · 3xl 22 · full 9999.
Citizen derives medium = 2 × base and large = 3 × base,
which cannot express that scale, so all three are set explicitly in
MediaWiki:Citizen.css.
Editing TemplateStyles: known limits
The TemplateStyles sanitizer is stricter than normal CSS. These were established by
probing the live wiki, not from documentation. A rejected declaration fails the
whole page save with templatestyles-error-bad-value-for-property —
it is not silently dropped.
var() accepted?
| |
|---|---|
color, background, background-color |
Yes |
border (shorthand), border-side, border-side-color |
Yes |
box-shadow — colour slot only |
Yes (0 4px 12px var(--x)); a whole-value var() is rejected
|
outline, text-decoration-color, linear-gradient() |
Yes |
border-radius, font-family, padding, border-color |
No — keep these literal |
color-mix() |
No — derive the value as a token in MediaWiki:Common.css instead |
custom-property declarations (--x: y) |
No — declare in MediaWiki:Common.css |
corner-shape (careui squircles) |
No — unrecognised property |
Because color-mix() and custom properties are both unavailable on the
template side, any derived tint (bg-primary/10 in careui terms) must be
pre-computed as its own token — hence --ohc-primary-bg,
--ohc-primary-border and the --ohc-status-*-bg family.
Checking your work
- OHC Network Wiki:Design/Preview renders every component in one page — open it in both themes.
- Contrast floors are careui's: 4.5:1 body, 3:1 large text and UI chrome.
- Remember MediaWiki invalidates dependent pages lazily. After editing a
styles.css, a page may serve stale CSS from the parser cache for a while; force a re-parse with?action=purgebefore concluding something is broken.