Skip to main content

Design System Reference

Repository: equa-patternlib-nextjs | Storybook: http://localhost:6006 | Next.js dev: http://localhost:3001

Overview

Equa’s design system is maintained in the equa-patternlib-nextjs repository and consumed by equa-web via the equa-patternlib package (installed from GitHub). Source: equa-web/package.json (dependency: equa-patternlib from github:EQUAStart/equa-patternlib-nextjs#master)

Component Inventory

Source: equa-patternlib-nextjs/stories/ (45 story files verified)
ComponentStory FilePurpose
EquaAvatarEquaAvatar.stories.tsxUser/org profile images with fallback initials
EquaBadgeEquaBadge.stories.tsxStatus indicators and labels
EquaButtonEquaButton.stories.tsxPrimary, secondary, ghost, danger actions
EquaCardEquaCard.stories.tsxContent containers with header/body/footer
EquaCheckboxEquaCheckbox.stories.tsxBoolean input with label
EquaChipEquaChip.stories.tsxTag-style compact labels
EquaDatePickerEquaDatePicker.stories.tsxDate selection with calendar dropdown
EquaDropdownEquaDropdown.stories.tsxSelect menus and option lists
EquaFileUploadEquaFileUpload.stories.tsxDrag-and-drop file upload zone
EquaInputEquaInput.stories.tsxText, email, password, number inputs
EquaMenuEquaMenu.stories.tsxNavigation and context menus
EquaModalEquaModal.stories.tsxDialog overlays for forms and confirmations
EquaPaginationEquaPagination.stories.tsxPage navigation controls
EquaProgressEquaProgress.stories.tsxProgress bars and loading indicators
EquaRadioEquaRadio.stories.tsxRadio button groups
EquaRatingEquaRating.stories.tsxStar rating display/input
EquaSidebarEquaSidebar.stories.tsxNavigation sidebar layout
EquaSkeletonEquaSkeleton.stories.tsxLoading placeholder shapes
EquaSliderEquaSlider.stories.tsxRange slider input
EquaStepperEquaStepper.stories.tsxMulti-step progress indicator
EquaSwitchEquaSwitch.stories.tsxToggle switch input
EquaTableEquaTable.stories.tsxData tables with sorting and pagination
EquaTabsEquaTabs.stories.tsxTab navigation
EquaToastEquaToast.stories.tsxNotification toasts
EquaToggleEquaToggle.stories.tsxOn/off toggle
EquaTooltipEquaTooltip.stories.tsxHover tooltips

Token Architecture (Cross-Framework)

The Equa design system uses a JSON-first token pipeline that feeds both React (Storybook + equa-web) and Lit (gateway dashboard) systems.

Source of Truth

design-tokens.json (W3C format)

       ├──→ design-tokens.css   (CSS custom properties — consumed by gateway Lit + Storybook)
       ├──→ tokens/index.ts     (typed JS exports — available for React imports)
       └──→ generated-theme-values.ts  (JS constants — consumed by theme.ts)
Build command: npm run tokens in equa-patternlib-nextjs CI check: npm run tokens:check — exits 1 if generated files are stale

Gateway Consumption (Lit + CSS Custom Properties)

The gateway loads design-tokens.css via styles.css:1, then base.css aliases short names to canonical tokens:
/* base.css — alias layer */
:root {
  --bg: var(--color-ui-background);
  --card: var(--color-ui-surface);
  --accent: var(--color-brand-primary);
  /* ~67 aliases total */
}
Gateway component CSS uses the short names (var(--bg), var(--card)), which resolve through the alias chain to canonical token values. This means gateway CSS files never need to change when token values are updated.

Patternlib Consumption (React + styled-components)

The patternlib’s theme.ts imports from generated-theme-values.ts:
import { RADIUS_SM, SHADOW_SM, COLOR_UI_BACKGROUND } from './generated-theme-values';

export const equaTheme: Theme = {
  radius: RADIUS_SM,       // '6px'
  boxShadow: SHADOW_SM,    // '0 1px 2px rgba(0, 0, 0, 0.2)'
  header: COLOR_UI_BACKGROUND,
  // ...
};
Components access tokens via props.theme.xxx in styled-components. Values stay in sync because generated-theme-values.ts is produced from the same design-tokens.json.

Modifying Tokens

  1. Edit equa-patternlib-nextjs/src/tokens/design-tokens.json
  2. Run npm run tokens to regenerate CSS, TS, and theme values
  3. Copy updated design-tokens.css + design-tokens.json to equabot-gateway/ui/src/tokens/
  4. Copy updated theme.ts + generated-theme-values.ts to equa-web/src/styles/
  5. Verify: npm run tokens:check exits 0, npm run test passes in both repos

Design Tokens

Source: equa-patternlib-nextjs/stories/DesignTokens.mdx

Color Palette

Token CategoryPurpose
BrandPrimary green (#33AA40), secondary, accent
BackgroundSurface (#263946), card, elevated, overlay
NeutralText (#e4e4e7), borders (#435763), dividers, disabled states
SemanticSuccess (green), warning (amber), error (red), info (blue)

Typography

TokenValue
--font-family-baseNunito Sans, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, sans-serif
--font-family-monoJetBrains Mono, ui-monospace, SFMono-Regular, SF Mono, Menlo, Monaco, Consolas, monospace
Font sizes--font-size-xxs (12px) through --font-size-xxxl (48px)
Font loading: All @font-face declarations in equa-web/src/styles/global.ts include font-display: swap to prevent Flash of Invisible Text (FOIT). The 6 NunitoSans variants (Regular, SemiBold, Black, Bold, ExtraBold, Light) load progressively; text renders immediately with the system fallback font and swaps to NunitoSans when available. New @font-face rules must always include font-display: swap.

Spacing

Scale from --spacing-xxs (4px) to --spacing-xxxl (50px), used for padding, margins, and gaps.

Border Radius

TokenValueUsage
--radius-sm6pxSmall elements (chips, badges)
--radius-md8pxDefault (buttons, inputs, cards)
--radius-lg12pxLarger containers (modals)
--radius-xl16pxExtra-large containers
--radius-full9999pxPills and circles

Shadows

Base shadows use rgba(0, 0, 0, 0.2) opacity. Gateway extends with --shadow-glow and --card-highlight for dark-mode depth effects.

Themes

ThemeSystemsDescription
Equa (Dark)Gateway, Storybook, equa-webDefault dark teal/navy palette with green accent
LightGateway, Storybook, equa-webWhite/gray palette with green accent
MidnightStorybook, equa-web onlyDarker navy palette (not in gateway)
The token system provides dark and light themes. Midnight is an equa-web consumer feature, not needed in the gateway admin tool. Theme switching in equa-web: ThemeProvider in equa-web/src/app/app.tsx, persisted via cookies. Theme switching in gateway: [data-theme="light"] CSS override block, with system preference detection.

Integration Pattern

In equa-web

Components are re-exported via equa-web/src/shared/components/ for local aliasing:
import { EquaButton } from '@components/EquaButton';
The webpack alias @components maps to src/shared/components/.

In Storybook

cd ~/Documents/repos/equa-patternlib-nextjs
npm run storybook
# Opens at http://localhost:6006

Storybook Configuration

Source: equa-patternlib-nextjs/stories/Configure.mdx Covers: styling setup, context providers, asset loading, and addon configuration.

Gateway-Aligned Components

In addition to the core patternlib components, 10 gateway-aligned components bridge the gateway Lit UI and the React Storybook:
ComponentStoryGateway CSS MatchStatus
ChatBubbleEquaChatBubble.chat-bubble, .chat-lineShared
CodeBlockEquaCodeBlock.code-blockShared
LogEntryEquaLogEntry.log-row, .log-levelShared
KeyValueRowEquaKeyValueRow.config-diff__itemShared
FormLayoutEquaFormLayout.field, .cfg-input, .cfg-toggleShared
ConfigSectionEquaConfigSection.config-section-card, .config-section-heroShared
ToolCardEquaToolCard.chat-tool-cardShared
ChatComposeEquaChatCompose.chat-composeShared
ExecApprovalEquaExecApproval.exec-approval-card, .exec-approval-overlayShared
ConfigSearchEquaConfigSearch.config-searchShared

Gateway-Internal Patterns (Not in Storybook)

These 4 patterns remain gateway-only due to low cross-product reuse:
PatternGateway CSSRationale
Chat Split Container.chat-split-containerTightly coupled to Lit resize observer
Config Diff.config-diffSpecific to gateway config key/value changes
Compaction Indicator.compaction-indicatorSingle-use AI context compaction animation
QR Code Display.qr-wrapTrivial dashed-border wrapper

Adding New Components

  1. Create the component in equa-patternlib-nextjs/src/components/
  2. Create a story file in stories/EquaComponentName.stories.tsx
  3. Export from the package index
  4. Install updated package in equa-web via yarn upgrade equa-patternlib
  5. Re-export in equa-web/src/shared/components/ if using the alias pattern