OpenELIS Global Style Guide — v1 Foundations

OpenELIS Global Style Guide — v1 Foundations

OpenELIS Global — Style Guide v1 Foundations

Status: Published v1 Foundations (2026-04-23)
Owner: Casey Iiams-Hauser · Audience: Developers + designers contributing to OpenELIS Global
Source of truth: Live app at testing.openelis-global.org + DIGI-UW/OpenELIS-Global-2 develop branch. All tokens in this document are observed from the shipped app, not aspirational.
Supersedes: Replaces the prior body of this page (Taib, May 2025) in color + typography sections. Prior framing is preserved in §1 and §2. See §13 Migration notes.


Table of contents

  1. Purpose & scope

  2. Design system stack

  3. Brand tokens

  4. Typography

  5. Color

  6. Spacing, radius, elevation

  7. Forms

  8. Voice & tone

  9. Notifications

  10. Accessibility floor

  11. Known non-Carbon utilities

  12. Appendix — known technical debt

  13. Migration notes


1. Purpose & scope

OpenELIS Global is a laboratory information system used across diverse health systems and countries. Each deployment has different needs, but they share the same challenges: inconsistent user experience, uneven frontend tooling, and fragmented engineering practices across contributors. Historically, visual and interaction design across OpenELIS implementations has drifted, making collaboration harder and increasing the cost of maintenance and onboarding.

This guide is the response. It sets the baseline for a unified, modern, accessible design language across every OpenELIS Global interface, regardless of country, customization, or use case. It helps contributors ship faster with fewer regressions. It ensures the software stays usable for everyone — users on low-bandwidth networks, older hardware, and varying levels of digital literacy or ability.

This documentation is not theoretical. It is derived from the shipped app and the repo — real implementation experience, active deployments, and the lessons of maintaining a global open-source LIS. The aim is to reduce guesswork, eliminate inconsistency, and make OpenELIS easier to contribute to, extend, and scale.

Objectives

  • A clear, consistent user experience across every OpenELIS interface.

  • Maintainability and scalability of both design and code.

  • Accessibility, internationalization, and responsive behavior by default.

  • A shared vocabulary that lets distributed contributors collaborate without re-litigating decisions.

Who this guide is for

  • Software engineers writing frontend or backend code that touches the UI.

  • UX/UI designers producing layouts, workflows, and visual elements.

  • QA testers verifying functionality aligns with expected behavior.

  • Documentation writers preparing user manuals and technical guides.

  • Implementers and administrators customizing or deploying OpenELIS for a specific lab or country.

