Skip to content

Ekonavi/lib-theme

Repository files navigation

@ekonavi/theme

Shared design tokens, themes, and Tailwind CSS 4 integration for all Ekonavi apps.

Overview

This package provides a single source of truth for:

  • Brand color palette (greens, earths, neutrals)
  • Theme variants (forest + earthy, each with light/dark modes)
  • Tailwind 4 @theme inline integration (CSS vars → utility classes)
  • shadcn/ui base layer (border, body, heading defaults)
  • Shared utility classes (scrollbar, radio chips, product grid, etc.)

No compiled CSS is shipped. Each consuming app runs its own Tailwind 4 build, avoiding class collisions entirely.

Quick Start

1. Install

pnpm add @ekonavi/theme

2. Import in your app's globals.css

@import "tailwindcss";
@import "tw-animate-css";
@import "@ekonavi/theme";

/* Tell Tailwind 4 to scan the theme package for class usage */
@source '../node_modules/@ekonavi/theme';

/* App-specific styles below */

2b. Add Vite alias (required)

CSS @import cannot resolve Node.js package exports. Add aliases to vite.config.ts:

// vite.config.ts
resolve: {
  alias: {
    '@ekonavi/theme/extras.css': path.resolve(__dirname, 'node_modules/@ekonavi/theme/src/tokens/extras.css'),
    '@ekonavi/theme': path.resolve(__dirname, 'node_modules/@ekonavi/theme/src/index.css'),
  }
}

3. Apply a theme class

Add one of these classes to your <html> element:

Class Description
forest-light Green dominant, light mode
forest-dark Green dominant, dark mode
earthy-light Brown/amber dominant, light mode
earthy-dark Brown/amber dominant, dark mode
// Next.js layout.tsx example
export default function RootLayout({ children }) {
  return (
    <html className="forest-light">
      <body>{children}</body>
    </html>
  );
}

4. Theme switching with next-themes

import { ThemeProvider } from "next-themes";

// Map next-themes values to CSS classes
const themeMap = {
  "forest-light": "forest-light",
  "forest-dark": "forest-dark",
  "earthy-light": "earthy-light",
  "earthy-dark": "earthy-dark",
};

export function Providers({ children }) {
  return (
    <ThemeProvider
      attribute="class"
      themes={Object.keys(themeMap)}
      defaultTheme="forest-light"
    >
      {children}
    </ThemeProvider>
  );
}

Available Exports

Import Path Contents
@ekonavi/theme Everything (tokens + tailwind + base + utilities)
@ekonavi/theme/tokens All token files only (no utilities/base)
@ekonavi/theme/tokens/colors Brand color palette only
@ekonavi/theme/tokens/forest Forest theme vars only
@ekonavi/theme/tokens/earthy Earthy theme vars only
@ekonavi/theme/tokens/typography Font definitions only
@ekonavi/theme/tokens/spacing Spacing/radius/layout only
@ekonavi/theme/extras.css Air, Sea, Midnight themes
@ekonavi/theme/tailwind.css @theme inline block only
@ekonavi/theme/shadcn-base.css Base layer only
@ekonavi/theme/utilities.css Utility classes only

Brand Palette Utilities

In addition to semantic colors (bg-primary, text-foreground, etc.), the theme exposes brand colors directly:

<div class="bg-eko-sage text-eko-deep-green">Sage background</div>
<div class="bg-eko-amber text-white">Amber CTA</div>
<div class="border-eko-dark-teal">Teal border</div>
<div class="bg-eko-gold">Gold badge</div>

Available: eko-sage, eko-deep-green, eko-dark-teal, eko-light-green, eko-dark-green-bg, eko-amber, eko-coral, eko-earth-brown, eko-cream, eko-gold, eko-warm-beige

Typography

Fonts are defined as CSS custom properties. Load them in your app:

// Next.js app/layout.tsx
import { Josefin_Sans } from "next/font/google";

const josefin = Josefin_Sans({
  subsets: ["latin"],
  variable: "--font-josefin",
});

export default function RootLayout({ children }) {
  return (
    <html className={`forest-light ${josefin.variable}`}>
      <body>{children}</body>
    </html>
  );
}

Fonts Reference

  • Body: Josefin Sans (Google Fonts)
  • Display/Headings: Bryndan Write (custom — load via @font-face)

Local Development

When working on the theme package alongside an app:

# Option A: pnpm link
cd ekonavi-theme && pnpm link --global
cd ../your-app && pnpm link --global @ekonavi/theme

# Option B: yalc (more reliable)
cd ekonavi-theme && yalc publish
cd ../your-app && yalc add @ekonavi/theme

File Structure

@ekonavi/theme/
├── src/
│   ├── tokens/
│   │   ├── colors.css        ← brand palette (--eko-sage, --eko-amber, etc.)
│   │   ├── forest.css        ← .forest-light, .forest-dark
│   │   ├── earthy.css        ← .earthy-light, .earthy-dark
│   │   ├── extras.css        ← .air-*, .sea-*, .midnight-*
│   │   ├── typography.css    ← font families, sizes, weights
│   │   ├── spacing.css       ← radius, sidebar, z-index
│   │   └── index.css         ← imports all tokens
│   ├── tailwind.css          ← @theme inline block
│   ├── shadcn-base.css       ← @layer base rules
│   ├── utilities.css         ← shared utility classes
│   └── index.css             ← main entry point
├── package.json
└── README.md

About

NPM Package for Ekonavi Multi-App Shared Style System

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages