Skip to main content
Components emit classes bound to Ekanos’s semantic design tokens. You control theming through imports and CSS.

Stylesheet options

Option 1: Pre-compiled stylesheet (standalone)

Self-contained: Tailwind Preflight, design tokens, light and dark, and every utility class this package’s components emit — derived by compiling the class strings found in the built bundles. Nothing else to install, no build step, no config; it works in Next.js, Vite, CRA, or a plain <link rel="stylesheet">. Limits:
  • A Tailwind class you write in your own markup (p-8, grid-cols-3) has no rule in it and does nothing. Style your own markup with plain CSS, or take the Tailwind path.
  • Preflight is a global reset: it normalises margins, headings, and form controls across your whole page. If that is unwelcome, use the Tailwind path and control layering yourself.

Option 2: Tailwind integration (with your build)

Registers the token map (--color-primary → --primary, the --radius-* scale, the shadow-* elevation utilities), the token values for both themes, the base rules, the dark: variant, and an @source pointing at this package’s bundles so your Tailwind v4 build generates the components’ utilities itself. You then get the Ekanos tokens in your own class strings too.
Pick one path. Do not also import styles.css: loading both means two copies of every utility.

Individual pieces (advanced)

theme.css already includes both of these. They are published separately if you want the pieces:
  • @ekanos/ui/tokens.css — just the custom properties (light and dark), no Tailwind at-rules
  • @ekanos/ui/base.css — the base rules: a default border colour, the missing-icon placeholders, and the opt-in .ekanos-root page shell (no Preflight)
Neither registers the Tailwind token map or @source, so on their own they do not make Tailwind generate the components’ utilities.

Design tokens

Semantic color tokens

tokens.css is generated from Ekanos’s own design system and checked by value in the package build, so the preset matches the app exactly. As of 0.4.0 that includes the -strong text steps for status colors (--destructive-strong, --warning-strong, --info-strong, with text-warning-strong and text-info-strong utilities) and --favorite (text-favorite), which were missing or stale before. Overlays also use the elevation tiers: dialogs take shadow-modal, select and dropdown menus take shadow-popover, and inputs, textareas and select triggers fill with bg-card so they stay visible on the warm page background. tokens.css also carries status (success, warning, info), chart (--chart-1…--chart-5), sidebar, and assistant tokens, the elevation scale, --radius, and the fonts.

Tailwind classes

Elevation tokens (shadows)

The Tailwind path exposes the full scale: shadow-flat, shadow-sunken, shadow-inset, shadow-card, shadow-widget, shadow-rail, shadow-popover, shadow-sticky, shadow-modal, shadow-overlay. The compiled styles.css includes only what the components use (shadow-card).

Spacing, radius, typography

Dark mode

Dark mode is applied by CSS class or attribute, with a fallback to OS preference: So an app with no theme toggle still follows the OS, and one with a toggle works by setting the class or attribute.

With next-themes

With plain JavaScript

With data attributes

Page background

The stylesheet doesn’t force a page background. To adopt Ekanos’s surface (which makes dark mode look right):
.ekanos-root sets background-color: var(--background), color: var(--foreground), font-family: var(--font-sans), and font smoothing. You can put it on <body> or on any wrapper around Ekanos UI. Without it, the stylesheet leaves your page background alone, so in dark mode you get dark cards on whatever background your page already has.

Customizing tokens

The token values ship inside the base cascade layer, so an unlayered rule that redefines a token (for example :root { --primary: … }) takes precedence on either path. Redefine it for dark mode too (.dark, [data-theme='dark'], and the prefers-color-scheme case), or the override applies only where you set it. On the Tailwind path, add your own colours with Tailwind v4’s CSS-first @theme block as usual; the components keep using the semantic tokens.

Fonts

Ekanos pairs Figtree (body) with Bricolage Grotesque (headings). This package names them in --font-sans / --font-heading but doesn’t load them; no webfont is bundled or fetched. To match Ekanos exactly, load them yourself:
Or use your project’s fonts. Everything still renders with the package’s system fallback stack.

Troubleshooting

Styling not applied to components

  1. Check that you imported either styles.css (standalone) or theme.css (Tailwind), not both
  2. If using Tailwind, import theme.css after @import 'tailwindcss'; its @source points Tailwind at the package’s bundles, so you do not add one by hand
  3. If only your own classes are unstyled on the styles.css path, that is expected: it contains only the components’ utilities

Dark mode not working

  1. Check that an ancestor has .dark or [data-theme='dark'], or that the OS prefers dark and :root has no .light / [data-theme='light']
  2. If using next-themes, verify it wraps your app with attribute="class"
  3. If cards are dark but the page is not, add class="ekanos-root"

Fonts look wrong

Load Figtree and Bricolage Grotesque from Google Fonts (or your own CDN). The package defines --font-sans and --font-heading but doesn’t include the font files.