What v1 covers (and what it doesn't)

v1 covers brand tokens, typography, color, spacing/radius, forms, voice & tone, notifications, accessibility floor, and known non-Carbon utilities.

v1 does not cover component-level patterns (data tables, workplan grids, referral queues, report shells), page-shell patterns, iconography catalog, or data-viz conventions. Those land in v2 Patterns.

How to use this page

Every section has a stable heading. Reference those headings from Jira stories, PR descriptions, and design reviews. If a new UI introduces something this guide doesn't cover, the default is to follow Carbon upstream and raise a v2 Patterns ticket.


2. Design system stack

Why Carbon

OpenELIS Global adopts the IBM Carbon Design System as the foundation for its UI layer. Carbon is professionally maintained, actively developed, shipped with a first-class React component library, has strong accessibility defaults built in, and provides a token-based theming surface that makes it straightforward to apply OpenELIS's brand without maintaining a bespoke component library.

Carbon enables OpenELIS to maintain a unified, scalable interface while reducing maintenance overhead. Contributors focus on lab-specific functionality rather than on reinventing inputs, tables, and modals.

Alternative design systems (Ant Design, Material UI, Bootstrap) were considered; Carbon was chosen for: (1) open-source enterprise-grade maintenance by IBM, (2) explicit design-token + theming architecture that supports the split-shell brand override we ship, (3) native React components with TypeScript support, and (4) strong accessibility + i18n story aligned with OpenELIS's global deployment profile.

Key principles for implementers

  1. Consistency — Use Carbon components for all new features. Do not reach for non-Carbon alternatives when a Carbon component exists.

  2. Extensibility — Customize via Carbon theme tokens, not custom CSS. The split-shell brand override is the template.

  3. Interoperability — Follow Carbon's API patterns when integrating with third-party libraries (Formik, charting, maps, etc.).

Dependency matrix

The shipped versions (from frontend/package.json):

Package

Version

Role

Package

Version

Role

@carbon/react

^1.15.0

Current React component library (class prefix cds--)

@carbon/themes

11.10.0

Token packages (White, Gray 10, Gray 90, Gray 100)

@carbon/icons-react

^11.17.0

Iconography

@carbon/charts

^1.27.2

Data visualization

@carbon/charts-react

React bindings for charts

carbon-components

^10.58.12

Legacy v10 (class prefix bx--) — isolated to older pages, being migrated out

react

17.0.2

Still on React 17

sass

1.79.5

SCSS compiler

single-spa

5.x

Micro-frontend plumbing for JSP ↔ React coexistence

Rule: New code uses @carbon/react (prefix cds--) only. Do not introduce new carbon-components v10 (bx--) imports. Existing v10 usage is legacy and will be migrated out incrementally.


3. Brand tokens

OpenELIS ships a split-shell theme: the top header and left side nav render in Carbon's g100 dark theme with a navy override; the content area renders in Carbon's White theme with a custom warm-light background.

Canonical theme file: frontend/src/index.scss

Token

Value

Where applied

Token

Value

Where applied

Brand navy

#295785

.cds--header background, side-nav layer-01, CSS variable --site-branding-header

Brand navy (hover)

#072655

.cds--header hover, layer-hover-01

Content background

#f5f6f8

.cds--content background (custom, slightly warmer than Carbon default #f4f4f4)

Shell text on navy

#ffffff

Header and side-nav text-primary, text-secondary, icons

For implementers rebranding OpenELIS: change --site-branding-header for the header color, and the layer-01 override in index.scss for the side nav. Those are the two hooks.

The #0f62fe Carbon Blue 60 still governs primary buttons, links, and focus rings inside the content area — that's unchanged from Carbon defaults.


4. Typography

Base font stack (shipped):

"IBM Plex Sans", system-ui, -apple-system, "system-ui", ".SFNSText-Regular", sans-serif

Body: 16px / 400 / #161616 (Carbon Gray 100). Links: #0f62fe / 14px (Carbon Blue 60, --cds-link-primary).

Heading rule

Semantic heading level must match the Carbon productive-type scale:

HTML element

Carbon token

Size

Weight

Use

HTML element

Carbon token

Size

Weight

Use

h1

productive-heading-06

42px

300

Page title (one per page)

h2

productive-heading-05

32px

400

Primary section

h3

productive-heading-04

28px

400

Subsection

h4

productive-heading-03

20px

400

Sub-subsection

h5

productive-heading-02

16px

600

Small heading

h6

productive-heading-01

14px

600

Label-like heading

Known drift (flag for cleanup): the current order-entry page uses h2 at both 32px and 20px and h3 at 28px — heading levels don't correlate with the type scale. Also, dashboard h4 is styled with #4b5563 (Tailwind Gray 600), not a Carbon gray. New code must conform to the table above; cleanup tickets are queued in §12.

Numeric + tabular data: use font-variant-numeric: tabular-nums on tables of counts, accession numbers, and result values so digits align across rows.

Line-height and letter-spacing come from the Carbon type tokens themselves — do not override them with custom values. If a layout feels too tight or too loose, adjust container spacing, not the font metrics.

Do not use all-caps headings. Do not introduce new font families.

Carbon type token reference

A shorthand mapping between Carbon type tokens and their typical role in OpenELIS:

Carbon token

Role

Use

Carbon token

Role

Use

productive-heading-06

Page title

h1 on page shells

productive-heading-05

Major section

h2 section breaks

productive-heading-04

Subsection

h3 subsections

productive-heading-03

Minor subsection

h4 within a section

productive-heading-02

Small heading

h5, card / panel title

productive-heading-01

Label-like heading

h6, table header emphasis

body-long-02

Long-form body

Paragraph body in descriptive content

body-long-01

Default body

Body copy in forms and admin pages

body-short-02

Compact body

Inline text in table cells

body-short-01

Labels and UI text

Input labels, small UI text

helper-text-01

Helper text

Helper text under form inputs, captions

label-01

Form labels

Input and select labels


5. Color

OpenELIS uses Carbon White as the base content theme, with the split-shell navy described in §3. Status + notification semantic colors come from Carbon directly and are pinned below.

Status + notification colors (Carbon)

Semantic role

Token

Hex

Semantic role

Token

Hex

Error / danger

--cds-support-error

#da1e28 (Red 60)

Warning

--cds-support-warning

#f1c21b (Yellow 30)

Success

--cds-support-success

#24a148 (Green 50)

Info

--cds-support-info

#0043ce (Blue 70)

Neutral scale (in use)

Token

Hex

Use

Token

Hex

Use

--cds-background

#ffffff

Tile, modal, input background (Carbon White theme)

--cds-layer-01 (content)

#f4f4f4

Field 01, card surfaces

Content area override

#f5f6f8

.cds--content custom background

--cds-border-subtle-01

#e0e0e0

Dividers

--cds-text-primary

#161616

Body text, icons

--cds-text-secondary

#525252

De-emphasized text, helper text

--cds-text-placeholder

#a8a8a8

Placeholders, disabled text

Interaction tokens (Carbon defaults in the content area)

These are Carbon defaults that drive buttons, links, and focus — they are NOT the OpenELIS brand (navy #295785 is). They govern interactive elements inside the White-theme content area only.

Token

Hex

Use

Token

Hex

Use

--cds-link-primary

#0f62fe

Primary link color, primary button

--cds-link-secondary

#0043ce

Secondary link, hover state

--cds-link-visited

#8a3ffc

Visited link

--cds-button-primary

#0f62fe

Primary action button

--cds-button-secondary

#393939

Secondary action button

--cds-button-secondary-hover

#474747

Secondary button hover

--cds-button-tertiary

#0f62fe

Tertiary action button

--cds-focus

#0f62fe

Focus ring (do not override)

Rule: if you're about to introduce a hex value that isn't in this page or in Carbon's default tokens, stop — you're drifting. Use the nearest Carbon token or file a ticket to extend this page.


6. Spacing, radius, elevation

Spacing

Use Carbon's 8px-step spacing scale via tokens: $spacing-01 (2px) through $spacing-13 (160px). The most common in OpenELIS: $spacing-03 (8px), $spacing-05 (16px), $spacing-07 (32px).

Do not use raw pixel values in new code. Do not use Tailwind spacing utilities.

Radius

OpenELIS is a sharp-cornered app. border-radius: 0 is the default across inputs, buttons, cards, modals, and tiles. Carbon's own default.

Two intentional exceptions:

Element

Radius

Rationale

Element

Radius

Rationale

Dashboard tiles

5px

Deliberate softness on the dashboard home — the one place users spend free-scan time

Tags (.cds--tag)

16px

Carbon tag default — pill-style

Do not introduce other radii. If you think you need one, file a ticket first.

Elevation

Use Carbon's $shadow tokens for elevation (modals, dropdowns). Do not layer custom box-shadow values.


7. Forms

OpenELIS uses @carbon/react inputs wired to formik for state + yup for validation.

Field anatomy

Property

Value

Property

Value

Field height