EMA Design System

One design language for all our projects. Framework-agnostic web components, a tight and fast UX, premium animations, four themes, full mobile responsiveness — and an advanced data grid built in.

27+ components

Inputs, selects, autocomplete, modals, toasts, tabs, datepicker and more — all as native custom elements that work in any stack.

Advanced data grid

Server & client pagination, search, filters, grouping, drill-down, inline editing, keyboard navigation, column resize/show/hide.

4 themes, token-driven

Light, Dark, Navy and Emerald. Every color, size and shadow is a CSS custom property — restyle the entire system in one place.

Installation

Copy the ema/ folder into your project and include three files. No build step, no dependencies, no framework required.

<!-- 1. Styles -->
<link rel="stylesheet" href="ema/css/tokens.css">
<link rel="stylesheet" href="ema/css/components.css">
<link rel="stylesheet" href="ema/css/grid.css">        <!-- only if you use <ema-grid> -->

<!-- 2. Scripts -->
<script src="ema/js/ema.js" defer></script>
<script src="ema/js/ema-grid.js" defer></script>       <!-- only if you use <ema-grid> -->

<!-- 3. Base class on body -->
<body class="ema-body">

Then use components as plain HTML:

Save Cancel

Theming

Themes are applied with a single attribute on <html>. Try the colored dots in the top bar — every component on this page re-themes instantly.

<html data-theme="dark">     <!-- light (default) | dark | navy | emerald -->

Runtime settings — EMA.configure()

Theme, brand colors, corner style and density are all configurable at runtime and persist to localStorage automatically (restored when ema.js loads). Try the ⚙ gear in the top bar of this site.

EMA.configure({
  theme:     'navy',        // light | dark | navy | emerald
  primary:   '#7c3aed',     // any hex — hover/active/soft tones are derived
  secondary: '#0d9488',     //   automatically and adapt to every theme
  radius:    'rounded',     // sharp (default) | subtle | rounded
  density:   'medium',      // tight (default) | compact | medium | large
  headerBg:  '#1a4c87',     // header color: table headers, modal/drawer/card heads
  formLayout:'left',        // top (default) | left (labels beside) | compact
  menu:      'rail',        // sidebar | rail | top — app-shell menu (demo apps)
});

EMA.getSettings();          // current saved settings
EMA.resetSettings();        // back to defaults (sharp, tight, brand colors)

Corner radius

Sharp edges are the default. Soften globally with one attribute (or via EMA.configure):

<html>                          <!-- default: sharp, square corners -->
<html data-radius="subtle">     <!-- 2–8px -->
<html data-radius="rounded">    <!-- 4–16px -->

Density

Tight is the default (14px text, 34px controls). Four modes adjust control heights, text and spacing:

<html data-density="compact">   <!-- densest, for data-heavy screens -->
<html>                          <!-- default: tight -->
<html data-density="medium">    <!-- relaxed controls (40px) -->
<html data-density="large">     <!-- spacious, touch-friendly (44px) -->

Custom branding (CSS only)

Prefer static config? Override tokens after importing tokens.css:

:root {
  --ema-primary: #0b5fa5;          /* your brand navy-blue */
  --ema-secondary: #138a50;        /* your brand green     */
}

Color tokens

The primary palette is a navy / light-blue ramp; the secondary palette is green. Status colors cover success, warning, danger and info.

Primary — navy blue

Secondary — green

Neutrals

Semantic tokens

Components never reference raw ramp colors — they use semantic tokens that change per theme:

TokenPurpose
--ema-primary / -hover / -activeBrand actions, focus, selection
--ema-primary-soft / -soft-2Tinted backgrounds (selected options, soft buttons)
--ema-secondary…Success-leaning accents, edit highlights
--ema-bg / --ema-surface / --ema-surface-2/3Page and layered panel backgrounds
--ema-text / --ema-text-2 / --ema-text-3Primary / secondary / muted text
--ema-border / --ema-border-strongHairlines and control outlines
--ema-danger / -warning / -success / -infoStatus colors (each with a -soft tint)
--ema-shadow-sm/md/lg/xlElevation scale
--ema-radius-xs…xl / -fullCorner radii
--ema-dur-fast/med/slow + --ema-ease*Motion durations and easing curves

Typography & spacing

The UI font stack prefers Inter / Segoe UI. The base UI size is a tight 14px, with a 4px spacing scale and 34px default control height — built for dense, professional applications.

TokenValueUse
--ema-text-xs / sm12 / 13pxMeta text, table headers, hints
--ema-text-md14pxDefault UI text
--ema-text-lg / xl / 2xl / 3xl16–30pxHeadings
--ema-sp-1 … --ema-sp-124–48pxMargins, paddings, gaps
--ema-control-h-sm / md / lg28 / 34 / 40pxButtons and inputs

UX principles

PrincipleHow the system enforces it
Tight by default14px base font, 34px controls, 4px spacing grid. data-density="compact" for even denser screens.
Keyboard firstEvery interactive component is focusable and operable with the keyboard; the grid supports full arrow-key cell navigation and Enter-to-edit.
Motion with purposeAnimations run 120–320ms on spring/ease-out curves and respect prefers-reduced-motion.
Mobile responsiveLayout utilities collapse below 900/600px; grids scroll horizontally; modals, toasts and toolbars adapt to small screens.
AccessibleVisible focus rings, ARIA roles on composite widgets, color-contrast-checked palettes in all four themes.

Next steps

Building or extending the system? Read the rendered README and DEVELOPMENT guide (architecture, conventions, how to author new components) — always in sync with the markdown files in the repository root.